summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2019-02-22 20:29:46 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2019-02-22 20:29:46 +0100
commit7b271baae19db1528fbe6621bdf50af89a5a336b (patch)
tree4fc24a8f2be20aa90e90f6e1bcb62d69f4946235
parent67b9965fe473d18f13ed4c40f1e4e008eb870322 (diff)
downloadcontext-7b271baae19db1528fbe6621bdf50af89a5a336b.tar.gz
2019-02-22 19:43:00
-rw-r--r--context/data/scite/context/documents/scite-context-readme.pdfbin212702 -> 212528 bytes
-rw-r--r--context/data/scite/context/documents/scite-context-readme.tex160
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-context.lua4
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-interfaces.lua16
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-metafun.lua4
-rw-r--r--context/data/scite/context/lexers/data/scite-context-data-tex.lua6
-rw-r--r--context/data/scite/context/lexers/scite-context-lexer-json.lua100
-rw-r--r--context/data/scite/context/lexers/scite-context-lexer-mps.lua11
-rw-r--r--context/data/scite/context/lexers/scite-context-lexer-pdf.lua24
-rw-r--r--context/data/scite/context/lexers/scite-context-lexer-tex.lua2
-rw-r--r--context/data/scite/context/lexers/scite-context-lexer.lua417
-rw-r--r--context/data/scite/context/scite-context-data-context.properties385
-rw-r--r--context/data/scite/context/scite-context-data-interfaces.properties2881
-rw-r--r--context/data/scite/context/scite-context-data-metafun.properties93
-rw-r--r--context/data/scite/context/scite-context-data-tex.properties107
-rw-r--r--context/data/scite/context/scite-context-external.properties5
-rw-r--r--context/data/scite/context/scite-context.properties46
-rw-r--r--context/data/scite/context/scite-ctx-bidi.lua2
-rw-r--r--context/data/scite/context/scite-ctx-context.properties50
-rw-r--r--context/data/scite/context/scite-ctx-example.properties24
-rw-r--r--context/data/scite/context/scite-ctx-templates.lua31
-rw-r--r--context/data/scite/context/scite-ctx.lua249
-rw-r--r--context/data/scite/context/scite-ctx.properties22
-rw-r--r--context/data/scite/context/scite-pragma.properties6
-rw-r--r--context/data/textadept/context/data/scite-context-data-bidi.lua10357
-rw-r--r--context/data/textadept/context/data/scite-context-data-context.lua4
-rw-r--r--context/data/textadept/context/data/scite-context-data-interfaces.lua16
-rw-r--r--context/data/textadept/context/data/scite-context-data-metafun.lua4
-rw-r--r--context/data/textadept/context/data/scite-context-data-tex.lua6
-rw-r--r--context/data/textadept/context/init.lua76
-rw-r--r--context/data/textadept/context/lexers/lexer.lua2664
-rw-r--r--context/data/textadept/context/lexers/scite-context-lexer-bnf.lua99
-rw-r--r--context/data/textadept/context/lexers/scite-context-lexer-json.lua100
-rw-r--r--context/data/textadept/context/lexers/scite-context-lexer-mps.lua11
-rw-r--r--context/data/textadept/context/lexers/scite-context-lexer-pdf.lua24
-rw-r--r--context/data/textadept/context/lexers/scite-context-lexer-tex.lua34
-rw-r--r--context/data/textadept/context/lexers/scite-context-lexer.lua405
-rw-r--r--context/data/textadept/context/lexers/text.lua35
-rw-r--r--context/data/textadept/context/modules/textadept-context-files.lua16
-rw-r--r--context/data/textadept/context/modules/textadept-context-settings.lua44
-rw-r--r--doc/context/documents/general/manuals/bidi.pdfbin136420 -> 136679 bytes
-rw-r--r--doc/context/documents/general/manuals/graphics.pdfbin0 -> 245028 bytes
-rw-r--r--doc/context/documents/general/manuals/interaction.pdfbin0 -> 316342 bytes
-rw-r--r--doc/context/documents/general/manuals/luatex.pdfbin1172923 -> 1518264 bytes
-rw-r--r--doc/context/documents/general/manuals/musings.pdfbin0 -> 5761926 bytes
-rw-r--r--doc/context/documents/general/manuals/nodes.pdfbin349282 -> 346558 bytes
-rw-r--r--doc/context/documents/general/manuals/onandon.pdfbin2920276 -> 6602776 bytes
-rw-r--r--doc/context/documents/general/manuals/rules-mkiv.pdfbin155750 -> 187549 bytes
-rw-r--r--doc/context/documents/general/manuals/texit.pdfbin0 -> 163390 bytes
-rw-r--r--doc/context/documents/general/manuals/tiptrick.pdfbin47528 -> 47908 bytes
-rw-r--r--doc/context/documents/general/manuals/tools-mkiv.pdfbin358708 -> 357263 bytes
-rw-r--r--doc/context/documents/general/manuals/xml-mkiv.pdfbin1353423 -> 1008282 bytes
-rw-r--r--doc/context/documents/general/manuals/xtables-mkiv.pdfbin154883 -> 157802 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-cs.pdfbin844437 -> 858631 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-de.pdfbin842070 -> 859030 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-en.pdfbin846220 -> 865671 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-fr.pdfbin840822 -> 857355 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-it.pdfbin843093 -> 862588 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-cs.pdfbin359482 -> 348597 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-de.pdfbin441554 -> 433010 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-en.pdfbin356210 -> 346384 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-fr.pdfbin359600 -> 349176 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-it.pdfbin358138 -> 347797 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-nl.pdfbin356957 -> 347138 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-mapping-ro.pdfbin610343 -> 510503 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-nl.pdfbin835674 -> 852315 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-ro.pdfbin840784 -> 856589 bytes
-rw-r--r--doc/context/examples/calculator/calculator.pdfbin0 -> 145209 bytes
-rw-r--r--doc/context/examples/calculator/calculator.tex1871
-rw-r--r--doc/context/examples/clock/clock.pdfbin0 -> 65731 bytes
-rw-r--r--doc/context/examples/clock/clock.tex156
-rw-r--r--doc/context/presentations/bachotex/2005/bachotex-2005-fonts.tex1
-rw-r--r--doc/context/presentations/bachotex/2005/bachotex-2005-hyphenation.tex1
-rw-r--r--doc/context/presentations/bachotex/2009/bachotex-2009-luatex.tex1
-rw-r--r--doc/context/presentations/bachotex/2009/bachotex-2009-math.tex1
-rw-r--r--doc/context/presentations/bachotex/2009/bachotex-2009-opentype.tex1
-rw-r--r--doc/context/presentations/bachotex/2011/bachotex-2011-ebook.tex1
-rw-r--r--doc/context/presentations/bachotex/2011/bachotex-2011-math.tex1
-rw-r--r--doc/context/presentations/bachotex/2011/bachotex-2011-metapost.tex1
-rw-r--r--doc/context/presentations/bachotex/2012/bachotex-2012-context.tex1
-rw-r--r--doc/context/presentations/bachotex/2012/bachotex-2012-future.tex1
-rw-r--r--doc/context/presentations/bachotex/2014/bachotex-2014-luatex.tex1
-rw-r--r--doc/context/presentations/bachotex/2014/bachotex-2014-metapost.tex1
-rw-r--r--doc/context/presentations/bachotex/2018/bachotex-2018-fonteffects.pdfbin0 -> 269685 bytes
-rw-r--r--doc/context/presentations/bachotex/2018/bachotex-2018-fonteffects.tex912
-rw-r--r--doc/context/presentations/bachotex/2018/bachotex-2018-mp.pdfbin0 -> 422585 bytes
-rw-r--r--doc/context/presentations/bachotex/2018/bachotex-2018-mp.tex1856
-rw-r--r--doc/context/presentations/context/2007/context-2007-luatex.tex1
-rw-r--r--doc/context/presentations/context/2007/context-2007-mkiv.tex1
-rw-r--r--doc/context/presentations/context/2010/context-2010-just-in-time-1.tex1
-rw-r--r--doc/context/presentations/context/2010/context-2010-just-in-time-2.tex1
-rw-r--r--doc/context/presentations/context/2010/context-2010-requirements.tex1
-rw-r--r--doc/context/presentations/context/2010/context-2010-structure-matters.tex1
-rw-r--r--doc/context/presentations/context/2010/context-2010-workflows.tex1
-rw-r--r--doc/context/presentations/examples/present-steps-001.pdfbin0 -> 12778 bytes
-rw-r--r--doc/context/presentations/examples/present-steps-001.tex114
-rw-r--r--doc/context/presentations/tug/2001/tug-2001-ideas.pdfbin0 -> 659331 bytes
-rw-r--r--doc/context/presentations/tug/2001/tug-2001-ideas.tex445
-rw-r--r--doc/context/presentations/tug/2007/tug-2007-fonts.pdfbin0 -> 120377 bytes
-rw-r--r--doc/context/scripts/mkii/ctxtools.man2
-rw-r--r--doc/context/scripts/mkii/imgtopdf.man2
-rw-r--r--doc/context/scripts/mkii/mptopdf.man2
-rw-r--r--doc/context/scripts/mkii/pdftools.man2
-rw-r--r--doc/context/scripts/mkii/pstopdf.man2
-rw-r--r--doc/context/scripts/mkii/rlxtools.man2
-rw-r--r--doc/context/scripts/mkii/texexec.man2
-rw-r--r--doc/context/scripts/mkii/texmfstart.html4
-rw-r--r--doc/context/scripts/mkii/texmfstart.man10
-rw-r--r--doc/context/scripts/mkii/texmfstart.xml4
-rw-r--r--doc/context/scripts/mkii/textools.man2
-rw-r--r--doc/context/scripts/mkii/texutil.man2
-rw-r--r--doc/context/scripts/mkii/tmftools.man2
-rw-r--r--doc/context/scripts/mkii/xmltools.man2
-rw-r--r--doc/context/scripts/mkiv/context.html2
-rw-r--r--doc/context/scripts/mkiv/context.man8
-rw-r--r--doc/context/scripts/mkiv/context.xml6
-rw-r--r--doc/context/scripts/mkiv/luatools.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-babel.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-base.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-bibtex.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-cache.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-chars.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-check.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-colors.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-context.html2
-rw-r--r--doc/context/scripts/mkiv/mtx-context.man8
-rw-r--r--doc/context/scripts/mkiv/mtx-context.xml6
-rw-r--r--doc/context/scripts/mkiv/mtx-dvi.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-epub.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-evohome.html1
-rw-r--r--doc/context/scripts/mkiv/mtx-evohome.man5
-rw-r--r--doc/context/scripts/mkiv/mtx-evohome.xml1
-rw-r--r--doc/context/scripts/mkiv/mtx-fcd.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-flac.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-fonts.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-grep.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-interface.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-metapost.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-metatex.html49
-rw-r--r--doc/context/scripts/mkiv/mtx-metatex.man30
-rw-r--r--doc/context/scripts/mkiv/mtx-metatex.xml16
-rw-r--r--doc/context/scripts/mkiv/mtx-modules.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-package.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-patterns.html61
-rw-r--r--doc/context/scripts/mkiv/mtx-patterns.man48
-rw-r--r--doc/context/scripts/mkiv/mtx-patterns.xml34
-rw-r--r--doc/context/scripts/mkiv/mtx-pdf.html3
-rw-r--r--doc/context/scripts/mkiv/mtx-pdf.man8
-rw-r--r--doc/context/scripts/mkiv/mtx-pdf.xml7
-rw-r--r--doc/context/scripts/mkiv/mtx-plain.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-profile.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-rsync.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-scite.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-server.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-texworks.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-timing.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-tools.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-unicode.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-unzip.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-update.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-watch.man2
-rw-r--r--doc/context/scripts/mkiv/mtx-youless.html4
-rw-r--r--doc/context/scripts/mkiv/mtx-youless.man2
-rw-r--r--doc/context/scripts/mkiv/mtxrun.html4
-rw-r--r--doc/context/scripts/mkiv/mtxrun.man10
-rw-r--r--doc/context/scripts/mkiv/mtxrun.xml4
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-demo-rule.lua47
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-extensions.tex13
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-features.tex2
-rw-r--r--doc/context/sources/general/fonts/fonts/fonts-tricks.tex2
-rw-r--r--doc/context/sources/general/manuals/about/about-metafun.tex12
-rw-r--r--doc/context/sources/general/manuals/cld/cld-moreonfunctions.tex39
-rw-r--r--doc/context/sources/general/manuals/graphics/graphics.tex415
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-actions.tex204
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-annotations.tex106
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-attachments.tex174
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-bookmarks.tex75
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-buttons.tex98
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-comments.tex194
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-contents.tex11
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-enabling.tex117
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-hyperlinks.tex32
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-importing.tex73
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-introduction.tex58
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-javascript.tex136
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-menus.tex12
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-progress.tex11
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-structure.tex76
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-style.tex59
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-tagging.tex26
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-titlepage.tex47
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-transitions.tex64
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction-widgets.tex977
-rw-r--r--doc/context/sources/general/manuals/interaction/interaction.tex34
-rw-r--r--doc/context/sources/general/manuals/languages/languages-numbering.tex4
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-contents.tex1
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-enhancements.tex1052
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-firstpage.tex32
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-fonts.tex497
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-introduction.tex130
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-languages.tex793
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-logos.tex2
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-lua.tex508
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-math.tex1628
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-modifications.tex668
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-nodes.tex1768
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-preamble.tex110
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-registers.tex47
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-statistics.tex17
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-style.tex204
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex-titlepage.tex57
-rw-r--r--doc/context/sources/general/manuals/luatex/luatex.tex37
-rw-r--r--doc/context/sources/general/manuals/math/math-input.tex30
-rw-r--r--doc/context/sources/general/manuals/metafun/metafun-lua.tex581
-rw-r--r--doc/context/sources/general/manuals/musings/musings-children.tex1253
-rw-r--r--doc/context/sources/general/manuals/musings/musings-contents.tex7
-rw-r--r--doc/context/sources/general/manuals/musings/musings-introduction.tex31
-rw-r--r--doc/context/sources/general/manuals/musings/musings-perception.tex180
-rw-r--r--doc/context/sources/general/manuals/musings/musings-roadmap.tex372
-rw-r--r--doc/context/sources/general/manuals/musings/musings-stability.tex388
-rw-r--r--doc/context/sources/general/manuals/musings/musings-staygo.tex461
-rw-r--r--doc/context/sources/general/manuals/musings/musings-style.tex92
-rw-r--r--doc/context/sources/general/manuals/musings/musings-titlepage.tex46
-rw-r--r--doc/context/sources/general/manuals/musings/musings-whytex.tex326
-rw-r--r--doc/context/sources/general/manuals/musings/musings.tex21
-rw-r--r--doc/context/sources/general/manuals/nodes/nodes.tex102
-rw-r--r--doc/context/sources/general/manuals/notnow/notnow-sidefloats.tex2
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-110.tex137
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-53.tex288
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-emoji.tex16
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-execute.tex396
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-expansion.tex307
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-fences.tex499
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-media.tex220
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-modern.tex1284
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-performance.tex523
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-runtoks.tex531
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon-variable.tex328
-rw-r--r--doc/context/sources/general/manuals/onandon/onandon.tex22
-rw-r--r--doc/context/sources/general/manuals/rules/rules-mkiv.tex232
-rw-r--r--doc/context/sources/general/manuals/texit/texit-conditions.tex108
-rw-r--r--doc/context/sources/general/manuals/texit/texit-contents.tex9
-rw-r--r--doc/context/sources/general/manuals/texit/texit-introduction.tex24
-rw-r--r--doc/context/sources/general/manuals/texit/texit-leaders.tex247
-rw-r--r--doc/context/sources/general/manuals/texit/texit-lookahead.tex387
-rw-r--r--doc/context/sources/general/manuals/texit/texit-style.tex52
-rw-r--r--doc/context/sources/general/manuals/texit/texit-titlepage.tex40
-rw-r--r--doc/context/sources/general/manuals/texit/texit.tex19
-rw-r--r--doc/context/sources/general/manuals/tools/tools-mkiv.tex921
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-commands.tex893
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-contents.tex12
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-converter.tex300
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-examples.tex948
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-expressions.tex645
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-filtering.tex262
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-introduction.tex42
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-lookups.tex314
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-lpath.tex207
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-style.tex155
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-titlepage.tex47
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv-tricks.tex814
-rw-r--r--doc/context/sources/general/manuals/xml/xml-mkiv.tex4365
-rw-r--r--doc/context/sources/general/manuals/xtables/xtables-mkiv.tex95
-rw-r--r--metapost/context/base/mpii/mp-text.mpii3
-rw-r--r--metapost/context/base/mpiv/metafun.mpiv1
-rw-r--r--metapost/context/base/mpiv/minifun.mpiv45
-rw-r--r--metapost/context/base/mpiv/mp-asnc.mpiv216
-rw-r--r--metapost/context/base/mpiv/mp-bare.mpiv92
-rw-r--r--metapost/context/base/mpiv/mp-base.mpiv105
-rw-r--r--metapost/context/base/mpiv/mp-blob.mpiv112
-rw-r--r--metapost/context/base/mpiv/mp-grap.mpiv28
-rw-r--r--metapost/context/base/mpiv/mp-grph.mpiv155
-rw-r--r--metapost/context/base/mpiv/mp-luas.mpiv146
-rw-r--r--metapost/context/base/mpiv/mp-mlib.mpiv485
-rw-r--r--metapost/context/base/mpiv/mp-node.mpiv8
-rw-r--r--metapost/context/base/mpiv/mp-page.mpiv5
-rw-r--r--metapost/context/base/mpiv/mp-tool.mpiv68
-rw-r--r--metapost/context/base/mpiv/mp-tres.mpiv63
-rw-r--r--scripts/context/lua/mtx-colors.lua9
-rw-r--r--scripts/context/lua/mtx-context.lua158
-rw-r--r--scripts/context/lua/mtx-context.xml6
-rw-r--r--scripts/context/lua/mtx-evohome.lua1
-rw-r--r--scripts/context/lua/mtx-fonts.lua2
-rw-r--r--scripts/context/lua/mtx-metatex.lua80
-rw-r--r--scripts/context/lua/mtx-package.lua21
-rw-r--r--scripts/context/lua/mtx-patterns.lua1
-rw-r--r--scripts/context/lua/mtx-pdf.lua288
-rw-r--r--scripts/context/lua/mtx-server.lua2
-rw-r--r--scripts/context/lua/mtx-tools.lua8
-rw-r--r--scripts/context/lua/mtx-unicode.lua49
-rw-r--r--scripts/context/lua/mtx-update.lua2
-rw-r--r--scripts/context/lua/mtx-youless.lua2
-rw-r--r--scripts/context/lua/mtxlibs.lua15
-rw-r--r--scripts/context/lua/mtxrun.lua34238
-rw-r--r--scripts/context/perl/mptopdf.pl24
-rw-r--r--scripts/context/stubs/install/first-setup.sh22
-rw-r--r--scripts/context/stubs/mswin/metatex.exebin4608 -> 0 bytes
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua34238
-rw-r--r--scripts/context/stubs/setup/setuptex18
-rw-r--r--scripts/context/stubs/setup/setuptex.csh13
-rw-r--r--scripts/context/stubs/unix/metatex2
-rw-r--r--scripts/context/stubs/unix/mtxrun34238
-rw-r--r--scripts/context/stubs/win64/metatex.exebin15360 -> 0 bytes
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua34238
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/core-sys.mkii12
-rw-r--r--tex/context/base/mkii/enco-agr.mkii3
-rw-r--r--tex/context/base/mkii/enco-def.mkii1
-rw-r--r--tex/context/base/mkii/enco-uc.mkii2
-rw-r--r--tex/context/base/mkii/mult-cs.mkii10
-rw-r--r--tex/context/base/mkii/mult-de.mkii8
-rw-r--r--tex/context/base/mkii/mult-en.mkii7
-rw-r--r--tex/context/base/mkii/mult-fr.mkii7
-rw-r--r--tex/context/base/mkii/mult-it.mkii8
-rw-r--r--tex/context/base/mkii/mult-nl.mkii12
-rw-r--r--tex/context/base/mkii/mult-pe.mkii7
-rw-r--r--tex/context/base/mkii/mult-ro.mkii8
-rw-r--r--tex/context/base/mkii/strc-reg.mkii4
-rw-r--r--tex/context/base/mkii/unic-003.mkii4
-rw-r--r--tex/context/base/mkii/xetx-chr.mkii1
-rw-r--r--tex/context/base/mkiv/anch-bck.mkvi24
-rw-r--r--tex/context/base/mkiv/anch-pgr.lua140
-rw-r--r--tex/context/base/mkiv/anch-pgr.mkiv14
-rw-r--r--tex/context/base/mkiv/anch-pos.lua166
-rw-r--r--tex/context/base/mkiv/anch-pos.mkiv18
-rw-r--r--tex/context/base/mkiv/anch-snc.lua271
-rw-r--r--tex/context/base/mkiv/anch-snc.mkiv272
-rw-r--r--tex/context/base/mkiv/anch-tab.mkiv17
-rw-r--r--tex/context/base/mkiv/attr-col.lua48
-rw-r--r--tex/context/base/mkiv/attr-ini.lua5
-rw-r--r--tex/context/base/mkiv/attr-ini.mkiv36
-rw-r--r--tex/context/base/mkiv/back-exp.lua936
-rw-r--r--tex/context/base/mkiv/back-exp.mkiv28
-rw-r--r--tex/context/base/mkiv/back-ini.lua221
-rw-r--r--tex/context/base/mkiv/back-ini.mkiv116
-rw-r--r--tex/context/base/mkiv/back-pdf.lua301
-rw-r--r--tex/context/base/mkiv/back-pdf.mkiv188
-rw-r--r--tex/context/base/mkiv/back-pdp.lua453
-rw-r--r--tex/context/base/mkiv/back-res.lua44
-rw-r--r--tex/context/base/mkiv/back-swf.mkiv101
-rw-r--r--tex/context/base/mkiv/bibl-bib.mkiv6
-rw-r--r--tex/context/base/mkiv/bibl-tra.mkiv2
-rw-r--r--tex/context/base/mkiv/buff-imp-default.mkiv10
-rw-r--r--tex/context/base/mkiv/buff-ini.lua25
-rw-r--r--tex/context/base/mkiv/buff-ini.mkiv46
-rw-r--r--tex/context/base/mkiv/buff-ver.lua23
-rw-r--r--tex/context/base/mkiv/buff-ver.mkiv19
-rw-r--r--tex/context/base/mkiv/catc-ini.mkiv161
-rw-r--r--tex/context/base/mkiv/char-act.mkiv47
-rw-r--r--tex/context/base/mkiv/char-def.lua5239
-rw-r--r--tex/context/base/mkiv/char-emj.lua2566
-rw-r--r--tex/context/base/mkiv/char-ini.lua60
-rw-r--r--tex/context/base/mkiv/char-ini.mkiv16
-rw-r--r--tex/context/base/mkiv/char-tex.lua33
-rw-r--r--tex/context/base/mkiv/char-utf.lua13
-rw-r--r--tex/context/base/mkiv/chem-str.lua4
-rw-r--r--tex/context/base/mkiv/chem-str.mkiv12
-rw-r--r--tex/context/base/mkiv/cldf-bas.lua155
-rw-r--r--tex/context/base/mkiv/cldf-ini.lua658
-rw-r--r--tex/context/base/mkiv/cldf-ini.mkiv8
-rw-r--r--tex/context/base/mkiv/cldf-int.lua5
-rw-r--r--tex/context/base/mkiv/cldf-scn.lua7
-rw-r--r--tex/context/base/mkiv/cldf-ver.lua87
-rw-r--r--tex/context/base/mkiv/colo-imp-crayola.mkiv10
-rw-r--r--tex/context/base/mkiv/colo-imp-svg.mkiv164
-rw-r--r--tex/context/base/mkiv/colo-ini.lua66
-rw-r--r--tex/context/base/mkiv/colo-ini.mkiv19
-rw-r--r--tex/context/base/mkiv/colo-run.lua2
-rw-r--r--tex/context/base/mkiv/cont-log.mkiv40
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv18
-rw-r--r--tex/context/base/mkiv/cont-run.lua48
-rw-r--r--tex/context/base/mkiv/cont-run.mkiv20
-rw-r--r--tex/context/base/mkiv/context.mkiv62
-rw-r--r--tex/context/base/mkiv/core-con.lua393
-rw-r--r--tex/context/base/mkiv/core-con.mkiv212
-rw-r--r--tex/context/base/mkiv/core-dat.lua62
-rw-r--r--tex/context/base/mkiv/core-dat.mkiv33
-rw-r--r--tex/context/base/mkiv/core-def.mkiv2
-rw-r--r--tex/context/base/mkiv/core-env.lua67
-rw-r--r--tex/context/base/mkiv/core-env.mkiv46
-rw-r--r--tex/context/base/mkiv/core-lmt.lua34
-rw-r--r--tex/context/base/mkiv/core-lmt.mkiv32
-rw-r--r--tex/context/base/mkiv/core-sys.lua8
-rw-r--r--tex/context/base/mkiv/core-two.lua93
-rw-r--r--tex/context/base/mkiv/core-two.mkiv8
-rw-r--r--tex/context/base/mkiv/core-uti.lua23
-rw-r--r--tex/context/base/mkiv/data-aux.lua2
-rw-r--r--tex/context/base/mkiv/data-pre.lua26
-rw-r--r--tex/context/base/mkiv/data-res.lua6
-rw-r--r--tex/context/base/mkiv/data-tex.lua8
-rw-r--r--tex/context/base/mkiv/data-tre.lua5
-rw-r--r--tex/context/base/mkiv/data-use.lua6
-rw-r--r--tex/context/base/mkiv/data-zip.lua10
-rw-r--r--tex/context/base/mkiv/driv-ini.lua194
-rw-r--r--tex/context/base/mkiv/driv-ini.mkiv25
-rw-r--r--tex/context/base/mkiv/export-example.css37
-rw-r--r--tex/context/base/mkiv/file-job.lua3
-rw-r--r--tex/context/base/mkiv/file-job.mkvi19
-rw-r--r--tex/context/base/mkiv/file-mod.mkvi32
-rw-r--r--tex/context/base/mkiv/font-aux.lua1
-rw-r--r--tex/context/base/mkiv/font-cff.lua554
-rw-r--r--tex/context/base/mkiv/font-cft.lua10
-rw-r--r--tex/context/base/mkiv/font-chk.lua94
-rw-r--r--tex/context/base/mkiv/font-col.lua191
-rw-r--r--tex/context/base/mkiv/font-col.mkvi5
-rw-r--r--tex/context/base/mkiv/font-con.lua179
-rw-r--r--tex/context/base/mkiv/font-ctx.lua585
-rw-r--r--tex/context/base/mkiv/font-def.lua120
-rw-r--r--tex/context/base/mkiv/font-dsp.lua736
-rw-r--r--tex/context/base/mkiv/font-emp.mkvi22
-rw-r--r--tex/context/base/mkiv/font-enh.lua16
-rw-r--r--tex/context/base/mkiv/font-ext.lua1856
-rw-r--r--tex/context/base/mkiv/font-fbk.lua272
-rw-r--r--tex/context/base/mkiv/font-fea.mkvi10
-rw-r--r--tex/context/base/mkiv/font-fil.mkvi33
-rw-r--r--tex/context/base/mkiv/font-gds.mkvi2
-rw-r--r--tex/context/base/mkiv/font-hsh.lua101
-rw-r--r--tex/context/base/mkiv/font-imp-dimensions.lua115
-rw-r--r--tex/context/base/mkiv/font-imp-effects.lua414
-rw-r--r--tex/context/base/mkiv/font-imp-italics.lua147
-rw-r--r--tex/context/base/mkiv/font-imp-ligatures.lua136
-rw-r--r--tex/context/base/mkiv/font-imp-math.lua81
-rw-r--r--tex/context/base/mkiv/font-imp-notused.lua168
-rw-r--r--tex/context/base/mkiv/font-imp-properties.lua130
-rw-r--r--tex/context/base/mkiv/font-imp-quality.lua527
-rw-r--r--tex/context/base/mkiv/font-imp-reorder.lua174
-rw-r--r--tex/context/base/mkiv/font-imp-tex.lua144
-rw-r--r--tex/context/base/mkiv/font-imp-tracing.lua281
-rw-r--r--tex/context/base/mkiv/font-imp-unicode.lua82
-rw-r--r--tex/context/base/mkiv/font-ini.lua47
-rw-r--r--tex/context/base/mkiv/font-ini.mkvi99
-rw-r--r--tex/context/base/mkiv/font-lib.mkvi43
-rw-r--r--tex/context/base/mkiv/font-map.lua160
-rw-r--r--tex/context/base/mkiv/font-mat.mkvi30
-rw-r--r--tex/context/base/mkiv/font-mis.lua14
-rw-r--r--tex/context/base/mkiv/font-mps.lua131
-rw-r--r--tex/context/base/mkiv/font-nod.lua187
-rw-r--r--tex/context/base/mkiv/font-ocl.lua349
-rw-r--r--tex/context/base/mkiv/font-one.lua15
-rw-r--r--tex/context/base/mkiv/font-onr.lua79
-rw-r--r--tex/context/base/mkiv/font-osd.lua121
-rw-r--r--tex/context/base/mkiv/font-ota.lua10
-rw-r--r--tex/context/base/mkiv/font-otc.lua322
-rw-r--r--tex/context/base/mkiv/font-otj.lua110
-rw-r--r--tex/context/base/mkiv/font-otl.lua41
-rw-r--r--tex/context/base/mkiv/font-oto.lua69
-rw-r--r--tex/context/base/mkiv/font-otr.lua275
-rw-r--r--tex/context/base/mkiv/font-ots.lua500
-rw-r--r--tex/context/base/mkiv/font-ott.lua50
-rw-r--r--tex/context/base/mkiv/font-oup.lua644
-rw-r--r--tex/context/base/mkiv/font-pre.mkiv49
-rw-r--r--tex/context/base/mkiv/font-prv.lua78
-rw-r--r--tex/context/base/mkiv/font-sel.lua149
-rw-r--r--tex/context/base/mkiv/font-set.mkvi6
-rw-r--r--tex/context/base/mkiv/font-shp.lua128
-rw-r--r--tex/context/base/mkiv/font-sol.lua128
-rw-r--r--tex/context/base/mkiv/font-sty.mkvi25
-rw-r--r--tex/context/base/mkiv/font-sym.mkvi2
-rw-r--r--tex/context/base/mkiv/font-syn.lua5
-rw-r--r--tex/context/base/mkiv/font-tfm.lua448
-rw-r--r--tex/context/base/mkiv/font-tra.mkiv2
-rw-r--r--tex/context/base/mkiv/font-ttf.lua465
-rw-r--r--tex/context/base/mkiv/font-var.mkvi2
-rw-r--r--tex/context/base/mkiv/font-vfc.lua123
-rw-r--r--tex/context/base/mkiv/font-vir.lua23
-rw-r--r--tex/context/base/mkiv/font-web.lua20
-rw-r--r--tex/context/base/mkiv/good-ctx.lua84
-rw-r--r--tex/context/base/mkiv/grph-epd.lua20
-rw-r--r--tex/context/base/mkiv/grph-inc.lua286
-rw-r--r--tex/context/base/mkiv/grph-inc.mkiv101
-rw-r--r--tex/context/base/mkiv/grph-mem.lua164
-rw-r--r--tex/context/base/mkiv/grph-pat.lua4
-rw-r--r--tex/context/base/mkiv/grph-rul.lua149
-rw-r--r--tex/context/base/mkiv/grph-swf.lua3
-rw-r--r--tex/context/base/mkiv/grph-trf.mkiv39
-rw-r--r--tex/context/base/mkiv/java-imp-example.mkiv (renamed from tex/context/base/mkiv/java-imp-exa.mkiv)5
-rw-r--r--tex/context/base/mkiv/java-imp-fields.mkiv (renamed from tex/context/base/mkiv/java-imp-fld.mkiv)47
-rw-r--r--tex/context/base/mkiv/java-imp-highlight.mkiv (renamed from tex/context/base/mkiv/java-imp-rhh.mkiv)2
-rw-r--r--tex/context/base/mkiv/java-imp-print.mkiv (renamed from tex/context/base/mkiv/java-imp-fil.mkiv)4
-rw-r--r--tex/context/base/mkiv/java-imp-steps.mkiv (renamed from tex/context/base/mkiv/java-imp-stp.mkiv)2
-rw-r--r--tex/context/base/mkiv/java-imp-videoplayer.mkiv82
-rw-r--r--tex/context/base/mkiv/java-imp-vplayer.mkiv105
-rw-r--r--tex/context/base/mkiv/java-ini.lua8
-rw-r--r--tex/context/base/mkiv/java-ini.mkiv17
-rw-r--r--tex/context/base/mkiv/l-bit32.lua10
-rw-r--r--tex/context/base/mkiv/l-dir.lua82
-rw-r--r--tex/context/base/mkiv/l-file.lua38
-rw-r--r--tex/context/base/mkiv/l-lpeg.lua195
-rw-r--r--tex/context/base/mkiv/l-lua.lua40
-rw-r--r--tex/context/base/mkiv/l-macro-imp-optimize.lua29
-rw-r--r--tex/context/base/mkiv/l-macro.lua95
-rw-r--r--tex/context/base/mkiv/l-number.lua23
-rw-r--r--tex/context/base/mkiv/l-os.lua132
-rw-r--r--tex/context/base/mkiv/l-package.lua4
-rw-r--r--tex/context/base/mkiv/l-sandbox.lua3
-rw-r--r--tex/context/base/mkiv/l-sha.lua27
-rw-r--r--tex/context/base/mkiv/l-table.lua132
-rw-r--r--tex/context/base/mkiv/l-unicode.lua228
-rw-r--r--tex/context/base/mkiv/lang-def.lua9
-rw-r--r--tex/context/base/mkiv/lang-def.mkiv44
-rw-r--r--tex/context/base/mkiv/lang-dis.lua107
-rw-r--r--tex/context/base/mkiv/lang-exp.lua36
-rw-r--r--tex/context/base/mkiv/lang-hyp.lua68
-rw-r--r--tex/context/base/mkiv/lang-hyp.mkiv9
-rw-r--r--tex/context/base/mkiv/lang-ini.mkiv270
-rw-r--r--tex/context/base/mkiv/lang-lab.mkiv12
-rw-r--r--tex/context/base/mkiv/lang-mis.mkiv156
-rw-r--r--tex/context/base/mkiv/lang-rep.lua7
-rw-r--r--tex/context/base/mkiv/lang-spa.mkiv18
-rw-r--r--tex/context/base/mkiv/lang-txt.lua102
-rw-r--r--tex/context/base/mkiv/lang-url.lua22
-rw-r--r--tex/context/base/mkiv/lang-wrd.lua16
-rw-r--r--tex/context/base/mkiv/lpdf-ano.lua276
-rw-r--r--tex/context/base/mkiv/lpdf-aux.lua152
-rw-r--r--tex/context/base/mkiv/lpdf-col.lua47
-rw-r--r--tex/context/base/mkiv/lpdf-epa.lua783
-rw-r--r--tex/context/base/mkiv/lpdf-epd.lua518
-rw-r--r--tex/context/base/mkiv/lpdf-fld.lua180
-rw-r--r--tex/context/base/mkiv/lpdf-fmt.lua21
-rw-r--r--tex/context/base/mkiv/lpdf-fnt.lua202
-rw-r--r--tex/context/base/mkiv/lpdf-grp.lua72
-rw-r--r--tex/context/base/mkiv/lpdf-ini.lua1297
-rw-r--r--tex/context/base/mkiv/lpdf-mis.lua126
-rw-r--r--tex/context/base/mkiv/lpdf-nod.lua214
-rw-r--r--tex/context/base/mkiv/lpdf-pda.xml85
-rw-r--r--tex/context/base/mkiv/lpdf-pde.lua1157
-rw-r--r--tex/context/base/mkiv/lpdf-pdx.xml1
-rw-r--r--tex/context/base/mkiv/lpdf-pua.xml41
-rw-r--r--tex/context/base/mkiv/lpdf-ren.lua12
-rw-r--r--tex/context/base/mkiv/lpdf-res.lua26
-rw-r--r--tex/context/base/mkiv/lpdf-swf.lua46
-rw-r--r--tex/context/base/mkiv/lpdf-tag.lua244
-rw-r--r--tex/context/base/mkiv/lpdf-u3d.lua26
-rw-r--r--tex/context/base/mkiv/lpdf-wid.lua40
-rw-r--r--tex/context/base/mkiv/lpdf-xmp.lua75
-rw-r--r--tex/context/base/mkiv/luat-bas.mkiv2
-rw-r--r--tex/context/base/mkiv/luat-cbk.lua6
-rw-r--r--tex/context/base/mkiv/luat-cnf.lua4
-rw-r--r--tex/context/base/mkiv/luat-cod.lua64
-rw-r--r--tex/context/base/mkiv/luat-env.lua24
-rw-r--r--tex/context/base/mkiv/luat-fio.lua4
-rw-r--r--tex/context/base/mkiv/luat-fmt.lua14
-rw-r--r--tex/context/base/mkiv/luat-ini.lua16
-rw-r--r--tex/context/base/mkiv/luat-ini.mkiv127
-rw-r--r--tex/context/base/mkiv/luat-lib.mkiv16
-rw-r--r--tex/context/base/mkiv/luat-run.lua111
-rw-r--r--tex/context/base/mkiv/luat-soc.lua11
-rw-r--r--tex/context/base/mkiv/luat-soc.mkiv52
-rw-r--r--tex/context/base/mkiv/luat-sto.lua2
-rw-r--r--tex/context/base/mkiv/luat-usr.lua3
-rw-r--r--tex/context/base/mkiv/luat-usr.mkiv4
-rw-r--r--tex/context/base/mkiv/lxml-aux.lua25
-rw-r--r--tex/context/base/mkiv/lxml-css.lua137
-rw-r--r--tex/context/base/mkiv/lxml-inf.lua3
-rw-r--r--tex/context/base/mkiv/lxml-ini.mkiv21
-rw-r--r--tex/context/base/mkiv/lxml-lpt.lua276
-rw-r--r--tex/context/base/mkiv/lxml-tex.lua426
-rw-r--r--tex/context/base/mkiv/m-fonts-plugins.mkiv5
-rw-r--r--tex/context/base/mkiv/math-act.lua44
-rw-r--r--tex/context/base/mkiv/math-ali.mkiv29
-rw-r--r--tex/context/base/mkiv/math-arr.mkiv57
-rw-r--r--tex/context/base/mkiv/math-dim.lua3
-rw-r--r--tex/context/base/mkiv/math-dir.lua30
-rw-r--r--tex/context/base/mkiv/math-ext.lua27
-rw-r--r--tex/context/base/mkiv/math-fbk.lua201
-rw-r--r--tex/context/base/mkiv/math-fen.mkiv120
-rw-r--r--tex/context/base/mkiv/math-frc.lua4
-rw-r--r--tex/context/base/mkiv/math-frc.mkiv42
-rw-r--r--tex/context/base/mkiv/math-inc.lua87
-rw-r--r--tex/context/base/mkiv/math-inc.mkiv69
-rw-r--r--tex/context/base/mkiv/math-ini.lua9
-rw-r--r--tex/context/base/mkiv/math-ini.mkiv146
-rw-r--r--tex/context/base/mkiv/math-noa.lua742
-rw-r--r--tex/context/base/mkiv/math-pln.mkiv2
-rw-r--r--tex/context/base/mkiv/math-spa.lua37
-rw-r--r--tex/context/base/mkiv/math-stc.mkvi14
-rw-r--r--tex/context/base/mkiv/math-tag.lua437
-rw-r--r--tex/context/base/mkiv/math-vfu.lua344
-rw-r--r--tex/context/base/mkiv/meta-blb.lua322
-rw-r--r--tex/context/base/mkiv/meta-blb.mkiv56
-rw-r--r--tex/context/base/mkiv/meta-fnt.lua24
-rw-r--r--tex/context/base/mkiv/meta-imp-dum.mkiv4
-rw-r--r--tex/context/base/mkiv/meta-imp-mat.mkiv38
-rw-r--r--tex/context/base/mkiv/meta-imp-txt.mkiv76
-rw-r--r--tex/context/base/mkiv/meta-ini.lua8
-rw-r--r--tex/context/base/mkiv/meta-ini.mkiv57
-rw-r--r--tex/context/base/mkiv/meta-nod.lua81
-rw-r--r--tex/context/base/mkiv/meta-nod.mkiv31
-rw-r--r--tex/context/base/mkiv/meta-pdf.lua76
-rw-r--r--tex/context/base/mkiv/meta-pdh.mkiv24
-rw-r--r--tex/context/base/mkiv/meta-tex.lua6
-rw-r--r--tex/context/base/mkiv/metatex.tex30
-rw-r--r--tex/context/base/mkiv/mlib-ctx.lua87
-rw-r--r--tex/context/base/mkiv/mlib-int.lua191
-rw-r--r--tex/context/base/mkiv/mlib-lua.lua1175
-rw-r--r--tex/context/base/mkiv/mlib-pdf.lua598
-rw-r--r--tex/context/base/mkiv/mlib-pdf.mkiv30
-rw-r--r--tex/context/base/mkiv/mlib-pps.lua1151
-rw-r--r--tex/context/base/mkiv/mlib-pps.mkiv35
-rw-r--r--tex/context/base/mkiv/mlib-run.lua279
-rw-r--r--tex/context/base/mkiv/mtx-context-domotica.tex31
-rw-r--r--tex/context/base/mkiv/mtx-context-fonts.tex98
-rw-r--r--tex/context/base/mkiv/mtx-context-listing.tex4
-rw-r--r--tex/context/base/mkiv/mtx-context-xml.tex5
-rw-r--r--tex/context/base/mkiv/mult-aux.mkiv562
-rw-r--r--tex/context/base/mkiv/mult-def.lua33
-rw-r--r--tex/context/base/mkiv/mult-fun.lua34
-rw-r--r--tex/context/base/mkiv/mult-ini.lua16
-rw-r--r--tex/context/base/mkiv/mult-ini.mkiv15
-rw-r--r--tex/context/base/mkiv/mult-low.lua58
-rw-r--r--tex/context/base/mkiv/mult-prm.lua32
-rw-r--r--tex/context/base/mkiv/mult-prm.mkiv3
-rw-r--r--tex/context/base/mkiv/mult-sys.mkiv2
-rw-r--r--tex/context/base/mkiv/node-acc.lua72
-rw-r--r--tex/context/base/mkiv/node-aux.lua198
-rw-r--r--tex/context/base/mkiv/node-bck.lua378
-rw-r--r--tex/context/base/mkiv/node-bck.mkiv21
-rw-r--r--tex/context/base/mkiv/node-dir.lua359
-rw-r--r--tex/context/base/mkiv/node-fin.lua472
-rw-r--r--tex/context/base/mkiv/node-fin.mkiv4
-rw-r--r--tex/context/base/mkiv/node-fnt.lua545
-rw-r--r--tex/context/base/mkiv/node-ini.lua146
-rw-r--r--tex/context/base/mkiv/node-ini.mkiv4
-rw-r--r--tex/context/base/mkiv/node-ltp.lua3261
-rw-r--r--tex/context/base/mkiv/node-met.lua172
-rw-r--r--tex/context/base/mkiv/node-mig.lua6
-rw-r--r--tex/context/base/mkiv/node-nut.lua327
-rw-r--r--tex/context/base/mkiv/node-par.lua48
-rw-r--r--tex/context/base/mkiv/node-ppt.lua173
-rw-r--r--tex/context/base/mkiv/node-pro.lua137
-rw-r--r--tex/context/base/mkiv/node-ref.lua291
-rw-r--r--tex/context/base/mkiv/node-res.lua329
-rw-r--r--tex/context/base/mkiv/node-rul.lua374
-rw-r--r--tex/context/base/mkiv/node-rul.mkiv39
-rw-r--r--tex/context/base/mkiv/node-scn.lua31
-rw-r--r--tex/context/base/mkiv/node-ser.lua8
-rw-r--r--tex/context/base/mkiv/node-shp.lua86
-rw-r--r--tex/context/base/mkiv/node-syn.lua109
-rw-r--r--tex/context/base/mkiv/node-tex.lua45
-rw-r--r--tex/context/base/mkiv/node-tra.lua256
-rw-r--r--tex/context/base/mkiv/node-tsk.lua609
-rw-r--r--tex/context/base/mkiv/node-tst.lua10
-rw-r--r--tex/context/base/mkiv/pack-bar.mkiv6
-rw-r--r--tex/context/base/mkiv/pack-bck.mkvi48
-rw-r--r--tex/context/base/mkiv/pack-box.mkiv1
-rw-r--r--tex/context/base/mkiv/pack-com.mkiv18
-rw-r--r--tex/context/base/mkiv/pack-cut.mkiv78
-rw-r--r--tex/context/base/mkiv/pack-lyr.mkiv86
-rw-r--r--tex/context/base/mkiv/pack-mrl.mkiv83
-rw-r--r--tex/context/base/mkiv/pack-obj.lua43
-rw-r--r--tex/context/base/mkiv/pack-obj.mkiv14
-rw-r--r--tex/context/base/mkiv/pack-rul.lua159
-rw-r--r--tex/context/base/mkiv/pack-rul.mkiv190
-rw-r--r--tex/context/base/mkiv/page-bck.mkiv2
-rw-r--r--tex/context/base/mkiv/page-box.mkvi23
-rw-r--r--tex/context/base/mkiv/page-cst.lua161
-rw-r--r--tex/context/base/mkiv/page-cst.mkiv5
-rw-r--r--tex/context/base/mkiv/page-ffl.mkiv39
-rw-r--r--tex/context/base/mkiv/page-flt.mkiv10
-rw-r--r--tex/context/base/mkiv/page-imp.mkiv92
-rw-r--r--tex/context/base/mkiv/page-inf.mkiv8
-rw-r--r--tex/context/base/mkiv/page-ini.lua43
-rw-r--r--tex/context/base/mkiv/page-ini.mkiv7
-rw-r--r--tex/context/base/mkiv/page-inj.mkvi2
-rw-r--r--tex/context/base/mkiv/page-lay.mkiv157
-rw-r--r--tex/context/base/mkiv/page-lin.lua44
-rw-r--r--tex/context/base/mkiv/page-lin.mkvi10
-rw-r--r--tex/context/base/mkiv/page-mix.lua19
-rw-r--r--tex/context/base/mkiv/page-mix.mkiv27
-rw-r--r--tex/context/base/mkiv/page-mul.mkiv36
-rw-r--r--tex/context/base/mkiv/page-one.mkiv63
-rw-r--r--tex/context/base/mkiv/page-otr.mkvi14
-rw-r--r--tex/context/base/mkiv/page-pcl.mkiv79
-rw-r--r--tex/context/base/mkiv/page-run.mkiv7
-rw-r--r--tex/context/base/mkiv/page-sel.mkvi4
-rw-r--r--tex/context/base/mkiv/page-set.mkiv67
-rw-r--r--tex/context/base/mkiv/page-sid.mkiv153
-rw-r--r--tex/context/base/mkiv/page-smp.mkiv59
-rw-r--r--tex/context/base/mkiv/page-spr.mkiv35
-rw-r--r--tex/context/base/mkiv/page-str.lua73
-rw-r--r--tex/context/base/mkiv/page-str.mkiv2
-rw-r--r--tex/context/base/mkiv/page-txt.mkvi33
-rw-r--r--tex/context/base/mkiv/publ-aut.lua48
-rw-r--r--tex/context/base/mkiv/publ-dat.lua123
-rw-r--r--tex/context/base/mkiv/publ-imp-apa.mkvi87
-rw-r--r--tex/context/base/mkiv/publ-imp-cite.mkvi3
-rw-r--r--tex/context/base/mkiv/publ-inc.lua26
-rw-r--r--tex/context/base/mkiv/publ-inc.mkiv63
-rw-r--r--tex/context/base/mkiv/publ-ini.lua43
-rw-r--r--tex/context/base/mkiv/publ-ini.mkiv75
-rw-r--r--tex/context/base/mkiv/scrn-bar.mkvi2
-rw-r--r--tex/context/base/mkiv/scrn-but.mkvi19
-rw-r--r--tex/context/base/mkiv/scrn-fld.mkvi106
-rw-r--r--tex/context/base/mkiv/scrn-ini.mkvi2
-rw-r--r--tex/context/base/mkiv/scrn-pag.mkvi20
-rw-r--r--tex/context/base/mkiv/scrn-ref.mkvi18
-rw-r--r--tex/context/base/mkiv/scrn-wid.mkvi97
-rw-r--r--tex/context/base/mkiv/scrp-cjk.lua107
-rw-r--r--tex/context/base/mkiv/scrp-eth.lua86
-rw-r--r--tex/context/base/mkiv/scrp-ini.lua247
-rw-r--r--tex/context/base/mkiv/scrp-ini.mkiv23
-rw-r--r--tex/context/base/mkiv/scrp-tib.lua81
-rw-r--r--tex/context/base/mkiv/sort-ini.lua29
-rw-r--r--tex/context/base/mkiv/sort-lan.lua46
-rw-r--r--tex/context/base/mkiv/spac-adj.lua67
-rw-r--r--tex/context/base/mkiv/spac-adj.mkiv51
-rw-r--r--tex/context/base/mkiv/spac-ali.lua16
-rw-r--r--tex/context/base/mkiv/spac-ali.mkiv134
-rw-r--r--tex/context/base/mkiv/spac-chr.lua100
-rw-r--r--tex/context/base/mkiv/spac-chr.mkiv2
-rw-r--r--tex/context/base/mkiv/spac-flr.mkiv34
-rw-r--r--tex/context/base/mkiv/spac-grd.mkiv4
-rw-r--r--tex/context/base/mkiv/spac-hor.mkiv56
-rw-r--r--tex/context/base/mkiv/spac-lin.mkiv4
-rw-r--r--tex/context/base/mkiv/spac-pag.mkiv5
-rw-r--r--tex/context/base/mkiv/spac-par.mkiv14
-rw-r--r--tex/context/base/mkiv/spac-prf.lua27
-rw-r--r--tex/context/base/mkiv/spac-ver.lua421
-rw-r--r--tex/context/base/mkiv/spac-ver.mkiv186
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin26054 -> 26589 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin255106 -> 268348 bytes
-rw-r--r--tex/context/base/mkiv/strc-blk.lua92
-rw-r--r--tex/context/base/mkiv/strc-blk.mkiv128
-rw-r--r--tex/context/base/mkiv/strc-con.mkvi18
-rw-r--r--tex/context/base/mkiv/strc-def.mkiv11
-rw-r--r--tex/context/base/mkiv/strc-doc.lua138
-rw-r--r--tex/context/base/mkiv/strc-doc.mkiv27
-rw-r--r--tex/context/base/mkiv/strc-flt.lua34
-rw-r--r--tex/context/base/mkiv/strc-flt.mkvi312
-rw-r--r--tex/context/base/mkiv/strc-itm.mkvi4
-rw-r--r--tex/context/base/mkiv/strc-lnt.mkvi6
-rw-r--r--tex/context/base/mkiv/strc-lst.lua37
-rw-r--r--tex/context/base/mkiv/strc-lst.mkvi17
-rw-r--r--tex/context/base/mkiv/strc-mar.lua180
-rw-r--r--tex/context/base/mkiv/strc-mat.mkiv16
-rw-r--r--tex/context/base/mkiv/strc-not.lua39
-rw-r--r--tex/context/base/mkiv/strc-not.mkvi55
-rw-r--r--tex/context/base/mkiv/strc-num.lua27
-rw-r--r--tex/context/base/mkiv/strc-num.mkiv16
-rw-r--r--tex/context/base/mkiv/strc-pag.lua16
-rw-r--r--tex/context/base/mkiv/strc-pag.mkiv29
-rw-r--r--tex/context/base/mkiv/strc-ref.lua102
-rw-r--r--tex/context/base/mkiv/strc-ref.mkvi502
-rw-r--r--tex/context/base/mkiv/strc-reg.lua407
-rw-r--r--tex/context/base/mkiv/strc-reg.mkiv232
-rw-r--r--tex/context/base/mkiv/strc-ren.mkiv46
-rw-r--r--tex/context/base/mkiv/strc-sbe.mkiv4
-rw-r--r--tex/context/base/mkiv/strc-sec.mkiv107
-rw-r--r--tex/context/base/mkiv/strc-syn.mkiv4
-rw-r--r--tex/context/base/mkiv/strc-tag.lua106
-rw-r--r--tex/context/base/mkiv/strc-tag.mkiv108
-rw-r--r--tex/context/base/mkiv/strc-usr.lua29
-rw-r--r--tex/context/base/mkiv/strc-usr.mkiv180
-rw-r--r--tex/context/base/mkiv/supp-box.lua236
-rw-r--r--tex/context/base/mkiv/supp-box.mkiv182
-rw-r--r--tex/context/base/mkiv/supp-dir.mkiv56
-rw-r--r--tex/context/base/mkiv/supp-mat.mkiv2
-rw-r--r--tex/context/base/mkiv/symb-emj.lua27
-rw-r--r--tex/context/base/mkiv/symb-imp-fontawesome.mkiv1505
-rw-r--r--tex/context/base/mkiv/symb-imp-mis.mkiv23
-rw-r--r--tex/context/base/mkiv/symb-imp-mvs.mkiv18
-rw-r--r--tex/context/base/mkiv/symb-ini.mkiv76
-rw-r--r--tex/context/base/mkiv/symb-run.mkiv62
-rw-r--r--tex/context/base/mkiv/syst-aux.lua133
-rw-r--r--tex/context/base/mkiv/syst-aux.mkiv1521
-rw-r--r--tex/context/base/mkiv/syst-cmp.lua8
-rw-r--r--tex/context/base/mkiv/syst-cmp.mkiv22
-rw-r--r--tex/context/base/mkiv/syst-ini.mkiv643
-rw-r--r--tex/context/base/mkiv/syst-lua.lua11
-rw-r--r--tex/context/base/mkiv/syst-lua.mkiv36
-rw-r--r--tex/context/base/mkiv/syst-rtp.mkiv (renamed from tex/context/base/mkii/syst-rtp.mkiv)0
-rw-r--r--tex/context/base/mkiv/tabl-com.mkiv64
-rw-r--r--tex/context/base/mkiv/tabl-ltb.mkiv8
-rw-r--r--tex/context/base/mkiv/tabl-ntb.mkiv100
-rw-r--r--tex/context/base/mkiv/tabl-tab.mkiv38
-rw-r--r--tex/context/base/mkiv/tabl-tbl.mkiv463
-rw-r--r--tex/context/base/mkiv/tabl-tsp.mkiv29
-rw-r--r--tex/context/base/mkiv/tabl-xtb.lua13
-rw-r--r--tex/context/base/mkiv/tabl-xtb.mkvi149
-rw-r--r--tex/context/base/mkiv/task-ini.lua345
-rw-r--r--tex/context/base/mkiv/toks-aux.mkiv51
-rw-r--r--tex/context/base/mkiv/toks-ini.lua115
-rw-r--r--tex/context/base/mkiv/toks-ini.mkiv5
-rw-r--r--tex/context/base/mkiv/toks-scn.lua70
-rw-r--r--tex/context/base/mkiv/toks-scn.mkiv22
-rw-r--r--tex/context/base/mkiv/trac-deb.lua41
-rw-r--r--tex/context/base/mkiv/trac-inf.lua42
-rw-r--r--tex/context/base/mkiv/trac-jus.lua10
-rw-r--r--tex/context/base/mkiv/trac-log.lua63
-rw-r--r--tex/context/base/mkiv/trac-par.lua29
-rw-r--r--tex/context/base/mkiv/trac-set.lua17
-rw-r--r--tex/context/base/mkiv/trac-vis.lua366
-rw-r--r--tex/context/base/mkiv/trac-vis.mkiv7
-rw-r--r--tex/context/base/mkiv/type-ini.mkvi90
-rw-r--r--tex/context/base/mkiv/type-set.mkiv2
-rw-r--r--tex/context/base/mkiv/typo-bld.lua61
-rw-r--r--tex/context/base/mkiv/typo-brk.lua30
-rw-r--r--tex/context/base/mkiv/typo-cap.lua173
-rw-r--r--tex/context/base/mkiv/typo-cap.mkiv62
-rw-r--r--tex/context/base/mkiv/typo-chr.lua205
-rw-r--r--tex/context/base/mkiv/typo-chr.mkiv19
-rw-r--r--tex/context/base/mkiv/typo-cln.lua12
-rw-r--r--tex/context/base/mkiv/typo-del.mkiv118
-rw-r--r--tex/context/base/mkiv/typo-dha.lua58
-rw-r--r--tex/context/base/mkiv/typo-dig.lua20
-rw-r--r--tex/context/base/mkiv/typo-dir.lua17
-rw-r--r--tex/context/base/mkiv/typo-dir.mkiv190
-rw-r--r--tex/context/base/mkiv/typo-drp.lua45
-rw-r--r--tex/context/base/mkiv/typo-drp.mkiv2
-rw-r--r--tex/context/base/mkiv/typo-dua.lua144
-rw-r--r--tex/context/base/mkiv/typo-dub.lua271
-rw-r--r--tex/context/base/mkiv/typo-duc.lua278
-rw-r--r--tex/context/base/mkiv/typo-fkr.lua17
-rw-r--r--tex/context/base/mkiv/typo-fln.lua64
-rw-r--r--tex/context/base/mkiv/typo-fln.mkiv2
-rw-r--r--tex/context/base/mkiv/typo-itc.lua69
-rw-r--r--tex/context/base/mkiv/typo-krn.lua314
-rw-r--r--tex/context/base/mkiv/typo-lin.lua93
-rw-r--r--tex/context/base/mkiv/typo-mar.lua83
-rw-r--r--tex/context/base/mkiv/typo-mar.mkiv12
-rw-r--r--tex/context/base/mkiv/typo-pag.lua5
-rw-r--r--tex/context/base/mkiv/typo-par.mkiv2
-rw-r--r--tex/context/base/mkiv/typo-pnc.lua21
-rw-r--r--tex/context/base/mkiv/typo-rep.lua10
-rw-r--r--tex/context/base/mkiv/typo-rub.lua42
-rw-r--r--tex/context/base/mkiv/typo-rub.mkiv9
-rw-r--r--tex/context/base/mkiv/typo-scr.mkiv6
-rw-r--r--tex/context/base/mkiv/typo-spa.lua12
-rw-r--r--tex/context/base/mkiv/typo-sus.lua9
-rw-r--r--tex/context/base/mkiv/typo-tal.lua37
-rw-r--r--tex/context/base/mkiv/typo-wrp.lua85
-rw-r--r--tex/context/base/mkiv/typo-wrp.mkiv9
-rw-r--r--tex/context/base/mkiv/util-deb.lua83
-rw-r--r--tex/context/base/mkiv/util-env.lua45
-rw-r--r--tex/context/base/mkiv/util-evo.lua109
-rw-r--r--tex/context/base/mkiv/util-fil.lua66
-rw-r--r--tex/context/base/mkiv/util-fmt.lua11
-rw-r--r--tex/context/base/mkiv/util-jsn.lua95
-rw-r--r--tex/context/base/mkiv/util-lib.lua62
-rw-r--r--tex/context/base/mkiv/util-lua.lua7
-rw-r--r--tex/context/base/mkiv/util-mrg.lua1
-rw-r--r--tex/context/base/mkiv/util-prs.lua35
-rw-r--r--tex/context/base/mkiv/util-sac.lua113
-rw-r--r--tex/context/base/mkiv/util-seq.lua370
-rw-r--r--tex/context/base/mkiv/util-sha.lua35
-rw-r--r--tex/context/base/mkiv/util-soc-imp-copas.lua931
-rw-r--r--tex/context/base/mkiv/util-soc-imp-ftp.lua402
-rw-r--r--tex/context/base/mkiv/util-soc-imp-headers.lua145
-rw-r--r--tex/context/base/mkiv/util-soc-imp-http.lua436
-rw-r--r--tex/context/base/mkiv/util-soc-imp-ltn12.lua387
-rw-r--r--tex/context/base/mkiv/util-soc-imp-mime.lua104
-rw-r--r--tex/context/base/mkiv/util-soc-imp-reset.lua13
-rw-r--r--tex/context/base/mkiv/util-soc-imp-smtp.lua267
-rw-r--r--tex/context/base/mkiv/util-soc-imp-socket.lua193
-rw-r--r--tex/context/base/mkiv/util-soc-imp-tp.lua144
-rw-r--r--tex/context/base/mkiv/util-soc-imp-url.lua268
-rw-r--r--tex/context/base/mkiv/util-soc.lua32
-rw-r--r--tex/context/base/mkiv/util-sql-imp-ffi.lua590
-rw-r--r--tex/context/base/mkiv/util-sql-imp-library.lua8
-rw-r--r--tex/context/base/mkiv/util-sql-imp-sqlite.lua13
-rw-r--r--tex/context/base/mkiv/util-sql-logins.lua12
-rw-r--r--tex/context/base/mkiv/util-sql-users.lua10
-rw-r--r--tex/context/base/mkiv/util-sta.lua14
-rw-r--r--tex/context/base/mkiv/util-sto.lua13
-rw-r--r--tex/context/base/mkiv/util-str.lua526
-rw-r--r--tex/context/base/mkiv/util-tab.lua54
-rw-r--r--tex/context/base/mkiv/util-you.lua1
-rw-r--r--tex/context/fonts/mkiv/type-imp-cambria.mkiv11
-rw-r--r--tex/context/fonts/mkiv/type-imp-dejavu.mkiv5
-rw-r--r--tex/context/fonts/mkiv/type-imp-firacode.mkiv54
-rw-r--r--tex/context/fonts/mkiv/type-imp-latinmodern.mkiv4
-rw-r--r--tex/context/fonts/mkiv/type-imp-lato.mkiv3
-rw-r--r--tex/context/fonts/mkiv/type-imp-lucida-typeone.mkiv2
-rw-r--r--tex/context/fonts/mkiv/type-imp-modernlatin.mkiv56
-rw-r--r--tex/context/fonts/mkiv/type-imp-opendyslexic.mkiv7
-rw-r--r--tex/context/fonts/mkiv/type-imp-plex.mkiv370
-rw-r--r--tex/context/fonts/mkiv/type-imp-source.mkiv48
-rw-r--r--tex/context/fonts/mkiv/type-imp-texgyre.mkiv17
-rw-r--r--tex/context/interface/mkii/keys-cs.xml10
-rw-r--r--tex/context/interface/mkii/keys-de.xml8
-rw-r--r--tex/context/interface/mkii/keys-en.xml7
-rw-r--r--tex/context/interface/mkii/keys-fr.xml7
-rw-r--r--tex/context/interface/mkii/keys-it.xml8
-rw-r--r--tex/context/interface/mkii/keys-nl.xml12
-rw-r--r--tex/context/interface/mkii/keys-pe.xml7
-rw-r--r--tex/context/interface/mkii/keys-ro.xml8
-rw-r--r--tex/context/interface/mkiv/context-en.xml1416
-rw-r--r--tex/context/interface/mkiv/i-attribute.xml2
-rw-r--r--tex/context/interface/mkiv/i-backend.xml26
-rw-r--r--tex/context/interface/mkiv/i-block.xml25
-rw-r--r--tex/context/interface/mkiv/i-boxes.xml15
-rw-r--r--tex/context/interface/mkiv/i-buffer.xml8
-rw-r--r--tex/context/interface/mkiv/i-character.xml8
-rw-r--r--tex/context/interface/mkiv/i-characteralign.xml51
-rw-r--r--tex/context/interface/mkiv/i-color.xml4
-rw-r--r--tex/context/interface/mkiv/i-columns.xml8
-rw-r--r--tex/context/interface/mkiv/i-commandhandler.xml12
-rw-r--r--tex/context/interface/mkiv/i-common-keyword.xml17
-rw-r--r--tex/context/interface/mkiv/i-common-value.xml87
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin846220 -> 865671 bytes
-rw-r--r--tex/context/interface/mkiv/i-context.xml6
-rw-r--r--tex/context/interface/mkiv/i-contextname.xml2353
-rw-r--r--tex/context/interface/mkiv/i-delimitedtext.xml5
-rw-r--r--tex/context/interface/mkiv/i-description.xml5
-rw-r--r--tex/context/interface/mkiv/i-document.xml30
-rw-r--r--tex/context/interface/mkiv/i-effect.xml2
-rw-r--r--tex/context/interface/mkiv/i-enumeration.xml5
-rw-r--r--tex/context/interface/mkiv/i-file.xml2
-rw-r--r--tex/context/interface/mkiv/i-filler.xml16
-rw-r--r--tex/context/interface/mkiv/i-fittingpage.xml2
-rw-r--r--tex/context/interface/mkiv/i-floats.xml222
-rw-r--r--tex/context/interface/mkiv/i-fonts.xml36
-rw-r--r--tex/context/interface/mkiv/i-formula.xml3
-rw-r--r--tex/context/interface/mkiv/i-framed.xml17
-rw-r--r--tex/context/interface/mkiv/i-graphics.xml22
-rw-r--r--tex/context/interface/mkiv/i-grid.xml9
-rw-r--r--tex/context/interface/mkiv/i-hspace.xml7
-rw-r--r--tex/context/interface/mkiv/i-interactionscreen.xml1
-rw-r--r--tex/context/interface/mkiv/i-kerning.xml32
-rw-r--r--tex/context/interface/mkiv/i-label.xml5
-rw-r--r--tex/context/interface/mkiv/i-language.xml10
-rw-r--r--tex/context/interface/mkiv/i-layout.xml5
-rw-r--r--tex/context/interface/mkiv/i-linefiller.xml105
-rw-r--r--tex/context/interface/mkiv/i-list.xml64
-rw-r--r--tex/context/interface/mkiv/i-math.xml14
-rw-r--r--tex/context/interface/mkiv/i-mathfence.xml3
-rw-r--r--tex/context/interface/mkiv/i-mathmatrix.xml9
-rw-r--r--tex/context/interface/mkiv/i-mathname.xml1091
-rw-r--r--tex/context/interface/mkiv/i-narrow.xml6
-rw-r--r--tex/context/interface/mkiv/i-note.xml6
-rw-r--r--tex/context/interface/mkiv/i-pagecolumns.xml90
-rw-r--r--tex/context/interface/mkiv/i-pagegrid.xml325
-rw-r--r--tex/context/interface/mkiv/i-pagemarks.xml18
-rw-r--r--tex/context/interface/mkiv/i-pagestate.xml41
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin61029 -> 61161 bytes
-rw-r--r--tex/context/interface/mkiv/i-register.xml24
-rw-r--r--tex/context/interface/mkiv/i-ruby.xml1
-rw-r--r--tex/context/interface/mkiv/i-scale.xml3
-rw-r--r--tex/context/interface/mkiv/i-script.xml22
-rw-r--r--tex/context/interface/mkiv/i-section.xml2
-rw-r--r--tex/context/interface/mkiv/i-setups.xml9
-rw-r--r--tex/context/interface/mkiv/i-startstop.xml30
-rw-r--r--tex/context/interface/mkiv/i-strut.xml2
-rw-r--r--tex/context/interface/mkiv/i-symbol.xml5
-rw-r--r--tex/context/interface/mkiv/i-system.xml53
-rw-r--r--tex/context/interface/mkiv/i-tabulation.xml23
-rw-r--r--tex/context/interface/mkiv/i-tagging.xml10
-rw-r--r--tex/context/interface/mkiv/i-texts.xml79
-rw-r--r--tex/context/interface/mkiv/i-token.xml31
-rw-r--r--tex/context/interface/mkiv/i-unit.xml12
-rw-r--r--tex/context/interface/mkiv/i-userdata.xml85
-rw-r--r--tex/context/interface/mkiv/i-verbatim.xml4
-rw-r--r--tex/context/interface/mkiv/i-visualizer.xml20
-rw-r--r--tex/context/interface/mkiv/i-vspace.xml109
-rw-r--r--tex/context/interface/mkiv/i-whitespace.xml6
-rw-r--r--tex/context/interface/mkiv/i-xml.xml28
-rw-r--r--tex/context/interface/mkiv/i-xtable.xml48
-rw-r--r--tex/context/modules/common/s-abbreviations-logos.tex3
-rw-r--r--tex/context/modules/mkiv/m-asymptote.lua2
-rw-r--r--tex/context/modules/mkiv/m-asymptote.mkiv58
-rw-r--r--tex/context/modules/mkiv/m-chart.lua17
-rw-r--r--tex/context/modules/mkiv/m-chart.mkvi7
-rw-r--r--tex/context/modules/mkiv/m-format.mkiv4
-rw-r--r--tex/context/modules/mkiv/m-matrix.mkiv153
-rw-r--r--tex/context/modules/mkiv/m-maybe.mkiv57
-rw-r--r--tex/context/modules/mkiv/m-old-columnsets.mkiv7
-rw-r--r--tex/context/modules/mkiv/m-old-multicolumns.mkiv7
-rw-r--r--tex/context/modules/mkiv/m-oldfun.mkiv4
-rw-r--r--tex/context/modules/mkiv/m-oldnum.mkiv25
-rw-r--r--tex/context/modules/mkiv/m-punk.mkiv27
-rw-r--r--tex/context/modules/mkiv/m-scite.mkiv36
-rw-r--r--tex/context/modules/mkiv/m-units.mkiv14
-rw-r--r--tex/context/modules/mkiv/ppchtex.mkiv8
-rw-r--r--tex/context/modules/mkiv/s-article-basic.mkiv19
-rw-r--r--tex/context/modules/mkiv/s-article-titlepage.mkiv65
-rw-r--r--tex/context/modules/mkiv/s-article-titletop.mkiv68
-rw-r--r--tex/context/modules/mkiv/s-cgj.mkiv714
-rw-r--r--tex/context/modules/mkiv/s-evohome.mkiv16
-rw-r--r--tex/context/modules/mkiv/s-fonts-basics.mkiv2
-rw-r--r--tex/context/modules/mkiv/s-fonts-charts.mkiv70
-rw-r--r--tex/context/modules/mkiv/s-fonts-complete.mkiv119
-rw-r--r--tex/context/modules/mkiv/s-fonts-effects.mkiv59
-rw-r--r--tex/context/modules/mkiv/s-fonts-features.lua173
-rw-r--r--tex/context/modules/mkiv/s-fonts-features.mkiv1
-rw-r--r--tex/context/modules/mkiv/s-fonts-shapes.lua380
-rw-r--r--tex/context/modules/mkiv/s-fonts-shapes.mkiv21
-rw-r--r--tex/context/modules/mkiv/s-fonts-statistics.mkiv80
-rw-r--r--tex/context/modules/mkiv/s-fonts-system.lua274
-rw-r--r--tex/context/modules/mkiv/s-fonts-system.mkiv17
-rw-r--r--tex/context/modules/mkiv/s-fonts-tables.lua655
-rw-r--r--tex/context/modules/mkiv/s-fonts-tables.mkiv22
-rw-r--r--tex/context/modules/mkiv/s-fonts-variable.mkiv30
-rw-r--r--tex/context/modules/mkiv/s-languages-hyphenation.lua7
-rw-r--r--tex/context/modules/mkiv/s-languages-system.lua2
-rw-r--r--tex/context/modules/mkiv/s-maps.mkiv8
-rw-r--r--tex/context/modules/mkiv/s-present-dark.mkiv357
-rw-r--r--tex/context/modules/mkiv/s-present-steps.mkiv177
-rw-r--r--tex/context/modules/mkiv/s-references-identify.mkiv69
-rw-r--r--tex/context/modules/mkiv/s-xml-analyzers.lua6
-rw-r--r--tex/context/modules/mkiv/s-youless.mkiv60
-rw-r--r--tex/context/modules/mkiv/x-asciimath.lua24
-rw-r--r--tex/context/modules/mkiv/x-mathml.mkiv2
-rw-r--r--tex/context/modules/mkiv/x-setups-basics.mkiv19
-rw-r--r--tex/context/modules/mkiv/x-setups-overview.mkiv9
-rw-r--r--tex/context/patterns/common/lang-agr.rme41
-rw-r--r--tex/context/patterns/common/lang-bg.rme935
-rw-r--r--tex/context/patterns/common/lang-de.rme65
-rw-r--r--tex/context/patterns/common/lang-deo.rme65
-rw-r--r--tex/context/patterns/common/lang-fr.rme9
-rw-r--r--tex/context/patterns/common/lang-la.rme96
-rw-r--r--tex/context/patterns/common/lang-th.rme35
-rw-r--r--tex/context/patterns/mkii/lang-agr.pat72
-rw-r--r--tex/context/patterns/mkii/lang-bg.pat8508
-rw-r--r--tex/context/patterns/mkii/lang-de.pat22403
-rw-r--r--tex/context/patterns/mkii/lang-deo.pat21973
-rw-r--r--tex/context/patterns/mkii/lang-fr.pat4
-rw-r--r--tex/context/patterns/mkii/lang-la.pat1
-rw-r--r--tex/context/patterns/mkii/lang-th.pat321
-rw-r--r--tex/context/patterns/mkiv/lang-agr.lua47
-rw-r--r--tex/context/patterns/mkiv/lang-bg.lua943
-rw-r--r--tex/context/patterns/mkiv/lang-de.lua71
-rw-r--r--tex/context/patterns/mkiv/lang-deo.lua71
-rw-r--r--tex/context/patterns/mkiv/lang-fr.lua15
-rw-r--r--tex/context/patterns/mkiv/lang-la.lua102
-rw-r--r--tex/context/patterns/mkiv/lang-th.lua41
-rw-r--r--tex/context/sample/third/aesop-de.tex (renamed from tex/context/sample/common/aesop-de.tex)0
-rw-r--r--tex/context/sample/third/cervantes-es.tex (renamed from tex/context/sample/common/cervantes-es.tex)0
-rw-r--r--tex/context/sample/third/khatt-ar.tex (renamed from tex/context/sample/common/khatt-ar.tex)0
-rw-r--r--tex/context/sample/third/khatt-en.tex (renamed from tex/context/sample/common/khatt-en.tex)0
-rw-r--r--tex/context/sample/third/quevedo-es.tex (renamed from tex/context/sample/common/quevedo-es.tex)0
-rw-r--r--tex/generic/context/luatex/luatex-basics-gen.lua259
-rw-r--r--tex/generic/context/luatex/luatex-basics-nod.lua317
-rw-r--r--tex/generic/context/luatex/luatex-core.lua72
-rw-r--r--tex/generic/context/luatex/luatex-fonts-def.lua (renamed from tex/context/base/mkiv/font-xtx.lua)29
-rw-r--r--tex/generic/context/luatex/luatex-fonts-enc.lua3
-rw-r--r--tex/generic/context/luatex/luatex-fonts-ext.lua251
-rw-r--r--tex/generic/context/luatex/luatex-fonts-gbn.lua (renamed from tex/context/base/mkiv/font-gbn.lua)106
-rw-r--r--tex/generic/context/luatex/luatex-fonts-lig.lua2
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua59318
-rw-r--r--tex/generic/context/luatex/luatex-fonts-mis.lua5
-rw-r--r--tex/generic/context/luatex/luatex-fonts-syn.lua7
-rw-r--r--tex/generic/context/luatex/luatex-fonts.lua127
-rw-r--r--tex/generic/context/luatex/luatex-languages.lua15
-rw-r--r--tex/generic/context/luatex/luatex-mplib.lua6
-rw-r--r--tex/generic/context/luatex/luatex-pdf.tex6
-rw-r--r--tex/generic/context/luatex/luatex-swiglib.lua2
-rw-r--r--tex/generic/context/luatex/luatex-test.tex14
1048 files changed, 253450 insertions, 143473 deletions
diff --git a/context/data/scite/context/documents/scite-context-readme.pdf b/context/data/scite/context/documents/scite-context-readme.pdf
index 3abc5f16d..834cd54da 100644
--- a/context/data/scite/context/documents/scite-context-readme.pdf
+++ b/context/data/scite/context/documents/scite-context-readme.pdf
Binary files differ
diff --git a/context/data/scite/context/documents/scite-context-readme.tex b/context/data/scite/context/documents/scite-context-readme.tex
index d9fca8640..fe5120264 100644
--- a/context/data/scite/context/documents/scite-context-readme.tex
+++ b/context/data/scite/context/documents/scite-context-readme.tex
@@ -1,7 +1,8 @@
% interface=en modes=icon,screen language=uk
-\usemodule[art-01]
-\usemodule[abr-02]
+\usemodule[article-basic]
+\usemodule[abbreviations-smallcaps]
+\usemodule[scite]
\unexpanded\def\METAPOST{MetaPost}
\unexpanded\def\METAFUN {MetaFun}
@@ -60,21 +61,21 @@
\startmode[icon,screen]
- \setuppapersize[S66][S66]
+ \setuppapersize[S66][S66]
- \setupbodyfont[10pt]
+ \setupbodyfont[10pt]
\stopmode
\startmode[icon]
- \starttext
+ \starttext
- \startTEXpage
- \useMPgraphic{TitlePage}{darkness=0.4}
- \stopTEXpage
+ \startTEXpage
+ \useMPgraphic{TitlePage}{darkness=0.4}
+ \stopTEXpage
- \stoptext
+ \stoptext
\stopmode
@@ -104,12 +105,12 @@
\definedfont[SerifBold sa 2.48]IN CONTEXT MkIV\kern.25\bodyfontsize}
\startTEXpage
- \tightlayer[TitlePage]
+ \tightlayer[TitlePage]
\stopTEXpage
% main text
-\subject{Warning}
+\startsubject[title={Warning}]
\SCITE\ version 3.61 works ok but 3.62 crashes. It'a a real pity that \SCITE\
doesn't have the scintillua lexer built in, which would also make integration a
@@ -117,7 +118,7 @@ bit nicer by sharing the \LUA\ instance. The \CONTEXT\ lexing discussed here is
the lexing I assume when using \CONTEXT\ \MKIV, but alas it's not easy to get it
running on \UNIX\ and on \MACOSX\ there is no \LUA\ lexing available.
-\subject{About \SCITE}
+\startsubject[title={About \SCITE}]
For a long time at \PRAGMA\ we used \TEXEDIT, an editor we'd written in \MODULA.
It had some project management features and recognized the project structure in
@@ -154,7 +155,9 @@ under:
Normally a user will not have to dive into the implementation details but in
principle you can tweak the properties files to suit your purpose.
-\subject{The look and feel}
+\stopsubject
+
+\startsubject[title={The look and feel}]
The color scheme that we use is consistent over the lexers but we use more colors
that in the traditional lexing. For instance, \TEX\ primitives, low level \TEX\
@@ -175,7 +178,9 @@ for instance because they have an uppercase character. In \in {figure}
[maxheight=1.2\textwidth,
maxwidth=.9\textheight]}}
-\subject{Installing \SCITE}
+\stopsubject
+
+\startsubject[title={Installing \SCITE}]
Installing \SCITE\ is straightforward. We are most familiar with \MSWINDOWS\ but
for other operating systems installation is not much different. First you need to
@@ -220,7 +225,9 @@ On \LINUX\ the files end up in:
Where the second path is the path we will put more files.
-\subject{Installing \type {scintillua}}
+\stopsubject
+
+\startsubject[title={Installing \type {scintillua}}]
Next you need to install the lpeg lexers. \footnote {Versions later than 2.11
will not run on \MSWINDOWS\ 2K. In that case you need to comment the external
@@ -258,7 +265,9 @@ a case you should downgrade or use \type {wine} with the \MSWINDOWS\ binaries
instead. After installation you need to restart \SCITE\ in order to see if things
work out as expected.
-\subject{Installing the \CONTEXT\ lexers}
+\stopsubject
+
+\startsubject[title={Installing the \CONTEXT\ lexers}]
When we started using this nice extension, we ran into issues and as a
consequence shipped a patched \LUA\ code. We also needed some more control as we
@@ -321,7 +330,9 @@ as well).
% \item rxvt (a console, only needed on \UNIX)
% \stopitemize
-\subject{Fonts}
+\stopsubject
+
+\startsubject[title={Fonts}]
The configuration file defaults to the Dejavu fonts. These free fonts are part of
the \CONTEXT\ suite (also known as the standalone distribution). Of course you
@@ -333,13 +344,17 @@ in:
<contextroot>/tex/texmf/fonts/truetype/public/dejavu
\stoptyping
-\subject{Extensions}
+\stopsubject
+
+\startsubject[title={Extensions}]
Just a quick note to some extensions. If you select a part of the text (normally
you do this with the shift key pressed) and you hit \type {Shift-F11}, you get a
menu with some options. More (robust) ones will be provided at some point.
-\subject{Spell checking}
+\stopsubject
+
+\startsubject[title={Spell checking}]
If you want to have spell checking, you need have files with correct words on
each line. The first line of a file determines the language:
@@ -427,7 +442,9 @@ usual \XML\ marker line:
<?context-directive editor language uk ?>
\stoptyping
-\subject{Interface selection}
+\stopsubject
+
+\startsubject[title={Interface selection}]
In a similar fashion you can drive the interface checking:
@@ -435,7 +452,9 @@ In a similar fashion you can drive the interface checking:
% interface=nl
\stoptyping
-\subject{Property files}
+\stopsubject
+
+\startsubject[title={Property files}]
The internal lexers are controlled by the property files while the external ones
are steered with themes. Unfortunately there is hardly any access to properties
@@ -444,7 +463,9 @@ programs like \type {mtxrun}. This means that we cannot use configuration files
in the \CONTEXT\ distribution directly. Hopefully this changes with future
releases.
-\subject{The external lexers}
+\stopsubject
+
+\startsubject[title={The external lexers}]
These are the more advanced lexers. They provide more detail and the \CONTEXT\
lexer also supports nested \METAPOST\ and \LUA. Currently there is no detailed
@@ -475,7 +496,9 @@ indicates that there is a special space character there, for instance \type
{0xA0}, the nonbreakable space. Of course we assume that you use \UTF8 as input
encoding.
-\subject{The internal lexers}
+\stopsubject
+
+\startsubject[title={The internal lexers}]
\SCITE\ has quite some built in lexers. A lexer is responsible for highlighting
the syntax of your document. The way a \TEX\ file is treated is configured in the
@@ -563,7 +586,9 @@ seen as a command. When set to zero, only the primitive \type {\if}'s will be
treated. In order not to confuse you, when this property is set to one, the lexer
will not color an \type {\ifwhatever} that follows an \type {\newif}.
-\subject{The \METAPOST\ lexer}
+\stopsubject
+
+\startsubject[title={The \METAPOST\ lexer}]
The \METAPOST\ lexer is set up slightly different from its \TEX\ counterpart,
first of all because \METAPOST\ is more a language that \TEX. As with the \TEX\
@@ -626,7 +651,9 @@ The lexer is able to recognize \type {btex}||\type {etex} and will treat anythin
in between as just text. The same happens with strings (between \type {"}). Both
act on a per line basis.
-\subject{Using \ConTeXt}
+\stopsubject
+
+\startsubject[title={Using \ConTeXt}]
When \type {mtxrun} is in your path, \CONTEXT\ should run out of the box. You can
find \type {mtxrun} in:
@@ -640,7 +667,9 @@ or in a similar path that suits the operating system that you use.
When you hit \type{CTRL-12} your document will be processed. Take a look at the
\type {Tools} menu to see what more is provided.
-\subject{Extensions (using \LUA)}
+\stopsubject
+
+\startsubject[title={Extensions (using \LUA)}]
When the \LUA\ extensions are loaded, you will see a message in the log pane that
looks like:
@@ -676,79 +705,38 @@ in a (chosen) language. This is handy when you occasionally have to key in (snip
a language you're not familiar with. More alphabets will be added (we take data from some
\CONTEXT\ language relates files).
-\subject{Templates}
+\stopsubject
-There is an experimental template mechanism. One option is to define templates in
-a properties file. The property file \type {scite-ctx-context} contains
-definitions like:
+\startsubject[title={Templates}]
-\starttyping
-command.25.$(file.patterns.context)=insert_template \
-$(ctx.template.list.context)
+It is possible to define (and use) templates. There is a demo file in the distribution called
+\type {scite-ctx-templates.lua}. You can put a similar file in your working path or one or two
+levels up from there. If not found, the default (demo) file will be used. a manu is called up
+with \type {ctrl-i}.
-ctx.template.list.context=\
- itemize=structure.itemize.context|\
- tabulate=structure.tabulate.context|\
- natural TABLE=structure.TABLE.context|\
- use MP graphic=graphics.usemp.context|\
- reuse MP graphic=graphics.reusemp.context|\
- typeface definition=fonts.typeface.context
+A template file is a \LUA\ file and looks like this:
-ctx.template.structure.itemize.context=\
-\startitemize\n\
-\item ?\n\
-\item ?\n\
-\item ?\n\
-\stopitemize\n
-\stoptyping
+\typefile{../scite-ctx-templates.lua}
-The file \type {scite-ctx-example} defines \XML\ variants:
+In \XML\ sources you can add a line:
\starttyping
-command.25.$(file.patterns.example)=insert_template \
-$(ctx.template.list.example)
-
-ctx.template.list.example=\
- bold=font.bold.example|\
- emphasized=font.emphasized.example|\
- |\
- inline math=math.inline.example|\
- display math=math.display.example|\
- |\
- itemize=structure.itemize.example
-
-ctx.template.structure.itemize.example=\
-<itemize>\n\
-<item>?</item>\n\
-<item>?</item>\n\
-<item>?</item>\n\
-</itemize>\n
+<?context-directive job ctxtemplate mytemplates.lua ?>
\stoptyping
-For larger projects it makes sense to keep templates with the project. In one of
-our projects we have a directory in the path where the project files are kept
-which holds template files:
+The file will be searched for in the current direct and upto two levels higher. When no file
+is found the \TEX\ distribution is checked.
-\starttyping
-..../ctx-templates/achtergronden.xml
-..../ctx-templates/bewijs.xml
-\stoptyping
-
-One could define a template menu like we did previously:
+The files \type {scite-ctx-example} and \type {scite-ctx-context} define the menu commands,
+like:
\starttyping
-ctx.templatelist.example=\
- achtergronden=mathadore.achtergronden|\
- bewijs=mathadore.bewijs|\
-
-ctx.template.mathadore.achtergronden.file=smt-achtergronden.xml
-ctx.template.mathadore.bewijs.file=smt-bewijs.xml
+command.25.$(file.patterns.example)=insert_template
\stoptyping
-However, when no such menu is defined, we will automatically scan the directory
-and build the menu without user intervention.
+\stopsubject
-\subject{Using \SCITE}
+\startsubject[title={Using \SCITE}]
The following keybindings are available in \SCITE. Most of this list is taken
from the on|-|line help pages.
@@ -821,7 +809,9 @@ from the on|-|line help pages.
\page
-\subject{Affiliation}
+\stopsubject
+
+\startsubject[title={Affiliation}]
\starttabulate[|l|l|]
\NC author \NC Hans Hagen \NC \NR
diff --git a/context/data/scite/context/lexers/data/scite-context-data-context.lua b/context/data/scite/context/lexers/data/scite-context-data-context.lua
index 15ce97796..afb6565eb 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-context.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-context.lua
@@ -1,4 +1,4 @@
return {
- ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plustwohundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "maxcardminusone", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxcount", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "ctdcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "hyphenasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "mathexheight", "mathemwidth", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "muquad", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifelsemode", "doifmodeelse", "doifnotmode", "startmodeset", "stopmodeset", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifelseallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "everystarttext", "everystoptext", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "definemode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "lrm", "rlm", "bidilre", "bidirle", "bidipop", "bidilro", "bidirlo", "breakablethinspace", "nobreakspace", "nonbreakablespace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "enquad", "emquad", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj", "optionalspace", "asciispacechar", "softhyphen", "Ux", "eUx", "Umathaccents", "parfillleftskip", "parfillrightskip" },
- ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "strippedcsname", "checkedstrippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthsargumenttrue", "sixthargumentfalse", "sixtsargumenttrue", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "startpickupmath", "stoppickupmath", "reqno", "mathortext", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "normalbaselineskip", "normallineskip", "normallineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "ignoreparskip", "forcestrutdepth", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "setexpandeddummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "installctxfunctioncall", "installprotectedctxfunction", "installprotectedctxfunctioncall", "installctxscanner", "installctxscannercall", "resetctxscanner", "installprotectedctxscanner", "installprotectedctxscannercall", "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand", "carryoverpar", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "checkedlefttoright", "checkedrighttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "dirlre", "dirrle", "dirlro", "dirrlo", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "frule", "compoundhyphenpenalty", "start", "stop" },
+ ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "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", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "directionlefttoright", "directionrighttoleft", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "contextformat", "contextversion", "contextkind", "contextlmtxmode", "contextmark", "mksuffix", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "ctdcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "leftparentasciicode", "rightparentasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "hyphenasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "mathexheight", "mathemwidth", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "muquad", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifelsemode", "doifmodeelse", "doifnotmode", "startmodeset", "stopmodeset", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifelseallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", "doifelsedocumentvariable", "doifdocumentvariableelse", "doifdocumentvariable", "doifnotdocumentvariable", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "everystarttext", "everystoptext", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "definemode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "lrm", "rlm", "bidilre", "bidirle", "bidipop", "bidilro", "bidirlo", "breakablethinspace", "nobreakspace", "nonbreakablespace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "enquad", "emquad", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj", "optionalspace", "asciispacechar", "softhyphen", "Ux", "eUx", "Umathaccents", "parfillleftskip", "parfillrightskip" },
+ ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "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", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "autorule", "strippedcsname", "checkedstrippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthargumenttrue", "sixthargumentfalse", "sixthargumenttrue", "seventhargumentfalse", "seventhargumenttrue", "vkern", "hkern", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "startpickupmath", "stoppickupmath", "reqno", "mathortext", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "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", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "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", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "firstinset", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doifelseassignmentcs", "doifassignmentelsecs", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "ignoreparskip", "forcestrutdepth", "onlynonbreakablespace", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "setexpandeddummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "onlypdfobjectcompression", "nopdfobjectcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "installprotectedctxfunction", "installprotectedctxscanner", "installctxscanner", "resetctxscanner", "cldprocessfile", "cldloadfile", "cldloadviafile", "cldcontext", "cldcommand", "carryoverpar", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "checkedlefttoright", "checkedrighttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "dirlre", "dirrle", "dirlro", "dirrlo", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "naturaltpack", "reversehbox", "reversevbox", "reversevtop", "reversehpack", "reversevpack", "reversetpack", "frule", "compoundhyphenpenalty", "start", "stop" },
} \ No newline at end of file
diff --git a/context/data/scite/context/lexers/data/scite-context-data-interfaces.lua b/context/data/scite/context/lexers/data/scite-context-data-interfaces.lua
index 14036ae5d..6547cad51 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-interfaces.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-interfaces.lua
@@ -1,11 +1,11 @@
return {
- ["common"]={ "AEacute", "AEligature", "AEmacron", "AMSTEX", "Aacute", "Abreve", "Abreveacute", "Abrevedotbelow", "Abrevegrave", "Abrevehook", "Abrevetilde", "Acaron", "Acircumflex", "Acircumflexacute", "Acircumflexdotbelow", "Acircumflexgrave", "Acircumflexhook", "Acircumflextilde", "Adiaeresis", "Adiaeresismacron", "Adotaccent", "Adotaccentmacron", "Adotbelow", "Adoublegrave", "AfterPar", "Agrave", "Ahook", "Ainvertedbreve", "Alpha", "Alphabeticnumerals", "AmSTeX", "Amacron", "And", "Angstrom", "Aogonek", "Aring", "Aringacute", "Arrowvert", "Astroke", "Atilde", "BeforePar", "Beta", "Bhook", "Big", "Bigg", "Biggl", "Biggm", "Biggr", "Bigl", "Bigm", "Bigr", "Box", "Bumpeq", "CONTEXT", "Cacute", "Cap", "Caps", "Ccaron", "Ccedilla", "Ccircumflex", "Cdotaccent", "Character", "Characters", "Chi", "Chook", "ConTeXt", "Context", "ConvertConstantAfter", "ConvertToConstant", "Cstroke", "Cup", "DZcaronligature", "DZligature", "Dafrican", "Dcaron", "Ddownarrow", "Delta", "Dhook", "Doteq", "Downarrow", "Dstroke", "Dzcaronligature", "Dzligature", "ETEX", "Eacute", "Ebreve", "Ecaron", "Ecedilla", "Ecircumflex", "Ecircumflexacute", "Ecircumflexdotbelow", "Ecircumflexgrave", "Ecircumflexhook", "Ecircumflextilde", "Ediaeresis", "Edotaccent", "Edotbelow", "Edoublegrave", "Egrave", "Ehook", "Einvertedbreve", "Emacron", "Eogonek", "Epsilon", "Eta", "Eth", "Etilde", "Eulerconst", "EveryLine", "EveryPar", "Fhook", "Finv", "Gacute", "Game", "Gamma", "Gbreve", "Gcaron", "Gcircumflex", "Gcommaaccent", "Gdotaccent", "GetPar", "Ghook", "GotoPar", "Greeknumerals", "Gstroke", "Hat", "Hcaron", "Hcircumflex", "Hstroke", "IJligature", "INRSTEX", "Iacute", "Ibreve", "Icaron", "Icircumflex", "Idiaeresis", "Idotaccent", "Idotbelow", "Idoublegrave", "Igrave", "Ihook", "Iinvertedbreve", "Im", "Imacron", "Iogonek", "Iota", "Istroke", "Itilde", "Jcircumflex", "Join", "Kappa", "Kcaron", "Kcommaaccent", "Khook", "LAMSTEX", "LATEX", "LJligature", "LUAJITTEX", "LUATEX", "LaTeX", "Lacute", "LamSTeX", "Lambda", "Lbar", "Lcaron", "Lcommaaccent", "Ldotmiddle", "Ldsh", "Leftarrow", "Leftrightarrow", "Ljligature", "Lleftarrow", "Longleftarrow", "Longleftrightarrow", "Longmapsfrom", "Longmapsto", "Longrightarrow", "Lsh", "Lstroke", "Lua", "LuaTeX", "LuajitTeX", "METAFONT", "METAFUN", "METAPOST", "MKII", "MKIV", "MKIX", "MKVI", "MKXI", "MONTH", "MONTHLONG", "MONTHSHORT", "MPII", "MPIV", "MPVI", "MPanchor", "MPbetex", "MPc", "MPcode", "MPcolor", "MPcoloronly", "MPcolumn", "MPd", "MPdrawing", "MPfontsizehskip", "MPgetmultipars", "MPgetmultishape", "MPgetposboxes", "MPh", "MPinclusions", "MPleftskip", "MPll", "MPlr", "MPls", "MPmenubuttons", "MPn", "MPoptions", "MPoverlayanchor", "MPp", "MPpage", "MPpardata", "MPplus", "MPpos", "MPpositiongraphic", "MPposset", "MPr", "MPrawvar", "MPregion", "MPrest", "MPrightskip", "MPrs", "MPstring", "MPtext", "MPtransparency", "MPul", "MPur", "MPv", "MPvar", "MPvariable", "MPvv", "MPw", "MPwhd", "MPx", "MPxy", "MPxywhd", "MPy", "Mapsfrom", "Mapsto", "MetaFont", "MetaFun", "MetaPost", "Mu", "NJligature", "Nacute", "Ncaron", "Ncommaaccent", "Nearrow", "Neng", "Ngrave", "Njligature", "NormalizeFontHeight", "NormalizeFontWidth", "NormalizeTextHeight", "NormalizeTextWidth", "Ntilde", "Nu", "Numbers", "Nwarrow", "OEligature", "Oacute", "Obreve", "Ocaron", "Ocircumflex", "Ocircumflexacute", "Ocircumflexdotbelow", "Ocircumflexgrave", "Ocircumflexhook", "Ocircumflextilde", "Odiaeresis", "Odiaeresismacron", "Odotaccent", "Odotaccentmacron", "Odotbelow", "Odoublegrave", "Ograve", "Ohook", "Ohorn", "Ohornacute", "Ohorndotbelow", "Ohorngrave", "Ohornhook", "Ohorntilde", "Ohungarumlaut", "Oinvertedbreve", "Omacron", "Omega", "Omicron", "Oogonek", "Oogonekmacron", "Ostroke", "Ostrokeacute", "Otilde", "Otildemacron", "P", "PDFETEX", "PDFTEX", "PDFcolor", "PICTEX", "PPCHTEX", "PPCHTeX", "PRAGMA", "Phi", "Phook", "Pi", "PiCTeX", "Plankconst", "PointsToBigPoints", "PointsToReal", "PointsToWholeBigPoints", "PropertyLine", "Psi", "PtToCm", "Racute", "Rcaron", "Rcommaaccent", "Rdoublegrave", "Rdsh", "Re", "ReadFile", "Relbar", "Rho", "Rightarrow", "Rinvertedbreve", "Romannumerals", "Rrightarrow", "Rsh", "S", "Sacute", "ScaledPointsToBigPoints", "ScaledPointsToWholeBigPoints", "Scaron", "Scedilla", "Schwa", "Scircumflex", "Scommaaccent", "Searrow", "Sigma", "Smallcapped", "Subset", "Supset", "Swarrow", "TABLE", "TEX", "TaBlE", "Tau", "Tcaron", "Tcedilla", "Tcommaaccent", "TeX", "TheNormalizedFontSize", "Theta", "Thook", "Thorn", "TransparencyHack", "Tstroke", "Uacute", "Ubreve", "Ucaron", "Ucircumflex", "Udiaeresis", "Udiaeresisacute", "Udiaeresiscaron", "Udiaeresisgrave", "Udiaeresismacron", "Udotbelow", "Udoublegrave", "Ugrave", "Uhook", "Uhorn", "Uhornacute", "Uhorndotbelow", "Uhorngrave", "Uhornhook", "Uhorntilde", "Uhungarumlaut", "Uinvertedbreve", "Umacron", "Uogonek", "Uparrow", "Updownarrow", "Upsilon", "Uring", "Utilde", "Uuparrow", "VDash", "Vdash", "VerboseNumber", "Vert", "Vvdash", "WEEKDAY", "WORD", "WORDS", "Wcircumflex", "WidthSpanningText", "Word", "Words", "XETEX", "XeTeX", "Xi", "Yacute", "Ycircumflex", "Ydiaeresis", "Ydotbelow", "Ygrave", "Yhook", "Ymacron", "Ytilde", "Zacute", "Zcaron", "Zdotaccent", "Zeta", "Zhook", "Zstroke", "aacute", "abbreviation", "abjadnaivenumerals", "abjadnodotnumerals", "abjadnumerals", "about", "abreve", "abreveacute", "abrevedotbelow", "abrevegrave", "abrevehook", "abrevetilde", "acaron", "acircumflex", "acircumflexacute", "acircumflexdotbelow", "acircumflexgrave", "acircumflexhook", "acircumflextilde", "activatespacehandler", "actuarial", "acute", "acwopencirclearrow", "adaptcollector", "adaptfontfeature", "adaptlayout", "adaptpapersize", "addfeature", "addfontpath", "addtoJSpreamble", "addtocommalist", "addvalue", "adiaeresis", "adiaeresismacron", "adotaccent", "adotaccentmacron", "adotbelow", "adoublegrave", "aeacute", "aeligature", "aemacron", "afghanicurrency", "aftersplitstring", "aftertestandsplitstring", "agrave", "ahook", "ainvertedbreve", "aleph", "alignbottom", "aligned", "alignedbox", "alignedline", "alignhere", "alignmentcharacter", "allinputpaths", "alpha", "alphabeticnumerals", "alwayscitation", "alwayscite", "amacron", "amalg", "ampersand", "anchor", "angle", "aogonek", "appendetoks", "appendgvalue", "appendtocommalist", "appendtoks", "appendtoksonce", "appendvalue", "apply", "applyalternativestyle", "applyprocessor", "applytocharacters", "applytofirstcharacter", "applytosplitstringchar", "applytosplitstringcharspaced", "applytosplitstringline", "applytosplitstringlinespaced", "applytosplitstringword", "applytosplitstringwordspaced", "applytowords", "approx", "approxEq", "approxeq", "approxnEq", "arabicakbar", "arabicalayhe", "arabicallah", "arabicallallahou", "arabicasterisk", "arabicbasmalah", "arabiccomma", "arabiccuberoot", "arabicdateseparator", "arabicdecimals", "arabicdisputedendofayah", "arabicendofayah", "arabicexnumerals", "arabicfootnotemarker", "arabicfourthroot", "arabichighain", "arabichighalayheassallam", "arabichigheqala", "arabichighesala", "arabichighfootnotemarker", "arabichighjeem", "arabichighlamalef", "arabichighmadda", "arabichighmeemlong", "arabichighmeemshort", "arabichighnisf", "arabichighnoon", "arabichighnoonkasra", "arabichighqaf", "arabichighqif", "arabichighradiallahouanhu", "arabichighrahmatullahalayhe", "arabichighrubc", "arabichighsad", "arabichighsajda", "arabichighsakta", "arabichighsallallahou", "arabichighseen", "arabichighsmallsafha", "arabichightah", "arabichightakhallus", "arabichighthalatha", "arabichighwaqf", "arabichighyeh", "arabichighzain", "arabicjallajalalouhou", "arabiclettermark", "arabiclowmeemlong", "arabiclownoonkasra", "arabiclowseen", "arabicmisra", "arabicmuhammad", "arabicnumber", "arabicnumberabove", "arabicnumerals", "arabicparenleft", "arabicparenright", "arabicpercent", "arabicperiod", "arabicpermille", "arabicpertenthousand", "arabicpoeticverse", "arabicqala", "arabicquestion", "arabicrasoul", "arabicray", "arabicrialsign", "arabicsafha", "arabicsajdah", "arabicsalla", "arabicsamvat", "arabicsanah", "arabicsemicolon", "arabicshighthreedots", "arabicslcm", "arabicstartofrubc", "arabictripledot", "arabicvowelwaw", "arabicvowelyeh", "arabicwasallam", "arg", "aring", "aringacute", "arrowvert", "asciistr", "aside", "assignalfadimension", "assigndimen", "assigndimension", "assignifempty", "assigntranslation", "assignvalue", "assignwidth", "assumelongusagecs", "ast", "astype", "asymp", "at", "atilde", "atleftmargin", "atpage", "atrightmargin", "attachment", "autocap", "autodirhbox", "autodirvbox", "autodirvtop", "autoinsertnextspace", "autointegral", "automathematics", "autosetups", "availablehsize", "averagecharwidth", "backepsilon", "background", "backgroundimage", "backgroundimagefill", "backgroundline", "backprime", "backsim", "backslash", "bar", "barleftarrow", "barleftarrowrightarrowbar", "barovernorthwestarrow", "barwedge", "basegrid", "baselinebottom", "baselineleftbox", "baselinemiddlebox", "baselinerightbox", "bbordermatrix", "bbox", "because", "beforesplitstring", "beforetestandsplitstring", "beta", "beth", "between", "bhook", "big", "bigbodyfont", "bigcap", "bigcirc", "bigcircle", "bigcup", "bigdiamond", "bigg", "bigger", "biggl", "biggm", "biggr", "bigl", "bigm", "bigodot", "bigoplus", "bigotimes", "bigr", "bigskip", "bigsqcap", "bigsqcup", "bigsquare", "bigstar", "bigtimes", "bigtriangledown", "bigtriangleup", "bigudot", "biguplus", "bigvee", "bigwedge", "binom", "bitmapimage", "blacklozenge", "blackrule", "blackrules", "blacksquare", "blacktriangle", "blacktriangledown", "blacktriangleleft", "blacktriangleright", "blank", "blap", "bleed", "bleedheight", "bleedwidth", "blockligatures", "blockquote", "blocksynctexfile", "bodyfontenvironmentlist", "bodyfontsize", "bold", "boldface", "bolditalic", "boldslanted", "bookmark", "booleanmodevalue", "bordermatrix", "bot", "bottombox", "bottomleftbox", "bottomrightbox", "bowtie", "boxcursor", "boxdot", "boxmarker", "boxminus", "boxofsize", "boxplus", "boxreference", "boxtimes", "bpos", "breakablethinspace", "breakhere", "breve", "bstroke", "btxabbreviatedjournal", "btxaddjournal", "btxalwayscitation", "btxauthorfield", "btxdetail", "btxdirect", "btxdoif", "btxdoifcombiinlistelse", "btxdoifelse", "btxdoifelsecombiinlist", "btxdoifelsesameasprevious", "btxdoifelsesameaspreviouschecked", "btxdoifelseuservariable", "btxdoifnot", "btxdoifsameaspreviouscheckedelse", "btxdoifsameaspreviouselse", "btxdoifuservariableelse", "btxexpandedjournal", "btxfield", "btxfieldname", "btxfieldtype", "btxfirstofrange", "btxflush", "btxflushauthor", "btxflushauthorinverted", "btxflushauthorinvertedshort", "btxflushauthorname", "btxflushauthornormal", "btxflushauthornormalshort", "btxflushsuffix", "btxfoundname", "btxfoundtype", "btxhiddencitation", "btxhybridcite", "btxlabellanguage", "btxlabeltext", "btxlistcitation", "btxloadjournalist", "btxoneorrange", "btxremapauthor", "btxsavejournalist", "btxsetup", "btxsingularorplural", "btxsingularplural", "btxtextcitation", "buildmathaccent", "buildtextaccent", "buildtextbottomcomma", "buildtextbottomdot", "buildtextcedilla", "buildtextgrave", "buildtextmacron", "buildtextognek", "bullet", "button", "cacute", "calligraphic", "camel", "cap", "carriagereturn", "catcodetablename", "cbox", "ccaron", "ccedilla", "ccircumflex", "ccurl", "cdot", "cdotaccent", "cdotp", "cdots", "centeraligned", "centerbox", "centerdot", "centeredbox", "centeredlastline", "centerednextbox", "centerline", "cfrac", "chapter", "character", "characters", "chardescription", "charwidthlanguage", "check", "checkcharacteralign", "checkedchar", "checkedfiller", "checkedstrippedcsname", "checkinjector", "checkmark", "checknextindentation", "checknextinjector", "checkpage", "checkparameters", "checkpreviousinjector", "checksoundtrack", "checktwopassdata", "checkvariables", "chem", "chemical", "chemicalbottext", "chemicalmidtext", "chemicalsymbol", "chemicaltext", "chemicaltoptext", "chi", "chineseallnumerals", "chinesecapnumerals", "chinesenumerals", "chook", "circ", "circeq", "circlearrowleft", "circlearrowright", "circledR", "circledS", "circledast", "circledcirc", "circleddash", "circledequals", "circleonrightarrow", "citation", "cite", "clap", "classfont", "cldcommand", "cldcontext", "cldloadfile", "cldprocessfile", "cleftarrow", "clip", "clonefield", "clubsuit", "collect", "collectedtext", "collectexpanded", "colon", "coloncolonequals", "colonequals", "color", "colorbar", "colorcomponents", "colored", "coloronly", "colorvalue", "column", "columnbreak", "combinepages", "commalistelement", "commalistsentence", "commalistsize", "comment", "comparecolorgroup", "comparedimension", "comparedimensioneps", "comparepalet", "complement", "completebtxrendering", "completecontent", "completeindex", "completelist", "completelistofabbreviations", "completelistofchemicals", "completelistoffigures", "completelistofgraphics", "completelistofintermezzi", "completelistoflogos", "completelistofpublications", "completelistofsorts", "completelistofsynonyms", "completelistoftables", "completepagenumber", "completeregister", "complexes", "complexorsimple", "complexorsimpleempty", "component", "composedcollector", "composedlayer", "compresult", "cong", "constantdimen", "constantdimenargument", "constantemptyargument", "constantnumber", "constantnumberargument", "contentreference", "continuednumber", "continueifinputfile", "convertargument", "convertcommand", "convertedcounter", "converteddimen", "convertedsubcounter", "convertmonth", "convertnumber", "convertvalue", "convertvboxtohbox", "coprod", "copyboxfromcache", "copybtxlabeltext", "copyfield", "copyheadtext", "copylabeltext", "copymathlabeltext", "copyoperatortext", "copypages", "copyparameters", "copyposition", "copyprefixtext", "copyright", "copysuffixtext", "copytaglabeltext", "copyunittext", "correctwhitespace", "countersubs", "counttoken", "counttokens", "cramped", "crampedclap", "crampedllap", "crampedrlap", "crightarrow", "crightoverleftarrow", "cstroke", "ctop", "ctxcommand", "ctxdirectcommand", "ctxdirectlua", "ctxfunction", "ctxlatecommand", "ctxlatelua", "ctxloadluafile", "ctxlua", "ctxluabuffer", "ctxluacode", "ctxreport", "ctxsprint", "cup", "curlyeqprec", "curlyeqsucc", "curlyvee", "curlywedge", "currentassignmentlistkey", "currentassignmentlistvalue", "currentbtxuservariable", "currentcommalistitem", "currentcomponent", "currentdate", "currentenvironment", "currentfeaturetest", "currentheadnumber", "currentinterface", "currentlanguage", "currentlistentrydestinationattribute", "currentlistentrylimitedtext", "currentlistentrynumber", "currentlistentrypagenumber", "currentlistentryreferenceattribute", "currentlistentrytitle", "currentlistentrytitlerendered", "currentlistsymbol", "currentmainlanguage", "currentmessagetext", "currentmoduleparameter", "currentoutputstream", "currentproduct", "currentproject", "currentregime", "currentregisterpageuserdata", "currentresponses", "currenttime", "currentvalue", "currentxtablecolumn", "currentxtablerow", "curvearrowleft", "curvearrowright", "cwopencirclearrow", "cyrillicA", "cyrillicAE", "cyrillicAbreve", "cyrillicAdiaeresis", "cyrillicB", "cyrillicBIGYUS", "cyrillicBIGYUSiotified", "cyrillicC", "cyrillicCH", "cyrillicCHEDC", "cyrillicCHEDCabkhasian", "cyrillicCHEabkhasian", "cyrillicCHEdiaeresis", "cyrillicCHEkhakassian", "cyrillicCHEvertstroke", "cyrillicD", "cyrillicDASIAPNEUMATA", "cyrillicDJE", "cyrillicDZE", "cyrillicDZEabkhasian", "cyrillicDZHE", "cyrillicE", "cyrillicELtail", "cyrillicEMtail", "cyrillicENDC", "cyrillicENGHE", "cyrillicENhook", "cyrillicENtail", "cyrillicEREV", "cyrillicERY", "cyrillicERtick", "cyrillicEbreve", "cyrillicEdiaeresis", "cyrillicEgrave", "cyrillicEiotified", "cyrillicF", "cyrillicFITA", "cyrillicG", "cyrillicGHEmidhook", "cyrillicGHEstroke", "cyrillicGHEupturn", "cyrillicGJE", "cyrillicH", "cyrillicHA", "cyrillicHADC", "cyrillicHRDSN", "cyrillicI", "cyrillicIE", "cyrillicII", "cyrillicISHRT", "cyrillicISHRTtail", "cyrillicIZHITSA", "cyrillicIZHITSAdoublegrave", "cyrillicIdiaeresis", "cyrillicIgrave", "cyrillicImacron", "cyrillicJE", "cyrillicK", "cyrillicKADC", "cyrillicKAbashkir", "cyrillicKAhook", "cyrillicKAstroke", "cyrillicKAvertstroke", "cyrillicKJE", "cyrillicKOPPA", "cyrillicKSI", "cyrillicL", "cyrillicLITTLEYUS", "cyrillicLITTLEYUSiotified", "cyrillicLJE", "cyrillicM", "cyrillicN", "cyrillicNJE", "cyrillicO", "cyrillicOMEGA", "cyrillicOMEGAround", "cyrillicOMEGAtitlo", "cyrillicOT", "cyrillicObarred", "cyrillicObarreddiaeresis", "cyrillicOdiaeresis", "cyrillicP", "cyrillicPALATALIZATION", "cyrillicPALOCHKA", "cyrillicPEmidhook", "cyrillicPSI", "cyrillicPSILIPNEUMATA", "cyrillicR", "cyrillicS", "cyrillicSCHWA", "cyrillicSCHWAdiaeresis", "cyrillicSDSC", "cyrillicSEMISOFT", "cyrillicSFTSN", "cyrillicSH", "cyrillicSHCH", "cyrillicSHHA", "cyrillicT", "cyrillicTEDC", "cyrillicTETSE", "cyrillicTITLO", "cyrillicTSHE", "cyrillicU", "cyrillicUK", "cyrillicUSHRT", "cyrillicUdiaeresis", "cyrillicUdoubleacute", "cyrillicUmacron", "cyrillicV", "cyrillicYA", "cyrillicYAT", "cyrillicYERUdiaeresis", "cyrillicYI", "cyrillicYO", "cyrillicYU", "cyrillicYstr", "cyrillicYstrstroke", "cyrillicZ", "cyrillicZDSC", "cyrillicZEdiaeresis", "cyrillicZH", "cyrillicZHEbreve", "cyrillicZHEdescender", "cyrillicZHEdiaeresis", "cyrillica", "cyrillicabreve", "cyrillicadiaeresis", "cyrillicae", "cyrillicb", "cyrillicbigyus", "cyrillicbigyusiotified", "cyrillicc", "cyrillicch", "cyrilliccheabkhasian", "cyrillicchedc", "cyrillicchedcabkhasian", "cyrillicchediaeresis", "cyrillicchekhakassian", "cyrillicchevertstroke", "cyrillicd", "cyrillicdje", "cyrillicdze", "cyrillicdzeabkhasian", "cyrillicdzhe", "cyrillice", "cyrillicebreve", "cyrillicediaeresis", "cyrillicegrave", "cyrilliceiotified", "cyrilliceltail", "cyrillicemtail", "cyrillicendc", "cyrillicenghe", "cyrillicenhook", "cyrillicentail", "cyrillicerev", "cyrillicertick", "cyrillicery", "cyrillicf", "cyrillicfita", "cyrillicg", "cyrillicghemidhook", "cyrillicghestroke", "cyrillicgheupturn", "cyrillicgje", "cyrillich", "cyrillicha", "cyrillichadc", "cyrillichrdsn", "cyrillici", "cyrillicidiaeresis", "cyrillicie", "cyrillicigrave", "cyrillicii", "cyrillicimacron", "cyrillicishrt", "cyrillicishrttail", "cyrillicizhitsa", "cyrillicizhitsadoublegrave", "cyrillicje", "cyrillick", "cyrillickabashkir", "cyrillickadc", "cyrillickahook", "cyrillickastroke", "cyrillickavertstroke", "cyrillickje", "cyrillickoppa", "cyrillicksi", "cyrillicl", "cyrilliclittleyus", "cyrilliclittleyusiotified", "cyrilliclje", "cyrillicm", "cyrillicn", "cyrillicnje", "cyrillico", "cyrillicobarred", "cyrillicobarreddiaeresis", "cyrillicodiaeresis", "cyrillicomega", "cyrillicomegaround", "cyrillicomegatitlo", "cyrillicot", "cyrillicp", "cyrillicpemidhook", "cyrillicpsi", "cyrillicr", "cyrillics", "cyrillicschwa", "cyrillicschwadiaeresis", "cyrillicsdsc", "cyrillicsemisoft", "cyrillicsftsn", "cyrillicsh", "cyrillicshch", "cyrillicshha", "cyrillict", "cyrillictedc", "cyrillictetse", "cyrillictshe", "cyrillicu", "cyrillicudiaeresis", "cyrillicudoubleacute", "cyrillicuk", "cyrillicumacron", "cyrillicushrt", "cyrillicv", "cyrillicya", "cyrillicyat", "cyrillicyerudiaeresis", "cyrillicyi", "cyrillicyo", "cyrillicystr", "cyrillicystrstroke", "cyrillicyu", "cyrillicz", "cyrilliczdsc", "cyrilliczediaeresis", "cyrilliczh", "cyrilliczhebreve", "cyrilliczhedescender", "cyrilliczhediaeresis", "d", "dag", "dagger", "daleth", "dasharrow", "dashedleftarrow", "dashedrightarrow", "dashv", "datasetvariable", "date", "dayoftheweek", "dayspermonth", "dbinom", "dcaron", "dcurl", "ddag", "ddagger", "dddot", "ddot", "ddots", "decrement", "decrementcounter", "decrementedcounter", "decrementpagenumber", "decrementsubpagenumber", "decrementvalue", "defaultinterface", "defaultobjectpage", "defaultobjectreference", "defcatcodecommand", "defconvertedargument", "defconvertedcommand", "defconvertedvalue", "define", "defineMPinstance", "defineTABLEsetup", "defineaccent", "defineactivecharacter", "definealternativestyle", "defineanchor", "defineattachment", "defineattribute", "definebackground", "definebar", "defineblock", "definebodyfont", "definebodyfontenvironment", "definebodyfontswitch", "definebreakpoint", "definebreakpoints", "definebtx", "definebtxdataset", "definebtxregister", "definebtxrendering", "definebuffer", "definebutton", "definecapitals", "definecharacter", "definecharacterkerning", "definecharacterspacing", "definechemical", "definechemicals", "definechemicalsymbol", "definecollector", "definecolor", "definecolorgroup", "definecolumnbreak", "definecombination", "definecombinedlist", "definecommand", "definecomment", "definecomplexorsimple", "definecomplexorsimpleempty", "defineconversion", "defineconversionset", "definecounter", "definedataset", "definedelimitedtext", "definedeq", "definedescription", "definedfont", "defineeffect", "defineenumeration", "defineexpandable", "defineexternalfigure", "definefallbackfamily", "definefield", "definefieldbody", "definefieldbodyset", "definefieldcategory", "definefieldstack", "definefiguresymbol", "definefileconstant", "definefilefallback", "definefilesynonym", "definefiller", "definefirstline", "definefittingpage", "definefloat", "definefont", "definefontalternative", "definefontfallback", "definefontfamily", "definefontfamilypreset", "definefontfeature", "definefontfile", "definefontsize", "definefontsolution", "definefontstyle", "definefontsynonym", "defineformula", "defineformulaalternative", "defineformulaframed", "defineframed", "defineframedcontent", "defineframedtable", "defineframedtext", "definefrozenfont", "defineglobalcolor", "definegraphictypesynonym", "definegridsnapping", "definehbox", "definehead", "defineheadalternative", "definehelp", "definehigh", "definehighlight", "definehspace", "definehypenationfeatures", "defineindentedtext", "defineindenting", "defineinitial", "defineinsertion", "defineinteraction", "defineinteractionbar", "defineinteractionmenu", "defineinterfaceconstant", "defineinterfaceelement", "defineinterfacevariable", "defineinterlinespace", "defineintermediatecolor", "defineitemgroup", "defineitems", "definelabel", "definelabelclass", "definelayer", "definelayerpreset", "definelayout", "definelinefiller", "definelinenote", "definelinenumbering", "definelines", "definelist", "definelistalternative", "definelistextra", "definelow", "definelowhigh", "definelowmidhigh", "definemakeup", "definemarginblock", "definemargindata", "definemarker", "definemarking", "definemathaccent", "definemathalignment", "definemathcases", "definemathcommand", "definemathdouble", "definemathdoubleextensible", "definemathematics", "definemathextensible", "definemathfence", "definemathfraction", "definemathframed", "definemathmatrix", "definemathornament", "definemathover", "definemathoverextensible", "definemathovertextextensible", "definemathradical", "definemathstackers", "definemathstyle", "definemathtriplet", "definemathunder", "definemathunderextensible", "definemathundertextextensible", "definemathunstacked", "definemeasure", "definemessageconstant", "definemixedcolumns", "definemode", "definemultitonecolor", "definenamedcolor", "definenamespace", "definenarrower", "definenote", "defineornament", "defineoutputroutine", "defineoutputroutinecommand", "defineoverlay", "definepage", "definepagebreak", "definepagechecker", "definepagegrid", "definepagegridarea", "definepagegridspan", "definepageinjection", "definepageinjectionalternative", "definepageshift", "definepagestate", "definepairedbox", "definepalet", "definepapersize", "defineparagraph", "defineparagraphs", "defineparallel", "defineparbuilder", "defineplacement", "definepositioning", "defineprefixset", "defineprocesscolor", "defineprocessor", "defineprofile", "defineprogram", "definepushbutton", "definepushsymbol", "definereference", "definereferenceformat", "defineregister", "definerenderingwindow", "defineresetset", "definescale", "definescript", "definesection", "definesectionblock", "definesectionlevels", "defineselector", "defineseparatorset", "defineshift", "definesidebar", "definesort", "definesorting", "definespotcolor", "definestartstop", "definestyle", "definestyleinstance", "definesubfield", "definesubformula", "definesymbol", "definesynonym", "definesynonyms", "definesystemattribute", "definesystemconstant", "definesystemvariable", "definetabletemplate", "definetabulate", "definetabulation", "definetext", "definetextbackground", "definetextflow", "definetooltip", "definetransparency", "definetwopasslist", "definetype", "definetypeface", "definetypescriptprefix", "definetypescriptsynonym", "definetypesetting", "definetyping", "defineunit", "defineviewerlayer", "definevspace", "definevspacing", "definevspacingamount", "definextable", "delimited", "delimitedtext", "delta", "depthofstring", "depthonlybox", "depthspanningtext", "depthstrut", "determineheadnumber", "determinelistcharacteristics", "determinenoflines", "determineregistercharacteristics", "devanagarinumerals", "dfrac", "dhook", "diameter", "diamond", "diamondsuit", "differentialD", "differentiald", "digamma", "digits", "dimensiontocount", "directboxfromcache", "directcolor", "directcolored", "directconvertedcounter", "directcopyboxfromcache", "directdummyparameter", "directgetboxllx", "directgetboxlly", "directhighlight", "directlocalframed", "directluacode", "directselect", "directsetbar", "directsetup", "directsymbol", "directvspacing", "dis", "disabledirectives", "disableexperiments", "disablemode", "disableoutputstream", "disableparpositions", "disableregime", "disabletrackers", "displaymath", "displaymathematics", "displaymessage", "distributedhsize", "div", "dividedsize", "divideontimes", "divides", "doadaptleftskip", "doadaptrightskip", "doaddfeature", "doassign", "doassignempty", "doboundtext", "docheckassignment", "docheckedpagestate", "docheckedpair", "documentvariable", "dodoubleargument", "dodoubleargumentwithset", "dodoubleempty", "dodoubleemptywithset", "dodoublegroupempty", "doeassign", "doexpandedrecurse", "dofastloopcs", "dogetattribute", "dogetattributeid", "dogetcommacommandelement", "dogobbledoubleempty", "dogobblesingleempty", "doif", "doifMPgraphicelse", "doifallcommon", "doifallcommonelse", "doifalldefinedelse", "doifallmodes", "doifallmodeselse", "doifassignmentelse", "doifblackelse", "doifbothsides", "doifbothsidesoverruled", "doifboxelse", "doifbufferelse", "doifcolor", "doifcolorelse", "doifcommandhandler", "doifcommandhandlerelse", "doifcommon", "doifcommonelse", "doifcontent", "doifconversiondefinedelse", "doifconversionnumberelse", "doifcounter", "doifcounterelse", "doifcurrentfonthasfeatureelse", "doifdefined", "doifdefinedcounter", "doifdefinedcounterelse", "doifdefinedelse", "doifdimensionelse", "doifdimenstringelse", "doifdocumentargument", "doifdocumentargumentelse", "doifdocumentfilename", "doifdocumentfilenameelse", "doifdrawingblackelse", "doifelse", "doifelseMPgraphic", "doifelseallcommon", "doifelsealldefined", "doifelseallmodes", "doifelseassignment", "doifelseblack", "doifelsebox", "doifelseboxincache", "doifelsebuffer", "doifelsecolor", "doifelsecommandhandler", "doifelsecommon", "doifelseconversiondefined", "doifelseconversionnumber", "doifelsecounter", "doifelsecurrentfonthasfeature", "doifelsecurrentsortingused", "doifelsecurrentsynonymshown", "doifelsecurrentsynonymused", "doifelsedefined", "doifelsedefinedcounter", "doifelsedimension", "doifelsedimenstring", "doifelsedocumentargument", "doifelsedocumentfilename", "doifelsedrawingblack", "doifelseempty", "doifelseemptyvalue", "doifelseemptyvariable", "doifelseenv", "doifelsefastoptionalcheck", "doifelsefastoptionalcheckcs", "doifelsefieldbody", "doifelsefieldcategory", "doifelsefigure", "doifelsefile", "doifelsefiledefined", "doifelsefileexists", "doifelsefirstchar", "doifelseflagged", "doifelsefontchar", "doifelsefontpresent", "doifelsefontsynonym", "doifelsehasspace", "doifelsehelp", "doifelseincsname", "doifelseinelement", "doifelseinputfile", "doifelseinsertion", "doifelseinset", "doifelseinstring", "doifelseinsymbolset", "doifelseintoks", "doifelseintwopassdata", "doifelseitalic", "doifelselanguage", "doifelselayerdata", "doifelselayoutdefined", "doifelselayoutsomeline", "doifelselayouttextline", "doifelseleapyear", "doifelselist", "doifelselocation", "doifelselocfile", "doifelsemainfloatbody", "doifelsemarkedpage", "doifelsemarking", "doifelsemeaning", "doifelsemessage", "doifelsemode", "doifelsenextbgroup", "doifelsenextbgroupcs", "doifelsenextchar", "doifelsenextoptional", "doifelsenextoptionalcs", "doifelsenextparenthesis", "doifelsenonzeropositive", "doifelsenoteonsamepage", "doifelsenothing", "doifelsenumber", "doifelseobjectfound", "doifelseobjectreferencefound", "doifelseoddpage", "doifelseoddpagefloat", "doifelseoldercontext", "doifelseolderversion", "doifelseoverlapping", "doifelseoverlay", "doifelseparallel", "doifelseparentfile", "doifelsepath", "doifelsepathexists", "doifelsepatterns", "doifelseposition", "doifelsepositionaction", "doifelsepositiononpage", "doifelsepositionsonsamepage", "doifelsepositionsonthispage", "doifelsepositionsused", "doifelsereferencefound", "doifelserightpagefloat", "doifelserighttoleftinbox", "doifelsesamelinereference", "doifelsesamestring", "doifelsesetups", "doifelsesomebackground", "doifelsesomespace", "doifelsesomething", "doifelsesometoks", "doifelsestringinstring", "doifelsestructurelisthasnumber", "doifelsestructurelisthaspage", "doifelsesymboldefined", "doifelsesymbolset", "doifelsetext", "doifelsetextflow", "doifelsetextflowcollector", "doifelsetopofpage", "doifelsetypingfile", "doifelseundefined", "doifelseurldefined", "doifelsevalue", "doifelsevaluenothing", "doifelsevariable", "doifempty", "doifemptyelse", "doifemptytoks", "doifemptyvalue", "doifemptyvalueelse", "doifemptyvariable", "doifemptyvariableelse", "doifenv", "doifenvelse", "doiffastoptionalcheckcselse", "doiffastoptionalcheckelse", "doiffieldbodyelse", "doiffieldcategoryelse", "doiffigureelse", "doiffile", "doiffiledefinedelse", "doiffileelse", "doiffileexistselse", "doiffirstcharelse", "doifflaggedelse", "doiffontcharelse", "doiffontpresentelse", "doiffontsynonymelse", "doifhasspaceelse", "doifhelpelse", "doifincsnameelse", "doifinelementelse", "doifinputfileelse", "doifinsertionelse", "doifinset", "doifinsetelse", "doifinstring", "doifinstringelse", "doifinsymbolset", "doifinsymbolsetelse", "doifintokselse", "doifintwopassdataelse", "doifitalicelse", "doiflanguageelse", "doiflayerdataelse", "doiflayoutdefinedelse", "doiflayoutsomelineelse", "doiflayouttextlineelse", "doifleapyearelse", "doiflistelse", "doiflocationelse", "doiflocfileelse", "doifmainfloatbodyelse", "doifmarkingelse", "doifmeaningelse", "doifmessageelse", "doifmode", "doifmodeelse", "doifnextbgroupcselse", "doifnextbgroupelse", "doifnextcharelse", "doifnextoptionalcselse", "doifnextoptionalelse", "doifnextparenthesiselse", "doifnonzeropositiveelse", "doifnot", "doifnotallcommon", "doifnotallmodes", "doifnotcommandhandler", "doifnotcommon", "doifnotcounter", "doifnotdocumentargument", "doifnotdocumentfilename", "doifnotempty", "doifnotemptyvalue", "doifnotemptyvariable", "doifnotenv", "doifnoteonsamepageelse", "doifnotescollected", "doifnotfile", "doifnotflagged", "doifnothing", "doifnothingelse", "doifnotinset", "doifnotinsidesplitfloat", "doifnotinstring", "doifnotmode", "doifnotnumber", "doifnotsamestring", "doifnotsetups", "doifnotvalue", "doifnotvariable", "doifnumber", "doifnumberelse", "doifobjectfoundelse", "doifobjectreferencefoundelse", "doifoddpageelse", "doifoddpagefloatelse", "doifoldercontextelse", "doifolderversionelse", "doifoverlappingelse", "doifoverlayelse", "doifparallelelse", "doifparentfileelse", "doifpathelse", "doifpathexistselse", "doifpatternselse", "doifposition", "doifpositionaction", "doifpositionactionelse", "doifpositionelse", "doifpositiononpageelse", "doifpositionsonsamepageelse", "doifpositionsonthispageelse", "doifpositionsusedelse", "doifreferencefoundelse", "doifrightpagefloatelse", "doifrighttoleftinboxelse", "doifsamelinereferenceelse", "doifsamestring", "doifsamestringelse", "doifsetups", "doifsetupselse", "doifsomebackground", "doifsomebackgroundelse", "doifsomespaceelse", "doifsomething", "doifsomethingelse", "doifsometoks", "doifsometokselse", "doifstringinstringelse", "doifstructurelisthasnumberelse", "doifstructurelisthaspageelse", "doifsymboldefinedelse", "doifsymbolsetelse", "doiftext", "doiftextelse", "doiftextflowcollectorelse", "doiftextflowelse", "doiftopofpageelse", "doiftypingfileelse", "doifundefined", "doifundefinedcounter", "doifundefinedelse", "doifurldefinedelse", "doifvalue", "doifvalueelse", "doifvaluenothing", "doifvaluenothingelse", "doifvaluesomething", "doifvariable", "doifvariableelse", "doindentation", "dollar", "doloop", "doloopoverlist", "donothing", "dontconvertfont", "dontleavehmode", "dontpermitspacesbetweengroups", "dopositionaction", "doprocesslocalsetups", "doquadrupleargument", "doquadrupleempty", "doquadruplegroupempty", "doquintupleargument", "doquintupleempty", "doquintuplegroupempty", "dorechecknextindentation", "dorecurse", "dorepeatwithcommand", "doreplacefeature", "doresetandafffeature", "doresetattribute", "dorotatebox", "dosetattribute", "dosetleftskipadaption", "dosetrightskipadaption", "dosetupcheckedinterlinespace", "doseventupleargument", "doseventupleempty", "dosingleargument", "dosingleempty", "dosinglegroupempty", "dosixtupleargument", "dosixtupleempty", "dostepwiserecurse", "dosubtractfeature", "dot", "doteq", "doteqdot", "dotfskip", "dotlessI", "dotlessJ", "dotlessi", "dotlessj", "dotlessjstroke", "dotminus", "dotoks", "dotplus", "dotripleargument", "dotripleargumentwithset", "dotripleempty", "dotripleemptywithset", "dotriplegroupempty", "dots", "dottedcircle", "dottedrightarrow", "doublebar", "doublebond", "doublebrace", "doublebracket", "doublecap", "doublecup", "doubleparent", "doubleprime", "doubleverticalbar", "dowith", "dowithnextbox", "dowithnextboxcontent", "dowithnextboxcontentcs", "dowithnextboxcs", "dowithpargument", "dowithrange", "dowithwargument", "downarrow", "downdasharrow", "downdownarrows", "downharpoonleft", "downharpoonright", "downuparrows", "downwhitearrow", "downzigzagarrow", "dpofstring", "dstroke", "dtail", "dummydigit", "dummyparameter", "dzcaronligature", "dzligature", "eTeX", "eacute", "ebreve", "ecaron", "ecedilla", "ecircumflex", "ecircumflexacute", "ecircumflexdotbelow", "ecircumflexgrave", "ecircumflexhook", "ecircumflextilde", "edefconvertedargument", "ediaeresis", "edotaccent", "edotbelow", "edoublegrave", "efcmaxheight", "efcmaxwidth", "efcminheight", "efcminwidth", "efcparameter", "effect", "egrave", "ehook", "einvertedbreve", "elapsedseconds", "elapsedtime", "eleftarrowfill", "eleftharpoondownfill", "eleftharpoonupfill", "eleftrightarrowfill", "ell", "em", "emacron", "emdash", "emphasisboldface", "emphasistypeface", "emptylines", "emptyset", "emquad", "emspace", "enabledirectives", "enableexperiments", "enablemode", "enableoutputstream", "enableparpositions", "enableregime", "enabletrackers", "endash", "endnote", "enquad", "enskip", "enspace", "env", "environment", "envvar", "eogonek", "eoverbarfill", "eoverbracefill", "eoverbracketfill", "eoverparentfill", "epos", "epsilon", "eq", "eqcirc", "eqeq", "eqeqeq", "eqgtr", "eqless", "eqsim", "eqslantgtr", "eqslantless", "equaldigits", "equalscolon", "equiv", "erightarrowfill", "erightharpoondownfill", "erightharpoonupfill", "eta", "eth", "ethiopic", "etilde", "etwoheadrightarrowfill", "eunderbarfill", "eunderbracefill", "eunderbracketfill", "eunderparentfill", "exclamdown", "executeifdefined", "exists", "exitloop", "exitloopnow", "expandcheckedcsname", "expanded", "expandfontsynonym", "expdoif", "expdoifcommonelse", "expdoifelse", "expdoifelsecommon", "expdoifelseinset", "expdoifinsetelse", "expdoifnot", "exponentiale", "externalfigure", "externalfigurecollectionmaxheight", "externalfigurecollectionmaxwidth", "externalfigurecollectionminheight", "externalfigurecollectionminwidth", "externalfigurecollectionparameter", "fakebox", "fallingdotseq", "fastdecrement", "fastincrement", "fastlocalframed", "fastloopfinal", "fastloopindex", "fastscale", "fastsetup", "fastsetupwithargument", "fastsetupwithargumentswapped", "fastswitchtobodyfont", "fastsxsy", "feature", "fence", "fenced", "fetchallmarkings", "fetchallmarks", "fetchmark", "fetchmarking", "fetchonemark", "fetchonemarking", "fetchruntinecommand", "fetchtwomarkings", "fetchtwomarks", "ffiligature", "ffligature", "fflligature", "fhook", "field", "fieldbody", "fieldstack", "fifthoffivearguments", "fifthofsixarguments", "figurefilename", "figurefilepath", "figurefiletype", "figurefullname", "figureheight", "figurenaturalheight", "figurenaturalwidth", "figurespace", "figuresymbol", "figurewidth", "filename", "filigature", "filledhboxb", "filledhboxc", "filledhboxg", "filledhboxk", "filledhboxm", "filledhboxr", "filledhboxy", "filler", "fillinline", "fillinrules", "fillintext", "filterfromnext", "filterfromvalue", "filterpages", "filterreference", "findtwopassdata", "finishregisterentry", "firstcharacter", "firstcounter", "firstcountervalue", "firstoffivearguments", "firstoffourarguments", "firstofoneargument", "firstofoneunexpanded", "firstofsixarguments", "firstofthreearguments", "firstofthreeunexpanded", "firstoftwoarguments", "firstoftwounexpanded", "firstrealpage", "firstrealpagenumber", "firstsubcountervalue", "firstsubpage", "firstsubpagenumber", "firstuserpage", "firstuserpagenumber", "fitfield", "fitfieldframed", "fittopbaselinegrid", "fiveeighths", "fivesixths", "fixedspace", "fixedspaces", "flag", "flat", "flligature", "floatuserdataparameter", "flushbox", "flushboxregister", "flushcollector", "flushedrightlastline", "flushlayer", "flushlocalfloats", "flushnextbox", "flushnotes", "flushoutputstream", "flushshapebox", "flushtextflow", "flushtokens", "flushtoks", "fontalternative", "fontbody", "fontchar", "fontcharbyindex", "fontclass", "fontclassname", "fontface", "fontfeaturelist", "fontsize", "fontstyle", "footnote", "footnotetext", "forall", "forcecharacterstripping", "forcelocalfloats", "forgeteverypar", "forgetparameters", "forgetragged", "formula", "formulanumber", "foundbox", "fourfifths", "fourperemspace", "fourthoffivearguments", "fourthoffourarguments", "fourthofsixarguments", "frac", "framed", "frameddimension", "framedparameter", "framedtext", "freezedimenmacro", "freezemeasure", "frenchspacing", "from", "fromlinenote", "frown", "frozenhbox", "frule", "gacute", "gamma", "gbreve", "gcaron", "gcircumflex", "gcommaaccent", "gdefconvertedargument", "gdefconvertedcommand", "gdotaccent", "ge", "geq", "geqq", "geqslant", "getMPdrawing", "getMPlayer", "getboxfromcache", "getboxllx", "getboxlly", "getbuffer", "getbufferdata", "getcommacommandsize", "getcommalistsize", "getdayoftheweek", "getdayspermonth", "getdefinedbuffer", "getdocumentargument", "getdocumentargumentdefault", "getdocumentfilename", "getdummyparameters", "getemptyparameters", "geteparameters", "getexpandedparameters", "getfiguredimensions", "getfirstcharacter", "getfirsttwopassdata", "getfromcommacommand", "getfromcommalist", "getfromtwopassdata", "getglyphdirect", "getglyphstyled", "getgparameters", "getlasttwopassdata", "getlocalfloat", "getlocalfloats", "getmarking", "getmessage", "getnamedglyphdirect", "getnamedglyphstyled", "getnamedtwopassdatalist", "getnaturaldimensions", "getnoflines", "getobject", "getobjectdimensions", "getpaletsize", "getparameters", "getprivatechar", "getprivateslot", "getrandomcount", "getrandomdimen", "getrandomfloat", "getrandomnumber", "getrandomseed", "getraweparameters", "getrawgparameters", "getrawnoflines", "getrawparameters", "getrawxparameters", "getreference", "getreferenceentry", "getroundednoflines", "gets", "getsubstring", "gettwopassdata", "gettwopassdatalist", "getuvalue", "getvalue", "getvariable", "getvariabledefault", "getxparameters", "gg", "ggg", "gggtr", "gimel", "globaldisablemode", "globalenablemode", "globalletempty", "globalpopbox", "globalpopmacro", "globalpreventmode", "globalprocesscommalist", "globalpushbox", "globalpushmacro", "globalswapcounts", "globalswapdimens", "globalswapmacros", "globalundefine", "glyphfontfile", "gnapprox", "gneqq", "gnsim", "gobbledoubleempty", "gobbleeightarguments", "gobblefivearguments", "gobblefiveoptionals", "gobblefourarguments", "gobblefouroptionals", "gobbleninearguments", "gobbleoneargument", "gobbleoneoptional", "gobblesevenarguments", "gobblesingleempty", "gobblesixarguments", "gobblespacetokens", "gobbletenarguments", "gobblethreearguments", "gobblethreeoptionals", "gobbletwoarguments", "gobbletwooptionals", "gobbleuntil", "gobbleuntilrelax", "godown", "goto", "gotobox", "gotopage", "grabbufferdata", "grabbufferdatadirect", "grabuntil", "grave", "graycolor", "grayvalue", "greedysplitstring", "greekAlpha", "greekAlphadasia", "greekAlphadasiaperispomeni", "greekAlphadasiatonos", "greekAlphadasiavaria", "greekAlphaiotasub", "greekAlphaiotasubdasia", "greekAlphaiotasubdasiaperispomeni", "greekAlphaiotasubdasiatonos", "greekAlphaiotasubdasiavaria", "greekAlphaiotasubpsili", "greekAlphaiotasubpsiliperispomeni", "greekAlphaiotasubpsilitonos", "greekAlphaiotasubpsilivaria", "greekAlphamacron", "greekAlphapsili", "greekAlphapsiliperispomeni", "greekAlphapsilitonos", "greekAlphapsilivaria", "greekAlphatonos", "greekAlphavaria", "greekAlphavrachy", "greekBeta", "greekChi", "greekCoronis", "greekDelta", "greekEpsilon", "greekEpsilondasia", "greekEpsilondasiatonos", "greekEpsilondasiavaria", "greekEpsilonpsili", "greekEpsilonpsilitonos", "greekEpsilonpsilivaria", "greekEpsilontonos", "greekEpsilonvaria", "greekEta", "greekEtadasia", "greekEtadasiaperispomeni", "greekEtadasiatonos", "greekEtadasiavaria", "greekEtaiotasub", "greekEtaiotasubdasia", "greekEtaiotasubdasiaperispomeni", "greekEtaiotasubdasiatonos", "greekEtaiotasubdasiavaria", "greekEtaiotasubpsili", "greekEtaiotasubpsiliperispomeni", "greekEtaiotasubpsilitonos", "greekEtaiotasubpsilivaria", "greekEtapsili", "greekEtapsiliperispomeni", "greekEtapsilitonos", "greekEtapsilivaria", "greekEtatonos", "greekEtavaria", "greekGamma", "greekIota", "greekIotadasia", "greekIotadasiaperispomeni", "greekIotadasiatonos", "greekIotadasiavaria", "greekIotadialytika", "greekIotamacron", "greekIotapsili", "greekIotapsiliperispomeni", "greekIotapsilitonos", "greekIotapsilivaria", "greekIotatonos", "greekIotavaria", "greekIotavrachy", "greekKappa", "greekLambda", "greekMu", "greekNu", "greekOmega", "greekOmegadasia", "greekOmegadasiaperispomeni", "greekOmegadasiatonos", "greekOmegadasiavaria", "greekOmegaiotasub", "greekOmegaiotasubdasia", "greekOmegaiotasubdasiaperispomeni", "greekOmegaiotasubdasiatonos", "greekOmegaiotasubdasiavaria", "greekOmegaiotasubpsili", "greekOmegaiotasubpsiliperispomeni", "greekOmegaiotasubpsilitonos", "greekOmegaiotasubpsilivaria", "greekOmegapsili", "greekOmegapsiliperispomeni", "greekOmegapsilitonos", "greekOmegapsilivaria", "greekOmegatonos", "greekOmegavaria", "greekOmicron", "greekOmicrondasia", "greekOmicrondasiatonos", "greekOmicrondasiavaria", "greekOmicronpsili", "greekOmicronpsilitonos", "greekOmicronpsilivaria", "greekOmicrontonos", "greekOmicronvaria", "greekPhi", "greekPi", "greekPsi", "greekRho", "greekRhodasia", "greekSigma", "greekSigmalunate", "greekTau", "greekTheta", "greekUpsilon", "greekUpsilondasia", "greekUpsilondasiaperispomeni", "greekUpsilondasiatonos", "greekUpsilondasiavaria", "greekUpsilondialytika", "greekUpsilonmacron", "greekUpsilontonos", "greekUpsilonvaria", "greekUpsilonvrachy", "greekXi", "greekZeta", "greekalpha", "greekalphadasia", "greekalphadasiaperispomeni", "greekalphadasiatonos", "greekalphadasiavaria", "greekalphaiotasub", "greekalphaiotasubdasia", "greekalphaiotasubdasiaperispomeni", "greekalphaiotasubdasiatonos", "greekalphaiotasubdasiavaria", "greekalphaiotasubperispomeni", "greekalphaiotasubpsili", "greekalphaiotasubpsiliperispomeni", "greekalphaiotasubpsilitonos", "greekalphaiotasubpsilivaria", "greekalphaiotasubtonos", "greekalphaiotasubvaria", "greekalphamacron", "greekalphaoxia", "greekalphaperispomeni", "greekalphapsili", "greekalphapsiliperispomeni", "greekalphapsilitonos", "greekalphapsilivaria", "greekalphatonos", "greekalphavaria", "greekalphavrachy", "greekbeta", "greekchi", "greekdasia", "greekdasiaperispomeni", "greekdasiatonos", "greekdasiavaria", "greekdelta", "greekdialytikaperispomeni", "greekdialytikatonos", "greekdialytikavaria", "greekdigamma", "greekepsilon", "greekepsilonalt", "greekepsilondasia", "greekepsilondasiatonos", "greekepsilondasiavaria", "greekepsilonoxia", "greekepsilonpsili", "greekepsilonpsilitonos", "greekepsilonpsilivaria", "greekepsilontonos", "greekepsilonvaria", "greeketa", "greeketadasia", "greeketadasiaperispomeni", "greeketadasiatonos", "greeketadasiavaria", "greeketaiotasub", "greeketaiotasubdasia", "greeketaiotasubdasiaperispomeni", "greeketaiotasubdasiatonos", "greeketaiotasubdasiavaria", "greeketaiotasubperispomeni", "greeketaiotasubpsili", "greeketaiotasubpsiliperispomeni", "greeketaiotasubpsilitonos", "greeketaiotasubpsilivaria", "greeketaiotasubtonos", "greeketaiotasubvaria", "greeketaoxia", "greeketaperispomeni", "greeketapsili", "greeketapsiliperispomeni", "greeketapsilitonos", "greeketapsilivaria", "greeketatonos", "greeketavaria", "greekfinalsigma", "greekgamma", "greekiota", "greekiotadasia", "greekiotadasiaperispomeni", "greekiotadasiatonos", "greekiotadasiavaria", "greekiotadialytika", "greekiotadialytikaperispomeni", "greekiotadialytikatonos", "greekiotadialytikavaria", "greekiotamacron", "greekiotaoxia", "greekiotaperispomeni", "greekiotapsili", "greekiotapsiliperispomeni", "greekiotapsilitonos", "greekiotapsilivaria", "greekiotatonos", "greekiotavaria", "greekiotavrachy", "greekkappa", "greekkoppa", "greeklambda", "greekmu", "greeknu", "greeknumerals", "greeknumkoppa", "greekomega", "greekomegadasia", "greekomegadasiaperispomeni", "greekomegadasiatonos", "greekomegadasiavaria", "greekomegaiotasub", "greekomegaiotasubdasia", "greekomegaiotasubdasiaperispomeni", "greekomegaiotasubdasiatonos", "greekomegaiotasubdasiavaria", "greekomegaiotasubperispomeni", "greekomegaiotasubpsili", "greekomegaiotasubpsiliperispomeni", "greekomegaiotasubpsilitonos", "greekomegaiotasubpsilivaria", "greekomegaiotasubtonos", "greekomegaiotasubvaria", "greekomegaoxia", "greekomegaperispomeni", "greekomegapsili", "greekomegapsiliperispomeni", "greekomegapsilitonos", "greekomegapsilivaria", "greekomegatonos", "greekomegavaria", "greekomicron", "greekomicrondasia", "greekomicrondasiatonos", "greekomicrondasiavaria", "greekomicronoxia", "greekomicronpsili", "greekomicronpsilitonos", "greekomicronpsilivaria", "greekomicrontonos", "greekomicronvaria", "greekoxia", "greekperispomeni", "greekphi", "greekphialt", "greekpi", "greekpialt", "greekprosgegrammeni", "greekpsi", "greekpsili", "greekpsiliperispomeni", "greekpsilitonos", "greekpsilivaria", "greekrho", "greekrhoalt", "greekrhodasia", "greekrhopsili", "greeksampi", "greeksigma", "greeksigmalunate", "greekstigma", "greektau", "greektheta", "greekthetaalt", "greektonos", "greekupsilon", "greekupsilondasia", "greekupsilondasiaperispomeni", "greekupsilondasiatonos", "greekupsilondasiavaria", "greekupsilondiaeresis", "greekupsilondialytikaperispomeni", "greekupsilondialytikatonos", "greekupsilondialytikavaria", "greekupsilonmacron", "greekupsilonoxia", "greekupsilonperispomeni", "greekupsilonpsili", "greekupsilonpsiliperispomeni", "greekupsilonpsilitonos", "greekupsilonpsilivaria", "greekupsilontonos", "greekupsilonvaria", "greekupsilonvrachy", "greekvaria", "greekxi", "greekzeta", "grid", "groupedcommand", "gsetboxllx", "gsetboxlly", "gstroke", "gt", "gtrapprox", "gtrdot", "gtreqless", "gtreqqless", "gtrless", "gtrsim", "guilsingleleft", "guilsingleright", "gujaratinumerals", "gurmurkhinumerals", "hairline", "hairspace", "halflinestrut", "halfstrut", "halfwaybox", "handletokens", "handwritten", "hangul", "hanzi", "hash", "hat", "hbar", "hboxofvbox", "hboxreference", "hcaron", "hcircumflex", "hdofstring", "headhbox", "headlanguage", "headnumber", "headnumbercontent", "headnumberdistance", "headnumberwidth", "headreferenceattributes", "headsetupspacing", "headtext", "headtextcontent", "headtextdistance", "headtexts", "headtextwidth", "headvbox", "headwidth", "heartsuit", "hebrewAlef", "hebrewAyin", "hebrewBet", "hebrewDalet", "hebrewGimel", "hebrewHe", "hebrewHet", "hebrewKaf", "hebrewKaffinal", "hebrewLamed", "hebrewMem", "hebrewMemfinal", "hebrewNun", "hebrewNunfinal", "hebrewPe", "hebrewPefinal", "hebrewQof", "hebrewResh", "hebrewSamekh", "hebrewShin", "hebrewTav", "hebrewTet", "hebrewTsadi", "hebrewTsadifinal", "hebrewVav", "hebrewYod", "hebrewZayin", "heightanddepthofstring", "heightofstring", "heightspanningtext", "helptext", "hglue", "hiddenbar", "hiddencitation", "hiddencite", "hideblocks", "high", "highlight", "highordinalstr", "hilo", "himilo", "hl", "hookleftarrow", "hookrightarrow", "horizontalgrowingbar", "horizontalpositionbar", "hphantom", "hpos", "hsizefraction", "hslash", "hsmash", "hsmashbox", "hsmashed", "hspace", "hstroke", "htdpofstring", "htofstring", "hyphen", "hyphenatedcoloredword", "hyphenatedfile", "hyphenatedfilename", "hyphenatedhbox", "hyphenatedpar", "hyphenatedurl", "hyphenatedword", "iacute", "ibox", "ibreve", "icaron", "icircumflex", "ideographichalffillspace", "ideographicspace", "idiaeresis", "idotaccent", "idotbelow", "idoublegrave", "ifassignment", "iff", "ifinobject", "ifinoutputstream", "ifparameters", "iftrialtypesetting", "ignoreimplicitspaces", "ignorevalue", "igrave", "ihook", "iiiint", "iiiintop", "iiint", "iiintop", "iint", "iintop", "iinvertedbreve", "ijligature", "imacron", "imaginaryi", "imaginaryj", "imath", "immediatesavetwopassdata", "impliedby", "implies", "imply", "in", "includemenu", "includeversioninfo", "increment", "incrementcounter", "incrementedcounter", "incrementpagenumber", "incrementsubpagenumber", "incrementvalue", "indentation", "index", "infofont", "infofontbold", "inframed", "infty", "infull", "inheritparameter", "inhibitblank", "ininner", "ininneredge", "ininnermargin", "initializeboxstack", "inleft", "inleftedge", "inleftmargin", "inline", "inlinebuffer", "inlinedbox", "inlinemath", "inlinemathematics", "inlinemessage", "inlineordisplaymath", "inlineprettyprintbuffer", "inlinerange", "inmargin", "inmframed", "innerflushshapebox", "inother", "inouter", "inouteredge", "inoutermargin", "input", "inputfilebarename", "inputfilename", "inputfilerealsuffix", "inputfilesuffix", "inputgivenfile", "inright", "inrightedge", "inrightmargin", "insertpages", "installactionhandler", "installactivecharacter", "installanddefineactivecharacter", "installattributestack", "installautocommandhandler", "installautosetuphandler", "installbasicautosetuphandler", "installbasicparameterhandler", "installbottomframerenderer", "installcommandhandler", "installcorenamespace", "installdefinehandler", "installdefinitionset", "installdefinitionsetmember", "installdirectcommandhandler", "installdirectparameterhandler", "installdirectparametersethandler", "installdirectsetuphandler", "installdirectstyleandcolorhandler", "installframedautocommandhandler", "installframedcommandhandler", "installlanguage", "installleftframerenderer", "installnamespace", "installoutputroutine", "installpagearrangement", "installparameterhandler", "installparameterhashhandler", "installparametersethandler", "installparentinjector", "installrightframerenderer", "installrootparameterhandler", "installsetuphandler", "installsetuponlycommandhandler", "installshipoutmethod", "installsimplecommandhandler", "installsimpleframedcommandhandler", "installstyleandcolorhandler", "installswitchcommandhandler", "installswitchsetuphandler", "installtexdirective", "installtextracker", "installtopframerenderer", "installunitsseparator", "installunitsspace", "installversioninfo", "int", "intclockwise", "integerrounding", "integers", "interactionbar", "interactionbuttons", "interactionmenu", "intercal", "intertext", "intop", "invisibletimes", "invokepageheandler", "iogonek", "iota", "istltdir", "istrtdir", "italic", "italicbold", "italiccorrection", "italicface", "item", "items", "itemtag", "itilde", "jcaron", "jcircumflex", "jmath", "jobfilename", "jobfilesuffix", "kap", "kappa", "kcaron", "kcommaaccent", "keepblocks", "keeplinestogether", "keepunwantedspaces", "kerncharacters", "khook", "kkra", "koreancirclenumerals", "koreannumerals", "koreannumeralsc", "koreannumeralsp", "koreanparentnumerals", "lVert", "labellanguage", "labeltext", "labeltexts", "lacute", "lambda", "lambdabar", "land", "langle", "language", "languageCharacters", "languagecharacters", "languagecharwidth", "lastcounter", "lastcountervalue", "lastdigit", "lastlinewidth", "lastnaturalboxdp", "lastnaturalboxht", "lastnaturalboxwd", "lastpredefinedsymbol", "lastrealpage", "lastrealpagenumber", "lastsubcountervalue", "lastsubpage", "lastsubpagenumber", "lasttwodigits", "lastuserpage", "lastuserpagenumber", "lateluacode", "latin", "layeredtext", "layerheight", "layerwidth", "lazysavetaggedtwopassdata", "lazysavetwopassdata", "lbar", "lbox", "lbrace", "lbracket", "lcaron", "lceil", "lcommaaccent", "lcurl", "ldotmiddle", "ldotp", "ldots", "le", "leadsto", "left", "leftaligned", "leftarrow", "leftarrowtail", "leftarrowtriangle", "leftbottombox", "leftbox", "leftdasharrow", "leftguillemot", "leftharpoondown", "leftharpoonup", "lefthbox", "leftheadtext", "leftlabeltext", "leftleftarrows", "leftline", "leftmathlabeltext", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "leftrightarrow", "leftrightarrows", "leftrightarrowtriangle", "leftrightharpoons", "leftrightsquigarrow", "leftskipadaption", "leftsquigarrow", "leftsubguillemot", "leftthreetimes", "lefttopbox", "lefttoright", "lefttorighthbox", "lefttorightvbox", "lefttorightvtop", "leftwavearrow", "leftwhitearrow", "leq", "leqq", "leqslant", "lessapprox", "lessdot", "lesseqgtr", "lesseqqgtr", "lessgtr", "lesssim", "letbeundefined", "letcatcodecommand", "letcscsname", "letcsnamecs", "letcsnamecsname", "letdummyparameter", "letempty", "letgvalue", "letgvalueempty", "letgvalurelax", "letterampersand", "letterat", "letterbackslash", "letterbar", "letterbgroup", "letterclosebrace", "lettercolon", "letterdollar", "letterdoublequote", "letteregroup", "letterescape", "letterexclamationmark", "letterhash", "letterhat", "letterleftbrace", "letterleftbracket", "letterleftparenthesis", "letterless", "lettermore", "letteropenbrace", "letterpercent", "letterquestionmark", "letterrightbrace", "letterrightbracket", "letterrightparenthesis", "lettersinglequote", "letterslash", "letterspacing", "lettertilde", "letterunderscore", "letvalue", "letvalueempty", "letvaluerelax", "lfence", "lfloor", "lgroup", "lhbox", "lhooknwarrow", "lhooksearrow", "limitatefirstline", "limitatelines", "limitatetext", "line", "linefeed", "linenote", "linespanningtext", "linethickness", "linterval", "listcitation", "listcite", "listlength", "listnamespaces", "ljligature", "ll", "llangle", "llap", "llbracket", "llcorner", "lll", "llless", "lmoustache", "lnapprox", "lneq", "lneqq", "lnot", "lnsim", "loadanyfile", "loadanyfileonce", "loadbtxdefinitionfile", "loadbtxreplacementfile", "loadcldfile", "loadcldfileonce", "loadfontgoodies", "loadluafile", "loadluafileonce", "loadspellchecklist", "loadtexfile", "loadtexfileonce", "loadtypescriptfile", "localframed", "localframedwithsettings", "localhsize", "localpopbox", "localpopmacro", "localpushbox", "localpushmacro", "localundefine", "locatedfilepath", "locatefilepath", "locfilename", "logo", "lohi", "lointerval", "lomihi", "longleftarrow", "longleftrightarrow", "longmapsfrom", "longmapsto", "longrightarrow", "longrightsquigarrow", "looparrowleft", "looparrowright", "lor", "low", "lowerbox", "lowercased", "lowercasestring", "lowerleftdoubleninequote", "lowerleftsingleninequote", "lowerrightdoubleninequote", "lowerrightsingleninequote", "lozenge", "lparent", "lrcorner", "lrointerval", "lrtbbox", "lstroke", "lt", "ltimes", "ltop", "luaTeX", "luacode", "luaconditional", "luaenvironment", "luaexpanded", "luaexpr", "luafunction", "luajitTeX", "luamajorversion", "luaminorversion", "luaparameterset", "luasetup", "luaversion", "lvert", "m", "mLeftarrow", "mLeftrightarrow", "mRightarrow", "mainlanguage", "makecharacteractive", "makerawcommalist", "makestrutofbox", "maltese", "mapfontsize", "mapsdown", "mapsfrom", "mapsto", "mapsup", "margindata", "margintext", "markcontent", "marking", "markinjector", "markpage", "mat", "math", "mathampersand", "mathbf", "mathbi", "mathblackboard", "mathbs", "mathdefault", "mathdollar", "mathdouble", "mathematics", "mathfraktur", "mathfunction", "mathhash", "mathhyphen", "mathit", "mathitalic", "mathlabellanguage", "mathlabeltext", "mathlabeltexts", "mathop", "mathover", "mathpercent", "mathrm", "mathscript", "mathsl", "mathss", "mathtext", "mathtextbf", "mathtextbi", "mathtextbs", "mathtextit", "mathtextsl", "mathtexttf", "mathtf", "mathtriplet", "mathtt", "mathunder", "mathupright", "mathword", "mathwordbf", "mathwordbi", "mathwordbs", "mathwordit", "mathwordsl", "mathwordtf", "maxaligned", "mbox", "mcframed", "measure", "measured", "measuredangle", "measuredeq", "medskip", "medspace", "menubutton", "mequal", "message", "metaTeX", "mfence", "mframed", "mfunction", "mfunctionlabeltext", "mhbox", "mho", "mhookleftarrow", "mhookrightarrow", "mid", "midaligned", "middle", "middlealigned", "middlebox", "midhbox", "midsubsentence", "minimalhbox", "minus", "minuscolon", "mirror", "mixedcaps", "mkvibuffer", "mleftarrow", "mleftharpoondown", "mleftharpoonup", "mleftrightarrow", "mleftrightharpoons", "mmapsto", "models", "moduleparameter", "molecule", "mono", "monobold", "mononormal", "month", "monthlong", "monthshort", "mp", "mprandomnumber", "mrel", "mrightarrow", "mrightharpoondown", "mrightharpoonup", "mrightleftharpoons", "mrightoverleftarrow", "mtext", "mtriplerel", "mtwoheadleftarrow", "mtwoheadrightarrow", "mu", "multimap", "nHdownarrow", "nHuparrow", "nLeftarrow", "nLeftrightarrow", "nRightarrow", "nVDash", "nVdash", "nVleftarrow", "nVleftrightarrow", "nVrightarrow", "nabla", "nacute", "namedheadnumber", "namedstructureheadlocation", "namedstructureuservariable", "namedstructurevariable", "namedtaggedlabeltexts", "napostrophe", "napprox", "napproxEq", "narrownobreakspace", "nasymp", "natural", "naturalhbox", "naturalhpack", "naturalnumbers", "naturalvbox", "naturalvcenter", "naturalvpack", "naturalvtop", "naturalwd", "ncaron", "ncommaaccent", "ncong", "ncurl", "ndivides", "ne", "nearrow", "neg", "negatecolorbox", "negated", "negativesign", "negthinspace", "neng", "neq", "nequiv", "neswarrow", "newattribute", "newcatcodetable", "newcounter", "newevery", "newfrenchspacing", "newmode", "newsignal", "newsystemmode", "nexists", "nextbox", "nextboxdp", "nextboxht", "nextboxhtdp", "nextboxwd", "nextcounter", "nextcountervalue", "nextdepth", "nextparagraphs", "nextrealpage", "nextrealpagenumber", "nextsubcountervalue", "nextsubpage", "nextsubpagenumber", "nextuserpage", "nextuserpagenumber", "ngeq", "ngrave", "ngtr", "ngtrless", "ngtrsim", "ni", "nihongo", "nin", "njligature", "nleftarrow", "nleftrightarrow", "nleq", "nless", "nlessgtr", "nlesssim", "nmid", "nni", "nobar", "nobreakspace", "nocap", "nocitation", "nocite", "nodetostring", "noffigurepages", "noflines", "noflocalfloats", "noheaderandfooterlines", "noheightstrut", "noindentation", "noitem", "nonfrenchspacing", "nonmathematics", "normal", "normalboldface", "normalframedwithsettings", "normalitalicface", "normalizebodyfontsize", "normalizedfontsize", "normalizefontdepth", "normalizefontheight", "normalizefontline", "normalizefontwidth", "normalizetextdepth", "normalizetextheight", "normalizetextline", "normalizetextwidth", "normalslantedface", "normaltypeface", "nospace", "not", "note", "notesymbol", "notin", "notopandbottomlines", "notragged", "nowns", "nparallel", "nprec", "npreccurlyeq", "nrightarrow", "nsim", "nsimeq", "nsqsubseteq", "nsqsupseteq", "nsubset", "nsubseteq", "nsucc", "nsucccurlyeq", "nsupset", "nsupseteq", "ntilde", "ntimes", "ntriangleleft", "ntrianglelefteq", "ntriangleright", "ntrianglerighteq", "nu", "numberofpoints", "numbers", "nvDash", "nvdash", "nvleftarrow", "nvleftrightarrow", "nvrightarrow", "nwarrow", "nwsearrow", "oacute", "obeydepth", "objectdepth", "objectheight", "objectmargin", "objectwidth", "obox", "obreve", "ocaron", "ocircumflex", "ocircumflexacute", "ocircumflexdotbelow", "ocircumflexgrave", "ocircumflexhook", "ocircumflextilde", "odiaeresis", "odiaeresismacron", "odot", "odotaccent", "odotaccentmacron", "odotbelow", "odoublegrave", "oeligature", "offset", "offsetbox", "ograve", "ohm", "ohook", "ohorn", "ohornacute", "ohorndotbelow", "ohorngrave", "ohornhook", "ohorntilde", "ohungarumlaut", "oiiint", "oiint", "oint", "ointclockwise", "ointctrclockwise", "oinvertedbreve", "omacron", "omega", "omicron", "ominus", "onedigitrounding", "oneeighth", "onefifth", "onehalf", "onequarter", "onesixth", "onesuperior", "onethird", "oogonek", "oogonekmacron", "operatorlanguage", "operatortext", "oplus", "ordfeminine", "ordinaldaynumber", "ordinalstr", "ordmasculine", "ornamenttext", "oslash", "ostroke", "ostrokeacute", "otilde", "otildemacron", "otimes", "outputfilename", "outputstreambox", "outputstreamcopy", "outputstreamunvbox", "outputstreamunvcopy", "over", "overbar", "overbars", "overbarunderbar", "overbrace", "overbraceunderbrace", "overbracket", "overbracketunderbracket", "overlaybutton", "overlaycolor", "overlaydepth", "overlayfigure", "overlayheight", "overlaylinecolor", "overlaylinewidth", "overlayoffset", "overlayrollbutton", "overlaywidth", "overleftarrow", "overloaderror", "overparent", "overparentunderparent", "overrightarrow", "overset", "overstrike", "overstrikes", "owns", "page", "pagearea", "pagebreak", "pagefigure", "pagegridspanwidth", "pageinjection", "pagenumber", "pagereference", "pagestaterealpage", "paletsize", "paragraphmark", "parallel", "part", "partial", "pdfTeX", "pdfactualtext", "pdfbackendactualtext", "pdfbackendcurrentresources", "pdfbackendsetcatalog", "pdfbackendsetcolorspace", "pdfbackendsetextgstate", "pdfbackendsetinfo", "pdfbackendsetname", "pdfbackendsetpageattribute", "pdfbackendsetpageresource", "pdfbackendsetpagesattribute", "pdfbackendsetpattern", "pdfbackendsetshade", "pdfcolor", "pdfeTeX", "percent", "percentdimen", "periodcentered", "periods", "permitcaretescape", "permitcircumflexescape", "permitspacesbetweengroups", "perp", "persiandecimals", "persiandecimalseparator", "persiannumerals", "persianthousandsseparator", "perthousand", "phantom", "phantombox", "phi", "phook", "pi", "pickupgroupedcommand", "pitchfork", "placeattachments", "placebookmarks", "placebtxrendering", "placechemical", "placecitation", "placecombinedlist", "placecomments", "placecontent", "placecurrentformulanumber", "placedbox", "placefigure", "placefloat", "placefloatwithsetups", "placefootnotes", "placeformula", "placeframed", "placegraphic", "placeheadnumber", "placeheadtext", "placehelp", "placeindex", "placeinitial", "placeintermezzo", "placelayer", "placelayeredtext", "placelegend", "placelist", "placelistofabbreviations", "placelistofchemicals", "placelistoffigures", "placelistofgraphics", "placelistofintermezzi", "placelistoflogos", "placelistofpublications", "placelistofsorts", "placelistofsynonyms", "placelistoftables", "placelocalfootnotes", "placelocalnotes", "placement", "placenamedfloat", "placenamedformula", "placenotes", "placeongrid", "placeontopofeachother", "placepagenumber", "placepairedbox", "placeparallel", "placerawlist", "placeregister", "placerenderingwindow", "placesidebyside", "placesubformula", "placetable", "pm", "popattribute", "popmacro", "popmode", "popsystemmode", "position", "positionoverlay", "positionregionoverlay", "positivesign", "postponenotes", "prec", "precapprox", "preccurlyeq", "preceq", "preceqq", "precnapprox", "precneq", "precneqq", "precnsim", "precsim", "predefinedfont", "predefinefont", "predefinesymbol", "prefixedpagenumber", "prefixlanguage", "prefixtext", "prependetoks", "prependgvalue", "prependtocommalist", "prependtoks", "prependtoksonce", "prependvalue", "presetbtxlabeltext", "presetdocument", "presetfieldsymbols", "presetheadtext", "presetlabeltext", "presetmathlabeltext", "presetoperatortext", "presetprefixtext", "presetsuffixtext", "presettaglabeltext", "presetunittext", "pretocommalist", "prettyprintbuffer", "prevcounter", "prevcountervalue", "preventmode", "prevrealpage", "prevrealpagenumber", "prevsubcountervalue", "prevsubpage", "prevsubpagenumber", "prevuserpage", "prevuserpagenumber", "prime", "primes", "procent", "processMPbuffer", "processMPfigurefile", "processaction", "processallactionsinset", "processassignlist", "processassignmentcommand", "processassignmentlist", "processbetween", "processblocks", "processbodyfontenvironmentlist", "processcolorcomponents", "processcommacommand", "processcommalist", "processcommalistwithparameters", "processcontent", "processfile", "processfilemany", "processfilenone", "processfileonce", "processfirstactioninset", "processisolatedchars", "processisolatedwords", "processlinetablebuffer", "processlinetablefile", "processlist", "processmonth", "processranges", "processseparatedlist", "processtexbuffer", "processtokens", "processuntil", "processxtablebuffer", "processyear", "prod", "product", "profiledbox", "profilegivenbox", "program", "project", "propto", "pseudoMixedCapped", "pseudoSmallCapped", "pseudoSmallcapped", "pseudosmallcapped", "psi", "punctuationspace", "purenumber", "pushattribute", "pushbutton", "pushmacro", "pushmode", "pushoutputstream", "pushsystemmode", "putboxincache", "putnextboxincache", "qquad", "quad", "quadrupleprime", "quads", "quarterstrut", "questiondown", "questionedeq", "quitcommalist", "quitprevcommalist", "quittypescriptscanning", "quotation", "quote", "quotedbl", "quotedblbase", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "quotesingle", "quotesinglebase", "rVert", "racute", "raggedbottom", "raggedcenter", "raggedleft", "raggedright", "raggedwidecenter", "raisebox", "randomizetext", "randomnumber", "rangle", "rationals", "rawcounter", "rawcountervalue", "rawdate", "rawdoifelseinset", "rawdoifinset", "rawdoifinsetelse", "rawgetparameters", "rawprocessaction", "rawprocesscommacommand", "rawprocesscommalist", "rawstructurelistuservariable", "rawsubcountervalue", "rbox", "rbrace", "rbracket", "rcaron", "rceil", "rcommaaccent", "rdoublegrave", "readfile", "readfixfile", "readjobfile", "readlocfile", "readsetfile", "readsysfile", "readtexfile", "readxmlfile", "realSmallCapped", "realSmallcapped", "realpagenumber", "reals", "realsmallcapped", "recursedepth", "recurselevel", "recursestring", "redoconvertfont", "ref", "reference", "referenceprefix", "referring", "registerattachment", "registerctxluafile", "registered", "registerexternalfigure", "registerfontclass", "registerhyphenationexception", "registerhyphenationpattern", "registermenubuttons", "registersort", "registersynonym", "registerunit", "regular", "relatemarking", "relateparameterhandlers", "relaxvalueifundefined", "relbar", "remainingcharacters", "remark", "removebottomthings", "removedepth", "removefromcommalist", "removelastskip", "removelastspace", "removemarkedcontent", "removepunctuation", "removesubstring", "removetoks", "removeunwantedspaces", "replacefeature", "replaceincommalist", "replaceword", "rescan", "rescanwithsetup", "resetMPdrawing", "resetMPenvironment", "resetMPinstance", "resetallattributes", "resetandaddfeature", "resetbar", "resetboxesincache", "resetbreakpoints", "resetbuffer", "resetcharacteralign", "resetcharacterkerning", "resetcharacterspacing", "resetcharacterstripping", "resetcollector", "resetcounter", "resetdigitsmanipulation", "resetdirection", "resetfeature", "resetflag", "resetfontcolorsheme", "resetfontfallback", "resetfontsolution", "resethyphenationfeatures", "resetinjector", "resetinteractionmenu", "resetitaliccorrection", "resetlayer", "resetlocalfloats", "resetmarker", "resetmarking", "resetmode", "resetpagenumber", "resetparallel", "resetpath", "resetpenalties", "resetprofile", "resetrecurselevel", "resetreference", "resetreplacement", "resetscript", "resetsetups", "resetshownsynonyms", "resetsubpagenumber", "resetsymbolset", "resetsystemmode", "resettimer", "resettrackers", "resettrialtypesetting", "resetusedsortings", "resetusedsynonyms", "resetuserpagenumber", "resetvalue", "resetvisualizers", "reshapebox", "resolvedglyphdirect", "resolvedglyphstyled", "restartcounter", "restorebox", "restorecatcodes", "restorecounter", "restorecurrentattributes", "restoreendofline", "restoreglobalbodyfont", "restriction", "reusableMPgraphic", "reuseMPgraphic", "reuserandomseed", "reverseddoubleprime", "reversedprime", "reversedtripleprime", "revivefeature", "rfence", "rfloor", "rgroup", "rhbox", "rho", "rhooknearrow", "rhookswarrow", "right", "rightaligned", "rightangle", "rightarrow", "rightarrowbar", "rightarrowtail", "rightarrowtriangle", "rightbottombox", "rightbox", "rightdasharrow", "rightguillemot", "rightharpoondown", "rightharpoonup", "righthbox", "rightheadtext", "rightlabeltext", "rightleftarrows", "rightleftharpoons", "rightline", "rightmathlabeltext", "rightorleftpageaction", "rightrightarrows", "rightskipadaption", "rightsquigarrow", "rightsubguillemot", "rightthreearrows", "rightthreetimes", "righttoleft", "righttolefthbox", "righttoleftvbox", "righttoleftvtop", "righttopbox", "rightwavearrow", "rightwhitearrow", "ring", "rinterval", "rinvertedbreve", "risingdotseq", "rlap", "rlointerval", "rmoustache", "rneq", "robustaddtocommalist", "robustdoifelseinset", "robustdoifinsetelse", "robustpretocommalist", "rointerval", "rollbutton", "roman", "romanC", "romanD", "romanI", "romanII", "romanIII", "romanIV", "romanIX", "romanL", "romanM", "romanV", "romanVI", "romanVII", "romanVIII", "romanX", "romanXI", "romanXII", "romanc", "romand", "romani", "romanii", "romaniii", "romaniv", "romanix", "romanl", "romanm", "romannumerals", "romanv", "romanvi", "romanvii", "romanviii", "romanx", "romanxi", "romanxii", "rootradical", "rotate", "rparent", "rrangle", "rrbracket", "rrointerval", "rtimes", "rtop", "ruledhbox", "ruledhpack", "ruledmbox", "ruledtopv", "ruledtpack", "ruledvbox", "ruledvpack", "ruledvtop", "runMPbuffer", "runninghbox", "rvert", "sacute", "safechar", "samplefile", "sans", "sansbold", "sansnormal", "sansserif", "savebox", "savebtxdataset", "savebuffer", "savecounter", "savecurrentattributes", "savenormalmeaning", "savetaggedtwopassdata", "savetwopassdata", "sbox", "scale", "scaron", "scedilla", "schwa", "schwahook", "scircumflex", "scommaaccent", "screen", "searrow", "secondoffivearguments", "secondoffourarguments", "secondofsixarguments", "secondofthreearguments", "secondofthreeunexpanded", "secondoftwoarguments", "secondoftwounexpanded", "section", "sectionmark", "seeindex", "select", "selectblocks", "serializecommalist", "serializedcommalist", "serif", "serifbold", "serifnormal", "setJSpreamble", "setMPlayer", "setMPpositiongraphic", "setMPpositiongraphicrange", "setMPtext", "setMPvariable", "setMPvariables", "setbar", "setbigbodyfont", "setboxllx", "setboxlly", "setbreakpoints", "setcapstrut", "setcatcodetable", "setcharacteralign", "setcharactercasing", "setcharactercleaning", "setcharacterkerning", "setcharacterspacing", "setcharacterstripping", "setcharstrut", "setcollector", "setcolormodell", "setcounter", "setcounterown", "setcurrentfontclass", "setdataset", "setdefaultpenalties", "setdigitsmanipulation", "setdirection", "setdocumentargument", "setdocumentargumentdefault", "setdocumentfilename", "setdummyparameter", "setelementexporttag", "setemeasure", "setevalue", "setevariable", "setevariables", "setfirstline", "setflag", "setfont", "setfontcolorsheme", "setfontfeature", "setfontsolution", "setfontstrut", "setgmeasure", "setgvalue", "setgvariable", "setgvariables", "sethboxregister", "sethyphenatedurlafter", "sethyphenatedurlbefore", "sethyphenatedurlnormal", "sethyphenationfeatures", "setinitial", "setinjector", "setinteraction", "setinterfacecommand", "setinterfaceconstant", "setinterfaceelement", "setinterfacemessage", "setinterfacevariable", "setinternalrendering", "setitaliccorrection", "setlayer", "setlayerframed", "setlayertext", "setlinefiller", "setlocalhsize", "setmainbodyfont", "setmainparbuilder", "setmarker", "setmarking", "setmathstyle", "setmeasure", "setmessagetext", "setminus", "setmode", "setnostrut", "setnote", "setnotetext", "setobject", "setoldstyle", "setpagegrid", "setpagereference", "setpagestate", "setpagestaterealpageno", "setpenalties", "setpercentdimen", "setposition", "setpositionbox", "setpositiondata", "setpositiondataplus", "setpositiononly", "setpositionplus", "setpositionstrut", "setprofile", "setrandomseed", "setreference", "setreferencedobject", "setregisterentry", "setreplacement", "setrigidcolumnbalance", "setrigidcolumnhsize", "setscript", "setsectionblock", "setsimplecolumnhsize", "setsmallbodyfont", "setsmallcaps", "setstackbox", "setstructurepageregister", "setstrut", "setsuperiors", "setsystemmode", "settabular", "settaggedmetadata", "settextcontent", "settightobject", "settightreferencedobject", "settightunreferencedobject", "settrialtypesetting", "setuevalue", "setugvalue", "setunreferencedobject", "setup", "setupMPgraphics", "setupMPinstance", "setupMPpage", "setupMPvariables", "setupTABLE", "setupTEXpage", "setupalign", "setupalternativestyles", "setuparranging", "setupattachment", "setupattachments", "setupbackend", "setupbackground", "setupbackgrounds", "setupbar", "setupbars", "setupblackrules", "setupblank", "setupbleeding", "setupblock", "setupbodyfont", "setupbookmark", "setupbottom", "setupbottomtexts", "setupbtx", "setupbtxdataset", "setupbtxlabeltext", "setupbtxlist", "setupbtxregister", "setupbtxrendering", "setupbuffer", "setupbutton", "setupcapitals", "setupcaption", "setupcaptions", "setupcharacterkerning", "setupcharacterspacing", "setupchemical", "setupchemicalframed", "setupclipping", "setupcollector", "setupcolor", "setupcolors", "setupcolumns", "setupcolumnspan", "setupcombination", "setupcombinedlist", "setupcomment", "setupcontent", "setupcounter", "setupdataset", "setupdelimitedtext", "setupdescription", "setupdirections", "setupdocument", "setupeffect", "setupenumeration", "setupenumerations", "setupenv", "setupexport", "setupexternalfigure", "setupexternalsoundtracks", "setupfield", "setupfieldbody", "setupfieldcategory", "setupfieldcontentframed", "setupfieldlabelframed", "setupfields", "setupfieldtotalframed", "setupfiller", "setupfillinlines", "setupfillinrules", "setupfirstline", "setupfittingpage", "setupfloat", "setupfloatcaption", "setupfloats", "setupfloatsplitting", "setupfontexpansion", "setupfontprotrusion", "setupfonts", "setupfontsolution", "setupfooter", "setupfootertexts", "setupforms", "setupformula", "setupformulae", "setupformulaframed", "setupframed", "setupframedcontent", "setupframedtable", "setupframedtablecolumn", "setupframedtablerow", "setupframedtext", "setupframedtexts", "setupglobalreferenceprefix", "setuphead", "setupheadalternative", "setupheader", "setupheadertexts", "setupheadnumber", "setupheads", "setupheadtext", "setuphelp", "setuphigh", "setuphighlight", "setuphyphenation", "setuphyphenmark", "setupindentedtext", "setupindenting", "setupindex", "setupinitial", "setupinsertion", "setupinteraction", "setupinteractionbar", "setupinteractionmenu", "setupinteractionscreen", "setupinterlinespace", "setupitaliccorrection", "setupitemgroup", "setupitemizations", "setupitemize", "setupitems", "setuplabel", "setuplabeltext", "setuplanguage", "setuplayer", "setuplayeredtext", "setuplayout", "setuplayouttext", "setuplegend", "setuplinefiller", "setuplinefillers", "setuplinenote", "setuplinenumbering", "setuplines", "setuplinetable", "setuplinewidth", "setuplist", "setuplistalternative", "setuplistextra", "setuplocalfloats", "setuplocalinterlinespace", "setuplow", "setuplowhigh", "setuplowmidhigh", "setupmakeup", "setupmarginblock", "setupmargindata", "setupmarginframed", "setupmarginrule", "setupmarginrules", "setupmarking", "setupmathalignment", "setupmathcases", "setupmathematics", "setupmathfence", "setupmathfraction", "setupmathfractions", "setupmathframed", "setupmathlabeltext", "setupmathmatrix", "setupmathornament", "setupmathradical", "setupmathstackers", "setupmathstyle", "setupmixedcolumns", "setupmodule", "setupnarrower", "setupnotation", "setupnotations", "setupnote", "setupnotes", "setupoffset", "setupoffsetbox", "setupoperatortext", "setupoppositeplacing", "setupoutputroutine", "setuppagechecker", "setuppagecomment", "setuppagegrid", "setuppagegridarea", "setuppagegridareatext", "setuppagegridlines", "setuppagegridspan", "setuppagegridstart", "setuppageinjection", "setuppageinjectionalternative", "setuppagenumber", "setuppagenumbering", "setuppageshift", "setuppagestate", "setuppagetransitions", "setuppairedbox", "setuppalet", "setuppaper", "setuppapersize", "setupparagraph", "setupparagraphintro", "setupparagraphnumbering", "setupparagraphs", "setupparallel", "setupperiods", "setupplacement", "setuppositionbar", "setuppositioning", "setupprefixtext", "setupprocessor", "setupprofile", "setupprograms", "setupquotation", "setupquote", "setuprealpagenumber", "setupreferenceformat", "setupreferenceprefix", "setupreferencestructureprefix", "setupreferencing", "setupregister", "setupregisters", "setuprenderingwindow", "setuprotate", "setups", "setupscale", "setupscript", "setupscripts", "setupsectionblock", "setupselector", "setupshift", "setupsidebar", "setupsorting", "setupspacing", "setupspellchecking", "setupstartstop", "setupstretched", "setupstruts", "setupstyle", "setupsubformula", "setupsubformulas", "setupsubpagenumber", "setupsuffixtext", "setupsymbolset", "setupsynctex", "setupsynonyms", "setuptables", "setuptabulate", "setuptabulation", "setuptagging", "setuptaglabeltext", "setuptext", "setuptextbackground", "setuptextflow", "setuptextrules", "setuptexttexts", "setupthinrules", "setuptolerance", "setuptooltip", "setuptop", "setuptoptexts", "setuptype", "setuptyping", "setupunit", "setupunittext", "setupurl", "setupuserpagenumber", "setupversion", "setupviewerlayer", "setupvspacing", "setupwhitespace", "setupwithargument", "setupwithargumentswapped", "setupxml", "setupxtable", "setuvalue", "setuxvalue", "setvalue", "setvariable", "setvariables", "setvboxregister", "setvisualizerfont", "setvtopregister", "setwidthof", "setxmeasure", "setxvalue", "setxvariable", "setxvariables", "seveneighths", "sfrac", "shapedhbox", "sharp", "shiftdown", "shiftup", "showallmakeup", "showattributes", "showbodyfont", "showbodyfontenvironment", "showboxes", "showbtxdatasetauthors", "showbtxdatasetcompleteness", "showbtxdatasetfields", "showbtxfields", "showbtxhashedauthors", "showbtxtables", "showchardata", "showcharratio", "showcolor", "showcolorbar", "showcolorcomponents", "showcolorgroup", "showcolorset", "showcolorstruts", "showcounter", "showdirectives", "showdirsinmargin", "showedebuginfo", "showexperiments", "showfont", "showfontdata", "showfontitalics", "showfontkerns", "showfontparameters", "showfontstrip", "showfontstyle", "showframe", "showglyphs", "showgrid", "showgridsnapping", "showhelp", "showhyphenationtrace", "showhyphens", "showinjector", "showjustification", "showkerning", "showlayout", "showlayoutcomponents", "showligature", "showligatures", "showlogcategories", "showmakeup", "showmargins", "showmessage", "showminimalbaseline", "shownextbox", "showotfcomposition", "showpalet", "showparentchain", "showprint", "showsetups", "showsetupsdefinition", "showstruts", "showsymbolset", "showtimer", "showtokens", "showtrackers", "showvalue", "showvariable", "showwarning", "sigma", "sim", "simeq", "simplealignedbox", "simplealignedboxplus", "simplealignedspreadbox", "simplegroupedcommand", "simplereversealignedbox", "simplereversealignedboxplus", "singalcharacteralign", "singlebond", "singleverticalbar", "sixperemspace", "sixthofsixarguments", "slanted", "slantedbold", "slantedface", "slash", "slicepages", "slong", "slovenianNumerals", "sloveniannumerals", "small", "smallbodyfont", "smallbold", "smallbolditalic", "smallboldslanted", "smallcappedcharacters", "smallcappedromannumerals", "smaller", "smallitalicbold", "smallnormal", "smallskip", "smallslanted", "smallslantedbold", "smalltype", "smash", "smashbox", "smashboxed", "smashedhbox", "smashedvbox", "smile", "snaptogrid", "softhyphen", "solidus", "someheadnumber", "somekindoftab", "someline", "somelocalfloat", "somenamedheadnumber", "someplace", "somewhere", "space", "spadesuit", "spanishNumerals", "spanishnumerals", "speech", "sphericalangle", "splitatasterisk", "splitatcolon", "splitatcolons", "splitatcomma", "splitatperiod", "splitdfrac", "splitfilename", "splitfloat", "splitfrac", "splitoffbase", "splitofffull", "splitoffkind", "splitoffname", "splitoffpath", "splitoffroot", "splitofftokens", "splitofftype", "splitstring", "spreadhbox", "sqcap", "sqcup", "sqrt", "sqsubset", "sqsubseteq", "sqsubsetneq", "sqsupset", "sqsupseteq", "sqsupsetneq", "square", "squaredots", "ssharp", "stackrel", "star", "stareq", "startJScode", "startJSpreamble", "startLUA", "startMP", "startMPclip", "startMPcode", "startMPdefinitions", "startMPdrawing", "startMPenvironment", "startMPextensions", "startMPinclusions", "startMPinitializations", "startMPpage", "startMPpositiongraphic", "startMPpositionmethod", "startMPrun", "startPARSEDXML", "startTABLE", "startTABLEbody", "startTABLEfoot", "startTABLEhead", "startTABLEnext", "startTC", "startTD", "startTDs", "startTEX", "startTEXpage", "startTH", "startTN", "startTR", "startTRs", "startTX", "startTY", "startXML", "startalign", "startalignment", "startallmodes", "startappendices", "startarrangedpages", "startaside", "startattachment", "startbackground", "startbackmatter", "startbar", "startbbordermatrix", "startbitmapimage", "startblockquote", "startbodymatter", "startbordermatrix", "startboxedcolumns", "startbtxlabeltext", "startbtxrenderingdefinitions", "startbuffer", "startcases", "startcatcodetable", "startcenteraligned", "startchapter", "startcharacteralign", "startcheckedfences", "startchemical", "startchemicaltext", "startcollect", "startcollecting", "startcolor", "startcolorintent", "startcoloronly", "startcolorset", "startcolumns", "startcolumnspan", "startcombination", "startcomment", "startcomponent", "startcontextcode", "startcontextdefinitioncode", "startctxfunction", "startctxfunctiondefinition", "startcurrentcolor", "startcurrentlistentrywrapper", "startdelimited", "startdelimitedtext", "startdisplaymath", "startdmath", "startdocument", "starteffect", "startelement", "startembeddedxtable", "startendnote", "startendofline", "startenvironment", "startexceptions", "startexpanded", "startexpandedcollect", "startextendedcatcodetable", "startexternalfigurecollection", "startfact", "startfigure", "startfiguretext", "startfittingpage", "startfixed", "startfloatcombination", "startfont", "startfontclass", "startfontsolution", "startfootnote", "startformula", "startformulas", "startframed", "startframedcell", "startframedcontent", "startframedrow", "startframedtable", "startframedtext", "startfrontmatter", "startgoto", "startgraphictext", "startgridsnapping", "starthanging", "starthbox", "starthboxestohbox", "starthboxregister", "starthead", "startheadtext", "starthelptext", "starthiding", "starthighlight", "starthyphenation", "startimath", "startindentation", "startindentedtext", "startinteraction", "startinteractionmenu", "startinterface", "startintermezzotext", "startintertext", "startitem", "startitemgroup", "startitemgroupcolumns", "startitemize", "startknockout", "startlabeltext", "startlayout", "startleftaligned", "startlegend", "startline", "startlinealignment", "startlinecorrection", "startlinefiller", "startlinenote", "startlinenumbering", "startlines", "startlinetable", "startlinetablebody", "startlinetablecell", "startlinetablehead", "startlocalfootnotes", "startlocalheadsetup", "startlocallinecorrection", "startlocalnotes", "startlocalsetups", "startlua", "startluacode", "startluaparameterset", "startluasetups", "startmakeup", "startmarginblock", "startmarginrule", "startmarkedcontent", "startmathalignment", "startmathcases", "startmathlabeltext", "startmathmatrix", "startmathmode", "startmathstyle", "startmatrices", "startmatrix", "startmaxaligned", "startmdformula", "startmidaligned", "startmiddlealigned", "startmiddlemakeup", "startmixedcolumns", "startmode", "startmodeset", "startmodule", "startmoduletestsection", "startmpformula", "startnamedsection", "startnamedsubformulas", "startnarrow", "startnarrower", "startnegative", "startnicelyfilledbox", "startnointerference", "startnotallmodes", "startnotext", "startnotmode", "startoperatortext", "startopposite", "startoutputstream", "startoverlay", "startoverprint", "startpacked", "startpagecomment", "startpagefigure", "startpagegrid", "startpagegridspan", "startpagelayout", "startpagemakeup", "startpar", "startparagraph", "startparagraphs", "startparagraphscell", "startparbuilder", "startpart", "startpath", "startplacechemical", "startplacefigure", "startplacefloat", "startplaceformula", "startplacegraphic", "startplaceintermezzo", "startplacelegend", "startplacepairedbox", "startplacetable", "startpositioning", "startpositionoverlay", "startpositive", "startpostponing", "startprefixtext", "startprocessassignmentcommand", "startprocessassignmentlist", "startprocesscommacommand", "startprocesscommalist", "startproduct", "startproject", "startprotect", "startprotectedcolors", "startpublication", "startpunctuation", "startquotation", "startquote", "startrandomized", "startrandomseed", "startrawsetups", "startreadingfile", "startreferenceprefix", "startregime", "startregister", "startreusableMPgraphic", "startrightaligned", "startscript", "startsdformula", "startsection", "startsectionblock", "startsectionblockenvironment", "startsectionlevel", "startsetups", "startshapebox", "startshift", "startsidebar", "startsimplecolumns", "startspecialitem", "startspeech", "startspformula", "startsplitformula", "startspread", "startstandardmakeup", "startstartstop", "startstaticMPfigure", "startstaticMPgraphic", "startstrictinspectnextcharacter", "startstructurepageregister", "startstrut", "startstyle", "startsubformulas", "startsubject", "startsubjectlevel", "startsubsection", "startsubsentence", "startsubstack", "startsubsubject", "startsubsubsection", "startsubsubsubject", "startsubsubsubsection", "startsubsubsubsubject", "startsubsubsubsubsection", "startsubsubsubsubsubject", "startsuffixtext", "startsymbolset", "starttable", "starttablehead", "starttables", "starttabletail", "starttabletext", "starttabulate", "starttabulatehead", "starttabulatetail", "starttagged", "starttaglabeltext", "starttexcode", "starttexdefinition", "starttext", "starttextbackground", "starttextbackgroundmanual", "starttextcolor", "starttextcolorintent", "starttextflow", "starttextmakeup", "starttextrule", "starttitle", "starttokens", "starttransparent", "starttypescript", "starttypescriptcollection", "starttyping", "startuniqueMPgraphic", "startuniqueMPpagegraphic", "startunittext", "startunpacked", "startusableMPgraphic", "startuseMPgraphic", "startusemathstyleparameter", "startusingbtxspecification", "startvbox", "startvboxregister", "startvboxtohbox", "startvboxtohboxseparator", "startviewerlayer", "startvtop", "startvtopregister", "startxcell", "startxcellgroup", "startxgroup", "startxmldisplayverbatim", "startxmlinlineverbatim", "startxmlraw", "startxmlsetups", "startxrow", "startxrowgroup", "startxtable", "startxtablebody", "startxtablefoot", "startxtablehead", "startxtablenext", "stligature", "stopJScode", "stopJSpreamble", "stopLUA", "stopMP", "stopMPclip", "stopMPcode", "stopMPdefinitions", "stopMPdrawing", "stopMPenvironment", "stopMPextensions", "stopMPinclusions", "stopMPinitializations", "stopMPpage", "stopMPpositiongraphic", "stopMPpositionmethod", "stopMPrun", "stopPARSEDXML", "stopTABLE", "stopTABLEbody", "stopTABLEfoot", "stopTABLEhead", "stopTABLEnext", "stopTC", "stopTD", "stopTDs", "stopTEX", "stopTEXpage", "stopTH", "stopTN", "stopTR", "stopTRs", "stopTX", "stopTY", "stopXML", "stopalign", "stopalignment", "stopallmodes", "stopappendices", "stoparrangedpages", "stopaside", "stopattachment", "stopbackground", "stopbackmatter", "stopbar", "stopbbordermatrix", "stopbitmapimage", "stopblockquote", "stopbodymatter", "stopbordermatrix", "stopboxedcolumns", "stopbtxlabeltext", "stopbtxrenderingdefinitions", "stopbuffer", "stopcases", "stopcatcodetable", "stopcenteraligned", "stopchapter", "stopcharacteralign", "stopcheckedfences", "stopchemical", "stopchemicaltext", "stopcollect", "stopcollecting", "stopcolor", "stopcolorintent", "stopcoloronly", "stopcolorset", "stopcolumns", "stopcolumnspan", "stopcombination", "stopcomment", "stopcomponent", "stopcontextcode", "stopcontextdefinitioncode", "stopctxfunction", "stopctxfunctiondefinition", "stopcurrentcolor", "stopcurrentlistentrywrapper", "stopdelimited", "stopdelimitedtext", "stopdisplaymath", "stopdmath", "stopdocument", "stopeffect", "stopelement", "stopembeddedxtable", "stopendnote", "stopendofline", "stopenvironment", "stopexceptions", "stopexpanded", "stopexpandedcollect", "stopextendedcatcodetable", "stopexternalfigurecollection", "stopfact", "stopfigure", "stopfiguretext", "stopfittingpage", "stopfixed", "stopfloatcombination", "stopfont", "stopfontclass", "stopfontsolution", "stopfootnote", "stopformula", "stopformulas", "stopframed", "stopframedcell", "stopframedcontent", "stopframedrow", "stopframedtable", "stopframedtext", "stopfrontmatter", "stopgoto", "stopgraphictext", "stopgridsnapping", "stophanging", "stophbox", "stophboxestohbox", "stophboxregister", "stophead", "stopheadtext", "stophelptext", "stophiding", "stophighlight", "stophyphenation", "stopimath", "stopindentation", "stopindentedtext", "stopinteraction", "stopinteractionmenu", "stopinterface", "stopintermezzotext", "stopintertext", "stopitem", "stopitemgroup", "stopitemgroupcolumns", "stopitemize", "stopknockout", "stoplabeltext", "stoplayout", "stopleftaligned", "stoplegend", "stopline", "stoplinealignment", "stoplinecorrection", "stoplinefiller", "stoplinenote", "stoplinenumbering", "stoplines", "stoplinetable", "stoplinetablebody", "stoplinetablecell", "stoplinetablehead", "stoplocalfootnotes", "stoplocalheadsetup", "stoplocallinecorrection", "stoplocalnotes", "stoplocalsetups", "stoplua", "stopluacode", "stopluaparameterset", "stopluasetups", "stopmakeup", "stopmarginblock", "stopmarginrule", "stopmarkedcontent", "stopmathalignment", "stopmathcases", "stopmathlabeltext", "stopmathmatrix", "stopmathmode", "stopmathstyle", "stopmatrices", "stopmatrix", "stopmaxaligned", "stopmdformula", "stopmidaligned", "stopmiddlealigned", "stopmiddlemakeup", "stopmixedcolumns", "stopmode", "stopmodeset", "stopmodule", "stopmoduletestsection", "stopmpformula", "stopnamedsection", "stopnamedsubformulas", "stopnarrow", "stopnarrower", "stopnegative", "stopnicelyfilledbox", "stopnointerference", "stopnotallmodes", "stopnotext", "stopnotmode", "stopoperatortext", "stopopposite", "stopoutputstream", "stopoverlay", "stopoverprint", "stoppacked", "stoppagecomment", "stoppagefigure", "stoppagegrid", "stoppagegridspan", "stoppagelayout", "stoppagemakeup", "stoppar", "stopparagraph", "stopparagraphs", "stopparagraphscell", "stopparbuilder", "stoppart", "stoppath", "stopplacechemical", "stopplacefigure", "stopplacefloat", "stopplaceformula", "stopplacegraphic", "stopplaceintermezzo", "stopplacelegend", "stopplacepairedbox", "stopplacetable", "stoppositioning", "stoppositionoverlay", "stoppositive", "stoppostponing", "stopprefixtext", "stopprocessassignmentcommand", "stopprocessassignmentlist", "stopprocesscommacommand", "stopprocesscommalist", "stopproduct", "stopproject", "stopprotect", "stopprotectedcolors", "stoppublication", "stoppunctuation", "stopquotation", "stopquote", "stoprandomized", "stoprandomseed", "stoprawsetups", "stopreadingfile", "stopreferenceprefix", "stopregime", "stopregister", "stopreusableMPgraphic", "stoprightaligned", "stopscript", "stopsdformula", "stopsection", "stopsectionblock", "stopsectionblockenvironment", "stopsectionlevel", "stopsetups", "stopshapebox", "stopshift", "stopsidebar", "stopsimplecolumns", "stopspecialitem", "stopspeech", "stopspformula", "stopsplitformula", "stopspread", "stopstandardmakeup", "stopstartstop", "stopstaticMPfigure", "stopstaticMPgraphic", "stopstrictinspectnextcharacter", "stopstructurepageregister", "stopstrut", "stopstyle", "stopsubformulas", "stopsubject", "stopsubjectlevel", "stopsubsection", "stopsubsentence", "stopsubstack", "stopsubsubject", "stopsubsubsection", "stopsubsubsubject", "stopsubsubsubsection", "stopsubsubsubsubject", "stopsubsubsubsubsection", "stopsubsubsubsubsubject", "stopsuffixtext", "stopsymbolset", "stoptable", "stoptablehead", "stoptables", "stoptabletail", "stoptabletext", "stoptabulate", "stoptabulatehead", "stoptabulatetail", "stoptagged", "stoptaglabeltext", "stoptexcode", "stoptexdefinition", "stoptext", "stoptextbackground", "stoptextbackgroundmanual", "stoptextcolor", "stoptextcolorintent", "stoptextflow", "stoptextmakeup", "stoptextrule", "stoptitle", "stoptokens", "stoptransparent", "stoptypescript", "stoptypescriptcollection", "stoptyping", "stopuniqueMPgraphic", "stopuniqueMPpagegraphic", "stopunittext", "stopunpacked", "stopusableMPgraphic", "stopuseMPgraphic", "stopusemathstyleparameter", "stopusingbtxspecification", "stopvbox", "stopvboxregister", "stopvboxtohbox", "stopvboxtohboxseparator", "stopviewerlayer", "stopvtop", "stopvtopregister", "stopxcell", "stopxcellgroup", "stopxgroup", "stopxmldisplayverbatim", "stopxmlinlineverbatim", "stopxmlraw", "stopxmlsetups", "stopxrow", "stopxrowgroup", "stopxtable", "stopxtablebody", "stopxtablefoot", "stopxtablehead", "stopxtablenext", "stretched", "strictdoifelsenextoptional", "strictdoifnextoptionalelse", "stripcharacter", "strippedcsname", "stripspaces", "structurelistuservariable", "structurenumber", "structuretitle", "structureuservariable", "structurevariable", "strut", "strutdp", "strutgap", "strutht", "struthtdp", "struttedbox", "strutwd", "style", "styleinstance", "subject", "subpagenumber", "subsection", "subsentence", "subset", "subseteq", "subseteqq", "subsetneq", "subsetneqq", "substituteincommalist", "subsubject", "subsubsection", "subsubsubject", "subsubsubsection", "subsubsubsubject", "subsubsubsubsection", "subsubsubsubsubject", "subtractfeature", "succ", "succapprox", "succcurlyeq", "succeq", "succeqq", "succnapprox", "succneq", "succneqq", "succnsim", "succsim", "suffixlanguage", "suffixtext", "sum", "supset", "supseteq", "supseteqq", "supsetneq", "supsetneqq", "surd", "surdradical", "swapcounts", "swapdimens", "swapface", "swapmacros", "swaptypeface", "swarrow", "switchstyleonly", "switchtobodyfont", "switchtocolor", "switchtointerlinespace", "symbol", "symbolreference", "synchronizeblank", "synchronizeindenting", "synchronizemarking", "synchronizeoutputstreams", "synchronizestrut", "synchronizewhitespace", "synctexblockfilename", "synctexresetfilename", "synctexsetfilename", "systemlog", "systemlogfirst", "systemloglast", "systemsetups", "tLeftarrow", "tLeftrightarrow", "tRightarrow", "tabulateautoline", "tabulateautorule", "tabulateline", "tabulaterule", "taggedctxcommand", "taggedlabeltexts", "taglabellanguage", "taglabeltext", "tau", "tbinom", "tbox", "tcaron", "tcedilla", "tcommaaccent", "tcurl", "tequal", "test", "testandsplitstring", "testcolumn", "testfeature", "testfeatureonce", "testpage", "testpageonly", "testpagesync", "testtokens", "tex", "texdefinition", "texsetup", "textAngstrom", "textacute", "textampersand", "textasciicircum", "textasciitilde", "textat", "textbackslash", "textbar", "textbottomcomma", "textbottomdot", "textbraceleft", "textbraceright", "textbreve", "textbrokenbar", "textbullet", "textcaron", "textcedilla", "textcelsius", "textcent", "textcircledP", "textcircumflex", "textcitation", "textcite", "textcomma", "textcontrolspace", "textcurrency", "textdag", "textddag", "textdegree", "textdiaeresis", "textdiv", "textdollar", "textdong", "textdotaccent", "textellipsis", "texteuro", "textflowcollector", "textfraction", "textgrave", "texthash", "texthorizontalbar", "texthungarumlaut", "texthyphen", "textkelvin", "textlognot", "textmacron", "textmath", "textmho", "textminus", "textmu", "textmultiply", "textnumero", "textogonek", "textohm", "textormathchar", "textounce", "textpercent", "textperiod", "textplus", "textpm", "textreference", "textring", "textrule", "textslash", "textsterling", "texttilde", "textunderscore", "textvisiblespace", "textyen", "thai", "thainumerals", "thefirstcharacter", "thenormalizedbodyfontsize", "therefore", "theremainingcharacters", "theta", "thickspace", "thinrule", "thinrules", "thinspace", "thirdoffivearguments", "thirdoffourarguments", "thirdofsixarguments", "thirdofthreearguments", "thirdofthreeunexpanded", "thook", "thookleftarrow", "thookrightarrow", "thorn", "threedigitrounding", "threeeighths", "threefifths", "threeperemspace", "threequarter", "threesuperior", "tibetannumerals", "tightlayer", "tilde", "times", "tinyfont", "title", "tlap", "tleftarrow", "tleftharpoondown", "tleftharpoonup", "tleftrightarrow", "tleftrightharpoons", "tmapsto", "to", "tochar", "tolinenote", "tooltip", "top", "topbox", "topleftbox", "toplinebox", "toprightbox", "topskippedbox", "tracecatcodetables", "tracedfontname", "traceoutputroutines", "tracepositions", "trademark", "translate", "transparencycomponents", "transparent", "trel", "triangle", "triangledown", "triangleleft", "triangleq", "triangleright", "trightarrow", "trightharpoondown", "trightharpoonup", "trightleftharpoons", "trightoverleftarrow", "triplebond", "tripleprime", "tripleverticalbar", "truefilename", "truefontname", "tstroke", "ttraggedright", "ttriplerel", "ttwoheadleftarrow", "ttwoheadrightarrow", "turnediota", "twodigitrounding", "twofifths", "twoheaddownarrow", "twoheadleftarrow", "twoheadrightarrow", "twoheadrightarrowtail", "twoheaduparrow", "twosuperior", "twothirds", "tx", "txx", "typ", "type", "typebuffer", "typedefinedbuffer", "typeface", "typefile", "typeinlinebuffer", "typescriptone", "typescriptprefix", "typescriptthree", "typescripttwo", "typesetbuffer", "typesetfile", "uacute", "ubreve", "ucaron", "ucircumflex", "uconvertnumber", "udiaeresis", "udiaeresisacute", "udiaeresiscaron", "udiaeresisgrave", "udiaeresismacron", "udotbelow", "udots", "udoublegrave", "uedcatcodecommand", "ugrave", "uhook", "uhorn", "uhornacute", "uhorndotbelow", "uhorngrave", "uhornhook", "uhorntilde", "uhungarumlaut", "uinvertedbreve", "ulcorner", "umacron", "undefinevalue", "undepthed", "underbar", "underbars", "underbrace", "underbracket", "underdash", "underdashes", "underdot", "underdots", "underleftarrow", "underparent", "underrandom", "underrandoms", "underrightarrow", "underset", "understrike", "understrikes", "undoassign", "unexpandeddocumentvariable", "unframed", "unhhbox", "unihex", "uniqueMPgraphic", "uniqueMPpagegraphic", "unit", "unitlanguage", "unitshigh", "unitslow", "unittext", "unknown", "unprotected", "unregisterhyphenationpattern", "unspaceafter", "unspaceargument", "unspaced", "unspacestring", "untexargument", "untexcommand", "uogonek", "upand", "uparrow", "updasharrow", "updownarrow", "updownarrowbar", "updownarrows", "upharpoonleft", "upharpoonright", "uplus", "uppercased", "uppercasestring", "upperleftdoubleninequote", "upperleftdoublesixquote", "upperleftsingleninequote", "upperleftsinglesixquote", "upperrightdoubleninequote", "upperrightdoublesixquote", "upperrightsingleninequote", "upperrightsinglesixquote", "upsilon", "upuparrows", "upwhitearrow", "urcorner", "uring", "url", "useJSscripts", "useMPenvironmentbuffer", "useMPgraphic", "useMPlibrary", "useMPrun", "useMPvariables", "useURL", "usealignparameter", "useblankparameter", "useblocks", "usebodyfont", "usebodyfontparameter", "usebtxdataset", "usebtxdefinitions", "usecitation", "usecolors", "usecomponent", "usedirectory", "usedummycolorparameter", "usedummystyleandcolor", "usedummystyleparameter", "useenvironment", "useexternaldocument", "useexternalfigure", "useexternalrendering", "useexternalsoundtrack", "usefigurebase", "usefile", "usegridparameter", "useindentingparameter", "useindentnextparameter", "useinterlinespaceparameter", "uselanguageparameter", "useluamodule", "usemathstyleparameter", "usemodule", "useproduct", "useprofileparameter", "useproject", "usereferenceparameter", "userpagenumber", "usesetupsparameter", "usestaticMPfigure", "usesubpath", "usesymbols", "usetexmodule", "usetypescript", "usetypescriptfile", "useurl", "usezipfile", "utfchar", "utflower", "utfupper", "utilde", "utilityregisterlength", "vDash", "varTheta", "varepsilon", "varkappa", "varnothing", "varphi", "varpi", "varrho", "varsigma", "vartheta", "vboxreference", "vdash", "vdots", "vec", "vee", "veebar", "veeeq", "verbatim", "verbatimstring", "verbosenumber", "version", "vert", "verticalgrowingbar", "verticalpositionbar", "veryraggedcenter", "veryraggedleft", "veryraggedright", "vglue", "viewerlayer", "vl", "vphantom", "vpos", "vsmash", "vsmashbox", "vsmashed", "vspace", "vspacing", "wcircumflex", "wdofstring", "wedge", "wedgeeq", "weekday", "whitearrowupfrombar", "widehat", "widetilde", "widthofstring", "widthspanningtext", "withoutpt", "word", "wordright", "words", "wordtonumber", "wp", "wr", "writebetweenlist", "writedatatolist", "writestatus", "writetolist", "xLeftarrow", "xLeftrightarrow", "xRightarrow", "xdefconvertedargument", "xequal", "xfrac", "xhookleftarrow", "xhookrightarrow", "xi", "xleftarrow", "xleftharpoondown", "xleftharpoonup", "xleftrightarrow", "xleftrightharpoons", "xmapsto", "xmladdindex", "xmlafterdocumentsetup", "xmlaftersetup", "xmlall", "xmlappenddocumentsetup", "xmlappendsetup", "xmlapplyselectors", "xmlatt", "xmlattdef", "xmlattribute", "xmlattributedef", "xmlbadinclusions", "xmlbeforedocumentsetup", "xmlbeforesetup", "xmlchainatt", "xmlchainattdef", "xmlchecknamespace", "xmlcommand", "xmlconcat", "xmlconcatrange", "xmlcontext", "xmlcount", "xmldefaulttotext", "xmldirectives", "xmldirectivesafter", "xmldirectivesbefore", "xmldisplayverbatim", "xmldoif", "xmldoifelse", "xmldoifelseempty", "xmldoifelseselfempty", "xmldoifelsetext", "xmldoifelsevalue", "xmldoifnot", "xmldoifnotselfempty", "xmldoifnottext", "xmldoifselfempty", "xmldoiftext", "xmlelement", "xmlfilter", "xmlfirst", "xmlflush", "xmlflushcontext", "xmlflushdocumentsetups", "xmlflushlinewise", "xmlflushpure", "xmlflushspacewise", "xmlflushtext", "xmlinclude", "xmlinclusion", "xmlinclusions", "xmlinfo", "xmlinjector", "xmlinlineprettyprint", "xmlinlineprettyprinttext", "xmlinlineverbatim", "xmlinstalldirective", "xmllast", "xmllastatt", "xmllastmatch", "xmllastpar", "xmlloadbuffer", "xmlloaddata", "xmlloaddirectives", "xmlloadfile", "xmlloadonly", "xmlmain", "xmlmapvalue", "xmlname", "xmlnamespace", "xmlnonspace", "xmlpar", "xmlparam", "xmlpath", "xmlpos", "xmlposition", "xmlprependdocumentsetup", "xmlprependsetup", "xmlprettyprint", "xmlprettyprinttext", "xmlprocessbuffer", "xmlprocessdata", "xmlprocessfile", "xmlpure", "xmlraw", "xmlrefatt", "xmlregistereddocumentsetups", "xmlregisteredsetups", "xmlregisterns", "xmlremapname", "xmlremapnamespace", "xmlremovedocumentsetup", "xmlremovesetup", "xmlresetdocumentsetups", "xmlresetinjectors", "xmlresetsetups", "xmlsave", "xmlsetatt", "xmlsetattribute", "xmlsetentity", "xmlsetfunction", "xmlsetinjectors", "xmlsetpar", "xmlsetparam", "xmlsetsetup", "xmlsetup", "xmlshow", "xmlsnippet", "xmlstrip", "xmlstripnolines", "xmlstripped", "xmlstrippednolines", "xmltag", "xmltexentity", "xmltext", "xmltobuffer", "xmltobufferverbose", "xmltofile", "xmlvalue", "xmlverbatim", "xrel", "xrightarrow", "xrightharpoondown", "xrightharpoonup", "xrightleftharpoons", "xrightoverleftarrow", "xsplitstring", "xtriplerel", "xtwoheadleftarrow", "xtwoheadrightarrow", "xxfrac", "xypos", "yacute", "ycircumflex", "ydiaeresis", "ydotbelow", "yen", "ygrave", "yhook", "ymacron", "ytilde", "zacute", "zcaron", "zdotaccent", "zerowidthnobreakspace", "zerowidthspace", "zeta", "zhook", "zstroke", "zwj", "zwnj" },
- ["cs"]={ "Cisla", "Kap", "MESIC", "Rimskecislice", "SLOVA", "SLOVO", "Slova", "Slovo", "VSEDNIDEN", "Znak", "Znaky", "aktualnicislonadpisu", "aktualnidatum", "barevnalista", "barva", "cernalinka", "cernelinky", "cisla", "cislonadpisu", "cislorovnice", "cislostrany", "datum", "definuj", "definujakcent", "definujbarvu", "definujblok", "definujbloksekce", "definujbuffer", "definujfont", "definujformatodkazu", "definujhbox", "definujinterakcnimenu", "definujkombinovanyseznam", "definujkonverzi", "definujnadpis", "definujobrazeksymbol", "definujodkaz", "definujodstavce", "definujopis", "definujoramovani", "definujoramovanytext", "definujpaletu", "definujplvouciobjekt", "definujpodpole", "definujpole", "definujpopis", "definujpopisek", "definujprekryv", "definujprikaz", "definujprofil", "definujprogram", "definujprostredizakladnihofontu", "definujrejstrik", "definujsablonutabulky", "definujsekci", "definujseznam", "definujskupinubarev", "definujstartstop", "definujstyl", "definujstylfontu", "definujsymbol", "definujsynonumumfontu", "definujsynonyma", "definujtabelaci", "definujtext", "definujtrideni", "definujupravu", "definujvelikostpapiru", "definujvycet", "definujzakladnifont", "definujzasobnikpoli", "definujznaceni", "definujznak", "delkaseznamu", "externiobraz", "hlavnijazyk", "hodnotabarvy", "instalacejazyka", "interakcnilista", "interakcnitlacitka", "interaktivnimenu", "jazyk", "jdidolu", "jdina", "jdinabox", "jdinastranu", "klonujpole", "komponenta", "konvertujcislo", "kopirujpole", "korekcebilehomista", "matematika", "meritko", "mesic", "mezera", "mrizka", "nastavbarvu", "nastavbarvy", "nastavbilamista", "nastavblok", "nastavbloksekce", "nastavbuffer", "nastavcernelinky", "nastavcislonadpisu", "nastavcislostrany", "nastavcislovaniodstavcu", "nastavcislovaniradku", "nastavcislovanistran", "nastavcitaci", "nastavdeleniplvoucichobjektu", "nastavdelitko", "nastavdolnitexty", "nastavhorejsek", "nastavhornitexty", "nastavinterakci", "nastavinterakcnilistu", "nastavinterakcnimenu", "nastavinterakcniobrazovku", "nastavjazyk", "nastavkapitalky", "nastavkombinovanyseznam", "nastavkomentar", "nastavkomentarstrany", "nastavmarginalnilinky", "nastavmeziradkovoumezeru", "nastavnadpis", "nastavnadpisy", "nastavodkazovani", "nastavodsazovani", "nastavodstavce", "nastavopis", "nastavoramovanetexty", "nastavoramovani", "nastavorez", "nastavotoceni", "nastavpaletu", "nastavplvouciobjekt", "nastavplvouciobjekty", "nastavpodcislostrany", "nastavpole", "nastavpolozky", "nastavpopisek", "nastavpopisky", "nastavpozadi", "nastavprechodstrany", "nastavpreskok", "nastavprogramy", "nastavradkovani", "nastavradky", "nastavrejstrik", "nastavrovnice", "nastavsadusymbolu", "nastavseznam", "nastavsirkucary", "nastavsloupce", "nastavspodek", "nastavsynonyma", "nastavtabelaci", "nastavtabulky", "nastavtenkelinky", "nastavtext", "nastavtextovelinky", "nastavtexttexty", "nastavtextyupati", "nastavtextyzahlavi", "nastavtoleranci", "nastavtrideni", "nastavtype", "nastavumisteniprotejsku", "nastavumistovani", "nastavupati", "nastavupravu", "nastavurl", "nastavusporadani", "nastavvelikostpapiru", "nastavvsechnapole", "nastavvycty", "nastavvyplnovelinky", "nastavvyplnoveradky", "nastavvzhled", "nastavzahlavi", "nastavzakladnifont", "nastavzarovnani", "nastavznaceni", "nastavzuzeni", "nastrane", "nejakyradek", "nekde", "neznamo", "nivy", "nizky", "nokap", "obrazovka", "odkaz", "odkaznastranu", "odkaznatext", "odkazujici", "opis", "opissoubor", "oramovani", "oref", "orez", "otocit", "oznaceni", "pis", "plnezneni", "pole", "polozka", "polozky", "porovnejpaletu", "porovnejskupinubarev", "pozadi", "pozice", "poznamka", "pref", "prelozit", "prepninazakladnifont", "preskoc", "prizpusobivepole", "prizpusobvzhled", "produkt", "projekt", "prostredi", "resetznaceni", "rimskecislice", "rozdelplvouciobjekt", "roztazene", "schovejbloky", "sedabarva", "sloupec", "slovovpravo", "stanovcharakteristickuseznamu", "stanovcislonadpisu", "startbarva", "startinteraktivnimenu", "startjdina", "startkomponenta", "startmarginalnilinka", "startnadpis", "startoramovani", "startpolozka", "startpozadi", "startprodukt", "startprojekt", "startprostredi", "startpublikace", "startradek", "starttextovalinka", "startumistirovnici", "startzarovnanonastred", "startzarovnanovlevo", "startzarovnanovpravo", "startzhustene", "stopbarva", "stopinteraktivnimenu", "stopjdina", "stopkomponenta", "stopmarginalnilinka", "stopnadpis", "stoporamovani", "stoppolozka", "stoppozadi", "stopprodukt", "stopprojekt", "stopprostredi", "stoppublikace", "stopradek", "stoptextovalinka", "stopumistirovnici", "stopzarovnanonastred", "stopzarovnanovlevo", "stopzarovnanovpravo", "stopzhustene", "strana", "tecky", "tenkalinka", "tenkelinky", "textovalinka", "tlacitko", "tlacitkomenu", "tloustkacary", "tref", "tvrdamezera", "tvrdemezery", "ukazbarvu", "ukazmrizku", "ukaznastaveni", "ukazpaletu", "ukazpodpery", "ukazpostredizakladnihofontu", "ukazramecek", "ukazsadusymbolu", "ukazskupinubarev", "ukazupravu", "ukazvytisk", "ukazvzhled", "ukazzakladnifont", "umistikombinovanyseznam", "umistilokalnipoznamkypodcarou", "umistinadsebe", "umistinamrizku", "umistipodrovnici", "umistipoznamkypodcarou", "umistirejstrik", "umistirovnici", "umistiseznam", "umistivedlesebe", "umistizalozky", "urcicharakteristikurejstriku", "uzijJSscripts", "uzijURL", "uzijadresar", "uzijbloky", "uzijexternidokument", "uzijexterniobraz", "uzijexternizvuk", "uzijmodul", "uzijsymbol", "uzijurl", "verze", "vlasovalinka", "vradku", "vsedniden", "vyberbloky", "vyplnenytext", "vyplnovelinky", "vyplnovyradek", "vysoky", "zachovejbloky", "zadnamezera", "zadnehorniadolniradky", "zadnezahlaviaupati", "zalozka", "zapisdoseznamu", "zapismeziseznam", "zaramovani", "zarovnanonastred", "zarovnanovlevo", "zarovnanovpravo", "zasobnikpoli", "ziskejbuffer", "ziskejznaceni", "znaceni", "znak", "znaky", "zpracujbloky", "zrcadlit", "zref" },
- ["de"]={ "Buchstabe", "Buchstaben", "Kap", "MONAT", "Roemischezahlen", "WOCHENTAG", "WOERTER", "WORT", "Woerter", "Wort", "Ziffern", "amgitterausrichten", "aufseite", "ausfuelltext", "ausschnitt", "bearbeitebloecke", "behaltebloecke", "bei", "bemerkung", "benutzeverzeichnis", "beschriftung", "bestimmekopfnummer", "bestimmelistencharakeristika", "bestimmeregistercharakteristika", "bildschirm", "blanko", "buchstabe", "buchstaben", "datum", "defineschriftsynonym", "definiereabbsymbol", "definiereabsaetze", "definiereabschnitt", "definiereabschnittsblock", "definiereakzent", "definierebefehl", "definierebeschreibung", "definierebeschriftung", "definiereblock", "definierefarbe", "definierefarbengruppe", "definierefeld", "definierefeldstapel", "definierefliesstext", "definierefliesstextumgebung", "definieregleitobjekt", "definierehbox", "definiereinteraktionsmenue", "definierekonversion", "definierelabel", "definiereliste", "definieren", "definierenummerierung", "definiereoverlay", "definierepalette", "definierepapierformat", "definiereprofil", "definiereprogramme", "definierepuffer", "definierereferenz", "definierereferenzformat", "definiereregister", "definiereschrift", "definiereschriftstil", "definieresortieren", "definierestartstop", "definierestil", "definieresubfeld", "definieresymbol", "definieresynonyme", "definieretabellenvorlage", "definieretabulator", "definieretext", "definieretippen", "definiereueberschrift", "definiereumbruch", "definiereumrahmt", "definiereumrahmtertext", "definierezeichen", "definierezusammengestellteliste", "drehen", "duennelinie", "duennerumriss", "einezeile", "externeabbildung", "farbbalken", "farbe", "farbewert", "feld", "feldstapel", "festesspatium", "format", "formelnummer", "gefuelltesrechteck", "gefuelltezeile", "gestreckt", "gitter", "graufarbe", "haarlinie", "hauptsprache", "heutigesdatum", "heutigeskopfnummer", "hintergrund", "hoch", "holebeschriftung", "holepuffer", "imumriss", "installieresprache", "interaktionsbalken", "interaktionsknopfe", "interaktionsmenue", "inzeile", "irgendwo", "keinekopfundfusszeilen", "keinspatium", "keinzeilenobenundunten", "klonierefeld", "knopf", "komponente", "konvertierezahl", "kopfnummer", "kopierefeld", "korrigierezwischenraum", "liniendicke", "linksbuendig", "listenlaenge", "mathematik", "menueknopf", "monat", "nachunten", "nokap", "notiz", "passelayoutan", "passendfeld", "platzierebookmarks", "platziereformel", "platzierefussnoten", "platziereliste", "platzierelokalefussnoten", "platzierenebeneinander", "platziereregister", "platziereuntereinander", "platziereunterformel", "platzierezusammengestellteliste", "pos", "posten", "produkt", "programm", "projekt", "punkt", "rechteck", "rechtecke", "rechtsbuendig", "referenz", "referieren", "roemischezahlen", "ruecksetztenbeschriftung", "schreibezurliste", "schreibezwischenliste", "seite", "seitenreferenz", "seitenummer", "settext", "spalte", "spatium", "spiegeln", "sprache", "startfarbe", "starthintergrund", "startinteraktionsmenue", "startkleinerdurchschuss", "startkomponente", "startkopf", "startlinksbuendig", "startmarginallinie", "startplatziereformel", "startpos", "startprodukt", "startprojekt", "startpublikation", "startrechtsbuendig", "starttextlinie", "startumgebung", "startumrahmt", "startzeile", "startzentriert", "startzu", "stelleabsaetzeein", "stelleabsatznummerierungein", "stelleabschnittsblockein", "stelleanordnenein", "stelleaufzaehlungenein", "stelleausrichtungein", "stelleausschnittein", "stellebeschreibungein", "stellebeschriftungein", "stellebilderunterschriftein", "stellebildunterschriftein", "stellebindestrichein", "stelleblankoein", "stelleblockein", "stelledrehenein", "stelleduennerumrissein", "stelleeinziehenein", "stelleengerein", "stellefarbeein", "stellefarbenein", "stellefeldein", "stellefelderin", "stellefliesstextein", "stelleformelnein", "stellefusszeileein", "stellefusszeilentextein", "stellegefuelltesrechteckein", "stellegefuelltezeileein", "stellegegenueberplatzierenein", "stellegleitobjekteein", "stellegleitobjektein", "stellehintergruendeein", "stellehintergrundein", "stelleinteraktionein", "stelleinteraktionsbalkenein", "stelleinteraktionsbildschirmein", "stelleinteraktionsmenueein", "stellekommentarein", "stellekopfzahlein", "stellekopfzeileein", "stellekopfzeilentextein", "stellelayoutein", "stellelinienbreiteein", "stellelisteein", "stellemarginallinieein", "stellenobenein", "stellepaletteein", "stellepapierformatein", "stelleplatziegeteiltegleitobjekt", "stellepositionierenein", "stellepostenein", "stelleprogrammein", "stellepufferein", "stellerechteckein", "stellereferenzierenein", "stelleregisterein", "stelleseitenkommentarein", "stelleseitennummerein", "stelleseitennummeriernungein", "stelleseitenuebergangein", "stellesortierenein", "stellespaltenein", "stellespatiumein", "stellespracheein", "stellesymbolsetein", "stellesynonymein", "stelletabellenein", "stelletabulatorein", "stelletextein", "stelletextobenein", "stelletexttexteein", "stelletextumrissein", "stelletextuntenein", "stelletipein", "stelletippenein", "stelletoleranzein", "stelleueberschriftein", "stelleueberschriftenein", "stelleumbruchein", "stelleumrahmtein", "stelleumrahmtetexteein", "stelleuntenein", "stelleunterseitennummerein", "stelleurlein", "stelleversalienein", "stellezeilenabstandein", "stellezeilenein", "stellezeilennumerierungein", "stellezitierenein", "stellezusammengestelltelisteein", "stellezwischenraumein", "stopfarbe", "stophintergrund", "stopinteraktionsmenue", "stopkleinerdurchschuss", "stopkomponente", "stopkopf", "stoplinksbuendig", "stopmarginallinie", "stopplatziereformel", "stoppos", "stopprodukt", "stopprojekt", "stoppublikation", "stoprechtsbuendig", "stoptextlinie", "stopumgebung", "stopumrahmt", "stopzeile", "stopzentriert", "stopzu", "teilegleitobjekt", "textlinie", "textreferenz", "tief", "tiho", "tip", "tippedatei", "tippen", "tippepuffer", "ueber", "uebersetzten", "umgebung", "umrahmt", "unbekant", "verbergebloecke", "vergleichefarbengruppe", "vergleichepalette", "verwendeJSscript", "verwendeURL", "verwendebloecke", "verwendeexteresdokument", "verwendeexterneabbildung", "verwendeexternestonstueck", "verwendemodul", "verwendesymbole", "verwendeurl", "volleswort", "von", "waehlebloeckeaus", "wechselezumfliesstext", "wochentag", "wortrechts", "zeigedruck", "zeigeeinstellungen", "zeigefarbe", "zeigefarbengruppe", "zeigefliesstext", "zeigefliesstextumgebung", "zeigegitter", "zeigelayout", "zeigepalette", "zeigerahmen", "zeigestruts", "zeigeumbruch", "zentriert", "ziffern", "zu", "zurbox", "zurseite" },
+ ["common"]={ "AEacute", "AEligature", "AEmacron", "AMSTEX", "Aacute", "Abreve", "Abreveacute", "Abrevedotbelow", "Abrevegrave", "Abrevehook", "Abrevetilde", "Acaron", "Acircumflex", "Acircumflexacute", "Acircumflexdotbelow", "Acircumflexgrave", "Acircumflexhook", "Acircumflextilde", "Adiaeresis", "Adiaeresismacron", "Adotaccent", "Adotaccentmacron", "Adotbelow", "Adoublegrave", "AfterPar", "Agrave", "Ahook", "Ainvertedbreve", "Alpha", "Alphabeticnumerals", "AmSTeX", "Amacron", "And", "Angstrom", "Aogonek", "Aring", "Aringacute", "Arrowvert", "Astroke", "Atilde", "BeforePar", "Beta", "Bhook", "Big", "Bigg", "Biggl", "Biggm", "Biggr", "Bigl", "Bigm", "Bigr", "Box", "Bumpeq", "CONTEXT", "Cacute", "Cap", "Caps", "Ccaron", "Ccedilla", "Ccircumflex", "Cdotaccent", "Character", "Characters", "Chi", "Chook", "ConTeXt", "Context", "ConvertConstantAfter", "ConvertToConstant", "Cstroke", "Cup", "DZcaronligature", "DZligature", "Dafrican", "Dcaron", "Ddownarrow", "Delta", "Dhook", "Doteq", "Downarrow", "Dstroke", "Dzcaronligature", "Dzligature", "ETEX", "Eacute", "Ebreve", "Ecaron", "Ecedilla", "Ecircumflex", "Ecircumflexacute", "Ecircumflexdotbelow", "Ecircumflexgrave", "Ecircumflexhook", "Ecircumflextilde", "Ediaeresis", "Edotaccent", "Edotbelow", "Edoublegrave", "Egrave", "Ehook", "Einvertedbreve", "Emacron", "Eogonek", "Epsilon", "Eta", "Eth", "Etilde", "Eulerconst", "EveryLine", "EveryPar", "Fhook", "Finv", "Gacute", "Game", "Gamma", "Gbreve", "Gcaron", "Gcircumflex", "Gcommaaccent", "Gdotaccent", "GetPar", "Ghook", "GotoPar", "Greeknumerals", "Gstroke", "Hat", "Hcaron", "Hcircumflex", "Hstroke", "IJligature", "INRSTEX", "Iacute", "Ibreve", "Icaron", "Icircumflex", "Idiaeresis", "Idotaccent", "Idotbelow", "Idoublegrave", "Igrave", "Ihook", "Iinvertedbreve", "Im", "Imacron", "Iogonek", "Iota", "Istroke", "Itilde", "Jcircumflex", "Join", "Kappa", "Kcaron", "Kcommaaccent", "Khook", "LAMSTEX", "LATEX", "LJligature", "LUAJITTEX", "LUATEX", "LaTeX", "Lacute", "LamSTeX", "Lambda", "Lbar", "Lcaron", "Lcommaaccent", "Ldotmiddle", "Ldsh", "Leftarrow", "Leftrightarrow", "Ljligature", "Lleftarrow", "Longleftarrow", "Longleftrightarrow", "Longmapsfrom", "Longmapsto", "Longrightarrow", "Lsh", "Lstroke", "Lua", "LuaTeX", "LuajitTeX", "METAFONT", "METAFUN", "METAPOST", "MKII", "MKIV", "MKIX", "MKVI", "MKXI", "MONTH", "MONTHLONG", "MONTHSHORT", "MPII", "MPIV", "MPVI", "MPanchor", "MPbetex", "MPc", "MPcode", "MPcolor", "MPcoloronly", "MPcolumn", "MPd", "MPdrawing", "MPfontsizehskip", "MPgetmultipars", "MPgetmultishape", "MPgetposboxes", "MPh", "MPinclusions", "MPleftskip", "MPll", "MPlr", "MPls", "MPmenubuttons", "MPn", "MPoptions", "MPoverlayanchor", "MPp", "MPpage", "MPpardata", "MPplus", "MPpos", "MPpositiongraphic", "MPposset", "MPr", "MPrawvar", "MPregion", "MPrest", "MPrightskip", "MPrs", "MPstring", "MPtext", "MPtransparency", "MPul", "MPur", "MPv", "MPvar", "MPvariable", "MPvv", "MPw", "MPwhd", "MPx", "MPxy", "MPxywhd", "MPy", "Mapsfrom", "Mapsto", "MetaFont", "MetaFun", "MetaPost", "Mu", "NJligature", "Nacute", "Ncaron", "Ncommaaccent", "Nearrow", "Neng", "Ngrave", "Njligature", "NormalizeFontHeight", "NormalizeFontWidth", "NormalizeTextHeight", "NormalizeTextWidth", "Ntilde", "Nu", "Numbers", "Nwarrow", "OEligature", "Oacute", "Obreve", "Ocaron", "Ocircumflex", "Ocircumflexacute", "Ocircumflexdotbelow", "Ocircumflexgrave", "Ocircumflexhook", "Ocircumflextilde", "Odiaeresis", "Odiaeresismacron", "Odotaccent", "Odotaccentmacron", "Odotbelow", "Odoublegrave", "Ograve", "Ohook", "Ohorn", "Ohornacute", "Ohorndotbelow", "Ohorngrave", "Ohornhook", "Ohorntilde", "Ohungarumlaut", "Oinvertedbreve", "Omacron", "Omega", "Omicron", "Oogonek", "Oogonekmacron", "Ostroke", "Ostrokeacute", "Otilde", "Otildemacron", "P", "PDFETEX", "PDFTEX", "PDFcolor", "PICTEX", "PPCHTEX", "PPCHTeX", "PRAGMA", "Phi", "Phook", "Pi", "PiCTeX", "Plankconst", "PointsToBigPoints", "PointsToReal", "PointsToWholeBigPoints", "PropertyLine", "Psi", "PtToCm", "Racute", "Rcaron", "Rcommaaccent", "Rdoublegrave", "Rdsh", "Re", "ReadFile", "Relbar", "Rho", "Rightarrow", "Rinvertedbreve", "Romannumerals", "Rrightarrow", "Rsh", "S", "Sacute", "ScaledPointsToBigPoints", "ScaledPointsToWholeBigPoints", "Scaron", "Scedilla", "Schwa", "Scircumflex", "Scommaaccent", "Searrow", "Sigma", "Smallcapped", "Subset", "Supset", "Swarrow", "TABLE", "TEX", "TaBlE", "Tau", "Tcaron", "Tcedilla", "Tcommaaccent", "TeX", "TheNormalizedFontSize", "Theta", "Thook", "Thorn", "TransparencyHack", "Tstroke", "Uacute", "Ubreve", "Ucaron", "Ucircumflex", "Udiaeresis", "Udiaeresisacute", "Udiaeresiscaron", "Udiaeresisgrave", "Udiaeresismacron", "Udotbelow", "Udoublegrave", "Ugrave", "Uhook", "Uhorn", "Uhornacute", "Uhorndotbelow", "Uhorngrave", "Uhornhook", "Uhorntilde", "Uhungarumlaut", "Uinvertedbreve", "Umacron", "Uogonek", "Uparrow", "Updownarrow", "Upsilon", "Uring", "Utilde", "Uuparrow", "VDash", "Vdash", "VerboseNumber", "Vert", "Vvdash", "WEEKDAY", "WORD", "WORDS", "Wcircumflex", "WidthSpanningText", "Word", "Words", "XETEX", "XeTeX", "Xi", "Yacute", "Ycircumflex", "Ydiaeresis", "Ydotbelow", "Ygrave", "Yhook", "Ymacron", "Ytilde", "Zacute", "Zcaron", "Zdotaccent", "Zeta", "Zhook", "Zstroke", "aacute", "abbreviation", "abjadnaivenumerals", "abjadnodotnumerals", "abjadnumerals", "about", "abreve", "abreveacute", "abrevedotbelow", "abrevegrave", "abrevehook", "abrevetilde", "acaron", "acircumflex", "acircumflexacute", "acircumflexdotbelow", "acircumflexgrave", "acircumflexhook", "acircumflextilde", "activatespacehandler", "actuarial", "acute", "acwopencirclearrow", "adaptcollector", "adaptfontfeature", "adaptlayout", "adaptpapersize", "addfeature", "addfontpath", "addtoJSpreamble", "addtocommalist", "addvalue", "adiaeresis", "adiaeresismacron", "adotaccent", "adotaccentmacron", "adotbelow", "adoublegrave", "aeacute", "aeligature", "aemacron", "afghanicurrency", "aftersplitstring", "aftertestandsplitstring", "agrave", "ahook", "ainvertedbreve", "aleph", "alignbottom", "aligned", "alignedbox", "alignedline", "alignhere", "alignmentcharacter", "allinputpaths", "alpha", "alphabeticnumerals", "alwayscitation", "alwayscite", "amacron", "amalg", "ampersand", "anchor", "angle", "aogonek", "appendetoks", "appendgvalue", "appendtocommalist", "appendtoks", "appendtoksonce", "appendvalue", "apply", "applyalternativestyle", "applyprocessor", "applytocharacters", "applytofirstcharacter", "applytosplitstringchar", "applytosplitstringcharspaced", "applytosplitstringline", "applytosplitstringlinespaced", "applytosplitstringword", "applytosplitstringwordspaced", "applytowords", "approx", "approxEq", "approxeq", "approxnEq", "arabicakbar", "arabicalayhe", "arabicallah", "arabicallallahou", "arabicasterisk", "arabicbasmalah", "arabiccomma", "arabiccuberoot", "arabicdateseparator", "arabicdecimals", "arabicdisputedendofayah", "arabicendofayah", "arabicexnumerals", "arabicfootnotemarker", "arabicfourthroot", "arabichighain", "arabichighalayheassallam", "arabichigheqala", "arabichighesala", "arabichighfootnotemarker", "arabichighjeem", "arabichighlamalef", "arabichighmadda", "arabichighmeemlong", "arabichighmeemshort", "arabichighnisf", "arabichighnoon", "arabichighnoonkasra", "arabichighqaf", "arabichighqif", "arabichighradiallahouanhu", "arabichighrahmatullahalayhe", "arabichighrubc", "arabichighsad", "arabichighsajda", "arabichighsakta", "arabichighsallallahou", "arabichighseen", "arabichighsmallsafha", "arabichightah", "arabichightakhallus", "arabichighthalatha", "arabichighwaqf", "arabichighyeh", "arabichighzain", "arabicjallajalalouhou", "arabiclettermark", "arabiclowmeemlong", "arabiclownoonkasra", "arabiclowseen", "arabicmisra", "arabicmuhammad", "arabicnumber", "arabicnumberabove", "arabicnumerals", "arabicparenleft", "arabicparenright", "arabicpercent", "arabicperiod", "arabicpermille", "arabicpertenthousand", "arabicpoeticverse", "arabicqala", "arabicquestion", "arabicrasoul", "arabicray", "arabicrialsign", "arabicsafha", "arabicsajdah", "arabicsalla", "arabicsamvat", "arabicsanah", "arabicsemicolon", "arabicshighthreedots", "arabicslcm", "arabicstartofrubc", "arabictripledot", "arabicvowelwaw", "arabicvowelyeh", "arabicwasallam", "arg", "aring", "aringacute", "arrowvert", "asciistr", "aside", "assignalfadimension", "assigndimen", "assigndimension", "assignifempty", "assigntranslation", "assignvalue", "assignwidth", "assumelongusagecs", "ast", "astype", "asymp", "at", "atilde", "atleftmargin", "atpage", "atrightmargin", "attachment", "autocap", "autodirhbox", "autodirvbox", "autodirvtop", "autoinsertnextspace", "autointegral", "automathematics", "autopagestaterealpage", "autopagestaterealpageorder", "autosetups", "availablehsize", "averagecharwidth", "backepsilon", "background", "backgroundimage", "backgroundimagefill", "backgroundline", "backprime", "backsim", "backslash", "bar", "barleftarrow", "barleftarrowrightarrowbar", "barovernorthwestarrow", "barwedge", "basegrid", "baselinebottom", "baselineleftbox", "baselinemiddlebox", "baselinerightbox", "bbordermatrix", "bbox", "because", "beforesplitstring", "beforetestandsplitstring", "beta", "beth", "between", "bhook", "big", "bigbodyfont", "bigcap", "bigcirc", "bigcircle", "bigcup", "bigdiamond", "bigg", "bigger", "biggl", "biggm", "biggr", "bigl", "bigm", "bigodot", "bigoplus", "bigotimes", "bigr", "bigskip", "bigsqcap", "bigsqcup", "bigsquare", "bigstar", "bigtimes", "bigtriangledown", "bigtriangleup", "bigudot", "biguplus", "bigvee", "bigwedge", "binom", "bitmapimage", "blacklozenge", "blackrule", "blackrules", "blacksquare", "blacktriangle", "blacktriangledown", "blacktriangleleft", "blacktriangleright", "blank", "blap", "bleed", "bleedheight", "bleedwidth", "blockligatures", "blockquote", "blocksynctexfile", "blockuservariable", "bodyfontenvironmentlist", "bodyfontsize", "bold", "boldface", "bolditalic", "boldslanted", "bookmark", "booleanmodevalue", "bordermatrix", "bot", "bottombox", "bottomleftbox", "bottomrightbox", "bowtie", "boxcursor", "boxdot", "boxmarker", "boxminus", "boxofsize", "boxplus", "boxreference", "boxtimes", "bpos", "breakablethinspace", "breakhere", "breve", "bstroke", "btxabbreviatedjournal", "btxaddjournal", "btxalwayscitation", "btxauthorfield", "btxdetail", "btxdirect", "btxdoif", "btxdoifcombiinlistelse", "btxdoifelse", "btxdoifelsecombiinlist", "btxdoifelsesameasprevious", "btxdoifelsesameaspreviouschecked", "btxdoifelseuservariable", "btxdoifnot", "btxdoifsameaspreviouscheckedelse", "btxdoifsameaspreviouselse", "btxdoifuservariableelse", "btxexpandedjournal", "btxfield", "btxfieldname", "btxfieldtype", "btxfirstofrange", "btxflush", "btxflushauthor", "btxflushauthorinverted", "btxflushauthorinvertedshort", "btxflushauthorname", "btxflushauthornormal", "btxflushauthornormalshort", "btxflushsuffix", "btxfoundname", "btxfoundtype", "btxhiddencitation", "btxhybridcite", "btxlabellanguage", "btxlabeltext", "btxlistcitation", "btxloadjournalist", "btxoneorrange", "btxremapauthor", "btxsavejournalist", "btxsetup", "btxsingularorplural", "btxsingularplural", "btxtextcitation", "buildmathaccent", "buildtextaccent", "buildtextbottomcomma", "buildtextbottomdot", "buildtextcedilla", "buildtextgrave", "buildtextmacron", "buildtextognek", "bullet", "button", "cacute", "calligraphic", "camel", "cap", "carriagereturn", "catcodetablename", "cbox", "ccaron", "ccedilla", "ccircumflex", "ccurl", "cdot", "cdotaccent", "cdotp", "cdots", "centeraligned", "centerbox", "centerdot", "centeredbox", "centeredlastline", "centerednextbox", "centerline", "cfrac", "chapter", "character", "characters", "chardescription", "charwidthlanguage", "check", "checkcharacteralign", "checkedblank", "checkedchar", "checkedfiller", "checkedstrippedcsname", "checkinjector", "checkmark", "checknextindentation", "checknextinjector", "checkpage", "checkparameters", "checkpreviousinjector", "checksoundtrack", "checktwopassdata", "checkvariables", "chem", "chemical", "chemicalbottext", "chemicalmidtext", "chemicalsymbol", "chemicaltext", "chemicaltoptext", "chi", "chineseallnumerals", "chinesecapnumerals", "chinesenumerals", "chook", "circ", "circeq", "circlearrowleft", "circlearrowright", "circledR", "circledS", "circledast", "circledcirc", "circleddash", "circledequals", "circleonrightarrow", "citation", "cite", "clap", "classfont", "cldcommand", "cldcontext", "cldloadfile", "cldprocessfile", "cleftarrow", "clip", "clippedoverlayimage", "clonefield", "clubsuit", "collect", "collectedtext", "collectexpanded", "colon", "coloncolonequals", "colonequals", "color", "colorbar", "colorcomponents", "colored", "coloronly", "colorvalue", "column", "columnbreak", "columnsetspanwidth", "combinepages", "commalistelement", "commalistsentence", "commalistsize", "comment", "comparecolorgroup", "comparedimension", "comparedimensioneps", "comparepalet", "complement", "completebtxrendering", "completecontent", "completeindex", "completelist", "completelistofabbreviations", "completelistofchemicals", "completelistoffigures", "completelistofgraphics", "completelistofintermezzi", "completelistoflogos", "completelistofpublications", "completelistofsorts", "completelistofsynonyms", "completelistoftables", "completepagenumber", "completeregister", "complexes", "complexorsimple", "complexorsimpleempty", "component", "composedcollector", "composedlayer", "compresult", "cong", "constantdimen", "constantdimenargument", "constantemptyargument", "constantnumber", "constantnumberargument", "contentreference", "continuednumber", "continueifinputfile", "convertargument", "convertcommand", "convertedcounter", "converteddimen", "convertedsubcounter", "convertmonth", "convertnumber", "convertvalue", "convertvboxtohbox", "coprod", "copyboxfromcache", "copybtxlabeltext", "copyfield", "copyheadtext", "copylabeltext", "copymathlabeltext", "copyoperatortext", "copypages", "copyparameters", "copyposition", "copyprefixtext", "copyright", "copysetups", "copysuffixtext", "copytaglabeltext", "copyunittext", "correctwhitespace", "countersubs", "counttoken", "counttokens", "cramped", "crampedclap", "crampedllap", "crampedrlap", "crightarrow", "crightoverleftarrow", "cstroke", "ctop", "ctxcommand", "ctxdirectcommand", "ctxdirectlua", "ctxfunction", "ctxlatecommand", "ctxlatelua", "ctxloadluafile", "ctxlua", "ctxluabuffer", "ctxluacode", "ctxreport", "ctxsprint", "cup", "curlyeqprec", "curlyeqsucc", "curlyvee", "curlywedge", "currentassignmentlistkey", "currentassignmentlistvalue", "currentbtxuservariable", "currentcommalistitem", "currentcomponent", "currentdate", "currentenvironment", "currentfeaturetest", "currentheadnumber", "currentinterface", "currentlanguage", "currentlistentrydestinationattribute", "currentlistentrylimitedtext", "currentlistentrynumber", "currentlistentrypagenumber", "currentlistentryreferenceattribute", "currentlistentrytitle", "currentlistentrytitlerendered", "currentlistsymbol", "currentmainlanguage", "currentmessagetext", "currentmoduleparameter", "currentoutputstream", "currentproduct", "currentproject", "currentregime", "currentregisterpageuserdata", "currentresponses", "currenttime", "currentvalue", "currentxtablecolumn", "currentxtablerow", "curvearrowleft", "curvearrowright", "cwopencirclearrow", "cyrillicA", "cyrillicAE", "cyrillicAbreve", "cyrillicAdiaeresis", "cyrillicB", "cyrillicBIGYUS", "cyrillicBIGYUSiotified", "cyrillicC", "cyrillicCH", "cyrillicCHEDC", "cyrillicCHEDCabkhasian", "cyrillicCHEabkhasian", "cyrillicCHEdiaeresis", "cyrillicCHEkhakassian", "cyrillicCHEvertstroke", "cyrillicD", "cyrillicDASIAPNEUMATA", "cyrillicDJE", "cyrillicDZE", "cyrillicDZEabkhasian", "cyrillicDZHE", "cyrillicE", "cyrillicELtail", "cyrillicEMtail", "cyrillicENDC", "cyrillicENGHE", "cyrillicENhook", "cyrillicENtail", "cyrillicEREV", "cyrillicERY", "cyrillicERtick", "cyrillicEbreve", "cyrillicEdiaeresis", "cyrillicEgrave", "cyrillicEiotified", "cyrillicF", "cyrillicFITA", "cyrillicG", "cyrillicGHEmidhook", "cyrillicGHEstroke", "cyrillicGHEupturn", "cyrillicGJE", "cyrillicH", "cyrillicHA", "cyrillicHADC", "cyrillicHRDSN", "cyrillicI", "cyrillicIE", "cyrillicII", "cyrillicISHRT", "cyrillicISHRTtail", "cyrillicIZHITSA", "cyrillicIZHITSAdoublegrave", "cyrillicIdiaeresis", "cyrillicIgrave", "cyrillicImacron", "cyrillicJE", "cyrillicK", "cyrillicKADC", "cyrillicKAbashkir", "cyrillicKAhook", "cyrillicKAstroke", "cyrillicKAvertstroke", "cyrillicKJE", "cyrillicKOPPA", "cyrillicKSI", "cyrillicL", "cyrillicLITTLEYUS", "cyrillicLITTLEYUSiotified", "cyrillicLJE", "cyrillicM", "cyrillicN", "cyrillicNJE", "cyrillicO", "cyrillicOMEGA", "cyrillicOMEGAround", "cyrillicOMEGAtitlo", "cyrillicOT", "cyrillicObarred", "cyrillicObarreddiaeresis", "cyrillicOdiaeresis", "cyrillicP", "cyrillicPALATALIZATION", "cyrillicPALOCHKA", "cyrillicPEmidhook", "cyrillicPSI", "cyrillicPSILIPNEUMATA", "cyrillicR", "cyrillicS", "cyrillicSCHWA", "cyrillicSCHWAdiaeresis", "cyrillicSDSC", "cyrillicSEMISOFT", "cyrillicSFTSN", "cyrillicSH", "cyrillicSHCH", "cyrillicSHHA", "cyrillicT", "cyrillicTEDC", "cyrillicTETSE", "cyrillicTITLO", "cyrillicTSHE", "cyrillicU", "cyrillicUK", "cyrillicUSHRT", "cyrillicUdiaeresis", "cyrillicUdoubleacute", "cyrillicUmacron", "cyrillicV", "cyrillicYA", "cyrillicYAT", "cyrillicYERUdiaeresis", "cyrillicYI", "cyrillicYO", "cyrillicYU", "cyrillicYstr", "cyrillicYstrstroke", "cyrillicZ", "cyrillicZDSC", "cyrillicZEdiaeresis", "cyrillicZH", "cyrillicZHEbreve", "cyrillicZHEdescender", "cyrillicZHEdiaeresis", "cyrillica", "cyrillicabreve", "cyrillicadiaeresis", "cyrillicae", "cyrillicb", "cyrillicbigyus", "cyrillicbigyusiotified", "cyrillicc", "cyrillicch", "cyrilliccheabkhasian", "cyrillicchedc", "cyrillicchedcabkhasian", "cyrillicchediaeresis", "cyrillicchekhakassian", "cyrillicchevertstroke", "cyrillicd", "cyrillicdje", "cyrillicdze", "cyrillicdzeabkhasian", "cyrillicdzhe", "cyrillice", "cyrillicebreve", "cyrillicediaeresis", "cyrillicegrave", "cyrilliceiotified", "cyrilliceltail", "cyrillicemtail", "cyrillicendc", "cyrillicenghe", "cyrillicenhook", "cyrillicentail", "cyrillicerev", "cyrillicertick", "cyrillicery", "cyrillicf", "cyrillicfita", "cyrillicg", "cyrillicghemidhook", "cyrillicghestroke", "cyrillicgheupturn", "cyrillicgje", "cyrillich", "cyrillicha", "cyrillichadc", "cyrillichrdsn", "cyrillici", "cyrillicidiaeresis", "cyrillicie", "cyrillicigrave", "cyrillicii", "cyrillicimacron", "cyrillicishrt", "cyrillicishrttail", "cyrillicizhitsa", "cyrillicizhitsadoublegrave", "cyrillicje", "cyrillick", "cyrillickabashkir", "cyrillickadc", "cyrillickahook", "cyrillickastroke", "cyrillickavertstroke", "cyrillickje", "cyrillickoppa", "cyrillicksi", "cyrillicl", "cyrilliclittleyus", "cyrilliclittleyusiotified", "cyrilliclje", "cyrillicm", "cyrillicn", "cyrillicnje", "cyrillico", "cyrillicobarred", "cyrillicobarreddiaeresis", "cyrillicodiaeresis", "cyrillicomega", "cyrillicomegaround", "cyrillicomegatitlo", "cyrillicot", "cyrillicp", "cyrillicpemidhook", "cyrillicpsi", "cyrillicr", "cyrillics", "cyrillicschwa", "cyrillicschwadiaeresis", "cyrillicsdsc", "cyrillicsemisoft", "cyrillicsftsn", "cyrillicsh", "cyrillicshch", "cyrillicshha", "cyrillict", "cyrillictedc", "cyrillictetse", "cyrillictshe", "cyrillicu", "cyrillicudiaeresis", "cyrillicudoubleacute", "cyrillicuk", "cyrillicumacron", "cyrillicushrt", "cyrillicv", "cyrillicya", "cyrillicyat", "cyrillicyerudiaeresis", "cyrillicyi", "cyrillicyo", "cyrillicystr", "cyrillicystrstroke", "cyrillicyu", "cyrillicz", "cyrilliczdsc", "cyrilliczediaeresis", "cyrilliczh", "cyrilliczhebreve", "cyrilliczhedescender", "cyrilliczhediaeresis", "d", "dag", "dagger", "daleth", "dasharrow", "dashedleftarrow", "dashedrightarrow", "dashv", "datasetvariable", "date", "dayoftheweek", "dayspermonth", "dbinom", "dcaron", "dcurl", "ddag", "ddagger", "dddot", "ddot", "ddots", "decrement", "decrementcounter", "decrementedcounter", "decrementpagenumber", "decrementsubpagenumber", "decrementvalue", "defaultinterface", "defaultobjectpage", "defaultobjectreference", "defcatcodecommand", "defconvertedargument", "defconvertedcommand", "defconvertedvalue", "define", "defineMPinstance", "defineTABLEsetup", "defineaccent", "defineactivecharacter", "definealternativestyle", "defineanchor", "defineattachment", "defineattribute", "definebackground", "definebar", "defineblock", "definebodyfont", "definebodyfontenvironment", "definebodyfontswitch", "definebreakpoint", "definebreakpoints", "definebtx", "definebtxdataset", "definebtxregister", "definebtxrendering", "definebuffer", "definebutton", "definecapitals", "definecharacter", "definecharacterkerning", "definecharacterspacing", "definechemical", "definechemicals", "definechemicalsymbol", "definecollector", "definecolor", "definecolorgroup", "definecolumnbreak", "definecolumnset", "definecolumnsetarea", "definecolumnsetspan", "definecombination", "definecombinedlist", "definecommand", "definecomment", "definecomplexorsimple", "definecomplexorsimpleempty", "defineconversion", "defineconversionset", "definecounter", "definedataset", "definedelimitedtext", "definedeq", "definedescription", "definedfont", "defineeffect", "defineenumeration", "defineexpandable", "defineexternalfigure", "definefacingfloat", "definefallbackfamily", "definefield", "definefieldbody", "definefieldbodyset", "definefieldcategory", "definefieldstack", "definefiguresymbol", "definefileconstant", "definefilefallback", "definefilesynonym", "definefiller", "definefirstline", "definefittingpage", "definefloat", "definefont", "definefontalternative", "definefontfallback", "definefontfamily", "definefontfamilypreset", "definefontfeature", "definefontfile", "definefontsize", "definefontsolution", "definefontstyle", "definefontsynonym", "defineformula", "defineformulaalternative", "defineformulaframed", "defineframed", "defineframedcontent", "defineframedtable", "defineframedtext", "definefrozenfont", "defineglobalcolor", "definegraphictypesynonym", "definegridsnapping", "definehbox", "definehead", "defineheadalternative", "definehelp", "definehigh", "definehighlight", "definehspace", "definehypenationfeatures", "defineindentedtext", "defineindenting", "defineinitial", "defineinsertion", "defineinteraction", "defineinteractionbar", "defineinteractionmenu", "defineinterfaceconstant", "defineinterfaceelement", "defineinterfacevariable", "defineinterlinespace", "defineintermediatecolor", "defineitemgroup", "defineitems", "definelabel", "definelabelclass", "definelayer", "definelayerpreset", "definelayout", "definelinefiller", "definelinenote", "definelinenumbering", "definelines", "definelist", "definelistalternative", "definelistextra", "definelow", "definelowhigh", "definelowmidhigh", "definemakeup", "definemarginblock", "definemargindata", "definemarker", "definemarking", "definemathaccent", "definemathalignment", "definemathcases", "definemathcommand", "definemathdouble", "definemathdoubleextensible", "definemathematics", "definemathextensible", "definemathfence", "definemathfraction", "definemathframed", "definemathmatrix", "definemathornament", "definemathover", "definemathoverextensible", "definemathovertextextensible", "definemathradical", "definemathstackers", "definemathstyle", "definemathtriplet", "definemathunder", "definemathunderextensible", "definemathundertextextensible", "definemathunstacked", "definemeasure", "definemessageconstant", "definemixedcolumns", "definemode", "definemultitonecolor", "definenamedcolor", "definenamespace", "definenarrower", "definenote", "defineornament", "defineoutputroutine", "defineoutputroutinecommand", "defineoverlay", "definepage", "definepagebreak", "definepagechecker", "definepagecolumns", "definepageinjection", "definepageinjectionalternative", "definepageshift", "definepagestate", "definepairedbox", "definepalet", "definepapersize", "defineparagraph", "defineparagraphs", "defineparallel", "defineparbuilder", "defineperiodkerning", "defineplacement", "definepositioning", "defineprefixset", "defineprocesscolor", "defineprocessor", "defineprofile", "defineprogram", "definepushbutton", "definepushsymbol", "definereference", "definereferenceformat", "defineregister", "definerenderingwindow", "defineresetset", "defineruby", "definescale", "definescript", "definesection", "definesectionblock", "definesectionlevels", "defineselector", "defineseparatorset", "defineshift", "definesidebar", "definesort", "definesorting", "definespotcolor", "definestartstop", "definestyle", "definestyleinstance", "definesubfield", "definesubformula", "definesymbol", "definesynonym", "definesynonyms", "definesystemattribute", "definesystemconstant", "definesystemvariable", "definetabletemplate", "definetabulate", "definetabulation", "definetext", "definetextbackground", "definetextflow", "definetokenlist", "definetooltip", "definetransparency", "definetwopasslist", "definetype", "definetypeface", "definetypescriptprefix", "definetypescriptsynonym", "definetypesetting", "definetyping", "defineunit", "defineuserdata", "defineuserdataalternative", "defineviewerlayer", "definevspace", "definevspacing", "definevspacingamount", "definextable", "delimited", "delimitedtext", "delta", "depthofstring", "depthonlybox", "depthspanningtext", "depthstrut", "determineheadnumber", "determinelistcharacteristics", "determinenoflines", "determineregistercharacteristics", "devanagarinumerals", "dfrac", "dhook", "diameter", "diamond", "diamondsuit", "differentialD", "differentiald", "digamma", "digits", "dimensiontocount", "directboxfromcache", "directcolor", "directcolored", "directconvertedcounter", "directcopyboxfromcache", "directdummyparameter", "directgetboxllx", "directgetboxlly", "directhighlight", "directlocalframed", "directluacode", "directselect", "directsetbar", "directsetup", "directsymbol", "directvspacing", "dis", "disabledirectives", "disableexperiments", "disablemode", "disableoutputstream", "disableparpositions", "disableregime", "disabletrackers", "displaymath", "displaymathematics", "displaymessage", "distributedhsize", "div", "dividedsize", "divideontimes", "divides", "doadaptleftskip", "doadaptrightskip", "doaddfeature", "doassign", "doassignempty", "doboundtext", "docheckassignment", "docheckedpagestate", "docheckedpair", "documentvariable", "dodoubleargument", "dodoubleargumentwithset", "dodoubleempty", "dodoubleemptywithset", "dodoublegroupempty", "doeassign", "doexpandedrecurse", "dofastloopcs", "dogetattribute", "dogetattributeid", "dogetcommacommandelement", "dogobbledoubleempty", "dogobblesingleempty", "doif", "doifMPgraphicelse", "doifallcommon", "doifallcommonelse", "doifalldefinedelse", "doifallmodes", "doifallmodeselse", "doifassignmentelse", "doifassignmentelsecs", "doifblackelse", "doifbothsides", "doifbothsidesoverruled", "doifboxelse", "doifbufferelse", "doifcolor", "doifcolorelse", "doifcommandhandler", "doifcommandhandlerelse", "doifcommon", "doifcommonelse", "doifcontent", "doifconversiondefinedelse", "doifconversionnumberelse", "doifcounter", "doifcounterelse", "doifcurrentfonthasfeatureelse", "doifdefined", "doifdefinedcounter", "doifdefinedcounterelse", "doifdefinedelse", "doifdimensionelse", "doifdimenstringelse", "doifdocumentargument", "doifdocumentargumentelse", "doifdocumentfilename", "doifdocumentfilenameelse", "doifdocumentvariable", "doifdocumentvariableelse", "doifdrawingblackelse", "doifelse", "doifelseMPgraphic", "doifelseallcommon", "doifelsealldefined", "doifelseallmodes", "doifelseassignment", "doifelseassignmentcs", "doifelseblack", "doifelsebox", "doifelseboxincache", "doifelsebuffer", "doifelsecolor", "doifelsecommandhandler", "doifelsecommon", "doifelseconversiondefined", "doifelseconversionnumber", "doifelsecounter", "doifelsecurrentfonthasfeature", "doifelsecurrentsortingused", "doifelsecurrentsynonymshown", "doifelsecurrentsynonymused", "doifelsedefined", "doifelsedefinedcounter", "doifelsedimension", "doifelsedimenstring", "doifelsedocumentargument", "doifelsedocumentfilename", "doifelsedocumentvariable", "doifelsedrawingblack", "doifelseempty", "doifelseemptyvalue", "doifelseemptyvariable", "doifelseenv", "doifelsefastoptionalcheck", "doifelsefastoptionalcheckcs", "doifelsefieldbody", "doifelsefieldcategory", "doifelsefigure", "doifelsefile", "doifelsefiledefined", "doifelsefileexists", "doifelsefirstchar", "doifelseflagged", "doifelsefontchar", "doifelsefontfeature", "doifelsefontpresent", "doifelsefontsynonym", "doifelseframed", "doifelsehasspace", "doifelsehelp", "doifelseincsname", "doifelseinelement", "doifelseinputfile", "doifelseinsertion", "doifelseinset", "doifelseinstring", "doifelseinsymbolset", "doifelseintoks", "doifelseintwopassdata", "doifelseitalic", "doifelselanguage", "doifelselayerdata", "doifelselayoutdefined", "doifelselayoutsomeline", "doifelselayouttextline", "doifelseleapyear", "doifelselist", "doifelselocation", "doifelselocfile", "doifelsemainfloatbody", "doifelsemarkedpage", "doifelsemarking", "doifelsemeaning", "doifelsemessage", "doifelsemode", "doifelsenextbgroup", "doifelsenextbgroupcs", "doifelsenextchar", "doifelsenextoptional", "doifelsenextoptionalcs", "doifelsenextparenthesis", "doifelsenonzeropositive", "doifelsenoteonsamepage", "doifelsenothing", "doifelsenumber", "doifelseobjectfound", "doifelseobjectreferencefound", "doifelseoddpage", "doifelseoddpagefloat", "doifelseoldercontext", "doifelseolderversion", "doifelseoverlapping", "doifelseoverlay", "doifelseparallel", "doifelseparentfile", "doifelsepath", "doifelsepathexists", "doifelsepatterns", "doifelseposition", "doifelsepositionaction", "doifelsepositiononpage", "doifelsepositionsonsamepage", "doifelsepositionsonthispage", "doifelsepositionsused", "doifelsereferencefound", "doifelserightpage", "doifelserightpagefloat", "doifelserighttoleftinbox", "doifelsesamelinereference", "doifelsesamestring", "doifelsesetups", "doifelsesomebackground", "doifelsesomespace", "doifelsesomething", "doifelsesometoks", "doifelsestringinstring", "doifelsestructurelisthasnumber", "doifelsestructurelisthaspage", "doifelsesymboldefined", "doifelsesymbolset", "doifelsetext", "doifelsetextflow", "doifelsetextflowcollector", "doifelsetopofpage", "doifelsetypingfile", "doifelseundefined", "doifelseurldefined", "doifelsevalue", "doifelsevaluenothing", "doifelsevariable", "doifempty", "doifemptyelse", "doifemptytoks", "doifemptyvalue", "doifemptyvalueelse", "doifemptyvariable", "doifemptyvariableelse", "doifenv", "doifenvelse", "doiffastoptionalcheckcselse", "doiffastoptionalcheckelse", "doiffieldbodyelse", "doiffieldcategoryelse", "doiffigureelse", "doiffile", "doiffiledefinedelse", "doiffileelse", "doiffileexistselse", "doiffirstcharelse", "doifflaggedelse", "doiffontcharelse", "doiffontfeatureelse", "doiffontpresentelse", "doiffontsynonymelse", "doifhasspaceelse", "doifhelpelse", "doifincsnameelse", "doifinelementelse", "doifinputfileelse", "doifinsertionelse", "doifinset", "doifinsetelse", "doifinstring", "doifinstringelse", "doifinsymbolset", "doifinsymbolsetelse", "doifintokselse", "doifintwopassdataelse", "doifitalicelse", "doiflanguageelse", "doiflayerdataelse", "doiflayoutdefinedelse", "doiflayoutsomelineelse", "doiflayouttextlineelse", "doifleapyearelse", "doiflistelse", "doiflocationelse", "doiflocfileelse", "doifmainfloatbodyelse", "doifmarkingelse", "doifmeaningelse", "doifmessageelse", "doifmode", "doifmodeelse", "doifnextbgroupcselse", "doifnextbgroupelse", "doifnextcharelse", "doifnextoptionalcselse", "doifnextoptionalelse", "doifnextparenthesiselse", "doifnonzeropositiveelse", "doifnot", "doifnotallcommon", "doifnotallmodes", "doifnotcommandhandler", "doifnotcommon", "doifnotcounter", "doifnotdocumentargument", "doifnotdocumentfilename", "doifnotdocumentvariable", "doifnotempty", "doifnotemptyvalue", "doifnotemptyvariable", "doifnotenv", "doifnoteonsamepageelse", "doifnotescollected", "doifnotfile", "doifnotflagged", "doifnothing", "doifnothingelse", "doifnotinset", "doifnotinsidesplitfloat", "doifnotinstring", "doifnotmode", "doifnotnumber", "doifnotsamestring", "doifnotsetups", "doifnotvalue", "doifnotvariable", "doifnumber", "doifnumberelse", "doifobjectfoundelse", "doifobjectreferencefoundelse", "doifoddpageelse", "doifoddpagefloatelse", "doifoldercontextelse", "doifolderversionelse", "doifoverlappingelse", "doifoverlayelse", "doifparallelelse", "doifparentfileelse", "doifpathelse", "doifpathexistselse", "doifpatternselse", "doifposition", "doifpositionaction", "doifpositionactionelse", "doifpositionelse", "doifpositiononpageelse", "doifpositionsonsamepageelse", "doifpositionsonthispageelse", "doifpositionsusedelse", "doifreferencefoundelse", "doifrightpagefloatelse", "doifrighttoleftinboxelse", "doifsamelinereferenceelse", "doifsamestring", "doifsamestringelse", "doifsetups", "doifsetupselse", "doifsomebackground", "doifsomebackgroundelse", "doifsomespaceelse", "doifsomething", "doifsomethingelse", "doifsometoks", "doifsometokselse", "doifstringinstringelse", "doifstructurelisthasnumberelse", "doifstructurelisthaspageelse", "doifsymboldefinedelse", "doifsymbolsetelse", "doiftext", "doiftextelse", "doiftextflowcollectorelse", "doiftextflowelse", "doiftopofpageelse", "doiftypingfileelse", "doifundefined", "doifundefinedcounter", "doifundefinedelse", "doifunknownfontfeature", "doifurldefinedelse", "doifvalue", "doifvalueelse", "doifvaluenothing", "doifvaluenothingelse", "doifvaluesomething", "doifvariable", "doifvariableelse", "doindentation", "dollar", "doloop", "doloopoverlist", "donothing", "dontconvertfont", "dontleavehmode", "dontpermitspacesbetweengroups", "dopositionaction", "doprocesslocalsetups", "doquadrupleargument", "doquadrupleempty", "doquadruplegroupempty", "doquintupleargument", "doquintupleempty", "doquintuplegroupempty", "dorechecknextindentation", "dorecurse", "dorepeatwithcommand", "doreplacefeature", "doresetandafffeature", "doresetattribute", "dorotatebox", "dosetattribute", "dosetleftskipadaption", "dosetrightskipadaption", "dosetupcheckedinterlinespace", "doseventupleargument", "doseventupleempty", "dosingleargument", "dosingleempty", "dosinglegroupempty", "dosixtupleargument", "dosixtupleempty", "dostepwiserecurse", "dosubtractfeature", "dot", "doteq", "doteqdot", "dotfskip", "dotlessI", "dotlessJ", "dotlessi", "dotlessj", "dotlessjstroke", "dotminus", "dotoks", "dotplus", "dotripleargument", "dotripleargumentwithset", "dotripleempty", "dotripleemptywithset", "dotriplegroupempty", "dots", "dottedcircle", "dottedrightarrow", "doublebar", "doublebond", "doublebrace", "doublebracket", "doublecap", "doublecup", "doubleparent", "doubleprime", "doubleverticalbar", "dowith", "dowithnextbox", "dowithnextboxcontent", "dowithnextboxcontentcs", "dowithnextboxcs", "dowithpargument", "dowithrange", "dowithwargument", "downarrow", "downdasharrow", "downdownarrows", "downharpoonleft", "downharpoonright", "downuparrows", "downwhitearrow", "downzigzagarrow", "dpofstring", "dstroke", "dtail", "dummydigit", "dummyparameter", "dzcaronligature", "dzligature", "eTeX", "eacute", "ebreve", "ecaron", "ecedilla", "ecircumflex", "ecircumflexacute", "ecircumflexdotbelow", "ecircumflexgrave", "ecircumflexhook", "ecircumflextilde", "edefconvertedargument", "ediaeresis", "edotaccent", "edotbelow", "edoublegrave", "efcmaxheight", "efcmaxwidth", "efcminheight", "efcminwidth", "efcparameter", "effect", "egrave", "ehook", "einvertedbreve", "elapsedseconds", "elapsedtime", "eleftarrowfill", "eleftharpoondownfill", "eleftharpoonupfill", "eleftrightarrowfill", "ell", "em", "emacron", "emdash", "emphasisboldface", "emphasistypeface", "emptylines", "emptyset", "emquad", "emspace", "enabledirectives", "enableexperiments", "enablemode", "enableoutputstream", "enableparpositions", "enableregime", "enabletrackers", "endash", "endnote", "enquad", "enskip", "enspace", "env", "environment", "envvar", "eogonek", "eoverbarfill", "eoverbracefill", "eoverbracketfill", "eoverparentfill", "epos", "epsilon", "eq", "eqcirc", "eqeq", "eqeqeq", "eqgtr", "eqless", "eqsim", "eqslantgtr", "eqslantless", "equaldigits", "equalscolon", "equiv", "erightarrowfill", "erightharpoondownfill", "erightharpoonupfill", "eta", "eth", "ethiopic", "etilde", "etwoheadrightarrowfill", "eunderbarfill", "eunderbracefill", "eunderbracketfill", "eunderparentfill", "exclamdown", "executeifdefined", "exists", "exitloop", "exitloopnow", "expandcheckedcsname", "expanded", "expandeddoif", "expandeddoifelse", "expandeddoifnot", "expandfontsynonym", "expdoif", "expdoifcommonelse", "expdoifelse", "expdoifelsecommon", "expdoifelseinset", "expdoifinsetelse", "expdoifnot", "exponentiale", "externalfigure", "externalfigurecollectionmaxheight", "externalfigurecollectionmaxwidth", "externalfigurecollectionminheight", "externalfigurecollectionminwidth", "externalfigurecollectionparameter", "fakebox", "fallingdotseq", "fastdecrement", "fastincrement", "fastlocalframed", "fastloopfinal", "fastloopindex", "fastscale", "fastsetup", "fastsetupwithargument", "fastsetupwithargumentswapped", "fastswitchtobodyfont", "fastsxsy", "feature", "fence", "fenced", "fetchallmarkings", "fetchallmarks", "fetchmark", "fetchmarking", "fetchonemark", "fetchonemarking", "fetchruntinecommand", "fetchtwomarkings", "fetchtwomarks", "ffiligature", "ffligature", "fflligature", "fhook", "field", "fieldbody", "fieldstack", "fifthoffivearguments", "fifthofsixarguments", "figurefilename", "figurefilepath", "figurefiletype", "figurefullname", "figureheight", "figurenaturalheight", "figurenaturalwidth", "figurespace", "figuresymbol", "figurewidth", "filename", "filigature", "filledhboxb", "filledhboxc", "filledhboxg", "filledhboxk", "filledhboxm", "filledhboxr", "filledhboxy", "filler", "fillinline", "fillinrules", "fillintext", "fillupto", "filterfromnext", "filterfromvalue", "filterpages", "filterreference", "findtwopassdata", "finishregisterentry", "firstcharacter", "firstcounter", "firstcountervalue", "firstinlist", "firstoffivearguments", "firstoffourarguments", "firstofoneargument", "firstofoneunexpanded", "firstofsixarguments", "firstofthreearguments", "firstofthreeunexpanded", "firstoftwoarguments", "firstoftwounexpanded", "firstrealpage", "firstrealpagenumber", "firstsubcountervalue", "firstsubpage", "firstsubpagenumber", "firstuserpage", "firstuserpagenumber", "fitfield", "fitfieldframed", "fittopbaselinegrid", "fiveeighths", "fivesixths", "fixedspace", "fixedspaces", "flag", "flat", "flligature", "floatuserdataparameter", "flushbox", "flushboxregister", "flushcollector", "flushedrightlastline", "flushlayer", "flushlocalfloats", "flushnextbox", "flushnotes", "flushoutputstream", "flushshapebox", "flushtextflow", "flushtokens", "flushtoks", "fontalternative", "fontbody", "fontchar", "fontcharbyindex", "fontclass", "fontclassname", "fontface", "fontfeaturelist", "fontsize", "fontstyle", "footnote", "footnotetext", "forall", "forcecharacterstripping", "forcelocalfloats", "forgeteverypar", "forgetparameters", "forgetparskip", "forgetragged", "formula", "formulanumber", "foundbox", "fourfifths", "fourperemspace", "fourthoffivearguments", "fourthoffourarguments", "fourthofsixarguments", "frac", "framed", "frameddimension", "framedparameter", "framedtext", "freezedimenmacro", "freezemeasure", "frenchspacing", "from", "fromlinenote", "frown", "frozenhbox", "frule", "gacute", "gamma", "gbreve", "gcaron", "gcircumflex", "gcommaaccent", "gdefconvertedargument", "gdefconvertedcommand", "gdotaccent", "ge", "geq", "geqq", "geqslant", "getMPdrawing", "getMPlayer", "getboxfromcache", "getboxllx", "getboxlly", "getbuffer", "getbufferdata", "getcommacommandsize", "getcommalistsize", "getdayoftheweek", "getdayspermonth", "getdefinedbuffer", "getdocumentargument", "getdocumentargumentdefault", "getdocumentfilename", "getdummyparameters", "getemptyparameters", "geteparameters", "getexpandedparameters", "getfiguredimensions", "getfirstcharacter", "getfirsttwopassdata", "getfromcommacommand", "getfromcommalist", "getfromtwopassdata", "getglyphdirect", "getglyphstyled", "getgparameters", "getinlineuserdata", "getlasttwopassdata", "getlocalfloat", "getlocalfloats", "getmarking", "getmessage", "getnamedglyphdirect", "getnamedglyphstyled", "getnamedtwopassdatalist", "getnaturaldimensions", "getnoflines", "getobject", "getobjectdimensions", "getpaletsize", "getparameters", "getprivatechar", "getprivateslot", "getrandomcount", "getrandomdimen", "getrandomfloat", "getrandomnumber", "getrandomseed", "getraweparameters", "getrawgparameters", "getrawnoflines", "getrawparameters", "getrawxparameters", "getreference", "getreferenceentry", "getroundednoflines", "gets", "getsubstring", "gettokenlist", "gettwopassdata", "gettwopassdatalist", "getuserdata", "getuvalue", "getvalue", "getvariable", "getvariabledefault", "getxparameters", "gg", "ggg", "gggtr", "gimel", "globaldisablemode", "globalenablemode", "globalletempty", "globalpopbox", "globalpopmacro", "globalpreventmode", "globalprocesscommalist", "globalpushbox", "globalpushmacro", "globalswapcounts", "globalswapdimens", "globalswapmacros", "globalundefine", "glyphfontfile", "gnapprox", "gneqq", "gnsim", "gobbledoubleempty", "gobbleeightarguments", "gobblefivearguments", "gobblefiveoptionals", "gobblefourarguments", "gobblefouroptionals", "gobbleninearguments", "gobbleoneargument", "gobbleoneoptional", "gobblesevenarguments", "gobblesingleempty", "gobblesixarguments", "gobblespacetokens", "gobbletenarguments", "gobblethreearguments", "gobblethreeoptionals", "gobbletwoarguments", "gobbletwooptionals", "gobbleuntil", "gobbleuntilrelax", "godown", "goto", "gotobox", "gotopage", "grabbufferdata", "grabbufferdatadirect", "grabuntil", "grave", "graycolor", "grayvalue", "greedysplitstring", "greekAlpha", "greekAlphadasia", "greekAlphadasiaperispomeni", "greekAlphadasiatonos", "greekAlphadasiavaria", "greekAlphaiotasub", "greekAlphaiotasubdasia", "greekAlphaiotasubdasiaperispomeni", "greekAlphaiotasubdasiatonos", "greekAlphaiotasubdasiavaria", "greekAlphaiotasubpsili", "greekAlphaiotasubpsiliperispomeni", "greekAlphaiotasubpsilitonos", "greekAlphaiotasubpsilivaria", "greekAlphamacron", "greekAlphapsili", "greekAlphapsiliperispomeni", "greekAlphapsilitonos", "greekAlphapsilivaria", "greekAlphatonos", "greekAlphavaria", "greekAlphavrachy", "greekBeta", "greekChi", "greekCoronis", "greekDelta", "greekEpsilon", "greekEpsilondasia", "greekEpsilondasiatonos", "greekEpsilondasiavaria", "greekEpsilonpsili", "greekEpsilonpsilitonos", "greekEpsilonpsilivaria", "greekEpsilontonos", "greekEpsilonvaria", "greekEta", "greekEtadasia", "greekEtadasiaperispomeni", "greekEtadasiatonos", "greekEtadasiavaria", "greekEtaiotasub", "greekEtaiotasubdasia", "greekEtaiotasubdasiaperispomeni", "greekEtaiotasubdasiatonos", "greekEtaiotasubdasiavaria", "greekEtaiotasubpsili", "greekEtaiotasubpsiliperispomeni", "greekEtaiotasubpsilitonos", "greekEtaiotasubpsilivaria", "greekEtapsili", "greekEtapsiliperispomeni", "greekEtapsilitonos", "greekEtapsilivaria", "greekEtatonos", "greekEtavaria", "greekGamma", "greekIota", "greekIotadasia", "greekIotadasiaperispomeni", "greekIotadasiatonos", "greekIotadasiavaria", "greekIotadialytika", "greekIotamacron", "greekIotapsili", "greekIotapsiliperispomeni", "greekIotapsilitonos", "greekIotapsilivaria", "greekIotatonos", "greekIotavaria", "greekIotavrachy", "greekKappa", "greekLambda", "greekMu", "greekNu", "greekOmega", "greekOmegadasia", "greekOmegadasiaperispomeni", "greekOmegadasiatonos", "greekOmegadasiavaria", "greekOmegaiotasub", "greekOmegaiotasubdasia", "greekOmegaiotasubdasiaperispomeni", "greekOmegaiotasubdasiatonos", "greekOmegaiotasubdasiavaria", "greekOmegaiotasubpsili", "greekOmegaiotasubpsiliperispomeni", "greekOmegaiotasubpsilitonos", "greekOmegaiotasubpsilivaria", "greekOmegapsili", "greekOmegapsiliperispomeni", "greekOmegapsilitonos", "greekOmegapsilivaria", "greekOmegatonos", "greekOmegavaria", "greekOmicron", "greekOmicrondasia", "greekOmicrondasiatonos", "greekOmicrondasiavaria", "greekOmicronpsili", "greekOmicronpsilitonos", "greekOmicronpsilivaria", "greekOmicrontonos", "greekOmicronvaria", "greekPhi", "greekPi", "greekPsi", "greekRho", "greekRhodasia", "greekSigma", "greekSigmalunate", "greekTau", "greekTheta", "greekUpsilon", "greekUpsilondasia", "greekUpsilondasiaperispomeni", "greekUpsilondasiatonos", "greekUpsilondasiavaria", "greekUpsilondialytika", "greekUpsilonmacron", "greekUpsilontonos", "greekUpsilonvaria", "greekUpsilonvrachy", "greekXi", "greekZeta", "greekalpha", "greekalphadasia", "greekalphadasiaperispomeni", "greekalphadasiatonos", "greekalphadasiavaria", "greekalphaiotasub", "greekalphaiotasubdasia", "greekalphaiotasubdasiaperispomeni", "greekalphaiotasubdasiatonos", "greekalphaiotasubdasiavaria", "greekalphaiotasubperispomeni", "greekalphaiotasubpsili", "greekalphaiotasubpsiliperispomeni", "greekalphaiotasubpsilitonos", "greekalphaiotasubpsilivaria", "greekalphaiotasubtonos", "greekalphaiotasubvaria", "greekalphamacron", "greekalphaoxia", "greekalphaperispomeni", "greekalphapsili", "greekalphapsiliperispomeni", "greekalphapsilitonos", "greekalphapsilivaria", "greekalphatonos", "greekalphavaria", "greekalphavrachy", "greekbeta", "greekbetaalt", "greekchi", "greekdasia", "greekdasiaperispomeni", "greekdasiatonos", "greekdasiavaria", "greekdelta", "greekdialytikaperispomeni", "greekdialytikatonos", "greekdialytikavaria", "greekdigamma", "greekepsilon", "greekepsilonalt", "greekepsilondasia", "greekepsilondasiatonos", "greekepsilondasiavaria", "greekepsilonoxia", "greekepsilonpsili", "greekepsilonpsilitonos", "greekepsilonpsilivaria", "greekepsilontonos", "greekepsilonvaria", "greeketa", "greeketadasia", "greeketadasiaperispomeni", "greeketadasiatonos", "greeketadasiavaria", "greeketaiotasub", "greeketaiotasubdasia", "greeketaiotasubdasiaperispomeni", "greeketaiotasubdasiatonos", "greeketaiotasubdasiavaria", "greeketaiotasubperispomeni", "greeketaiotasubpsili", "greeketaiotasubpsiliperispomeni", "greeketaiotasubpsilitonos", "greeketaiotasubpsilivaria", "greeketaiotasubtonos", "greeketaiotasubvaria", "greeketaoxia", "greeketaperispomeni", "greeketapsili", "greeketapsiliperispomeni", "greeketapsilitonos", "greeketapsilivaria", "greeketatonos", "greeketavaria", "greekfinalsigma", "greekgamma", "greekiota", "greekiotadasia", "greekiotadasiaperispomeni", "greekiotadasiatonos", "greekiotadasiavaria", "greekiotadialytika", "greekiotadialytikaperispomeni", "greekiotadialytikatonos", "greekiotadialytikavaria", "greekiotamacron", "greekiotaoxia", "greekiotaperispomeni", "greekiotapsili", "greekiotapsiliperispomeni", "greekiotapsilitonos", "greekiotapsilivaria", "greekiotatonos", "greekiotavaria", "greekiotavrachy", "greekkappa", "greekkoppa", "greeklambda", "greekmu", "greeknu", "greeknumerals", "greeknumkoppa", "greekomega", "greekomegadasia", "greekomegadasiaperispomeni", "greekomegadasiatonos", "greekomegadasiavaria", "greekomegaiotasub", "greekomegaiotasubdasia", "greekomegaiotasubdasiaperispomeni", "greekomegaiotasubdasiatonos", "greekomegaiotasubdasiavaria", "greekomegaiotasubperispomeni", "greekomegaiotasubpsili", "greekomegaiotasubpsiliperispomeni", "greekomegaiotasubpsilitonos", "greekomegaiotasubpsilivaria", "greekomegaiotasubtonos", "greekomegaiotasubvaria", "greekomegaoxia", "greekomegaperispomeni", "greekomegapsili", "greekomegapsiliperispomeni", "greekomegapsilitonos", "greekomegapsilivaria", "greekomegatonos", "greekomegavaria", "greekomicron", "greekomicrondasia", "greekomicrondasiatonos", "greekomicrondasiavaria", "greekomicronoxia", "greekomicronpsili", "greekomicronpsilitonos", "greekomicronpsilivaria", "greekomicrontonos", "greekomicronvaria", "greekoxia", "greekperispomeni", "greekphi", "greekphialt", "greekpi", "greekpialt", "greekprosgegrammeni", "greekpsi", "greekpsili", "greekpsiliperispomeni", "greekpsilitonos", "greekpsilivaria", "greekrho", "greekrhoalt", "greekrhodasia", "greekrhopsili", "greeksampi", "greeksigma", "greeksigmalunate", "greekstigma", "greektau", "greektheta", "greekthetaalt", "greektonos", "greekupsilon", "greekupsilondasia", "greekupsilondasiaperispomeni", "greekupsilondasiatonos", "greekupsilondasiavaria", "greekupsilondiaeresis", "greekupsilondialytikaperispomeni", "greekupsilondialytikatonos", "greekupsilondialytikavaria", "greekupsilonmacron", "greekupsilonoxia", "greekupsilonperispomeni", "greekupsilonpsili", "greekupsilonpsiliperispomeni", "greekupsilonpsilitonos", "greekupsilonpsilivaria", "greekupsilontonos", "greekupsilonvaria", "greekupsilonvrachy", "greekvaria", "greekxi", "greekzeta", "grid", "groupedcommand", "gsetboxllx", "gsetboxlly", "gstroke", "gt", "gtrapprox", "gtrdot", "gtreqless", "gtreqqless", "gtrless", "gtrsim", "guilsingleleft", "guilsingleright", "gujaratinumerals", "gurmurkhinumerals", "hairline", "hairspace", "halflinestrut", "halfstrut", "halfwaybox", "handletokens", "handwritten", "hangul", "hanzi", "hash", "hat", "hbar", "hboxofvbox", "hboxreference", "hcaron", "hcircumflex", "hdofstring", "headhbox", "headlanguage", "headnumber", "headnumbercontent", "headnumberdistance", "headnumberwidth", "headreferenceattributes", "headsetupspacing", "headtext", "headtextcontent", "headtextdistance", "headtexts", "headtextwidth", "headvbox", "headwidth", "heartsuit", "hebrewAlef", "hebrewAyin", "hebrewBet", "hebrewDalet", "hebrewGimel", "hebrewHe", "hebrewHet", "hebrewKaf", "hebrewKaffinal", "hebrewLamed", "hebrewMem", "hebrewMemfinal", "hebrewNun", "hebrewNunfinal", "hebrewPe", "hebrewPefinal", "hebrewQof", "hebrewResh", "hebrewSamekh", "hebrewShin", "hebrewTav", "hebrewTet", "hebrewTsadi", "hebrewTsadifinal", "hebrewVav", "hebrewYod", "hebrewZayin", "heightanddepthofstring", "heightofstring", "heightspanningtext", "helptext", "hglue", "hiddenbar", "hiddencitation", "hiddencite", "hideblocks", "high", "highlight", "highordinalstr", "hilo", "himilo", "hl", "hookleftarrow", "hookrightarrow", "horizontalgrowingbar", "horizontalpositionbar", "hphantom", "hpos", "hsizefraction", "hslash", "hsmash", "hsmashbox", "hsmashed", "hspace", "hstroke", "htdpofstring", "htofstring", "hyphen", "hyphenatedcoloredword", "hyphenatedfile", "hyphenatedfilename", "hyphenatedhbox", "hyphenatedpar", "hyphenatedurl", "hyphenatedword", "iacute", "ibox", "ibreve", "icaron", "icircumflex", "ideographichalffillspace", "ideographicspace", "idiaeresis", "idotaccent", "idotbelow", "idoublegrave", "ifassignment", "iff", "ifinobject", "ifinoutputstream", "ifparameters", "iftrialtypesetting", "ignoreimplicitspaces", "ignoretagsinexport", "ignorevalue", "igrave", "ihook", "iiiint", "iiiintop", "iiint", "iiintop", "iint", "iintop", "iinvertedbreve", "ijligature", "imacron", "imaginaryi", "imaginaryj", "imath", "immediatesavetwopassdata", "impliedby", "implies", "imply", "in", "includemenu", "includeversioninfo", "increment", "incrementcounter", "incrementedcounter", "incrementpagenumber", "incrementsubpagenumber", "incrementvalue", "indentation", "index", "infofont", "infofontbold", "inframed", "infty", "infull", "inheritparameter", "inhibitblank", "ininner", "ininneredge", "ininnermargin", "initializeboxstack", "inleft", "inleftedge", "inleftmargin", "inline", "inlinebuffer", "inlinedbox", "inlinemath", "inlinemathematics", "inlinemessage", "inlineordisplaymath", "inlineprettyprintbuffer", "inlinerange", "inmargin", "inmframed", "innerflushshapebox", "inother", "inouter", "inouteredge", "inoutermargin", "input", "inputfilebarename", "inputfilename", "inputfilerealsuffix", "inputfilesuffix", "inputgivenfile", "inright", "inrightedge", "inrightmargin", "insertpages", "installactionhandler", "installactivecharacter", "installanddefineactivecharacter", "installattributestack", "installautocommandhandler", "installautosetuphandler", "installbasicautosetuphandler", "installbasicparameterhandler", "installbottomframerenderer", "installcommandhandler", "installcorenamespace", "installdefinehandler", "installdefinitionset", "installdefinitionsetmember", "installdirectcommandhandler", "installdirectparameterhandler", "installdirectparametersethandler", "installdirectsetuphandler", "installdirectstyleandcolorhandler", "installframedautocommandhandler", "installframedcommandhandler", "installglobalmacrostack", "installlanguage", "installleftframerenderer", "installmacrostack", "installnamespace", "installoutputroutine", "installpagearrangement", "installparameterhandler", "installparameterhashhandler", "installparametersethandler", "installparentinjector", "installrightframerenderer", "installrootparameterhandler", "installsetuphandler", "installsetuponlycommandhandler", "installshipoutmethod", "installsimplecommandhandler", "installsimpleframedcommandhandler", "installstyleandcolorhandler", "installswitchcommandhandler", "installswitchsetuphandler", "installtexdirective", "installtextracker", "installtopframerenderer", "installunitsseparator", "installunitsspace", "installversioninfo", "int", "intclockwise", "integerrounding", "integers", "interactionbar", "interactionbuttons", "interactionmenu", "intercal", "intertext", "intop", "invisibletimes", "invokepageheandler", "iogonek", "iota", "istltdir", "istrtdir", "italic", "italicbold", "italiccorrection", "italicface", "item", "items", "itemtag", "itilde", "jcaron", "jcircumflex", "jmath", "jobfilename", "jobfilesuffix", "kap", "kappa", "kcaron", "kcommaaccent", "keepblocks", "keeplinestogether", "keepunwantedspaces", "kerncharacters", "khook", "kkra", "koreancirclenumerals", "koreannumerals", "koreannumeralsc", "koreannumeralsp", "koreanparentnumerals", "lVert", "labellanguage", "labeltext", "labeltexts", "lacute", "lambda", "lambdabar", "land", "langle", "language", "languageCharacters", "languagecharacters", "languagecharwidth", "lastcounter", "lastcountervalue", "lastdigit", "lastlinewidth", "lastnaturalboxdp", "lastnaturalboxht", "lastnaturalboxwd", "lastpredefinedsymbol", "lastrealpage", "lastrealpagenumber", "lastsubcountervalue", "lastsubpage", "lastsubpagenumber", "lasttwodigits", "lastuserpage", "lastuserpagenumber", "lateluacode", "latin", "layeredtext", "layerheight", "layerwidth", "lazysavetaggedtwopassdata", "lazysavetwopassdata", "lbar", "lbox", "lbrace", "lbracket", "lcaron", "lceil", "lcommaaccent", "lcurl", "ldotmiddle", "ldotp", "ldots", "le", "leadsto", "left", "leftaligned", "leftarrow", "leftarrowtail", "leftarrowtriangle", "leftbottombox", "leftbox", "leftdasharrow", "leftguillemot", "leftharpoondown", "leftharpoonup", "lefthbox", "leftheadtext", "leftlabeltext", "leftleftarrows", "leftline", "leftmathlabeltext", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "leftrightarrow", "leftrightarrows", "leftrightarrowtriangle", "leftrightharpoons", "leftrightsquigarrow", "leftskipadaption", "leftsquigarrow", "leftsubguillemot", "leftthreetimes", "lefttopbox", "lefttoright", "lefttorighthbox", "lefttorightvbox", "lefttorightvtop", "leftwavearrow", "leftwhitearrow", "leq", "leqq", "leqslant", "lessapprox", "lessdot", "lesseqgtr", "lesseqqgtr", "lessgtr", "lesssim", "letbeundefined", "letcatcodecommand", "letcscsname", "letcsnamecs", "letcsnamecsname", "letdummyparameter", "letempty", "letgvalue", "letgvalueempty", "letgvalurelax", "letterampersand", "letterat", "letterbackslash", "letterbar", "letterbgroup", "letterclosebrace", "lettercolon", "letterdollar", "letterdoublequote", "letteregroup", "letterescape", "letterexclamationmark", "letterhash", "letterhat", "letterleftbrace", "letterleftbracket", "letterleftparenthesis", "letterless", "lettermore", "letteropenbrace", "letterpercent", "letterquestionmark", "letterrightbrace", "letterrightbracket", "letterrightparenthesis", "lettersinglequote", "letterslash", "letterspacing", "lettertilde", "letterunderscore", "letvalue", "letvalueempty", "letvaluerelax", "lfence", "lfloor", "lgroup", "lhbox", "lhooknwarrow", "lhooksearrow", "limitatefirstline", "limitatelines", "limitatetext", "line", "linebox", "linefeed", "linenote", "linespanningtext", "linethickness", "linterval", "listcitation", "listcite", "listlength", "listnamespaces", "ljligature", "ll", "llangle", "llap", "llbracket", "llcorner", "lll", "llless", "lmoustache", "lnapprox", "lneq", "lneqq", "lnot", "lnsim", "loadanyfile", "loadanyfileonce", "loadbtxdefinitionfile", "loadbtxreplacementfile", "loadcldfile", "loadcldfileonce", "loadfontgoodies", "loadluafile", "loadluafileonce", "loadspellchecklist", "loadtexfile", "loadtexfileonce", "loadtypescriptfile", "localframed", "localframedwithsettings", "localhsize", "localpopbox", "localpopmacro", "localpushbox", "localpushmacro", "localundefine", "locatedfilepath", "locatefilepath", "locfilename", "logo", "lohi", "lointerval", "lomihi", "longleftarrow", "longleftrightarrow", "longmapsfrom", "longmapsto", "longrightarrow", "longrightsquigarrow", "looparrowleft", "looparrowright", "lor", "low", "lowerbox", "lowercased", "lowercasestring", "lowerleftdoubleninequote", "lowerleftsingleninequote", "lowerrightdoubleninequote", "lowerrightsingleninequote", "lozenge", "lparent", "lrcorner", "lrointerval", "lrtbbox", "lstroke", "lt", "ltimes", "ltop", "luaTeX", "luacode", "luaconditional", "luaenvironment", "luaexpanded", "luaexpr", "luafunction", "luajitTeX", "luamajorversion", "luaminorversion", "luaparameterset", "luasetup", "luaversion", "lvert", "m", "mLeftarrow", "mLeftrightarrow", "mRightarrow", "mainlanguage", "makecharacteractive", "makerawcommalist", "makestrutofbox", "maltese", "mapfontsize", "mapsdown", "mapsfrom", "mapsto", "mapsup", "margindata", "margintext", "markcontent", "markedpages", "marking", "markinjector", "markpage", "mat", "math", "mathampersand", "mathbf", "mathbi", "mathblackboard", "mathbs", "mathdefault", "mathdollar", "mathdouble", "mathematics", "mathfraktur", "mathfunction", "mathhash", "mathhyphen", "mathit", "mathitalic", "mathlabellanguage", "mathlabeltext", "mathlabeltexts", "mathop", "mathover", "mathpercent", "mathrm", "mathscript", "mathsl", "mathss", "mathtext", "mathtextbf", "mathtextbi", "mathtextbs", "mathtextit", "mathtextsl", "mathtexttf", "mathtf", "mathtriplet", "mathtt", "mathunder", "mathupright", "mathword", "mathwordbf", "mathwordbi", "mathwordbs", "mathwordit", "mathwordsl", "mathwordtf", "maxaligned", "mbox", "mcframed", "measure", "measured", "measuredangle", "measuredeq", "medskip", "medspace", "menubutton", "mequal", "message", "metaTeX", "mfence", "mframed", "mfunction", "mfunctionlabeltext", "mhbox", "mho", "mhookleftarrow", "mhookrightarrow", "mid", "midaligned", "middle", "middlealigned", "middlebox", "midhbox", "midsubsentence", "minimalhbox", "minus", "minuscolon", "mirror", "mixedcaps", "mkvibuffer", "mleftarrow", "mleftharpoondown", "mleftharpoonup", "mleftrightarrow", "mleftrightharpoons", "mmapsto", "models", "moduleparameter", "molecule", "mono", "monobold", "mononormal", "month", "monthlong", "monthshort", "mp", "mprandomnumber", "mrel", "mrightarrow", "mrightharpoondown", "mrightharpoonup", "mrightleftharpoons", "mrightoverleftarrow", "mtext", "mtriplerel", "mtwoheadleftarrow", "mtwoheadrightarrow", "mu", "multimap", "nHdownarrow", "nHuparrow", "nLeftarrow", "nLeftrightarrow", "nRightarrow", "nVDash", "nVdash", "nVleftarrow", "nVleftrightarrow", "nVrightarrow", "nabla", "nacute", "namedheadnumber", "namedstructureheadlocation", "namedstructureuservariable", "namedstructurevariable", "namedtaggedlabeltexts", "napostrophe", "napprox", "napproxEq", "narrownobreakspace", "nasymp", "natural", "naturalhbox", "naturalhpack", "naturalnumbers", "naturalvbox", "naturalvcenter", "naturalvpack", "naturalvtop", "naturalwd", "ncaron", "ncommaaccent", "ncong", "ncurl", "ndivides", "ne", "nearrow", "neg", "negatecolorbox", "negated", "negativesign", "negemspace", "negenspace", "negthinspace", "neng", "neq", "nequiv", "neswarrow", "newattribute", "newcatcodetable", "newcounter", "newevery", "newfrenchspacing", "newmode", "newsignal", "newsystemmode", "nexists", "nextbox", "nextboxdp", "nextboxht", "nextboxhtdp", "nextboxwd", "nextcounter", "nextcountervalue", "nextdepth", "nextparagraphs", "nextrealpage", "nextrealpagenumber", "nextsubcountervalue", "nextsubpage", "nextsubpagenumber", "nextuserpage", "nextuserpagenumber", "ngeq", "ngrave", "ngtr", "ngtrless", "ngtrsim", "ni", "nihongo", "nin", "njligature", "nleftarrow", "nleftrightarrow", "nleq", "nless", "nlessgtr", "nlesssim", "nmid", "nni", "nobar", "nobreakspace", "nocap", "nocharacteralign", "nocitation", "nocite", "nodetostring", "noffigurepages", "noflines", "noflocalfloats", "noheaderandfooterlines", "noheightstrut", "noindentation", "noitem", "nonfrenchspacing", "nonmathematics", "normal", "normalboldface", "normalframedwithsettings", "normalitalicface", "normalizebodyfontsize", "normalizedfontsize", "normalizefontdepth", "normalizefontheight", "normalizefontline", "normalizefontwidth", "normalizetextdepth", "normalizetextheight", "normalizetextline", "normalizetextwidth", "normalslantedface", "normaltypeface", "nospace", "not", "note", "notesymbol", "notin", "notopandbottomlines", "notragged", "nowns", "nparallel", "nprec", "npreccurlyeq", "nrightarrow", "nsim", "nsimeq", "nsqsubseteq", "nsqsupseteq", "nsubset", "nsubseteq", "nsucc", "nsucccurlyeq", "nsupset", "nsupseteq", "ntilde", "ntimes", "ntriangleleft", "ntrianglelefteq", "ntriangleright", "ntrianglerighteq", "nu", "numberofpoints", "numbers", "nvDash", "nvdash", "nvleftarrow", "nvleftrightarrow", "nvrightarrow", "nwarrow", "nwsearrow", "oacute", "obeydepth", "objectdepth", "objectheight", "objectmargin", "objectwidth", "obox", "obreve", "ocaron", "ocircumflex", "ocircumflexacute", "ocircumflexdotbelow", "ocircumflexgrave", "ocircumflexhook", "ocircumflextilde", "odiaeresis", "odiaeresismacron", "odot", "odotaccent", "odotaccentmacron", "odotbelow", "odoublegrave", "oeligature", "offset", "offsetbox", "ograve", "ohm", "ohook", "ohorn", "ohornacute", "ohorndotbelow", "ohorngrave", "ohornhook", "ohorntilde", "ohungarumlaut", "oiiint", "oiint", "oint", "ointclockwise", "ointctrclockwise", "oinvertedbreve", "omacron", "omega", "omicron", "ominus", "onedigitrounding", "oneeighth", "onefifth", "onehalf", "onequarter", "onesixth", "onesuperior", "onethird", "oogonek", "oogonekmacron", "operatorlanguage", "operatortext", "oplus", "ordfeminine", "ordinaldaynumber", "ordinalstr", "ordmasculine", "ornamenttext", "oslash", "ostroke", "ostrokeacute", "otilde", "otildemacron", "otimes", "outputfilename", "outputstreambox", "outputstreamcopy", "outputstreamunvbox", "outputstreamunvcopy", "over", "overbar", "overbars", "overbarunderbar", "overbrace", "overbraceunderbrace", "overbracket", "overbracketunderbracket", "overlaybutton", "overlaycolor", "overlaydepth", "overlayfigure", "overlayheight", "overlayimage", "overlaylinecolor", "overlaylinewidth", "overlayoffset", "overlayrollbutton", "overlaywidth", "overleftarrow", "overloaderror", "overparent", "overparentunderparent", "overrightarrow", "overset", "overstrike", "overstrikes", "owns", "page", "pagearea", "pagebreak", "pagefigure", "pageinjection", "pagenumber", "pagereference", "pagestaterealpage", "pagestaterealpageorder", "paletsize", "paragraphmark", "parallel", "part", "partial", "pdfTeX", "pdfactualtext", "pdfbackendactualtext", "pdfbackendcurrentresources", "pdfbackendsetcatalog", "pdfbackendsetcolorspace", "pdfbackendsetextgstate", "pdfbackendsetinfo", "pdfbackendsetname", "pdfbackendsetpageattribute", "pdfbackendsetpageresource", "pdfbackendsetpagesattribute", "pdfbackendsetpattern", "pdfbackendsetshade", "pdfcolor", "pdfeTeX", "percent", "percentdimen", "periodcentered", "periods", "permitcaretescape", "permitcircumflexescape", "permitspacesbetweengroups", "perp", "persiandecimals", "persiandecimalseparator", "persiannumerals", "persianthousandsseparator", "perthousand", "phantom", "phantombox", "phi", "phook", "pi", "pickupgroupedcommand", "pitchfork", "placeattachments", "placebookmarks", "placebtxrendering", "placechemical", "placecitation", "placecombinedlist", "placecomments", "placecontent", "placecurrentformulanumber", "placedbox", "placefigure", "placefloat", "placefloatwithsetups", "placefootnotes", "placeformula", "placeframed", "placegraphic", "placeheadnumber", "placeheadtext", "placehelp", "placeindex", "placeinitial", "placeintermezzo", "placelayer", "placelayeredtext", "placelegend", "placelist", "placelistofabbreviations", "placelistofchemicals", "placelistoffigures", "placelistofgraphics", "placelistofintermezzi", "placelistoflogos", "placelistofpublications", "placelistofsorts", "placelistofsynonyms", "placelistoftables", "placelocalfootnotes", "placelocalnotes", "placement", "placenamedfloat", "placenamedformula", "placenotes", "placeongrid", "placeontopofeachother", "placepagenumber", "placepairedbox", "placeparallel", "placerawlist", "placeregister", "placerenderingwindow", "placesidebyside", "placesubformula", "placetable", "pm", "popattribute", "popmacro", "popmode", "popsystemmode", "position", "positionoverlay", "positionregionoverlay", "positivesign", "postponenotes", "prec", "precapprox", "preccurlyeq", "preceq", "preceqq", "precnapprox", "precneq", "precneqq", "precnsim", "precsim", "predefinedfont", "predefinefont", "predefinesymbol", "prefixedpagenumber", "prefixlanguage", "prefixtext", "prependetoks", "prependgvalue", "prependtocommalist", "prependtoks", "prependtoksonce", "prependvalue", "prerollblank", "presetbtxlabeltext", "presetdocument", "presetfieldsymbols", "presetheadtext", "presetlabeltext", "presetmathlabeltext", "presetoperatortext", "presetprefixtext", "presetsuffixtext", "presettaglabeltext", "presetunittext", "pretocommalist", "prettyprintbuffer", "prevcounter", "prevcountervalue", "preventmode", "prevrealpage", "prevrealpagenumber", "prevsubcountervalue", "prevsubpage", "prevsubpagenumber", "prevuserpage", "prevuserpagenumber", "prime", "primes", "procent", "processMPbuffer", "processMPfigurefile", "processaction", "processallactionsinset", "processassignlist", "processassignmentcommand", "processassignmentlist", "processbetween", "processblocks", "processbodyfontenvironmentlist", "processcolorcomponents", "processcommacommand", "processcommalist", "processcommalistwithparameters", "processcontent", "processfile", "processfilemany", "processfilenone", "processfileonce", "processfirstactioninset", "processisolatedchars", "processisolatedwords", "processlinetablebuffer", "processlinetablefile", "processlist", "processmonth", "processranges", "processseparatedlist", "processtexbuffer", "processtokens", "processuntil", "processxtablebuffer", "processyear", "prod", "product", "profiledbox", "profilegivenbox", "program", "project", "propto", "pseudoMixedCapped", "pseudoSmallCapped", "pseudoSmallcapped", "pseudosmallcapped", "psi", "punctuationspace", "purenumber", "pushattribute", "pushbutton", "pushmacro", "pushmode", "pushoutputstream", "pushsystemmode", "putboxincache", "putnextboxincache", "qquad", "quad", "quadrupleprime", "quads", "quarterstrut", "questiondown", "questionedeq", "quitcommalist", "quitprevcommalist", "quittypescriptscanning", "quotation", "quote", "quotedbl", "quotedblbase", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "quotesingle", "quotesinglebase", "rVert", "racute", "raggedbottom", "raggedcenter", "raggedleft", "raggedright", "raggedwidecenter", "raisebox", "randomizetext", "randomnumber", "rangle", "rationals", "rawcounter", "rawcountervalue", "rawdate", "rawdoifelseinset", "rawdoifinset", "rawdoifinsetelse", "rawgetparameters", "rawprocessaction", "rawprocesscommacommand", "rawprocesscommalist", "rawstructurelistuservariable", "rawsubcountervalue", "rbox", "rbrace", "rbracket", "rcaron", "rceil", "rcommaaccent", "rdoublegrave", "readfile", "readfixfile", "readjobfile", "readlocfile", "readsetfile", "readsysfile", "readtexfile", "readxmlfile", "realSmallCapped", "realSmallcapped", "realpagenumber", "reals", "realsmallcapped", "recursedepth", "recurselevel", "recursestring", "redoconvertfont", "ref", "reference", "referenceprefix", "referring", "registerattachment", "registerctxluafile", "registered", "registerexternalfigure", "registerfontclass", "registerhyphenationexception", "registerhyphenationpattern", "registermenubuttons", "registersort", "registersynonym", "registerunit", "regular", "relatemarking", "relateparameterhandlers", "relaxvalueifundefined", "relbar", "remainingcharacters", "remark", "removebottomthings", "removedepth", "removefromcommalist", "removelastskip", "removelastspace", "removemarkedcontent", "removepunctuation", "removesubstring", "removetoks", "removeunwantedspaces", "replacefeature", "replaceincommalist", "replaceword", "rescan", "rescanwithsetup", "resetMPdrawing", "resetMPenvironment", "resetMPinstance", "resetallattributes", "resetandaddfeature", "resetbar", "resetboxesincache", "resetbreakpoints", "resetbuffer", "resetcharacteralign", "resetcharacterkerning", "resetcharacterspacing", "resetcharacterstripping", "resetcollector", "resetcounter", "resetdigitsmanipulation", "resetdirection", "resetfeature", "resetflag", "resetfontcolorsheme", "resetfontfallback", "resetfontsolution", "resethyphenationfeatures", "resetinjector", "resetinteractionmenu", "resetitaliccorrection", "resetlayer", "resetlocalfloats", "resetmarker", "resetmarking", "resetmode", "resetpagenumber", "resetparallel", "resetpath", "resetpenalties", "resetperiodkerning", "resetprofile", "resetrecurselevel", "resetreference", "resetreplacement", "resetscript", "resetsetups", "resetshownsynonyms", "resetsubpagenumber", "resetsymbolset", "resetsystemmode", "resettimer", "resettokenlist", "resettrackers", "resettrialtypesetting", "resetusedsortings", "resetusedsynonyms", "resetuserpagenumber", "resetvalue", "resetvisualizers", "reshapebox", "resolvedglyphdirect", "resolvedglyphstyled", "restartcounter", "restorebox", "restorecatcodes", "restorecounter", "restorecurrentattributes", "restoreendofline", "restoreglobalbodyfont", "restriction", "reusableMPgraphic", "reuseMPgraphic", "reuserandomseed", "reverseddoubleprime", "reversedprime", "reversedtripleprime", "revivefeature", "rfence", "rfloor", "rgroup", "rhbox", "rho", "rhooknearrow", "rhookswarrow", "right", "rightaligned", "rightangle", "rightarrow", "rightarrowbar", "rightarrowtail", "rightarrowtriangle", "rightbottombox", "rightbox", "rightdasharrow", "rightguillemot", "rightharpoondown", "rightharpoonup", "righthbox", "rightheadtext", "rightlabeltext", "rightleftarrows", "rightleftharpoons", "rightline", "rightmathlabeltext", "rightorleftpageaction", "rightpageorder", "rightrightarrows", "rightskipadaption", "rightsquigarrow", "rightsubguillemot", "rightthreearrows", "rightthreetimes", "righttoleft", "righttolefthbox", "righttoleftvbox", "righttoleftvtop", "righttopbox", "rightwavearrow", "rightwhitearrow", "ring", "rinterval", "rinvertedbreve", "risingdotseq", "rlap", "rlointerval", "rmoustache", "rneq", "robustaddtocommalist", "robustdoifelseinset", "robustdoifinsetelse", "robustpretocommalist", "rointerval", "rollbutton", "roman", "romanC", "romanD", "romanI", "romanII", "romanIII", "romanIV", "romanIX", "romanL", "romanM", "romanV", "romanVI", "romanVII", "romanVIII", "romanX", "romanXI", "romanXII", "romanc", "romand", "romani", "romanii", "romaniii", "romaniv", "romanix", "romanl", "romanm", "romannumerals", "romanv", "romanvi", "romanvii", "romanviii", "romanx", "romanxi", "romanxii", "rootradical", "rotate", "rparent", "rrangle", "rrbracket", "rrointerval", "rtimes", "rtop", "ruby", "ruledhbox", "ruledhpack", "ruledmbox", "ruledtopv", "ruledtpack", "ruledvbox", "ruledvpack", "ruledvtop", "runMPbuffer", "runninghbox", "rvert", "sacute", "safechar", "samplefile", "sans", "sansbold", "sansnormal", "sansserif", "savebox", "savebtxdataset", "savebuffer", "savecounter", "savecurrentattributes", "savenormalmeaning", "savetaggedtwopassdata", "savetwopassdata", "sbox", "scale", "scaron", "scedilla", "schwa", "schwahook", "scircumflex", "scommaaccent", "screen", "searrow", "secondoffivearguments", "secondoffourarguments", "secondofsixarguments", "secondofthreearguments", "secondofthreeunexpanded", "secondoftwoarguments", "secondoftwounexpanded", "section", "sectionmark", "seeindex", "select", "selectblocks", "serializecommalist", "serializedcommalist", "serif", "serifbold", "serifnormal", "setJSpreamble", "setMPlayer", "setMPpositiongraphic", "setMPpositiongraphicrange", "setMPtext", "setMPvariable", "setMPvariables", "setautopagestaterealpageno", "setbar", "setbigbodyfont", "setboxllx", "setboxlly", "setbreakpoints", "setcapstrut", "setcatcodetable", "setcharacteralign", "setcharacteraligndetail", "setcharactercasing", "setcharactercleaning", "setcharacterkerning", "setcharacterspacing", "setcharacterstripping", "setcharstrut", "setcollector", "setcolormodell", "setcounter", "setcounterown", "setcurrentfontclass", "setdataset", "setdefaultpenalties", "setdigitsmanipulation", "setdirection", "setdocumentargument", "setdocumentargumentdefault", "setdocumentfilename", "setdummyparameter", "setelementexporttag", "setemeasure", "setevalue", "setevariable", "setevariables", "setfirstline", "setfirstpasscharacteralign", "setflag", "setfont", "setfontcolorsheme", "setfontfeature", "setfontsolution", "setfontstrut", "setglobalscript", "setgmeasure", "setgvalue", "setgvariable", "setgvariables", "sethboxregister", "sethyphenatedurlafter", "sethyphenatedurlbefore", "sethyphenatedurlnormal", "sethyphenationfeatures", "setinitial", "setinjector", "setinteraction", "setinterfacecommand", "setinterfaceconstant", "setinterfaceelement", "setinterfacemessage", "setinterfacevariable", "setinternalrendering", "setitaliccorrection", "setlayer", "setlayerframed", "setlayertext", "setlinefiller", "setlocalhsize", "setlocalscript", "setmainbodyfont", "setmainparbuilder", "setmarker", "setmarking", "setmathstyle", "setmeasure", "setmessagetext", "setminus", "setmode", "setnostrut", "setnote", "setnotetext", "setobject", "setoldstyle", "setpagereference", "setpagestate", "setpagestaterealpageno", "setpenalties", "setpercentdimen", "setperiodkerning", "setposition", "setpositionbox", "setpositiondata", "setpositiondataplus", "setpositiononly", "setpositionplus", "setpositionstrut", "setprofile", "setrandomseed", "setreference", "setreferencedobject", "setregisterentry", "setreplacement", "setrigidcolumnbalance", "setrigidcolumnhsize", "setscript", "setsecondpasscharacteralign", "setsectionblock", "setsimplecolumnhsize", "setsmallbodyfont", "setsmallcaps", "setstackbox", "setstructurepageregister", "setstrut", "setsuperiors", "setsystemmode", "settabular", "settaggedmetadata", "settextcontent", "settightobject", "settightreferencedobject", "settightstrut", "settightunreferencedobject", "settokenlist", "settrialtypesetting", "setuevalue", "setugvalue", "setunreferencedobject", "setup", "setupMPgraphics", "setupMPinstance", "setupMPpage", "setupMPvariables", "setupTABLE", "setupTEXpage", "setupalign", "setupalternativestyles", "setuparranging", "setupattachment", "setupattachments", "setupbackend", "setupbackground", "setupbackgrounds", "setupbar", "setupbars", "setupblackrules", "setupblank", "setupbleeding", "setupblock", "setupbodyfont", "setupbookmark", "setupbottom", "setupbottomtexts", "setupbtx", "setupbtxdataset", "setupbtxlabeltext", "setupbtxlist", "setupbtxregister", "setupbtxrendering", "setupbuffer", "setupbutton", "setupcapitals", "setupcaption", "setupcaptions", "setupcharacteralign", "setupcharacterkerning", "setupcharacterspacing", "setupchemical", "setupchemicalframed", "setupclipping", "setupcollector", "setupcolor", "setupcolors", "setupcolumns", "setupcolumnset", "setupcolumnsetarea", "setupcolumnsetareatext", "setupcolumnsetlines", "setupcolumnsetspan", "setupcolumnsetstart", "setupcolumnspan", "setupcombination", "setupcombinedlist", "setupcomment", "setupcontent", "setupcounter", "setupdataset", "setupdelimitedtext", "setupdescription", "setupdirections", "setupdocument", "setupeffect", "setupenumeration", "setupenumerations", "setupenv", "setupexport", "setupexternalfigure", "setupexternalsoundtracks", "setupfacingfloat", "setupfield", "setupfieldbody", "setupfieldcategory", "setupfieldcontentframed", "setupfieldlabelframed", "setupfields", "setupfieldtotalframed", "setupfiller", "setupfillinlines", "setupfillinrules", "setupfirstline", "setupfittingpage", "setupfloat", "setupfloatframed", "setupfloats", "setupfloatsplitting", "setupfontexpansion", "setupfontprotrusion", "setupfonts", "setupfontsolution", "setupfooter", "setupfootertexts", "setupforms", "setupformula", "setupformulae", "setupformulaframed", "setupframed", "setupframedcontent", "setupframedtable", "setupframedtablecolumn", "setupframedtablerow", "setupframedtext", "setupframedtexts", "setupglobalreferenceprefix", "setuphead", "setupheadalternative", "setupheader", "setupheadertexts", "setupheadnumber", "setupheads", "setupheadtext", "setuphelp", "setuphigh", "setuphighlight", "setuphyphenation", "setuphyphenmark", "setupindentedtext", "setupindenting", "setupindex", "setupinitial", "setupinsertion", "setupinteraction", "setupinteractionbar", "setupinteractionmenu", "setupinteractionscreen", "setupinterlinespace", "setupitaliccorrection", "setupitemgroup", "setupitemizations", "setupitemize", "setupitems", "setuplabel", "setuplabeltext", "setuplanguage", "setuplayer", "setuplayeredtext", "setuplayout", "setuplayouttext", "setuplegend", "setuplinefiller", "setuplinefillers", "setuplinenote", "setuplinenumbering", "setuplines", "setuplinetable", "setuplinewidth", "setuplist", "setuplistalternative", "setuplistextra", "setuplocalfloats", "setuplocalinterlinespace", "setuplow", "setuplowhigh", "setuplowmidhigh", "setupmakeup", "setupmarginblock", "setupmargindata", "setupmarginframed", "setupmarginrule", "setupmarginrules", "setupmarking", "setupmathalignment", "setupmathcases", "setupmathematics", "setupmathfence", "setupmathfraction", "setupmathfractions", "setupmathframed", "setupmathlabeltext", "setupmathmatrix", "setupmathornament", "setupmathradical", "setupmathstackers", "setupmathstyle", "setupmixedcolumns", "setupmodule", "setupnarrower", "setupnotation", "setupnotations", "setupnote", "setupnotes", "setupoffset", "setupoffsetbox", "setupoperatortext", "setupoppositeplacing", "setupoutputroutine", "setuppagechecker", "setuppagecolumns", "setuppagecomment", "setuppageinjection", "setuppageinjectionalternative", "setuppagenumber", "setuppagenumbering", "setuppageshift", "setuppagestate", "setuppagetransitions", "setuppairedbox", "setuppalet", "setuppaper", "setuppapersize", "setupparagraph", "setupparagraphintro", "setupparagraphnumbering", "setupparagraphs", "setupparallel", "setupperiodkerning", "setupperiods", "setupplacement", "setuppositionbar", "setuppositioning", "setupprefixtext", "setupprocessor", "setupprofile", "setupprograms", "setupquotation", "setupquote", "setuprealpagenumber", "setupreferenceformat", "setupreferenceprefix", "setupreferencestructureprefix", "setupreferencing", "setupregister", "setupregisters", "setuprenderingwindow", "setuprotate", "setupruby", "setups", "setupscale", "setupscript", "setupscripts", "setupsectionblock", "setupselector", "setupshift", "setupsidebar", "setupsorting", "setupspacing", "setupspellchecking", "setupstartstop", "setupstretched", "setupstruts", "setupstyle", "setupsubformula", "setupsubformulas", "setupsubpagenumber", "setupsuffixtext", "setupsymbolset", "setupsynctex", "setupsynonyms", "setuptables", "setuptabulate", "setuptabulation", "setuptagging", "setuptaglabeltext", "setuptext", "setuptextbackground", "setuptextflow", "setuptextrules", "setuptexttexts", "setupthinrules", "setuptolerance", "setuptooltip", "setuptop", "setuptoptexts", "setuptype", "setuptyping", "setupunit", "setupunittext", "setupurl", "setupuserdata", "setupuserdataalternative", "setupuserpagenumber", "setupversion", "setupviewerlayer", "setupvspacing", "setupwhitespace", "setupwithargument", "setupwithargumentswapped", "setupxml", "setupxtable", "setuvalue", "setuxvalue", "setvalue", "setvariable", "setvariables", "setvboxregister", "setvisualizerfont", "setvtopregister", "setwidthof", "setxmeasure", "setxvalue", "setxvariable", "setxvariables", "seveneighths", "sfrac", "shapedhbox", "sharp", "shiftbox", "shiftdown", "shiftup", "showallmakeup", "showattributes", "showbodyfont", "showbodyfontenvironment", "showboxes", "showbtxdatasetauthors", "showbtxdatasetcompleteness", "showbtxdatasetfields", "showbtxfields", "showbtxhashedauthors", "showbtxtables", "showchardata", "showcharratio", "showcolor", "showcolorbar", "showcolorcomponents", "showcolorgroup", "showcolorset", "showcolorstruts", "showcounter", "showdirectives", "showdirsinmargin", "showedebuginfo", "showexperiments", "showfont", "showfontdata", "showfontexpansion", "showfontitalics", "showfontkerns", "showfontparameters", "showfontstrip", "showfontstyle", "showframe", "showglyphdata", "showglyphs", "showgrid", "showgridsnapping", "showhelp", "showhyphenationtrace", "showhyphens", "showinjector", "showjustification", "showkerning", "showlayout", "showlayoutcomponents", "showligature", "showligatures", "showlogcategories", "showmakeup", "showmargins", "showmessage", "showminimalbaseline", "shownextbox", "showotfcomposition", "showpalet", "showparentchain", "showprint", "showsetups", "showsetupsdefinition", "showstruts", "showsymbolset", "showtimer", "showtokens", "showtrackers", "showvalue", "showvariable", "showwarning", "sigma", "signalrightpage", "sim", "simeq", "simplealignedbox", "simplealignedboxplus", "simplealignedspreadbox", "simplegroupedcommand", "simplereversealignedbox", "simplereversealignedboxplus", "singalcharacteralign", "singlebond", "singleverticalbar", "sixperemspace", "sixthofsixarguments", "slanted", "slantedbold", "slantedface", "slash", "slicepages", "slong", "slovenianNumerals", "sloveniannumerals", "small", "smallbodyfont", "smallbold", "smallbolditalic", "smallboldslanted", "smallcappedcharacters", "smallcappedromannumerals", "smaller", "smallitalicbold", "smallnormal", "smallskip", "smallslanted", "smallslantedbold", "smalltype", "smash", "smashbox", "smashboxed", "smashedhbox", "smashedvbox", "smile", "snaptogrid", "softhyphen", "solidus", "someheadnumber", "somekindoftab", "someline", "somelocalfloat", "somenamedheadnumber", "someplace", "somewhere", "space", "spaceddigits", "spaceddigitsmethod", "spaceddigitsseparator", "spaceddigitssymbol", "spadesuit", "spanishNumerals", "spanishnumerals", "speech", "sphericalangle", "splitatasterisk", "splitatcolon", "splitatcolons", "splitatcomma", "splitatperiod", "splitdfrac", "splitfilename", "splitfloat", "splitfrac", "splitoffbase", "splitofffull", "splitoffkind", "splitoffname", "splitoffpath", "splitoffroot", "splitofftokens", "splitofftype", "splitstring", "spreadhbox", "sqcap", "sqcup", "sqrt", "sqsubset", "sqsubseteq", "sqsubsetneq", "sqsupset", "sqsupseteq", "sqsupsetneq", "square", "squaredots", "ssharp", "stackrel", "star", "stareq", "startJScode", "startJSpreamble", "startLUA", "startMP", "startMPclip", "startMPcode", "startMPdefinitions", "startMPdrawing", "startMPenvironment", "startMPextensions", "startMPinclusions", "startMPinitializations", "startMPpage", "startMPpositiongraphic", "startMPpositionmethod", "startMPrun", "startPARSEDXML", "startTABLE", "startTABLEbody", "startTABLEfoot", "startTABLEhead", "startTABLEnext", "startTC", "startTD", "startTDs", "startTEX", "startTEXpage", "startTH", "startTN", "startTR", "startTRs", "startTX", "startTY", "startXML", "startalign", "startalignment", "startallmodes", "startappendices", "startarrangedpages", "startaside", "startattachment", "startbackground", "startbackmatter", "startbar", "startbbordermatrix", "startbitmapimage", "startblockquote", "startbodymatter", "startbordermatrix", "startboxedcolumns", "startbtxlabeltext", "startbtxrenderingdefinitions", "startbuffer", "startcases", "startcatcodetable", "startcenteraligned", "startchapter", "startcharacteralign", "startcheckedfences", "startchemical", "startchemicaltext", "startcollect", "startcollecting", "startcolor", "startcolorintent", "startcoloronly", "startcolorset", "startcolumns", "startcolumnset", "startcolumnsetspan", "startcolumnspan", "startcombination", "startcomment", "startcomponent", "startcontextcode", "startcontextdefinitioncode", "startctxfunction", "startctxfunctiondefinition", "startcurrentcolor", "startcurrentlistentrywrapper", "startdelimited", "startdelimitedtext", "startdisplaymath", "startdmath", "startdocument", "starteffect", "startelement", "startembeddedxtable", "startendnote", "startendofline", "startenvironment", "startexceptions", "startexpanded", "startexpandedcollect", "startextendedcatcodetable", "startexternalfigurecollection", "startfacingfloat", "startfact", "startfigure", "startfiguretext", "startfittingpage", "startfixed", "startfloatcombination", "startfont", "startfontclass", "startfontsolution", "startfootnote", "startformula", "startformulas", "startframed", "startframedcell", "startframedcontent", "startframedrow", "startframedtable", "startframedtext", "startfrontmatter", "startgoto", "startgraphictext", "startgridsnapping", "starthanging", "starthbox", "starthboxestohbox", "starthboxregister", "starthead", "startheadtext", "starthelptext", "starthiding", "starthighlight", "starthyphenation", "startimath", "startindentation", "startindentedtext", "startinteraction", "startinteractionmenu", "startinterface", "startintermezzotext", "startintertext", "startitem", "startitemgroup", "startitemgroupcolumns", "startitemize", "startknockout", "startlabeltext", "startlanguage", "startlayout", "startleftaligned", "startlegend", "startline", "startlinealignment", "startlinecorrection", "startlinefiller", "startlinenote", "startlinenumbering", "startlines", "startlinetable", "startlinetablebody", "startlinetablecell", "startlinetablehead", "startlocalfootnotes", "startlocalheadsetup", "startlocallinecorrection", "startlocalnotes", "startlocalsetups", "startlua", "startluacode", "startluaparameterset", "startluasetups", "startmakeup", "startmarginblock", "startmarginrule", "startmarkedcontent", "startmarkpages", "startmathalignment", "startmathcases", "startmathlabeltext", "startmathmatrix", "startmathmode", "startmathstyle", "startmatrices", "startmatrix", "startmaxaligned", "startmdformula", "startmidaligned", "startmiddlealigned", "startmiddlemakeup", "startmixedcolumns", "startmode", "startmodeset", "startmodule", "startmoduletestsection", "startmpformula", "startnamedsection", "startnamedsubformulas", "startnarrow", "startnarrower", "startnegative", "startnicelyfilledbox", "startnointerference", "startnotallmodes", "startnotext", "startnotmode", "startoperatortext", "startopposite", "startoutputstream", "startoverlay", "startoverprint", "startpacked", "startpagecolumns", "startpagecomment", "startpagefigure", "startpagelayout", "startpagemakeup", "startpar", "startparagraph", "startparagraphs", "startparagraphscell", "startparbuilder", "startpart", "startpath", "startplacechemical", "startplacefigure", "startplacefloat", "startplaceformula", "startplacegraphic", "startplaceintermezzo", "startplacelegend", "startplacepairedbox", "startplacetable", "startpositioning", "startpositionoverlay", "startpositive", "startpostponing", "startpostponingnotes", "startprefixtext", "startprocessassignmentcommand", "startprocessassignmentlist", "startprocesscommacommand", "startprocesscommalist", "startproduct", "startproject", "startprotect", "startprotectedcolors", "startpublication", "startpunctuation", "startquotation", "startquote", "startrandomized", "startrandomseed", "startrawsetups", "startreadingfile", "startreferenceprefix", "startregime", "startregister", "startreusableMPgraphic", "startrightaligned", "startruby", "startscript", "startsdformula", "startsection", "startsectionblock", "startsectionblockenvironment", "startsectionlevel", "startsetups", "startshapebox", "startshift", "startsidebar", "startsimplecolumns", "startspecialitem", "startspeech", "startspformula", "startsplitformula", "startsplittext", "startspread", "startstandardmakeup", "startstaticMPfigure", "startstaticMPgraphic", "startstrictinspectnextcharacter", "startstructurepageregister", "startstrut", "startstyle", "startsubformulas", "startsubject", "startsubjectlevel", "startsubsection", "startsubsentence", "startsubstack", "startsubsubject", "startsubsubsection", "startsubsubsubject", "startsubsubsubsection", "startsubsubsubsubject", "startsubsubsubsubsection", "startsubsubsubsubsubject", "startsuffixtext", "startsymbolset", "starttable", "starttablehead", "starttables", "starttabletail", "starttabletext", "starttabulate", "starttabulatehead", "starttabulatetail", "starttagged", "starttaglabeltext", "starttexcode", "starttexdefinition", "starttext", "starttextbackground", "starttextbackgroundmanual", "starttextcolor", "starttextcolorintent", "starttextflow", "starttextmakeup", "starttextrule", "starttitle", "starttokenlist", "starttokens", "starttransparent", "starttypescript", "starttypescriptcollection", "starttyping", "startuniqueMPgraphic", "startuniqueMPpagegraphic", "startunittext", "startunpacked", "startusableMPgraphic", "startuseMPgraphic", "startusemathstyleparameter", "startuserdata", "startusingbtxspecification", "startvbox", "startvboxregister", "startvboxtohbox", "startvboxtohboxseparator", "startviewerlayer", "startvtop", "startvtopregister", "startxcell", "startxcellgroup", "startxcolumn", "startxgroup", "startxmldisplayverbatim", "startxmlinlineverbatim", "startxmlraw", "startxmlsetups", "startxrow", "startxrowgroup", "startxtable", "startxtablebody", "startxtablefoot", "startxtablehead", "startxtablenext", "stligature", "stopJScode", "stopJSpreamble", "stopLUA", "stopMP", "stopMPclip", "stopMPcode", "stopMPdefinitions", "stopMPdrawing", "stopMPenvironment", "stopMPextensions", "stopMPinclusions", "stopMPinitializations", "stopMPpage", "stopMPpositiongraphic", "stopMPpositionmethod", "stopMPrun", "stopPARSEDXML", "stopTABLE", "stopTABLEbody", "stopTABLEfoot", "stopTABLEhead", "stopTABLEnext", "stopTC", "stopTD", "stopTDs", "stopTEX", "stopTEXpage", "stopTH", "stopTN", "stopTR", "stopTRs", "stopTX", "stopTY", "stopXML", "stopalign", "stopalignment", "stopallmodes", "stopappendices", "stoparrangedpages", "stopaside", "stopattachment", "stopbackground", "stopbackmatter", "stopbar", "stopbbordermatrix", "stopbitmapimage", "stopblockquote", "stopbodymatter", "stopbordermatrix", "stopboxedcolumns", "stopbtxlabeltext", "stopbtxrenderingdefinitions", "stopbuffer", "stopcases", "stopcatcodetable", "stopcenteraligned", "stopchapter", "stopcharacteralign", "stopcheckedfences", "stopchemical", "stopchemicaltext", "stopcollect", "stopcollecting", "stopcolor", "stopcolorintent", "stopcoloronly", "stopcolorset", "stopcolumns", "stopcolumnset", "stopcolumnsetspan", "stopcolumnspan", "stopcombination", "stopcomment", "stopcomponent", "stopcontextcode", "stopcontextdefinitioncode", "stopctxfunction", "stopctxfunctiondefinition", "stopcurrentcolor", "stopcurrentlistentrywrapper", "stopdelimited", "stopdelimitedtext", "stopdisplaymath", "stopdmath", "stopdocument", "stopeffect", "stopelement", "stopembeddedxtable", "stopendnote", "stopendofline", "stopenvironment", "stopexceptions", "stopexpanded", "stopexpandedcollect", "stopextendedcatcodetable", "stopexternalfigurecollection", "stopfacingfloat", "stopfact", "stopfigure", "stopfiguretext", "stopfittingpage", "stopfixed", "stopfloatcombination", "stopfont", "stopfontclass", "stopfontsolution", "stopfootnote", "stopformula", "stopformulas", "stopframed", "stopframedcell", "stopframedcontent", "stopframedrow", "stopframedtable", "stopframedtext", "stopfrontmatter", "stopgoto", "stopgraphictext", "stopgridsnapping", "stophanging", "stophbox", "stophboxestohbox", "stophboxregister", "stophead", "stopheadtext", "stophelptext", "stophiding", "stophighlight", "stophyphenation", "stopimath", "stopindentation", "stopindentedtext", "stopinteraction", "stopinteractionmenu", "stopinterface", "stopintermezzotext", "stopintertext", "stopitem", "stopitemgroup", "stopitemgroupcolumns", "stopitemize", "stopknockout", "stoplabeltext", "stoplanguage", "stoplayout", "stopleftaligned", "stoplegend", "stopline", "stoplinealignment", "stoplinecorrection", "stoplinefiller", "stoplinenote", "stoplinenumbering", "stoplines", "stoplinetable", "stoplinetablebody", "stoplinetablecell", "stoplinetablehead", "stoplocalfootnotes", "stoplocalheadsetup", "stoplocallinecorrection", "stoplocalnotes", "stoplocalsetups", "stoplua", "stopluacode", "stopluaparameterset", "stopluasetups", "stopmakeup", "stopmarginblock", "stopmarginrule", "stopmarkedcontent", "stopmarkpages", "stopmathalignment", "stopmathcases", "stopmathlabeltext", "stopmathmatrix", "stopmathmode", "stopmathstyle", "stopmatrices", "stopmatrix", "stopmaxaligned", "stopmdformula", "stopmidaligned", "stopmiddlealigned", "stopmiddlemakeup", "stopmixedcolumns", "stopmode", "stopmodeset", "stopmodule", "stopmoduletestsection", "stopmpformula", "stopnamedsection", "stopnamedsubformulas", "stopnarrow", "stopnarrower", "stopnegative", "stopnicelyfilledbox", "stopnointerference", "stopnotallmodes", "stopnotext", "stopnotmode", "stopoperatortext", "stopopposite", "stopoutputstream", "stopoverlay", "stopoverprint", "stoppacked", "stoppagecolumns", "stoppagecomment", "stoppagefigure", "stoppagelayout", "stoppagemakeup", "stoppar", "stopparagraph", "stopparagraphs", "stopparagraphscell", "stopparbuilder", "stoppart", "stoppath", "stopplacechemical", "stopplacefigure", "stopplacefloat", "stopplaceformula", "stopplacegraphic", "stopplaceintermezzo", "stopplacelegend", "stopplacepairedbox", "stopplacetable", "stoppositioning", "stoppositionoverlay", "stoppositive", "stoppostponing", "stoppostponingnotes", "stopprefixtext", "stopprocessassignmentcommand", "stopprocessassignmentlist", "stopprocesscommacommand", "stopprocesscommalist", "stopproduct", "stopproject", "stopprotect", "stopprotectedcolors", "stoppublication", "stoppunctuation", "stopquotation", "stopquote", "stoprandomized", "stoprandomseed", "stoprawsetups", "stopreadingfile", "stopreferenceprefix", "stopregime", "stopregister", "stopreusableMPgraphic", "stoprightaligned", "stopruby", "stopscript", "stopsdformula", "stopsection", "stopsectionblock", "stopsectionblockenvironment", "stopsectionlevel", "stopsetups", "stopshapebox", "stopshift", "stopsidebar", "stopsimplecolumns", "stopspecialitem", "stopspeech", "stopspformula", "stopsplitformula", "stopsplittext", "stopspread", "stopstandardmakeup", "stopstaticMPfigure", "stopstaticMPgraphic", "stopstrictinspectnextcharacter", "stopstructurepageregister", "stopstrut", "stopstyle", "stopsubformulas", "stopsubject", "stopsubjectlevel", "stopsubsection", "stopsubsentence", "stopsubstack", "stopsubsubject", "stopsubsubsection", "stopsubsubsubject", "stopsubsubsubsection", "stopsubsubsubsubject", "stopsubsubsubsubsection", "stopsubsubsubsubsubject", "stopsuffixtext", "stopsymbolset", "stoptable", "stoptablehead", "stoptables", "stoptabletail", "stoptabletext", "stoptabulate", "stoptabulatehead", "stoptabulatetail", "stoptagged", "stoptaglabeltext", "stoptexcode", "stoptexdefinition", "stoptext", "stoptextbackground", "stoptextbackgroundmanual", "stoptextcolor", "stoptextcolorintent", "stoptextflow", "stoptextmakeup", "stoptextrule", "stoptitle", "stoptokenlist", "stoptokens", "stoptransparent", "stoptypescript", "stoptypescriptcollection", "stoptyping", "stopuniqueMPgraphic", "stopuniqueMPpagegraphic", "stopunittext", "stopunpacked", "stopusableMPgraphic", "stopuseMPgraphic", "stopusemathstyleparameter", "stopuserdata", "stopusingbtxspecification", "stopvbox", "stopvboxregister", "stopvboxtohbox", "stopvboxtohboxseparator", "stopviewerlayer", "stopvtop", "stopvtopregister", "stopxcell", "stopxcellgroup", "stopxcolumn", "stopxgroup", "stopxmldisplayverbatim", "stopxmlinlineverbatim", "stopxmlraw", "stopxmlsetups", "stopxrow", "stopxrowgroup", "stopxtable", "stopxtablebody", "stopxtablefoot", "stopxtablehead", "stopxtablenext", "stretched", "strictdoifelsenextoptional", "strictdoifnextoptionalelse", "stripcharacter", "strippedcsname", "stripspaces", "structurelistuservariable", "structurenumber", "structuretitle", "structureuservariable", "structurevariable", "strut", "strutdp", "strutgap", "strutht", "struthtdp", "struttedbox", "strutwd", "style", "styleinstance", "subject", "subpagenumber", "subsection", "subsentence", "subset", "subseteq", "subseteqq", "subsetneq", "subsetneqq", "substituteincommalist", "subsubject", "subsubsection", "subsubsubject", "subsubsubsection", "subsubsubsubject", "subsubsubsubsection", "subsubsubsubsubject", "subtractfeature", "succ", "succapprox", "succcurlyeq", "succeq", "succeqq", "succnapprox", "succneq", "succneqq", "succnsim", "succsim", "suffixlanguage", "suffixtext", "sum", "supset", "supseteq", "supseteqq", "supsetneq", "supsetneqq", "surd", "surdradical", "swapcounts", "swapdimens", "swapface", "swapmacros", "swaptypeface", "swarrow", "switchstyleonly", "switchtobodyfont", "switchtocolor", "switchtointerlinespace", "symbol", "symbolreference", "synchronizeblank", "synchronizeindenting", "synchronizemarking", "synchronizeoutputstreams", "synchronizestrut", "synchronizewhitespace", "synctexblockfilename", "synctexresetfilename", "synctexsetfilename", "systemlog", "systemlogfirst", "systemloglast", "systemsetups", "tLeftarrow", "tLeftrightarrow", "tRightarrow", "tabulateautoline", "tabulateautorule", "tabulateline", "tabulaterule", "taggedctxcommand", "taggedlabeltexts", "taglabellanguage", "taglabeltext", "tau", "tbinom", "tbox", "tcaron", "tcedilla", "tcommaaccent", "tcurl", "tequal", "test", "testandsplitstring", "testcolumn", "testfeature", "testfeatureonce", "testpage", "testpageonly", "testpagesync", "testtokens", "tex", "texdefinition", "texsetup", "textAngstrom", "textacute", "textampersand", "textasciicircum", "textasciitilde", "textat", "textbackslash", "textbar", "textbottomcomma", "textbottomdot", "textbraceleft", "textbraceright", "textbreve", "textbrokenbar", "textbullet", "textcaron", "textcedilla", "textcelsius", "textcent", "textcircledP", "textcircumflex", "textcitation", "textcite", "textcomma", "textcontrolspace", "textcurrency", "textdag", "textddag", "textdegree", "textdiaeresis", "textdiv", "textdollar", "textdong", "textdotaccent", "textellipsis", "texteuro", "textflowcollector", "textfraction", "textgrave", "texthash", "texthorizontalbar", "texthungarumlaut", "texthyphen", "textkelvin", "textlognot", "textmacron", "textmath", "textmho", "textminus", "textmu", "textmultiply", "textnumero", "textogonek", "textohm", "textormathchar", "textormathchars", "textounce", "textpercent", "textperiod", "textplus", "textpm", "textreference", "textring", "textrule", "textslash", "textsterling", "texttilde", "textunderscore", "textvisiblespace", "textyen", "thai", "thainumerals", "thefirstcharacter", "thenormalizedbodyfontsize", "therefore", "theremainingcharacters", "theta", "thickspace", "thinrule", "thinrules", "thinspace", "thirdoffivearguments", "thirdoffourarguments", "thirdofsixarguments", "thirdofthreearguments", "thirdofthreeunexpanded", "thook", "thookleftarrow", "thookrightarrow", "thorn", "threedigitrounding", "threeeighths", "threefifths", "threeperemspace", "threequarter", "threesuperior", "tibetannumerals", "tightlayer", "tilde", "times", "tinyfont", "title", "tlap", "tleftarrow", "tleftharpoondown", "tleftharpoonup", "tleftrightarrow", "tleftrightharpoons", "tmapsto", "to", "tochar", "tolinenote", "tooltip", "top", "topbox", "topleftbox", "toplinebox", "toprightbox", "topskippedbox", "tracecatcodetables", "tracedfontname", "traceoutputroutines", "tracepositions", "trademark", "translate", "transparencycomponents", "transparent", "trel", "triangle", "triangledown", "triangleleft", "triangleq", "triangleright", "trightarrow", "trightharpoondown", "trightharpoonup", "trightleftharpoons", "trightoverleftarrow", "triplebond", "tripleprime", "tripleverticalbar", "truefilename", "truefontname", "tstroke", "ttraggedright", "ttriplerel", "ttwoheadleftarrow", "ttwoheadrightarrow", "turnediota", "twodigitrounding", "twofifths", "twoheaddownarrow", "twoheadleftarrow", "twoheadrightarrow", "twoheadrightarrowtail", "twoheaduparrow", "twosuperior", "twothirds", "tx", "txx", "typ", "type", "typebuffer", "typedefinedbuffer", "typeface", "typefile", "typeinlinebuffer", "typescriptone", "typescriptprefix", "typescriptthree", "typescripttwo", "typesetbuffer", "typesetfile", "uacute", "ubreve", "ucaron", "ucircumflex", "uconvertnumber", "udiaeresis", "udiaeresisacute", "udiaeresiscaron", "udiaeresisgrave", "udiaeresismacron", "udotbelow", "udots", "udoublegrave", "uedcatcodecommand", "ugrave", "uhook", "uhorn", "uhornacute", "uhorndotbelow", "uhorngrave", "uhornhook", "uhorntilde", "uhungarumlaut", "uinvertedbreve", "ulcorner", "umacron", "undefinevalue", "undepthed", "underbar", "underbars", "underbrace", "underbracket", "underdash", "underdashes", "underdot", "underdots", "underleftarrow", "underparent", "underrandom", "underrandoms", "underrightarrow", "underset", "understrike", "understrikes", "undoassign", "unexpandeddocumentvariable", "unframed", "unhhbox", "unihex", "uniqueMPgraphic", "uniqueMPpagegraphic", "unit", "unitlanguage", "unitshigh", "unitslow", "unittext", "unknown", "unprotected", "unregisterhyphenationpattern", "unspaceafter", "unspaceargument", "unspaced", "unspacestring", "untexargument", "untexcommand", "uogonek", "upand", "uparrow", "updasharrow", "updownarrow", "updownarrowbar", "updownarrows", "upharpoonleft", "upharpoonright", "uplus", "uppercased", "uppercasestring", "upperleftdoubleninequote", "upperleftdoublesixquote", "upperleftsingleninequote", "upperleftsinglesixquote", "upperrightdoubleninequote", "upperrightdoublesixquote", "upperrightsingleninequote", "upperrightsinglesixquote", "upsilon", "upuparrows", "upwhitearrow", "urcorner", "uring", "url", "useJSscripts", "useMPenvironmentbuffer", "useMPgraphic", "useMPlibrary", "useMPrun", "useMPvariables", "useURL", "usealignparameter", "useblankparameter", "useblocks", "usebodyfont", "usebodyfontparameter", "usebtxdataset", "usebtxdefinitions", "usecitation", "usecolors", "usecomponent", "usedirectory", "usedummycolorparameter", "usedummystyleandcolor", "usedummystyleparameter", "useenvironment", "useexternaldocument", "useexternalfigure", "useexternalrendering", "useexternalsoundtrack", "usefigurebase", "usefile", "usegridparameter", "useindentingparameter", "useindentnextparameter", "useinterlinespaceparameter", "uselanguageparameter", "useluamodule", "usemathstyleparameter", "usemodule", "useproduct", "useprofileparameter", "useproject", "usereferenceparameter", "userpagenumber", "usesetupsparameter", "usestaticMPfigure", "usesubpath", "usesymbols", "usetexmodule", "usetypescript", "usetypescriptfile", "useurl", "usezipfile", "utfchar", "utflower", "utfupper", "utilde", "utilityregisterlength", "vDash", "varTheta", "varepsilon", "varkappa", "varnothing", "varphi", "varpi", "varrho", "varsigma", "vartheta", "vboxreference", "vdash", "vdots", "vec", "vee", "veebar", "veeeq", "verbatim", "verbatimstring", "verbosenumber", "version", "vert", "verticalgrowingbar", "verticalpositionbar", "veryraggedcenter", "veryraggedleft", "veryraggedright", "vglue", "viewerlayer", "vl", "vphantom", "vpos", "vsmash", "vsmashbox", "vsmashed", "vspace", "vspacing", "wcircumflex", "wdofstring", "wedge", "wedgeeq", "weekday", "whitearrowupfrombar", "widehat", "widetilde", "widthofstring", "widthspanningtext", "withoutpt", "word", "wordright", "words", "wordtonumber", "wp", "wr", "writebetweenlist", "writedatatolist", "writestatus", "writetolist", "xLeftarrow", "xLeftrightarrow", "xRightarrow", "xdefconvertedargument", "xequal", "xfrac", "xhookleftarrow", "xhookrightarrow", "xi", "xleftarrow", "xleftharpoondown", "xleftharpoonup", "xleftrightarrow", "xleftrightharpoons", "xmapsto", "xmladdindex", "xmlafterdocumentsetup", "xmlaftersetup", "xmlall", "xmlappenddocumentsetup", "xmlappendsetup", "xmlapplyselectors", "xmlatt", "xmlattdef", "xmlattribute", "xmlattributedef", "xmlbadinclusions", "xmlbeforedocumentsetup", "xmlbeforesetup", "xmlchainatt", "xmlchainattdef", "xmlchecknamespace", "xmlcommand", "xmlconcat", "xmlconcatrange", "xmlcontext", "xmlcount", "xmldefaulttotext", "xmldirectives", "xmldirectivesafter", "xmldirectivesbefore", "xmldisplayverbatim", "xmldoif", "xmldoifatt", "xmldoifelse", "xmldoifelseatt", "xmldoifelseempty", "xmldoifelseselfempty", "xmldoifelsetext", "xmldoifelsevalue", "xmldoifnot", "xmldoifnotatt", "xmldoifnotselfempty", "xmldoifnottext", "xmldoifselfempty", "xmldoiftext", "xmlelement", "xmlfilter", "xmlfirst", "xmlflush", "xmlflushcontext", "xmlflushdocumentsetups", "xmlflushlinewise", "xmlflushpure", "xmlflushspacewise", "xmlflushtext", "xmlinclude", "xmlinclusion", "xmlinclusions", "xmlinfo", "xmlinjector", "xmlinlineprettyprint", "xmlinlineprettyprinttext", "xmlinlineverbatim", "xmlinstalldirective", "xmllast", "xmllastatt", "xmllastmatch", "xmllastpar", "xmlloadbuffer", "xmlloaddata", "xmlloaddirectives", "xmlloadfile", "xmlloadonly", "xmlmain", "xmlmapvalue", "xmlname", "xmlnamespace", "xmlnonspace", "xmlpar", "xmlparam", "xmlpath", "xmlpos", "xmlposition", "xmlprependdocumentsetup", "xmlprependsetup", "xmlprettyprint", "xmlprettyprinttext", "xmlprocessbuffer", "xmlprocessdata", "xmlprocessfile", "xmlpure", "xmlraw", "xmlrefatt", "xmlregistereddocumentsetups", "xmlregisteredsetups", "xmlregisterns", "xmlremapname", "xmlremapnamespace", "xmlremovedocumentsetup", "xmlremovesetup", "xmlresetdocumentsetups", "xmlresetinjectors", "xmlresetsetups", "xmlsave", "xmlsetatt", "xmlsetattribute", "xmlsetentity", "xmlsetfunction", "xmlsetinjectors", "xmlsetpar", "xmlsetparam", "xmlsetsetup", "xmlsetup", "xmlshow", "xmlsnippet", "xmlstrip", "xmlstripnolines", "xmlstripped", "xmlstrippednolines", "xmltag", "xmltexentity", "xmltext", "xmltobuffer", "xmltobufferverbose", "xmltofile", "xmlvalue", "xmlverbatim", "xrel", "xrightarrow", "xrightharpoondown", "xrightharpoonup", "xrightleftharpoons", "xrightoverleftarrow", "xsplitstring", "xtriplerel", "xtwoheadleftarrow", "xtwoheadrightarrow", "xxfrac", "xypos", "yacute", "ycircumflex", "ydiaeresis", "ydotbelow", "yen", "ygrave", "yhook", "ymacron", "ytilde", "zacute", "zcaron", "zdotaccent", "zerowidthnobreakspace", "zerowidthspace", "zeta", "zhook", "zstroke", "zwj", "zwnj" },
+ ["cs"]={ "Cisla", "Kap", "MESIC", "Rimskecislice", "SLOVA", "SLOVO", "Slova", "Slovo", "VSEDNIDEN", "Znak", "Znaky", "aktualnicislonadpisu", "aktualnidatum", "barevnalista", "barva", "cernalinka", "cernelinky", "cisla", "cislonadpisu", "cislorovnice", "cislostrany", "datum", "definuj", "definujakcent", "definujbarvu", "definujblok", "definujbloksekce", "definujbuffer", "definujfont", "definujformatodkazu", "definujhbox", "definujinterakcnimenu", "definujkombinovanyseznam", "definujkonverzi", "definujnadpis", "definujobrazeksymbol", "definujodkaz", "definujodstavce", "definujopis", "definujoramovani", "definujoramovanytext", "definujpaletu", "definujplvouciobjekt", "definujpodpole", "definujpole", "definujpopis", "definujpopisek", "definujprekryv", "definujprikaz", "definujprofil", "definujprogram", "definujprostredizakladnihofontu", "definujrejstrik", "definujsablonutabulky", "definujsekci", "definujseznam", "definujskupinubarev", "definujstartstop", "definujstyl", "definujstylfontu", "definujsymbol", "definujsynonumumfontu", "definujsynonyma", "definujtabelaci", "definujtext", "definujtrideni", "definujupravu", "definujvelikostpapiru", "definujvycet", "definujzakladnifont", "definujzasobnikpoli", "definujznaceni", "definujznak", "delkaseznamu", "externiobraz", "hlavnijazyk", "hodnotabarvy", "instalacejazyka", "interakcnilista", "interakcnitlacitka", "interaktivnimenu", "jazyk", "jdidolu", "jdina", "jdinabox", "jdinastranu", "klonujpole", "komponenta", "konvertujcislo", "kopirujpole", "korekcebilehomista", "matematika", "meritko", "mesic", "mezera", "mrizka", "nastavbarvu", "nastavbarvy", "nastavbilamista", "nastavblok", "nastavbloksekce", "nastavbuffer", "nastavcernelinky", "nastavcislonadpisu", "nastavcislostrany", "nastavcislovaniodstavcu", "nastavcislovaniradku", "nastavcislovanistran", "nastavcitaci", "nastavdeleniplvoucichobjektu", "nastavdelitko", "nastavdolnitexty", "nastavhorejsek", "nastavhornitexty", "nastavinterakci", "nastavinterakcnilistu", "nastavinterakcnimenu", "nastavinterakcniobrazovku", "nastavjazyk", "nastavkapitalky", "nastavkombinovanyseznam", "nastavkomentar", "nastavkomentarstrany", "nastavmarginalnilinky", "nastavmeziradkovoumezeru", "nastavnadpis", "nastavnadpisy", "nastavodkazovani", "nastavodsazovani", "nastavodstavce", "nastavopis", "nastavoramovanetexty", "nastavoramovani", "nastavorez", "nastavotoceni", "nastavpaletu", "nastavplvouciobjekt", "nastavplvouciobjekty", "nastavpodcislostrany", "nastavpole", "nastavpolozky", "nastavpopisek", "nastavpopisky", "nastavpozadi", "nastavprechodstrany", "nastavpreskok", "nastavprogramy", "nastavradkovani", "nastavradky", "nastavrejstrik", "nastavrovnice", "nastavsadusymbolu", "nastavseznam", "nastavsirkucary", "nastavsloupce", "nastavspodek", "nastavsynonyma", "nastavtabelaci", "nastavtabulky", "nastavtenkelinky", "nastavtext", "nastavtextovelinky", "nastavtexttexty", "nastavtextyupati", "nastavtextyzahlavi", "nastavtoleranci", "nastavtrideni", "nastavtype", "nastavumisteniprotejsku", "nastavumistovani", "nastavupati", "nastavupravu", "nastavurl", "nastavusporadani", "nastavvelikostpapiru", "nastavvsechnapole", "nastavvycty", "nastavvyplnovelinky", "nastavvyplnoveradky", "nastavvzhled", "nastavzahlavi", "nastavzakladnifont", "nastavzarovnani", "nastavznaceni", "nastavzuzeni", "nastrane", "nejakyradek", "nekde", "neznamo", "nivy", "nizky", "nokap", "obrazovka", "odkaz", "odkaznastranu", "odkaznatext", "odkazujici", "opis", "opissoubor", "oramovani", "oref", "orez", "otocit", "oznaceni", "pis", "plnezneni", "pole", "polozka", "polozky", "porovnejpaletu", "porovnejskupinubarev", "pozadi", "pozice", "poznamka", "pref", "prelozit", "prepninazakladnifont", "preskoc", "prizpusobivepole", "prizpusobvzhled", "produkt", "projekt", "prostredi", "resetznaceni", "rimskecislice", "rozdelplvouciobjekt", "roztazene", "schovejbloky", "sedabarva", "sloupec", "slovovpravo", "stanovcharakteristickuseznamu", "stanovcislonadpisu", "startbarva", "startinteraktivnimenu", "startjazyk", "startjdina", "startkomponenta", "startmarginalnilinka", "startnadpis", "startoramovani", "startpolozka", "startpozadi", "startprodukt", "startprojekt", "startprostredi", "startpublikace", "startradek", "starttextovalinka", "startumistirovnici", "startzarovnanonastred", "startzarovnanovlevo", "startzarovnanovpravo", "startzhustene", "stopbarva", "stopinteraktivnimenu", "stopjazyk", "stopjdina", "stopkomponenta", "stopmarginalnilinka", "stopnadpis", "stoporamovani", "stoppolozka", "stoppozadi", "stopprodukt", "stopprojekt", "stopprostredi", "stoppublikace", "stopradek", "stoptextovalinka", "stopumistirovnici", "stopzarovnanonastred", "stopzarovnanovlevo", "stopzarovnanovpravo", "stopzhustene", "strana", "tecky", "tenkalinka", "tenkelinky", "textovalinka", "tlacitko", "tlacitkomenu", "tloustkacary", "tref", "tvrdamezera", "tvrdemezery", "ukazbarvu", "ukazmrizku", "ukaznastaveni", "ukazpaletu", "ukazpodpery", "ukazpostredizakladnihofontu", "ukazramecek", "ukazsadusymbolu", "ukazskupinubarev", "ukazupravu", "ukazvytisk", "ukazvzhled", "ukazzakladnifont", "umistikombinovanyseznam", "umistilokalnipoznamkypodcarou", "umistinadsebe", "umistinamrizku", "umistipodrovnici", "umistipoznamkypodcarou", "umistirejstrik", "umistirovnici", "umistiseznam", "umistivedlesebe", "umistizalozky", "urcicharakteristikurejstriku", "uzijJSscripts", "uzijURL", "uzijadresar", "uzijbloky", "uzijexternidokument", "uzijexterniobraz", "uzijexternizvuk", "uzijmodul", "uzijsymbol", "uzijurl", "verze", "vlasovalinka", "vradku", "vsedniden", "vyberbloky", "vyplnenytext", "vyplnovelinky", "vyplnovyradek", "vysoky", "zachovejbloky", "zadnamezera", "zadnehorniadolniradky", "zadnezahlaviaupati", "zalozka", "zapisdoseznamu", "zapismeziseznam", "zaramovani", "zarovnanonastred", "zarovnanovlevo", "zarovnanovpravo", "zasobnikpoli", "ziskejbuffer", "ziskejznaceni", "znaceni", "znak", "znaky", "zpracujbloky", "zrcadlit", "zref" },
+ ["de"]={ "Buchstabe", "Buchstaben", "Kap", "MONAT", "Roemischezahlen", "WOCHENTAG", "WOERTER", "WORT", "Woerter", "Wort", "Ziffern", "amgitterausrichten", "aufseite", "ausfuelltext", "ausschnitt", "bearbeitebloecke", "behaltebloecke", "bei", "bemerkung", "benutzeverzeichnis", "beschriftung", "bestimmekopfnummer", "bestimmelistencharakeristika", "bestimmeregistercharakteristika", "bildschirm", "blanko", "buchstabe", "buchstaben", "datum", "defineschriftsynonym", "definiereabbsymbol", "definiereabsaetze", "definiereabschnitt", "definiereabschnittsblock", "definiereakzent", "definierebefehl", "definierebeschreibung", "definierebeschriftung", "definiereblock", "definierefarbe", "definierefarbengruppe", "definierefeld", "definierefeldstapel", "definierefliesstext", "definierefliesstextumgebung", "definieregleitobjekt", "definierehbox", "definiereinteraktionsmenue", "definierekonversion", "definierelabel", "definiereliste", "definieren", "definierenummerierung", "definiereoverlay", "definierepalette", "definierepapierformat", "definiereprofil", "definiereprogramme", "definierepuffer", "definierereferenz", "definierereferenzformat", "definiereregister", "definiereschrift", "definiereschriftstil", "definieresortieren", "definierestartstop", "definierestil", "definieresubfeld", "definieresymbol", "definieresynonyme", "definieretabellenvorlage", "definieretabulator", "definieretext", "definieretippen", "definiereueberschrift", "definiereumbruch", "definiereumrahmt", "definiereumrahmtertext", "definierezeichen", "definierezusammengestellteliste", "drehen", "duennelinie", "duennerumriss", "einezeile", "externeabbildung", "farbbalken", "farbe", "farbewert", "feld", "feldstapel", "festesspatium", "format", "formelnummer", "gefuelltesrechteck", "gefuelltezeile", "gestreckt", "gitter", "graufarbe", "haarlinie", "hauptsprache", "heutigesdatum", "heutigeskopfnummer", "hintergrund", "hoch", "holebeschriftung", "holepuffer", "imumriss", "installieresprache", "interaktionsbalken", "interaktionsknopfe", "interaktionsmenue", "inzeile", "irgendwo", "keinekopfundfusszeilen", "keinspatium", "keinzeilenobenundunten", "klonierefeld", "knopf", "komponente", "konvertierezahl", "kopfnummer", "kopierefeld", "korrigierezwischenraum", "liniendicke", "linksbuendig", "listenlaenge", "mathematik", "menueknopf", "monat", "nachunten", "nokap", "notiz", "passelayoutan", "passendfeld", "platzierebookmarks", "platziereformel", "platzierefussnoten", "platziereliste", "platzierelokalefussnoten", "platzierenebeneinander", "platziereregister", "platziereuntereinander", "platziereunterformel", "platzierezusammengestellteliste", "pos", "posten", "produkt", "programm", "projekt", "punkt", "rechteck", "rechtecke", "rechtsbuendig", "referenz", "referieren", "roemischezahlen", "ruecksetztenbeschriftung", "schreibezurliste", "schreibezwischenliste", "seite", "seitenreferenz", "seitenummer", "settext", "spalte", "spatium", "spiegeln", "sprache", "startfarbe", "starthintergrund", "startinteraktionsmenue", "startkleinerdurchschuss", "startkomponente", "startkopf", "startlinksbuendig", "startmarginallinie", "startplatziereformel", "startpos", "startprodukt", "startprojekt", "startpublikation", "startrechtsbuendig", "startsprache", "starttextlinie", "startumgebung", "startumrahmt", "startzeile", "startzentriert", "startzu", "stelleabsaetzeein", "stelleabsatznummerierungein", "stelleabschnittsblockein", "stelleanordnenein", "stelleaufzaehlungenein", "stelleausrichtungein", "stelleausschnittein", "stellebeschreibungein", "stellebeschriftungein", "stellebilderunterschriftein", "stellebildunterschriftein", "stellebindestrichein", "stelleblankoein", "stelleblockein", "stelledrehenein", "stelleduennerumrissein", "stelleeinziehenein", "stelleengerein", "stellefarbeein", "stellefarbenein", "stellefeldein", "stellefelderin", "stellefliesstextein", "stelleformelnein", "stellefusszeileein", "stellefusszeilentextein", "stellegefuelltesrechteckein", "stellegefuelltezeileein", "stellegegenueberplatzierenein", "stellegleitobjekteein", "stellegleitobjektein", "stellehintergruendeein", "stellehintergrundein", "stelleinteraktionein", "stelleinteraktionsbalkenein", "stelleinteraktionsbildschirmein", "stelleinteraktionsmenueein", "stellekommentarein", "stellekopfzahlein", "stellekopfzeileein", "stellekopfzeilentextein", "stellelayoutein", "stellelinienbreiteein", "stellelisteein", "stellemarginallinieein", "stellenobenein", "stellepaletteein", "stellepapierformatein", "stelleplatziegeteiltegleitobjekt", "stellepositionierenein", "stellepostenein", "stelleprogrammein", "stellepufferein", "stellerechteckein", "stellereferenzierenein", "stelleregisterein", "stelleseitenkommentarein", "stelleseitennummerein", "stelleseitennummeriernungein", "stelleseitenuebergangein", "stellesortierenein", "stellespaltenein", "stellespatiumein", "stellespracheein", "stellesymbolsetein", "stellesynonymein", "stelletabellenein", "stelletabulatorein", "stelletextein", "stelletextobenein", "stelletexttexteein", "stelletextumrissein", "stelletextuntenein", "stelletipein", "stelletippenein", "stelletoleranzein", "stelleueberschriftein", "stelleueberschriftenein", "stelleumbruchein", "stelleumrahmtein", "stelleumrahmtetexteein", "stelleuntenein", "stelleunterseitennummerein", "stelleurlein", "stelleversalienein", "stellezeilenabstandein", "stellezeilenein", "stellezeilennumerierungein", "stellezitierenein", "stellezusammengestelltelisteein", "stellezwischenraumein", "stopfarbe", "stophintergrund", "stopinteraktionsmenue", "stopkleinerdurchschuss", "stopkomponente", "stopkopf", "stoplinksbuendig", "stopmarginallinie", "stopplatziereformel", "stoppos", "stopprodukt", "stopprojekt", "stoppublikation", "stoprechtsbuendig", "stopsprache", "stoptextlinie", "stopumgebung", "stopumrahmt", "stopzeile", "stopzentriert", "stopzu", "teilegleitobjekt", "textlinie", "textreferenz", "tief", "tiho", "tip", "tippedatei", "tippen", "tippepuffer", "ueber", "uebersetzten", "umgebung", "umrahmt", "unbekant", "verbergebloecke", "vergleichefarbengruppe", "vergleichepalette", "verwendeJSscript", "verwendeURL", "verwendebloecke", "verwendeexteresdokument", "verwendeexterneabbildung", "verwendeexternestonstueck", "verwendemodul", "verwendesymbole", "verwendeurl", "volleswort", "von", "waehlebloeckeaus", "wechselezumfliesstext", "wochentag", "wortrechts", "zeigedruck", "zeigeeinstellungen", "zeigefarbe", "zeigefarbengruppe", "zeigefliesstext", "zeigefliesstextumgebung", "zeigegitter", "zeigelayout", "zeigepalette", "zeigerahmen", "zeigestruts", "zeigeumbruch", "zentriert", "ziffern", "zu", "zurbox", "zurseite" },
["en"]={},
- ["fr"]={ "Caractere", "Caracteres", "Chiffresromains", "JOURSEMAINE", "MOIS", "MOT", "MOTS", "Mot", "Mots", "Numeros", "a", "adaptedisposition", "ajustechamp", "alaligne", "alapage", "aligneadroite", "aligneagauche", "aligneaumilieu", "arriereplan", "baha", "barrecouleur", "barreinteraction", "bas", "bouton", "boutonmenu", "boutonsinteraction", "cacheblocs", "caractere", "caracteres", "champ", "changepolicecorps", "chiffresromains", "clonechamp", "colonne", "commentaire", "comparegroupecouleur", "comparepalette", "completenumeropage", "completeregistre", "composant", "concernant", "convertitnumero", "copitchamp", "corrigeespaceblanc", "couleur", "couleurgrise", "dactylographier", "dans", "datecourante", "de", "definicaractere", "definit", "definitaccent", "definitbloc", "definitblocsection", "definitbuffer", "definitcalque", "definitchamp", "definitcommande", "definitconversion", "definitcouleur", "definitdactylo", "definitdemarrestoppe", "definitdescription", "definitdisposition", "definitenumeration", "definitenvironnementpolicecorps", "definitetiquette", "definitflottant", "definitformatreference", "definitgroupecouleur", "definithbox", "definitliste", "definitlisteimbriquee", "definitmakeup", "definitmarquage", "definitmenuinteraction", "definitpalette", "definitparagraphes", "definitpilechamp", "definitpolice", "definitpolicecorps", "definitprofil", "definitprogramme", "definitreference", "definitregistre", "definitrevetement", "definitsautdecolonne", "definitsautdepage", "definitsection", "definitsouschamp", "definitstyle", "definitstylepolice", "definitsymbole", "definitsymbolefigure", "definitsynonymepolice", "definitsynonymes", "definittabulation", "definittaillepapier", "definittete", "definittexte", "definittrametableau", "definittri", "definittype", "definitvide", "demarreJScode", "demarreJSpreamble", "demarreLUA", "demarreMP", "demarreMPclip", "demarreMPcode", "demarreMPdefinitions", "demarreMPdrawing", "demarreMPenvironment", "demarreMPextensions", "demarreMPinclusions", "demarreMPinitializations", "demarreMPpage", "demarreMPpositiongraphic", "demarreMPpositionmethod", "demarreMPrun", "demarrePARSEDXML", "demarreTABLE", "demarreTABLEbody", "demarreTABLEfoot", "demarreTABLEhead", "demarreTABLEnext", "demarreTC", "demarreTD", "demarreTDs", "demarreTEX", "demarreTEXpage", "demarreTH", "demarreTN", "demarreTR", "demarreTRs", "demarreTX", "demarreTY", "demarreXML", "demarrealign", "demarrealigneadroite", "demarrealigneagauche", "demarrealigneaumilieu", "demarrealignment", "demarreallmodes", "demarreappendices", "demarrearrangedpages", "demarrearriereplan", "demarreaside", "demarreattachment", "demarrebackmatter", "demarrebar", "demarrebbordermatrix", "demarrebitmapimage", "demarreblockquote", "demarrebodymatter", "demarrebordermatrix", "demarreboxedcolumns", "demarrebtxlabeltext", "demarrebtxrenderingdefinitions", "demarrebuffer", "demarrecases", "demarrecatcodetable", "demarrecenteraligned", "demarrechapter", "demarrecharacteralign", "demarrecheckedfences", "demarrechemical", "demarrechemicaltext", "demarreciter", "demarrecollect", "demarrecollecting", "demarrecolorintent", "demarrecoloronly", "demarrecolorset", "demarrecolumns", "demarrecolumnspan", "demarrecombination", "demarrecomment", "demarrecomposant", "demarrecontextcode", "demarrecontextdefinitioncode", "demarrecouleur", "demarrectxfunction", "demarrectxfunctiondefinition", "demarrecurrentcolor", "demarrecurrentlistentrywrapper", "demarredelimited", "demarredelimitedtext", "demarredisplaymath", "demarredmath", "demarredocument", "demarreeffect", "demarreelement", "demarreembeddedxtable", "demarreendnote", "demarreendofline", "demarreenvironement", "demarreexceptions", "demarreexpanded", "demarreexpandedcollect", "demarreextendedcatcodetable", "demarreexternalfigurecollection", "demarrefact", "demarrefigure", "demarrefiguretext", "demarrefittingpage", "demarrefixed", "demarrefloatcombination", "demarrefont", "demarrefontclass", "demarrefontsolution", "demarrefootnote", "demarreformula", "demarreformulas", "demarreframed", "demarreframedcell", "demarreframedcontent", "demarreframedrow", "demarreframedtable", "demarreframedtext", "demarrefrontmatter", "demarregraphictext", "demarregridsnapping", "demarregroupe", "demarrehanging", "demarrehbox", "demarrehboxestohbox", "demarrehboxregister", "demarreheadtext", "demarrehelptext", "demarrehiding", "demarrehighlight", "demarrehyphenation", "demarreimath", "demarreindentation", "demarreindentedtext", "demarreinteraction", "demarreinterface", "demarreintermezzotext", "demarreintertext", "demarreitemgroup", "demarreitemgroupcolumns", "demarreitemize", "demarreknockout", "demarrelabeltext", "demarrelayout", "demarrelegend", "demarreligne", "demarreligneregleetexte", "demarrelinealignment", "demarrelinecorrection", "demarrelinefiller", "demarrelinenumbering", "demarrelines", "demarrelinetable", "demarrelinetablebody", "demarrelinetablecell", "demarrelinetablehead", "demarrelocalfootnotes", "demarrelocalheadsetup", "demarrelocallinecorrection", "demarrelocalnotes", "demarrelocalsetups", "demarrelua", "demarreluacode", "demarreluaparameterset", "demarreluasetups", "demarremakeup", "demarremargereglee", "demarremarginblock", "demarremarkedcontent", "demarremathalignment", "demarremathcases", "demarremathlabeltext", "demarremathmatrix", "demarremathmode", "demarremathstyle", "demarrematrices", "demarrematrix", "demarremaxaligned", "demarremdformula", "demarremenuinteraction", "demarremiddlealigned", "demarremiddlemakeup", "demarremixedcolumns", "demarremode", "demarremodeset", "demarremodule", "demarremoduletestsection", "demarrempformula", "demarrenamedsection", "demarrenamedsubformulas", "demarrenarrow", "demarrenarrower", "demarrenegative", "demarrenicelyfilledbox", "demarrenointerference", "demarrenotallmodes", "demarrenotext", "demarrenotmode", "demarreoperatortext", "demarreopposite", "demarreoutputstream", "demarreoverlay", "demarreoverprint", "demarrepagecomment", "demarrepagefigure", "demarrepagegrid", "demarrepagegridspan", "demarrepagelayout", "demarrepagemakeup", "demarrepar", "demarreparagraph", "demarreparagraphs", "demarreparagraphscell", "demarreparbuilder", "demarrepart", "demarrepath", "demarreplacechemical", "demarreplacefigure", "demarreplaceflottant", "demarreplaceformule", "demarreplacegraphic", "demarreplaceintermezzo", "demarreplacelegend", "demarreplacepairedbox", "demarreplacetable", "demarrepositioning", "demarrepositionoverlay", "demarrepositive", "demarrepostponing", "demarreprefixtext", "demarreprocessassignmentcommand", "demarreprocessassignmentlist", "demarreprocesscommacommand", "demarreprocesscommalist", "demarreproduit", "demarreprojet", "demarreprotect", "demarreprotectedcolors", "demarrepublication", "demarrepunctuation", "demarrequotation", "demarrequote", "demarrerandomized", "demarrerandomseed", "demarrerawsetups", "demarrereadingfile", "demarrereferenceprefix", "demarreregime", "demarrereusableMPgraphic", "demarrescript", "demarresdformula", "demarresection", "demarresectionblock", "demarresectionblockenvironment", "demarresectionlevel", "demarresetups", "demarreshapebox", "demarreshift", "demarresidebar", "demarresimplecolumns", "demarrespecialitem", "demarrespeech", "demarrespformula", "demarresplitformula", "demarrespread", "demarrestandardmakeup", "demarrestartstop", "demarrestaticMPfigure", "demarrestaticMPgraphic", "demarrestrictinspectnextcharacter", "demarrestrut", "demarrestyle", "demarresubformulas", "demarresubject", "demarresubjectlevel", "demarresubsection", "demarresubsentence", "demarresubstack", "demarresubsubject", "demarresubsubsection", "demarresubsubsubject", "demarresubsubsubsection", "demarresubsubsubsubject", "demarresubsubsubsubsection", "demarresubsubsubsubsubject", "demarresuffixtext", "demarresymbolset", "demarretable", "demarretablehead", "demarretables", "demarretabletail", "demarretabletext", "demarretabulate", "demarretabulatehead", "demarretabulatetail", "demarretagged", "demarretaglabeltext", "demarretete", "demarretexcode", "demarretexdefinition", "demarretext", "demarretextbackground", "demarretextbackgroundmanual", "demarretextcolor", "demarretextcolorintent", "demarretextflow", "demarretextmakeup", "demarretitle", "demarretokens", "demarretransparent", "demarretypescript", "demarretypescriptcollection", "demarretyping", "demarreuniqueMPgraphic", "demarreuniqueMPpagegraphic", "demarreunittext", "demarreunpacked", "demarreusableMPgraphic", "demarreuseMPgraphic", "demarreusemathstyleparameter", "demarreusingbtxspecification", "demarreva", "demarrevbox", "demarrevboxregister", "demarrevboxtohbox", "demarrevboxtohboxseparator", "demarreviewerlayer", "demarrevtop", "demarrevtopregister", "demarrexcell", "demarrexcellgroup", "demarrexgroup", "demarrexmldisplayverbatim", "demarrexmlinlineverbatim", "demarrexmlraw", "demarrexmlsetups", "demarrexrow", "demarrexrowgroup", "demarrextable", "demarrextablebody", "demarrextablefoot", "demarrextablehead", "demarrextablenext", "determinecaracteristiqueliste", "determinecaracteristiquesregistre", "determinenumerotete", "echelle", "ecran", "ecritdansliste", "ecritentreliste", "element", "elements", "environement", "espace", "espacefixe", "espacesfixes", "etire", "faitreference", "fichierdactylo", "figureexterne", "gardeblocs", "grille", "haut", "inconnu", "installelangue", "joursemaine", "langue", "langueprincipale", "largeurligne", "ligneh", "lignenoire", "ligneregleetexte", "lignesnoires", "llongueurliste", "marquage", "marquepage", "mathematique", "menuinteraction", "mois", "montrecadre", "montrecouleur", "montredisposition", "montreedition", "montreenvironnementpolicecorps", "montregrille", "montregroupecouleur", "montrejeusymboles", "montremakeup", "montrepalette", "montrepolicecorps", "montrereglages", "montrestruts", "motdroit", "numeroformule", "numeropage", "numeros", "numerotete", "numerotetecourant", "obtientmarquage", "oriente", "periodes", "pilechamp", "placecoteacote", "placeflottant", "placeformule", "placelesunsaudessusdesautres", "placeliste", "placelisteinmbriquee", "placemarquespages", "placenotespdp", "placenotespdplocales", "placenumeropage", "placenumerotete", "placeregistre", "placesousformule", "placesurgrille", "placetextetete", "prendbuffer", "produit", "programme", "projet", "qqpart", "razmarquage", "referencepage", "referencetexte", "reflete", "reglealignement", "reglearrangement", "reglearriereplan", "reglearriereplans", "reglebarreinteraction", "reglebloc", "regleblocsection", "reglebuffer", "reglecapitales", "reglechamp", "reglechamps", "regleclipping", "reglecolonnes", "reglecommentaire", "reglecommentairepage", "reglecompoetroite", "reglecomposeenalinea", "reglecouleur", "reglecouleurs", "regledactylo", "regledemarrestoppe", "regledisposition", "regleecraninteraction", "regleelements", "regleencadre", "regleentete", "regleenumerations", "regleepaisseurligne", "regleespaceblanc", "regleespacement", "regleespacementinterligne", "regleflottant", "regleflottants", "regleformulaires", "regleformules", "reglegroupeselements", "regleinf", "regleinteraction", "regleintitule", "regleintitules", "reglejeusymboles", "reglelangue", "reglelignes", "reglelignesnoires", "reglelignesreglestexte", "regleliste", "reglelisteimbriquee", "reglemakeup", "reglemargereglee", "reglemarquage", "reglemarquagehyphenation", "reglemenuinteraction", "reglenumeropage", "reglenumerotationligne", "reglenumerotationpage", "reglenumerotationparagraphe", "reglenumerotete", "regleoriente", "reglepalette", "reglepapier", "regleparagraphes", "reglepdp", "regleplacementopposition", "reglepolicecorps", "reglepositionnement", "regleprogrammes", "reglereferencage", "regleregistre", "regleremplitligne", "regleremplitlignesreglees", "regleseparationflottant", "reglesousnumeropage", "reglesup", "reglesynonymes", "regletableaux", "regletabulation", "regletaillepapier", "regletete", "regletetes", "regletexte", "regletextesentete", "regletextesinf", "regletextespdp", "regletextessup", "regletextestexte", "regletolerance", "regletraitsfins", "regletransitionspage", "regletri", "regletype", "regleurl", "remplitligne", "remplitlignesreglees", "remplittexte", "sansespace", "sanslignesenteteetpdp", "sanslignessupetinf", "selectionneblocs", "separeflottant", "settext", "sousnumeropage", "stoppeJScode", "stoppeJSpreamble", "stoppeLUA", "stoppeMP", "stoppeMPclip", "stoppeMPcode", "stoppeMPdefinitions", "stoppeMPdrawing", "stoppeMPenvironment", "stoppeMPextensions", "stoppeMPinclusions", "stoppeMPinitializations", "stoppeMPpage", "stoppeMPpositiongraphic", "stoppeMPpositionmethod", "stoppeMPrun", "stoppePARSEDXML", "stoppeTABLE", "stoppeTABLEbody", "stoppeTABLEfoot", "stoppeTABLEhead", "stoppeTABLEnext", "stoppeTC", "stoppeTD", "stoppeTDs", "stoppeTEX", "stoppeTEXpage", "stoppeTH", "stoppeTN", "stoppeTR", "stoppeTRs", "stoppeTX", "stoppeTY", "stoppeXML", "stoppealign", "stoppealigneadroite", "stoppealigneagauche", "stoppealigneaumilieu", "stoppealignment", "stoppeallmodes", "stoppeappendices", "stoppearrangedpages", "stoppearriereplan", "stoppeaside", "stoppeattachment", "stoppebackmatter", "stoppebar", "stoppebbordermatrix", "stoppebitmapimage", "stoppeblockquote", "stoppebodymatter", "stoppebordermatrix", "stoppeboxedcolumns", "stoppebtxlabeltext", "stoppebtxrenderingdefinitions", "stoppebuffer", "stoppecases", "stoppecatcodetable", "stoppecenteraligned", "stoppechapter", "stoppecharacteralign", "stoppecheckedfences", "stoppechemical", "stoppechemicaltext", "stoppecollect", "stoppecollecting", "stoppecolorintent", "stoppecoloronly", "stoppecolorset", "stoppecolumns", "stoppecolumnspan", "stoppecombination", "stoppecomment", "stoppecomposant", "stoppecontextcode", "stoppecontextdefinitioncode", "stoppecouleur", "stoppectxfunction", "stoppectxfunctiondefinition", "stoppecurrentcolor", "stoppecurrentlistentrywrapper", "stoppedelimited", "stoppedelimitedtext", "stoppedisplaymath", "stoppedmath", "stoppedocument", "stoppeeffect", "stoppeelement", "stoppeembeddedxtable", "stoppeendnote", "stoppeendofline", "stoppeenvironement", "stoppeexceptions", "stoppeexpanded", "stoppeexpandedcollect", "stoppeextendedcatcodetable", "stoppeexternalfigurecollection", "stoppefact", "stoppefigure", "stoppefiguretext", "stoppefittingpage", "stoppefixed", "stoppefloatcombination", "stoppefont", "stoppefontclass", "stoppefontsolution", "stoppefootnote", "stoppeformula", "stoppeformulas", "stoppeframed", "stoppeframedcell", "stoppeframedcontent", "stoppeframedrow", "stoppeframedtable", "stoppeframedtext", "stoppefrontmatter", "stoppegraphictext", "stoppegridsnapping", "stoppegroupe", "stoppehanging", "stoppehbox", "stoppehboxestohbox", "stoppehboxregister", "stoppeheadtext", "stoppehelptext", "stoppehiding", "stoppehighlight", "stoppehyphenation", "stoppeimath", "stoppeindentation", "stoppeindentedtext", "stoppeinteraction", "stoppeinterface", "stoppeintermezzotext", "stoppeintertext", "stoppeitemgroup", "stoppeitemgroupcolumns", "stoppeitemize", "stoppeknockout", "stoppelabeltext", "stoppelayout", "stoppelegend", "stoppeligne", "stoppeligneregleetexte", "stoppelinealignment", "stoppelinecorrection", "stoppelinefiller", "stoppelinenumbering", "stoppelines", "stoppelinetable", "stoppelinetablebody", "stoppelinetablecell", "stoppelinetablehead", "stoppelocalfootnotes", "stoppelocalheadsetup", "stoppelocallinecorrection", "stoppelocalnotes", "stoppelocalsetups", "stoppelua", "stoppeluacode", "stoppeluaparameterset", "stoppeluasetups", "stoppemakeup", "stoppemargereglee", "stoppemarginblock", "stoppemarkedcontent", "stoppemathalignment", "stoppemathcases", "stoppemathlabeltext", "stoppemathmatrix", "stoppemathmode", "stoppemathstyle", "stoppematrices", "stoppematrix", "stoppemaxaligned", "stoppemdformula", "stoppemenuinteraction", "stoppemiddlealigned", "stoppemiddlemakeup", "stoppemixedcolumns", "stoppemode", "stoppemodeset", "stoppemodule", "stoppemoduletestsection", "stoppempformula", "stoppenamedsection", "stoppenamedsubformulas", "stoppenarrow", "stoppenarrower", "stoppenegative", "stoppenicelyfilledbox", "stoppenointerference", "stoppenotallmodes", "stoppenotext", "stoppenotmode", "stoppeoperatortext", "stoppeopposite", "stoppeoutputstream", "stoppeoverlay", "stoppeoverprint", "stoppepagecomment", "stoppepagefigure", "stoppepagegrid", "stoppepagegridspan", "stoppepagelayout", "stoppepagemakeup", "stoppepar", "stoppeparagraph", "stoppeparagraphs", "stoppeparagraphscell", "stoppeparbuilder", "stoppepart", "stoppepath", "stoppeplacechemical", "stoppeplacefigure", "stoppeplaceflottant", "stoppeplaceformule", "stoppeplacegraphic", "stoppeplaceintermezzo", "stoppeplacelegend", "stoppeplacepairedbox", "stoppeplacetable", "stoppepositioning", "stoppepositionoverlay", "stoppepositive", "stoppepostponing", "stoppeprefixtext", "stoppeprocessassignmentcommand", "stoppeprocessassignmentlist", "stoppeprocesscommacommand", "stoppeprocesscommalist", "stoppeproduit", "stoppeprojet", "stoppeprotect", "stoppeprotectedcolors", "stoppepublication", "stoppepunctuation", "stoppequotation", "stoppequote", "stopperandomized", "stopperandomseed", "stopperawsetups", "stoppereadingfile", "stoppereferenceprefix", "stopperegime", "stoppereusableMPgraphic", "stoppescript", "stoppesdformula", "stoppesection", "stoppesectionblock", "stoppesectionblockenvironment", "stoppesectionlevel", "stoppesetups", "stoppeshapebox", "stoppeshift", "stoppesidebar", "stoppesimplecolumns", "stoppespecialitem", "stoppespeech", "stoppespformula", "stoppesplitformula", "stoppespread", "stoppestandardmakeup", "stoppestartstop", "stoppestaticMPfigure", "stoppestaticMPgraphic", "stoppestrictinspectnextcharacter", "stoppestrut", "stoppestyle", "stoppesubformulas", "stoppesubject", "stoppesubjectlevel", "stoppesubsection", "stoppesubsentence", "stoppesubstack", "stoppesubsubject", "stoppesubsubsection", "stoppesubsubsubject", "stoppesubsubsubsection", "stoppesubsubsubsubject", "stoppesubsubsubsubsection", "stoppesubsubsubsubsubject", "stoppesuffixtext", "stoppesymbolset", "stoppetable", "stoppetablehead", "stoppetables", "stoppetabletail", "stoppetabletext", "stoppetabulate", "stoppetabulatehead", "stoppetabulatetail", "stoppetagged", "stoppetaglabeltext", "stoppetete", "stoppetexcode", "stoppetexdefinition", "stoppetext", "stoppetextbackground", "stoppetextbackgroundmanual", "stoppetextcolor", "stoppetextcolorintent", "stoppetextflow", "stoppetextmakeup", "stoppetitle", "stoppetokens", "stoppetransparent", "stoppetypescript", "stoppetypescriptcollection", "stoppetyping", "stoppeuniqueMPgraphic", "stoppeuniqueMPpagegraphic", "stoppeunittext", "stoppeunpacked", "stoppeusableMPgraphic", "stoppeuseMPgraphic", "stoppeusemathstyleparameter", "stoppeusingbtxspecification", "stoppeva", "stoppevbox", "stoppevboxregister", "stoppevboxtohbox", "stoppevboxtohboxseparator", "stoppeviewerlayer", "stoppevtop", "stoppevtopregister", "stoppexcell", "stoppexcellgroup", "stoppexgroup", "stoppexmldisplayverbatim", "stoppexmlinlineverbatim", "stoppexmlraw", "stoppexmlsetups", "stoppexrow", "stoppexrowgroup", "stoppextable", "stoppextablebody", "stoppextablefoot", "stoppextablehead", "stoppextablenext", "symbole", "tapebuffer", "textenotepdp", "traduire", "traiteblocs", "traitfin", "traitsfins", "uneligne", "utiliseJSscripts", "utiliseURL", "utiliseblocs", "utilisechemin", "utilisedocumentexterne", "utilisefigureexterne", "utilisemodule", "utilisepsiteaudioexterne", "utilisesymboles", "utiliseurl", "va", "vaalaboite", "vaalapage", "vaenbas", "valeurcouleur", "vide" },
- ["it"]={ "GIORNOSETTIMANA", "Lettera", "Lettere", "MESE", "Numeri", "Numeriromani", "PAROLA", "PAROLE", "Parola", "Parole", "adattacampo", "adattalayout", "al", "allineacentro", "allineadestra", "allineasinistra", "ambiente", "ap", "apagina", "barracolori", "barrainterazione", "cambiaafontdeltesto", "campi", "capello", "chim", "circondato", "clonacampo", "colonna", "colore", "coloregrigio", "commento", "componenet", "confrontagruppocolori", "confrontatavolozza", "convertinumero", "copiacampo", "correggispaziobianco", "da", "daqualcheparte", "data", "datadioggi", "definisci", "definisciaccento", "definisciambientefontdeltesto", "definisciblocco", "definiscibloccosezione", "definiscibuffer", "definiscicampo", "definiscicapoversi", "definiscicarattere", "definiscicolore", "definiscicomando", "definisciconversione", "definiscidescrizione", "definiscidimensionicarta", "definiscielenco", "definiscielencocombinato", "definiscienumerazione", "definiscietichetta", "definiscifigurasimbolo", "definiscifont", "definiscifontdeltesto", "definisciformatoriferimento", "definiscigruppocolori", "definiscihbox", "definisciincorniciato", "definisciiniziatermina", "definiscilayout", "definiscimakeup", "definiscimarcatura", "definiscimenuinterazione", "definiscimodellotabella", "definiscioggettomobile", "definisciordinamento", "definisciprofilo", "definisciprogramma", "definisciregistro", "definisciriferimento", "definiscisezione", "definiscisimbolo", "definiscisinonimi", "definiscisinonimofont", "definiscisottocampo", "definiscisovrapposizione", "definiscistackcampi", "definiscistile", "definiscistilefont", "definiscitabulato", "definiscitavolozza", "definiscitesta", "definiscitesto", "definiscitestoincorniciato", "definiscitype", "definiscityping", "determinacaratteristicheregistro", "determinacarattersticheelenco", "determinanumerotesta", "elaborablocchi", "elementi", "elemento", "figuraesterna", "giornosettimana", "griglia", "ignoto", "impostaallineamento", "impostaampiezzariga", "impostabarrainterazione", "impostablocco", "impostabloccosezione", "impostabuffer", "impostacampi", "impostacampo", "impostacapoversi", "impostacaption", "impostacaptions", "impostacima", "impostaclippling", "impostacolonne", "impostacolore", "impostacolori", "impostacommento", "impostacommentopagina", "impostadimensionicarta", "impostaelementi", "impostaelencazioni", "impostaelenco", "impostaelencocombinato", "impostaenumerazioni", "impostafondo", "impostafontdeltesto", "impostaforms", "impostaformule", "impostaincorniciato", "impostainiziatermina", "impostainstestazione", "impostainterazione", "impostainterlinea", "impostalayout", "impostalineemargine", "impostalineenere", "impostalineeriempimento", "impostalineesottili", "impostalineetesto", "impostalingua", "impostamaiuscole", "impostamakeup", "impostamarcatura", "impostamenuinterazione", "impostamenzione", "impostanumerazionecapoversi", "impostanumerazionepagina", "impostanumerazionerighe", "impostanumeropagina", "impostanumerosottopagina", "impostanumerotesta", "impostaoggettimobili", "impostaoggettomobile", "impostaordinamento", "impostaparranging", "impostapdp", "impostapiustretto", "impostaposizionamento", "impostaposizionamentoopposti", "impostaprogrammi", "impostaregistro", "impostarientro", "impostariferimento", "impostarighe", "impostarigheriempimento", "impostarigovuoto", "impostarotazione", "impostaschermointerazione", "impostasegnosillabazione", "impostasetsimboli", "impostasfondi", "impostasfondo", "impostasinonimi", "impostaspaziatura", "impostaspaziobianco", "impostaspezzamentooggettomobile", "impostatabelle", "impostatabulato", "impostatavolozza", "impostatesta", "impostateste", "impostatesticima", "impostatestifondo", "impostatestiincorniciati", "impostatestiintestazioni", "impostatestipdp", "impostatesto", "impostatestotesti", "impostatolleranza", "impostatransizionepagina", "impostatype", "impostatyping", "impostaurl", "incorniciato", "iniziaJScode", "iniziaJSpreamble", "iniziaLUA", "iniziaMP", "iniziaMPclip", "iniziaMPcode", "iniziaMPdefinitions", "iniziaMPdrawing", "iniziaMPenvironment", "iniziaMPextensions", "iniziaMPinclusions", "iniziaMPinitializations", "iniziaMPpage", "iniziaMPpositiongraphic", "iniziaMPpositionmethod", "iniziaMPrun", "iniziaPARSEDXML", "iniziaTABLE", "iniziaTABLEbody", "iniziaTABLEfoot", "iniziaTABLEhead", "iniziaTABLEnext", "iniziaTC", "iniziaTD", "iniziaTDs", "iniziaTEX", "iniziaTEXpage", "iniziaTH", "iniziaTN", "iniziaTR", "iniziaTRs", "iniziaTX", "iniziaTY", "iniziaXML", "iniziaalign", "iniziaalignment", "iniziaallineacentro", "iniziaallineadestra", "iniziaallineasinistra", "iniziaallmodes", "iniziaambiente", "iniziaappendices", "iniziaarrangedpages", "iniziaaside", "iniziaattachment", "iniziabackmatter", "iniziabar", "iniziabbordermatrix", "iniziabitmapimage", "iniziablockquote", "iniziabodymatter", "iniziabordermatrix", "iniziaboxedcolumns", "iniziabtxlabeltext", "iniziabtxrenderingdefinitions", "iniziabuffer", "iniziacases", "iniziacatcodetable", "iniziacenteraligned", "iniziachapter", "iniziacharacteralign", "iniziacheckedfences", "iniziachemical", "iniziachemicaltext", "iniziacollect", "iniziacollecting", "iniziacolore", "iniziacolorintent", "iniziacoloronly", "iniziacolorset", "iniziacolumns", "iniziacolumnspan", "iniziacombination", "iniziacomment", "iniziacomponenet", "iniziacontextcode", "iniziacontextdefinitioncode", "iniziactxfunction", "iniziactxfunctiondefinition", "iniziacurrentcolor", "iniziacurrentlistentrywrapper", "iniziadelimited", "iniziadelimitedtext", "iniziadisplaymath", "iniziadmath", "iniziadocument", "iniziaeffect", "iniziaelement", "iniziaelemento", "iniziaembeddedxtable", "iniziaendnote", "iniziaendofline", "iniziaexceptions", "iniziaexpanded", "iniziaexpandedcollect", "iniziaextendedcatcodetable", "iniziaexternalfigurecollection", "iniziafact", "iniziafigure", "iniziafiguretext", "iniziafittingpage", "iniziafixed", "iniziafloatcombination", "iniziafont", "iniziafontclass", "iniziafontsolution", "iniziafootnote", "iniziaformula", "iniziaformulas", "iniziaframedcell", "iniziaframedcontent", "iniziaframedrow", "iniziaframedtable", "iniziaframedtext", "iniziafrontmatter", "iniziagraphictext", "iniziagridsnapping", "iniziahanging", "iniziahbox", "iniziahboxestohbox", "iniziahboxregister", "iniziaheadtext", "iniziahelptext", "iniziahiding", "iniziahighlight", "iniziahyphenation", "iniziaimath", "iniziaimpaccato", "iniziaincorniciato", "iniziaindentation", "iniziaindentedtext", "iniziainteraction", "iniziainterface", "iniziaintermezzotext", "iniziaintertext", "iniziaitemgroup", "iniziaitemgroupcolumns", "iniziaitemize", "iniziaknockout", "inizialabeltext", "inizialayout", "inizialegend", "inizialinealignment", "inizialineamargine", "inizialineatesto", "inizialinecorrection", "inizialinefiller", "inizialinenumbering", "inizialines", "inizialinetable", "inizialinetablebody", "inizialinetablecell", "inizialinetablehead", "inizialocalfootnotes", "inizialocalheadsetup", "inizialocallinecorrection", "inizialocalnotes", "inizialocalsetups", "inizialua", "inizialuacode", "inizialuaparameterset", "inizialuasetups", "iniziamakeup", "iniziamarginblock", "iniziamarkedcontent", "iniziamathalignment", "iniziamathcases", "iniziamathlabeltext", "iniziamathmatrix", "iniziamathmode", "iniziamathstyle", "iniziamatrices", "iniziamatrix", "iniziamaxaligned", "iniziamdformula", "iniziamenuinterattivo", "iniziamettiformula", "iniziamiddlealigned", "iniziamiddlemakeup", "iniziamixedcolumns", "iniziamode", "iniziamodeset", "iniziamodule", "iniziamoduletestsection", "iniziampformula", "inizianamedsection", "inizianamedsubformulas", "inizianarrow", "inizianarrower", "inizianegative", "inizianicelyfilledbox", "inizianointerference", "inizianotallmodes", "inizianotext", "inizianotmode", "iniziaoperatortext", "iniziaopposite", "iniziaoutputstream", "iniziaoverlay", "iniziaoverprint", "iniziapagecomment", "iniziapagefigure", "iniziapagegrid", "iniziapagegridspan", "iniziapagelayout", "iniziapagemakeup", "iniziapar", "iniziaparagraph", "iniziaparagraphs", "iniziaparagraphscell", "iniziaparbuilder", "iniziapart", "iniziapath", "iniziaplacechemical", "iniziaplacefigure", "iniziaplacefloat", "iniziaplacegraphic", "iniziaplaceintermezzo", "iniziaplacelegend", "iniziaplacepairedbox", "iniziaplacetable", "iniziapositioning", "iniziapositionoverlay", "iniziapositive", "iniziapostponing", "iniziaprefixtext", "iniziaprocessassignmentcommand", "iniziaprocessassignmentlist", "iniziaprocesscommacommand", "iniziaprocesscommalist", "iniziaprodotto", "iniziaprogetto", "iniziaprotect", "iniziaprotectedcolors", "iniziapubblicazione", "iniziapunctuation", "iniziaquotation", "iniziaquote", "iniziarandomized", "iniziarandomseed", "iniziarawsetups", "iniziareadingfile", "iniziareferenceprefix", "iniziaregime", "iniziareusableMPgraphic", "iniziariga", "iniziascript", "iniziasdformula", "iniziasection", "iniziasectionblock", "iniziasectionblockenvironment", "iniziasectionlevel", "iniziasetups", "iniziasfondo", "iniziashapebox", "iniziashift", "iniziasidebar", "iniziasimplecolumns", "iniziaspecialitem", "iniziaspeech", "iniziaspformula", "iniziasplitformula", "iniziaspread", "iniziastandardmakeup", "iniziastartstop", "iniziastaticMPfigure", "iniziastaticMPgraphic", "iniziastrictinspectnextcharacter", "iniziastrut", "iniziastyle", "iniziasubformulas", "iniziasubject", "iniziasubjectlevel", "iniziasubsection", "iniziasubsentence", "iniziasubstack", "iniziasubsubject", "iniziasubsubsection", "iniziasubsubsubject", "iniziasubsubsubsection", "iniziasubsubsubsubject", "iniziasubsubsubsubsection", "iniziasubsubsubsubsubject", "iniziasuffixtext", "iniziasymbolset", "iniziatable", "iniziatablehead", "iniziatables", "iniziatabletail", "iniziatabletext", "iniziatabulate", "iniziatabulatehead", "iniziatabulatetail", "iniziatagged", "iniziataglabeltext", "iniziatesta", "iniziatexcode", "iniziatexdefinition", "iniziatext", "iniziatextbackground", "iniziatextbackgroundmanual", "iniziatextcolor", "iniziatextcolorintent", "iniziatextflow", "iniziatextmakeup", "iniziatitle", "iniziatokens", "iniziatransparent", "iniziatypescript", "iniziatypescriptcollection", "iniziatyping", "iniziauniqueMPgraphic", "iniziauniqueMPpagegraphic", "iniziaunittext", "iniziaunpacked", "iniziausableMPgraphic", "iniziauseMPgraphic", "iniziausemathstyleparameter", "iniziausingbtxspecification", "iniziavaia", "iniziavbox", "iniziavboxregister", "iniziavboxtohbox", "iniziavboxtohboxseparator", "iniziaviewerlayer", "iniziavtop", "iniziavtopregister", "iniziaxcell", "iniziaxcellgroup", "iniziaxgroup", "iniziaxmldisplayverbatim", "iniziaxmlinlineverbatim", "iniziaxmlraw", "iniziaxmlsetups", "iniziaxrow", "iniziaxrowgroup", "iniziaxtable", "iniziaxtablebody", "iniziaxtablefoot", "iniziaxtablehead", "iniziaxtablenext", "inriga", "installalingua", "intorno", "lettera", "lettere", "lineanera", "lineasottile", "lineatesto", "lineenere", "lineeriempimento", "lineesottili", "lingua", "linguaprincipale", "lunghezzaelenco", "marcatura", "matematica", "menuinterattivo", "mese", "mettielenco", "mettielencocombinato", "mettifiancoafianco", "mettiformula", "mettiingriglia", "mettinotepdp", "mettinotepdplocali", "mettinumeropagina", "mettiregistro", "mettisegnalibro", "mettisottoformula", "mettiunosullaltro", "mostraambientefontdeltesto", "mostracolore", "mostracornice", "mostrafontdeltesto", "mostragriglia", "mostragruppocolori", "mostraimpostazioni", "mostralyout", "mostramakeup", "mostrasetsimboli", "mostrastampa", "mostrastruts", "mostratavolozza", "nascondiblocchi", "nientelineecimafondo", "nientelineintestazionepdp", "nientespazio", "nota", "numeri", "numeriromani", "numeroformula", "numeropagina", "numeropaginacompleto", "numerotesta", "numerotestacorrente", "pagina", "paroladestra", "ped", "pedap", "perlungo", "posizionanumerotesta", "posizionatestotesta", "posizione", "prendibuffer", "prendimarcatura", "prodotto", "progetto", "programma", "pulsante", "pulsantemenu", "pulsantinterazione", "punti", "qualcheriga", "reimpostamarcatura", "rif", "riferimento", "riferimentopagina", "riferimentotesto", "riflessione", "rigariempimento", "rigovuoto", "ruota", "scala", "schermo", "scrividentroelenco", "scriviinelenco", "segnalibro", "selezionablocchi", "settext", "sfondo", "simbolo", "spazifissi", "spazio", "spaziofisso", "spessoreriga", "spezzaoggettomobile", "stackcampi", "stirato", "terminaJScode", "terminaJSpreamble", "terminaLUA", "terminaMP", "terminaMPclip", "terminaMPcode", "terminaMPdefinitions", "terminaMPdrawing", "terminaMPenvironment", "terminaMPextensions", "terminaMPinclusions", "terminaMPinitializations", "terminaMPpage", "terminaMPpositiongraphic", "terminaMPpositionmethod", "terminaMPrun", "terminaPARSEDXML", "terminaTABLE", "terminaTABLEbody", "terminaTABLEfoot", "terminaTABLEhead", "terminaTABLEnext", "terminaTC", "terminaTD", "terminaTDs", "terminaTEX", "terminaTEXpage", "terminaTH", "terminaTN", "terminaTR", "terminaTRs", "terminaTX", "terminaTY", "terminaXML", "terminaalign", "terminaalignment", "terminaallineacentro", "terminaallineadestra", "terminaallineasinistra", "terminaallmodes", "terminaambiente", "terminaappendices", "terminaarrangedpages", "terminaaside", "terminaattachment", "terminabackmatter", "terminabar", "terminabbordermatrix", "terminabitmapimage", "terminablockquote", "terminabodymatter", "terminabordermatrix", "terminaboxedcolumns", "terminabtxlabeltext", "terminabtxrenderingdefinitions", "terminabuffer", "terminacases", "terminacatcodetable", "terminacenteraligned", "terminachapter", "terminacharacteralign", "terminacheckedfences", "terminachemical", "terminachemicaltext", "terminacollect", "terminacollecting", "terminacolore", "terminacolorintent", "terminacoloronly", "terminacolorset", "terminacolumns", "terminacolumnspan", "terminacombination", "terminacomment", "terminacomponenet", "terminacontextcode", "terminacontextdefinitioncode", "terminactxfunction", "terminactxfunctiondefinition", "terminacurrentcolor", "terminacurrentlistentrywrapper", "terminadelimited", "terminadelimitedtext", "terminadisplaymath", "terminadmath", "terminadocument", "terminaeffect", "terminaelement", "terminaelemento", "terminaembeddedxtable", "terminaendnote", "terminaendofline", "terminaexceptions", "terminaexpanded", "terminaexpandedcollect", "terminaextendedcatcodetable", "terminaexternalfigurecollection", "terminafact", "terminafigure", "terminafiguretext", "terminafittingpage", "terminafixed", "terminafloatcombination", "terminafont", "terminafontclass", "terminafontsolution", "terminafootnote", "terminaformula", "terminaformulas", "terminaframedcell", "terminaframedcontent", "terminaframedrow", "terminaframedtable", "terminaframedtext", "terminafrontmatter", "terminagraphictext", "terminagridsnapping", "terminahanging", "terminahbox", "terminahboxestohbox", "terminahboxregister", "terminaheadtext", "terminahelptext", "terminahiding", "terminahighlight", "terminahyphenation", "terminaimath", "terminaimpaccato", "terminaincorniciato", "terminaindentation", "terminaindentedtext", "terminainteraction", "terminainterface", "terminaintermezzotext", "terminaintertext", "terminaitemgroup", "terminaitemgroupcolumns", "terminaitemize", "terminaknockout", "terminalabeltext", "terminalayout", "terminalegend", "terminalinealignment", "terminalineamargine", "terminalineatesto", "terminalinecorrection", "terminalinefiller", "terminalinenumbering", "terminalines", "terminalinetable", "terminalinetablebody", "terminalinetablecell", "terminalinetablehead", "terminalocalfootnotes", "terminalocalheadsetup", "terminalocallinecorrection", "terminalocalnotes", "terminalocalsetups", "terminalua", "terminaluacode", "terminaluaparameterset", "terminaluasetups", "terminamakeup", "terminamarginblock", "terminamarkedcontent", "terminamathalignment", "terminamathcases", "terminamathlabeltext", "terminamathmatrix", "terminamathmode", "terminamathstyle", "terminamatrices", "terminamatrix", "terminamaxaligned", "terminamdformula", "terminamenuinterattivo", "terminamettiformula", "terminamiddlealigned", "terminamiddlemakeup", "terminamixedcolumns", "terminamode", "terminamodeset", "terminamodule", "terminamoduletestsection", "terminampformula", "terminanamedsection", "terminanamedsubformulas", "terminanarrow", "terminanarrower", "terminanegative", "terminanicelyfilledbox", "terminanointerference", "terminanotallmodes", "terminanotext", "terminanotmode", "terminaoperatortext", "terminaopposite", "terminaoutputstream", "terminaoverlay", "terminaoverprint", "terminapagecomment", "terminapagefigure", "terminapagegrid", "terminapagegridspan", "terminapagelayout", "terminapagemakeup", "terminapar", "terminaparagraph", "terminaparagraphs", "terminaparagraphscell", "terminaparbuilder", "terminapart", "terminapath", "terminaplacechemical", "terminaplacefigure", "terminaplacefloat", "terminaplacegraphic", "terminaplaceintermezzo", "terminaplacelegend", "terminaplacepairedbox", "terminaplacetable", "terminapositioning", "terminapositionoverlay", "terminapositive", "terminapostponing", "terminaprefixtext", "terminaprocessassignmentcommand", "terminaprocessassignmentlist", "terminaprocesscommacommand", "terminaprocesscommalist", "terminaprodotto", "terminaprogetto", "terminaprotect", "terminaprotectedcolors", "terminapubblicazione", "terminapunctuation", "terminaquotation", "terminaquote", "terminarandomized", "terminarandomseed", "terminarawsetups", "terminareadingfile", "terminareferenceprefix", "terminaregime", "terminareusableMPgraphic", "terminariga", "terminascript", "terminasdformula", "terminasection", "terminasectionblock", "terminasectionblockenvironment", "terminasectionlevel", "terminasetups", "terminasfondo", "terminashapebox", "terminashift", "terminasidebar", "terminasimplecolumns", "terminaspecialitem", "terminaspeech", "terminaspformula", "terminasplitformula", "terminaspread", "terminastandardmakeup", "terminastartstop", "terminastaticMPfigure", "terminastaticMPgraphic", "terminastrictinspectnextcharacter", "terminastrut", "terminastyle", "terminasubformulas", "terminasubject", "terminasubjectlevel", "terminasubsection", "terminasubsentence", "terminasubstack", "terminasubsubject", "terminasubsubsection", "terminasubsubsubject", "terminasubsubsubsection", "terminasubsubsubsubject", "terminasubsubsubsubsection", "terminasubsubsubsubsubject", "terminasuffixtext", "terminasymbolset", "terminatable", "terminatablehead", "terminatables", "terminatabletail", "terminatabletext", "terminatabulate", "terminatabulatehead", "terminatabulatetail", "terminatagged", "terminataglabeltext", "terminatesta", "terminatexcode", "terminatexdefinition", "terminatext", "terminatextbackground", "terminatextbackgroundmanual", "terminatextcolor", "terminatextcolorintent", "terminatextflow", "terminatextmakeup", "terminatitle", "terminatokens", "terminatransparent", "terminatypescript", "terminatypescriptcollection", "terminatyping", "terminauniqueMPgraphic", "terminauniqueMPpagegraphic", "terminaunittext", "terminaunpacked", "terminausableMPgraphic", "terminauseMPgraphic", "terminausemathstyleparameter", "terminausingbtxspecification", "terminavaia", "terminavbox", "terminavboxregister", "terminavboxtohbox", "terminavboxtohboxseparator", "terminaviewerlayer", "terminavtop", "terminavtopregister", "terminaxcell", "terminaxcellgroup", "terminaxgroup", "terminaxmldisplayverbatim", "terminaxmlinlineverbatim", "terminaxmlraw", "terminaxmlsetups", "terminaxrow", "terminaxrowgroup", "terminaxtable", "terminaxtablebody", "terminaxtablefoot", "terminaxtablehead", "terminaxtablenext", "testonotapdp", "testoriempimento", "tieniblocchi", "traduci", "usaJSscripts", "usaURL", "usablocco", "usacartella", "usacolonnasonoraesterna", "usadocumentoesterno", "usafiguraesterna", "usamodulo", "usasimboli", "usaurl", "vaia", "vaiabox", "vaiapagina", "vaigiu", "valorecolore", "versione" },
- ["nl"]={ "Cijfers", "Kap", "Letter", "Letters", "MAAND", "Romeins", "WEEKDAG", "WOORD", "WOORDEN", "Woord", "Woorden", "achtergrond", "bepaalkopnummer", "bepaallijstkenmerken", "bepaalregisterkenmerken", "bewaarbuffer", "blanko", "blokje", "blokjes", "cijfers", "converteernummer", "copieerveld", "corrigeerwitruimte", "datum", "definieer", "definieeraccent", "definieeralineas", "definieerblok", "definieerbuffer", "definieercombinatie", "definieercommando", "definieerconversie", "definieerfiguursymbool", "definieerfont", "definieerfontstijl", "definieerfontsynoniem", "definieerhbox", "definieeringesprongentext", "definieerinteractiemenu", "definieeritemgroep", "definieerkadertekst", "definieerkarakter", "definieerkleur", "definieerkleurgroep", "definieerkolomovergang", "definieerkop", "definieerkorps", "definieerkorpsomgeving", "definieerlayer", "definieerlayout", "definieerletter", "definieerlijst", "definieermarkering", "definieeromlijnd", "definieeropmaak", "definieeroverlay", "definieerpaginaovergang", "definieerpalet", "definieerpapierformaat", "definieerplaats", "definieerplaatsblok", "definieerprofiel", "definieerprogramma", "definieerreferentie", "definieerreferentieformaat", "definieerregister", "definieersamengesteldelijst", "definieersectie", "definieersectieblok", "definieersorteren", "definieerstartstop", "definieersubveld", "definieersymbool", "definieersynoniemen", "definieertabelvorm", "definieertabulatie", "definieertekst", "definieertekstachtergrond", "definieertype", "definieertypen", "definieerveld", "definieerveldstapel", "definieerwiskundeuitlijnen", "doordefinieren", "doorlabelen", "doornummeren", "dunnelijn", "dunnelijnen", "eenregel", "ergens", "externfiguur", "formulenummer", "gebruikJSscripts", "gebruikURL", "gebruikblokken", "gebruikexterndocument", "gebruikexternfiguur", "gebruikexterngeluidsfragment", "gebruikmodule", "gebruikpad", "gebruiksymbolen", "gebruiktypescript", "gebruiktypescriptfile", "gebruikurl", "geenbovenenonderregels", "geenhoofdenvoetregels", "geenspatie", "grijskleur", "haalbuffer", "haalmarkering", "haarlijn", "handhaafblokken", "hoofdtaal", "hoog", "huidigedatum", "huidigekopnummer", "inlijnd", "inregel", "installeertaal", "interactiebalk", "interactiebuttons", "interactiemenu", "invullijnen", "invulregel", "invultekst", "kleur", "kleurenbalk", "kleurwaarde", "kloonveld", "kolom", "kopnummer", "laag", "laho", "legeregels", "letter", "letters", "lijndikte", "lijstlengte", "maand", "markeer", "naar", "naarbox", "naarpagina", "nokap", "noot", "omgeving", "omlaag", "omlijnd", "onbekend", "onderdeel", "op", "oppagina", "pagina", "paginanummer", "paginareferentie", "paslayoutaan", "passendveld", "plaatsbookmarks", "plaatsformule", "plaatskopnummer", "plaatskoptekst", "plaatslijst", "plaatslijstmetsynoniemen", "plaatslokalevoetnoten", "plaatsnaastelkaar", "plaatsonderelkaar", "plaatsopgrid", "plaatspaginanummer", "plaatsplaatsblok", "plaatsregister", "plaatsruwelijst", "plaatssamengesteldelijst", "plaatssubformule", "plaatsvoetnoten", "positioneer", "produkt", "programma", "projekt", "punten", "refereer", "referentie", "regellinks", "regelmidden", "regelrechts", "resetmarkering", "romeins", "rooster", "roteer", "schaal", "scherm", "schrijfnaarlijst", "schrijftussenlijst", "selecteerblokken", "som", "spatie", "spiegel", "splitsplaatsblok", "startachtergrond", "startinteractiemenu", "startkantlijn", "startkleur", "startkop", "startlokalevoetnoten", "startmargeblok", "startnaar", "startomgeving", "startomlijnd", "startonderdeel", "startopelkaar", "startplaatsformule", "startplaatsplaatsblok", "startprodukt", "startprojekt", "startpublicatie", "startregel", "startregelcorrectie", "startregellinks", "startregelmidden", "startregelrechts", "startsom", "starttekstachtergrond", "starttekstlijn", "startuitlijnen", "stelachtergrondenin", "stelachtergrondin", "stelalineasin", "stelarrangerenin", "stelblankoin", "stelblokin", "stelblokjesin", "stelblokkopjein", "stelblokkopjesin", "stelbovenin", "stelboventekstenin", "stelbufferin", "stelciterenin", "stelclipin", "stelcommentaarin", "steldoordefinierenin", "steldoornummerenin", "steldunnelijnenin", "stelformulein", "stelformulesin", "stelformulierenin", "stelhoofdin", "stelhoofdtekstenin", "stelingesprongentextin", "stelinmargein", "stelinspringenin", "stelinteractiebalkin", "stelinteractiein", "stelinteractiemenuin", "stelinteractieschermin", "stelinterliniein", "stelinvullijnenin", "stelinvulregelsin", "stelitemgroepin", "stelitemsin", "stelkadertekstenin", "stelkadertekstin", "stelkantlijnin", "stelkapitalenin", "stelkleurenin", "stelkleurin", "stelkolommenin", "stelkopin", "stelkopnummerin", "stelkoppeltekenin", "stelkoppenin", "stelkorpsin", "stellayoutin", "stellijndiktein", "stellijstin", "stelmargeblokkenin", "stelmarkeringin", "stelnaastplaatsenin", "stelomlijndin", "stelonderin", "stelondertekstenin", "stelopmaakin", "stelopsommingenin", "stelpaginacommentaarin", "stelpaginanummerin", "stelpaginanummeringin", "stelpaginaovergangenin", "stelpaletin", "stelpapierformaatin", "stelpapierin", "stelparagraafnummerenin", "stelplaatsblokin", "stelplaatsblokkenin", "stelplaatsbloksplitsenin", "stelplaatsin", "stelpositionerenin", "stelprogrammasin", "stelrefererenin", "stelregelnummerenin", "stelregelsin", "stelregisterin", "stelroterenin", "stelsamengesteldelijstin", "stelsectieblokin", "stelsmallerin", "stelsorterenin", "stelspatieringin", "stelstartstopin", "stelsubpaginanummerin", "stelsymboolsetin", "stelsynoniemenin", "steltaalin", "steltabellenin", "steltabulatiein", "steltekstachtergrondin", "steltekstin", "steltekstinhoudin", "steltekstlijnenin", "stelteksttekstenin", "steltolerantiein", "steltypein", "steltypenin", "steluitlijnenin", "stelurlin", "stelveldenin", "stelveldin", "stelvoetin", "stelvoettekstenin", "stelwiskundeuitlijnenin", "stelwitruimtein", "stopachtergrond", "stopinteractiemenu", "stopkantlijn", "stopkleur", "stopkop", "stoplokalevoetnoten", "stopmargeblok", "stopnaar", "stopomgeving", "stopomlijnd", "stoponderdeel", "stopopelkaar", "stopplaatsformule", "stopplaatsplaatsblok", "stopprodukt", "stopprojekt", "stoppublicatie", "stopregel", "stopregelcorrectie", "stopregellinks", "stopregelmidden", "stopregelrechts", "stopsom", "stoptekstachtergrond", "stoptekstlijn", "stopuitlijnen", "subpaginanummer", "switchnaarkorps", "symbool", "taal", "tekstlijn", "tekstreferentie", "testkolom", "testpagina", "toelichting", "toongrid", "tooninstellingen", "toonkader", "toonkleur", "toonkleurgroep", "toonkorps", "toonkorpsomgeving", "toonlayout", "toonopmaak", "toonpalet", "toonprint", "toonstruts", "toonsymboolset", "uit", "uitgerekt", "vastespatie", "vastespaties", "veld", "veldstapel", "verbergblokken", "vergelijkkleurgroep", "vergelijkpalet", "versie", "vertaal", "verwerkblokken", "voetnoottekst", "volledigepaginanummer", "volledigregister", "voluit", "weekdag", "wiskunde", "woordrechts" },
- ["pe"]={ "آیتم", "آیتمها", "آینه", "از", "استفاده‌بلوکها", "استفاده‌دستخط‌تایپ", "استفاده‌شکل‌خارجی", "استفاده‌قطعه‌موزیک‌خارجی", "استفاده‌مدول", "استفاده‌مسیر", "استفاده‌نمادها", "استفاده‌نوشتارخارجی", "استفاده‌پرونده‌دستخط‌تایپ", "اعدادلاتین", "افزودن", "انتخاب‌بلوکها", "بارگذاری‌آرایش", "بارگذاری‌آیتمها", "بارگذاری‌ارجاع", "بارگذاری‌اندازه‌برگ", "بارگذاری‌باریکتر", "بارگذاری‌بافر", "بارگذاری‌بالا", "بارگذاری‌بردباری", "بارگذاری‌برنامه‌ها", "بارگذاری‌برگ", "بارگذاری‌بلوک", "بارگذاری‌بلوک‌بخش", "بارگذاری‌تایپ", "بارگذاری‌تایپ‌کردن", "بارگذاری‌ترتیب", "بارگذاری‌تنظیم", "بارگذاری‌تنظیم‌ریاضی", "بارگذاری‌ته‌برگ", "بارگذاری‌تورفتگی", "بارگذاری‌توضیح", "بارگذاری‌توضیح‌صفحه", "بارگذاری‌ثبت", "بارگذاری‌جانشانی", "بارگذاری‌جدولها", "بارگذاری‌جدول‌بندی", "بارگذاری‌خالی", "بارگذاری‌خطها", "بارگذاری‌خطهای‌حاشیه", "بارگذاری‌خطهای‌سیاه", "بارگذاری‌خطهای‌متن", "بارگذاری‌خطها‌ی‌نازک", "بارگذاری‌درج‌درخطها", "بارگذاری‌درج‌مخالف", "بارگذاری‌دوران", "بارگذاری‌رنگ", "بارگذاری‌رنگها", "بارگذاری‌زبان", "بارگذاری‌ستونها", "بارگذاری‌سر", "بارگذاری‌سربرگ", "بارگذاری‌سرها", "بارگذاری‌شرح", "بارگذاری‌شرحها", "بارگذاری‌شروع‌پایان", "بارگذاری‌شماره‌زیرصفحه", "بارگذاری‌شماره‌سر", "بارگذاری‌شماره‌صفحه", "بارگذاری‌شماره‌گذاریها", "بارگذاری‌شماره‌گذاری‌صفحه", "بارگذاری‌شماره‌گذاری‌پاراگراف", "بارگذاری‌شماره‌‌گذاری‌خط", "بارگذاری‌شناور", "بارگذاری‌شناورها", "بارگذاری‌شکافتن‌شناورها", "بارگذاری‌طرح", "بارگذاری‌طرح‌بندی", "بارگذاری‌عرض‌خط", "بارگذاری‌فاصله‌بین‌خط", "بارگذاری‌فرمولها", "بارگذاری‌فضای‌سفید", "بارگذاری‌فضا‌گذاری", "بارگذاری‌قالبی", "بارگذاری‌قلم‌متن", "بارگذاری‌لوح", "بارگذاری‌لیست", "بارگذاری‌لیست‌ترکیبی", "بارگذاری‌مترادفها", "بارگذاری‌متن", "بارگذاری‌متنهای‌بالا", "بارگذاری‌متن‌سربرگ", "بارگذاری‌متن‌قالبی", "بارگذاری‌متن‌متنها", "بارگذاری‌متن‌پانوشت", "بارگذاری‌متن‌پایین", "بارگذاری‌مجموعه‌نماد", "بارگذاری‌منوی‌پانل", "بارگذاری‌مکان‌گذاری", "بارگذاری‌میدان", "بارگذاری‌میدانها", "بارگذاری‌میله‌پانل", "بارگذاری‌نشانه‌شکستن", "بارگذاری‌نشانه‌گذاری", "بارگذاری‌نقل", "بارگذاری‌پاراگرافها", "بارگذاری‌پانل", "بارگذاری‌پایین", "بارگذاری‌پرده‌پانل", "بارگذاری‌پرکردن‌خطها", "بارگذاری‌پس‌زمینه", "بارگذاری‌پس‌زمینه‌ها", "بارگذاری‌چیدن", "بارگذاری‌گذارصفحه", "بارگذاری‌گروههای‌آیتم", "بارگذاری‌گروه‌آیتم", "بازنشانی‌نشانه‌گذاری", "بدون‌خط‌بالاوپایین", "بدون‌خط‌سروته‌برگ", "بدون‌فضا", "برنامه", "بروبه", "بروبه‌جعبه", "بروبه‌صفحه", "بروپایین", "بلند", "بلوکهای‌پردازش", "بلوکها‌پنهان", "بنویس‌بین‌لیست", "بنویس‌در‌لیست", "تاریخ", "تاریخ‌جاری", "تایپ", "تایپ‌بافر", "تایپ‌پرونده", "ترجمه", "تعریف", "تعریف‌آرایش", "تعریف‌الگوی‌جدول", "تعریف‌اندازه‌برگ", "تعریف‌بافر", "تعریف‌بخش", "تعریف‌برنامه", "تعریف‌برچسب", "تعریف‌بلوک", "تعریف‌بلوک‌بخش", "تعریف‌تایپ", "تعریف‌تایپ‌کردن", "تعریف‌تبدیل", "تعریف‌ترتیب", "تعریف‌ترکیب", "تعریف‌تنظیم‌ریاضی", "تعریف‌توده‌میدان", "تعریف‌ثبت", "تعریف‌جانشانی", "تعریف‌جدول‌بندی", "تعریف‌جعبه‌‌افقی", "تعریف‌حرف", "تعریف‌رنگ", "تعریف‌زیرمیدان", "تعریف‌سبک", "تعریف‌سبک‌قلم", "تعریف‌سر", "تعریف‌شرح", "تعریف‌شروع‌پایان", "تعریف‌شماره‌بندی", "تعریف‌شمایل‌مرجع", "تعریف‌شناور", "تعریف‌شکستن‌ستون", "تعریف‌شکست‌صفحه", "تعریف‌طرح‌بندی", "تعریف‌فرمان", "تعریف‌قالبی", "تعریف‌قلم", "تعریف‌قلم‌متن", "تعریف‌لایه", "تعریف‌لهجه", "تعریف‌لوح", "تعریف‌لیست", "تعریف‌لیست‌ترکیبی", "تعریف‌مترادفها", "تعریف‌مترادف‌قلم", "تعریف‌متن", "تعریف‌متن‌قالبی", "تعریف‌محیط‌قلم‌بدنه", "تعریف‌مرجع", "تعریف‌منوی‌پانل", "تعریف‌میدان", "تعریف‌نشانه‌گذاری", "تعریف‌نماد", "تعریف‌نمادشکل", "تعریف‌پاراگرافها", "تعریف‌پروفایل", "تعریف‌پوشش", "تعریف‌گروه‌آیتم", "تعریف‌گروه‌رنگ", "تعیین‌شماره‌سر", "تعیین‌محتوای‌متن", "تعیین‌مشخصات‌ثبت", "تعیین‌مشخصات‌لیست", "تغییربه‌قلم‌بدنه", "تنظیم‌راست", "تنظیم‌طرح‌بندی", "تنظیم‌وسط", "توجه", "توری", "تولید", "تک", "ثبت‌کامل", "حرف", "حرفها", "حفظ‌بلوکها", "خالی", "خطهای‌سیاه", "خطهای‌نازک", "خطها‌خالی", "خط‌سیاه", "خط‌متن", "خط‌مو", "خط‌نازک", "خ‌ا", "خ‌ع", "در", "درج‌ثبت", "درج‌درخط", "درج‌درخطها", "درج‌درمتن", "درج‌در‌بالای‌یکدیگر", "درج‌در‌توری", "درج‌زیرفرمول", "درج‌شماره‌سر", "درج‌شماره‌صفحه", "درج‌شناور", "درج‌فرمول", "درج‌لیست", "درج‌لیست‌خام", "درج‌لیست‌مختلط", "درج‌متن‌سر", "درج‌پانوشتها", "درج‌پانوشتهای‌موضعی", "درج‌چوب‌خط", "درج‌کنار‌به‌کنار", "درخط", "درصفحه", "درقالبی", "درمورد", "درون", "درپر", "دریافت‌بافر", "دریافت‌نشانه", "دوران", "دکمه", "دکمه‌منو", "دکمه‌پانل", "رج", "رنگ", "رنگ‌خاکستری", "روزهفته", "ریاضی", "زبان", "زبان‌اصلی", "ستون", "ستون‌امتحان", "سرپوش‌کوچک‌نه", "شروعJScode", "شروعJSpreamble", "شروعLUA", "شروعMP", "شروعMPclip", "شروعMPcode", "شروعMPdefinitions", "شروعMPdrawing", "شروعMPenvironment", "شروعMPextensions", "شروعMPinclusions", "شروعMPinitializations", "شروعMPpage", "شروعMPpositiongraphic", "شروعMPpositionmethod", "شروعMPrun", "شروعPARSEDXML", "شروعTABLE", "شروعTABLEbody", "شروعTABLEfoot", "شروعTABLEhead", "شروعTABLEnext", "شروعTC", "شروعTD", "شروعTDs", "شروعTEX", "شروعTEXpage", "شروعTH", "شروعTN", "شروعTR", "شروعTRs", "شروعTX", "شروعTY", "شروعXML", "شروعalign", "شروعalignment", "شروعallmodes", "شروعappendices", "شروعarrangedpages", "شروعaside", "شروعattachment", "شروعbackmatter", "شروعbar", "شروعbbordermatrix", "شروعbitmapimage", "شروعblockquote", "شروعbodymatter", "شروعbordermatrix", "شروعboxedcolumns", "شروعbtxlabeltext", "شروعbtxrenderingdefinitions", "شروعbuffer", "شروعcases", "شروعcatcodetable", "شروعcenteraligned", "شروعchapter", "شروعcharacteralign", "شروعcheckedfences", "شروعchemical", "شروعchemicaltext", "شروعcollect", "شروعcollecting", "شروعcolorintent", "شروعcoloronly", "شروعcolorset", "شروعcolumns", "شروعcolumnspan", "شروعcombination", "شروعcomment", "شروعcontextcode", "شروعcontextdefinitioncode", "شروعctxfunction", "شروعctxfunctiondefinition", "شروعcurrentcolor", "شروعcurrentlistentrywrapper", "شروعdelimited", "شروعdelimitedtext", "شروعdisplaymath", "شروعdmath", "شروعdocument", "شروعeffect", "شروعelement", "شروعembeddedxtable", "شروعendnote", "شروعendofline", "شروعexceptions", "شروعexpanded", "شروعexpandedcollect", "شروعextendedcatcodetable", "شروعexternalfigurecollection", "شروعfact", "شروعfigure", "شروعfiguretext", "شروعfittingpage", "شروعfixed", "شروعfloatcombination", "شروعfont", "شروعfontclass", "شروعfontsolution", "شروعfootnote", "شروعformula", "شروعformulas", "شروعframedcell", "شروعframedcontent", "شروعframedrow", "شروعframedtable", "شروعframedtext", "شروعfrontmatter", "شروعgraphictext", "شروعgridsnapping", "شروعhanging", "شروعhbox", "شروعhboxestohbox", "شروعhboxregister", "شروعheadtext", "شروعhelptext", "شروعhiding", "شروعhighlight", "شروعhyphenation", "شروعimath", "شروعindentation", "شروعindentedtext", "شروعinteraction", "شروعinterface", "شروعintermezzotext", "شروعintertext", "شروعitemgroup", "شروعitemgroupcolumns", "شروعitemize", "شروعknockout", "شروعlabeltext", "شروعlayout", "شروعlegend", "شروعlinealignment", "شروعlinecorrection", "شروعlinefiller", "شروعlinenumbering", "شروعlines", "شروعlinetable", "شروعlinetablebody", "شروعlinetablecell", "شروعlinetablehead", "شروعlocalfootnotes", "شروعlocalheadsetup", "شروعlocallinecorrection", "شروعlocalnotes", "شروعlocalsetups", "شروعlua", "شروعluacode", "شروعluaparameterset", "شروعluasetups", "شروعmakeup", "شروعmarginblock", "شروعmarkedcontent", "شروعmathalignment", "شروعmathcases", "شروعmathlabeltext", "شروعmathmatrix", "شروعmathmode", "شروعmathstyle", "شروعmatrices", "شروعmatrix", "شروعmaxaligned", "شروعmdformula", "شروعmiddlealigned", "شروعmiddlemakeup", "شروعmixedcolumns", "شروعmode", "شروعmodeset", "شروعmodule", "شروعmoduletestsection", "شروعmpformula", "شروعnamedsection", "شروعnamedsubformulas", "شروعnarrow", "شروعnarrower", "شروعnegative", "شروعnicelyfilledbox", "شروعnointerference", "شروعnotallmodes", "شروعnotext", "شروعnotmode", "شروعoperatortext", "شروعopposite", "شروعoutputstream", "شروعoverlay", "شروعoverprint", "شروعpagecomment", "شروعpagefigure", "شروعpagegrid", "شروعpagegridspan", "شروعpagelayout", "شروعpagemakeup", "شروعpar", "شروعparagraph", "شروعparagraphs", "شروعparagraphscell", "شروعparbuilder", "شروعpart", "شروعpath", "شروعplacechemical", "شروعplacefigure", "شروعplacegraphic", "شروعplaceintermezzo", "شروعplacelegend", "شروعplacepairedbox", "شروعplacetable", "شروعpositioning", "شروعpositionoverlay", "شروعpositive", "شروعpostponing", "شروعprefixtext", "شروعprocessassignmentcommand", "شروعprocessassignmentlist", "شروعprocesscommacommand", "شروعprocesscommalist", "شروعprotect", "شروعprotectedcolors", "شروعpunctuation", "شروعquotation", "شروعquote", "شروعrandomized", "شروعrandomseed", "شروعrawsetups", "شروعreadingfile", "شروعreferenceprefix", "شروعregime", "شروعreusableMPgraphic", "شروعscript", "شروعsdformula", "شروعsection", "شروعsectionblock", "شروعsectionblockenvironment", "شروعsectionlevel", "شروعsetups", "شروعshapebox", "شروعshift", "شروعsidebar", "شروعsimplecolumns", "شروعspecialitem", "شروعspeech", "شروعspformula", "شروعsplitformula", "شروعspread", "شروعstandardmakeup", "شروعstartstop", "شروعstaticMPfigure", "شروعstaticMPgraphic", "شروعstrictinspectnextcharacter", "شروعstrut", "شروعstyle", "شروعsubformulas", "شروعsubject", "شروعsubjectlevel", "شروعsubsection", "شروعsubsentence", "شروعsubstack", "شروعsubsubject", "شروعsubsubsection", "شروعsubsubsubject", "شروعsubsubsubsection", "شروعsubsubsubsubject", "شروعsubsubsubsubsection", "شروعsubsubsubsubsubject", "شروعsuffixtext", "شروعsymbolset", "شروعtable", "شروعtablehead", "شروعtables", "شروعtabletail", "شروعtabletext", "شروعtabulate", "شروعtabulatehead", "شروعtabulatetail", "شروعtagged", "شروعtaglabeltext", "شروعtexcode", "شروعtexdefinition", "شروعtext", "شروعtextbackground", "شروعtextbackgroundmanual", "شروعtextcolor", "شروعtextcolorintent", "شروعtextflow", "شروعtextmakeup", "شروعtitle", "شروعtokens", "شروعtransparent", "شروعtypescript", "شروعtypescriptcollection", "شروعtyping", "شروعuniqueMPgraphic", "شروعuniqueMPpagegraphic", "شروعunittext", "شروعunpacked", "شروعusableMPgraphic", "شروعuseMPgraphic", "شروعusemathstyleparameter", "شروعusingbtxspecification", "شروعvbox", "شروعvboxregister", "شروعvboxtohbox", "شروعvboxtohboxseparator", "شروعviewerlayer", "شروعvtop", "شروعvtopregister", "شروعxcell", "شروعxcellgroup", "شروعxgroup", "شروعxmldisplayverbatim", "شروعxmlinlineverbatim", "شروعxmlraw", "شروعxmlsetups", "شروعxrow", "شروعxrowgroup", "شروعxtable", "شروعxtablebody", "شروعxtablefoot", "شروعxtablehead", "شروعxtablenext", "شروعآیتم", "شروعبروبه", "شروعتنظیم‌راست", "شروعتنظیم‌وسط", "شروعتولید", "شروعخط‌حاشیه", "شروعخط‌متن", "شروعدرج‌شناور", "شروعدرج‌فرمول", "شروعرنگ", "شروعسر", "شروعفشرده", "شروعقالبی", "شروعمحیط", "شروعمنوی‌پانل", "شروعمولفه", "شروعنشر", "شروعپروژه", "شروعپس‌زمینه", "شروعچپ‌چین", "شروع‌خط", "شماره‌زیرصفحه", "شماره‌سر", "شماره‌سرجاری", "شماره‌صفحه", "شماره‌صفحه‌کامل", "شماره‌فرمول", "شماره‌مبدل", "شماره‌ها", "شکافتن‌شناور", "شکل‌خارجی", "صفحه", "صفحه‌تست", "طول‌لیست", "عرض‌خط", "فضا", "فضاهای‌ثابت", "فضای‌ثابت", "فضای‌سفیدصحیح", "قالبی", "لوح‌مقایسه", "ماه", "متن‌پانوشت", "محیط", "مراجعه", "مرجع", "مرجع‌صفحه", "مرجع‌متن", "مقایسه‌گروه‌رنگ", "مقداررنگ", "مقیاس", "منوی‌پانل", "مولفه", "مکان", "میدان", "میدان‌شبیه‌سازی", "میدان‌پشته", "میدان‌کپی", "میله‌رنگ", "میله‌پانل", "ناشناس", "نسخه", "نشانه‌گذاری", "نصب‌زبان", "نقطه‌ها", "نماد", "نمایش‌آرایش", "نمایش‌بارگذاریها", "نمایش‌بستها", "نمایش‌توری", "نمایش‌رنگ", "نمایش‌طرح‌بندی", "نمایش‌قالب", "نمایش‌قلم‌بدنه", "نمایش‌لوح", "نمایش‌مجموعه‌علامت", "نمایش‌محیط‌قلم‌بدنه", "نمایش‌چاپ", "نمایش‌گروه‌رنگ", "پابا", "پایانJScode", "پایانJSpreamble", "پایانLUA", "پایانMP", "پایانMPclip", "پایانMPcode", "پایانMPdefinitions", "پایانMPdrawing", "پایانMPenvironment", "پایانMPextensions", "پایانMPinclusions", "پایانMPinitializations", "پایانMPpage", "پایانMPpositiongraphic", "پایانMPpositionmethod", "پایانMPrun", "پایانPARSEDXML", "پایانTABLE", "پایانTABLEbody", "پایانTABLEfoot", "پایانTABLEhead", "پایانTABLEnext", "پایانTC", "پایانTD", "پایانTDs", "پایانTEX", "پایانTEXpage", "پایانTH", "پایانTN", "پایانTR", "پایانTRs", "پایانTX", "پایانTY", "پایانXML", "پایانalign", "پایانalignment", "پایانallmodes", "پایانappendices", "پایانarrangedpages", "پایانaside", "پایانattachment", "پایانbackmatter", "پایانbar", "پایانbbordermatrix", "پایانbitmapimage", "پایانblockquote", "پایانbodymatter", "پایانbordermatrix", "پایانboxedcolumns", "پایانbtxlabeltext", "پایانbtxrenderingdefinitions", "پایانbuffer", "پایانcases", "پایانcatcodetable", "پایانcenteraligned", "پایانchapter", "پایانcharacteralign", "پایانcheckedfences", "پایانchemical", "پایانchemicaltext", "پایانcollect", "پایانcollecting", "پایانcolorintent", "پایانcoloronly", "پایانcolorset", "پایانcolumns", "پایانcolumnspan", "پایانcombination", "پایانcomment", "پایانcontextcode", "پایانcontextdefinitioncode", "پایانctxfunction", "پایانctxfunctiondefinition", "پایانcurrentcolor", "پایانcurrentlistentrywrapper", "پایانdelimited", "پایانdelimitedtext", "پایانdisplaymath", "پایانdmath", "پایانdocument", "پایانeffect", "پایانelement", "پایانembeddedxtable", "پایانendnote", "پایانendofline", "پایانexceptions", "پایانexpanded", "پایانexpandedcollect", "پایانextendedcatcodetable", "پایانexternalfigurecollection", "پایانfact", "پایانfigure", "پایانfiguretext", "پایانfittingpage", "پایانfixed", "پایانfloatcombination", "پایانfont", "پایانfontclass", "پایانfontsolution", "پایانfootnote", "پایانformula", "پایانformulas", "پایانframedcell", "پایانframedcontent", "پایانframedrow", "پایانframedtable", "پایانframedtext", "پایانfrontmatter", "پایانgraphictext", "پایانgridsnapping", "پایانhanging", "پایانhbox", "پایانhboxestohbox", "پایانhboxregister", "پایانheadtext", "پایانhelptext", "پایانhiding", "پایانhighlight", "پایانhyphenation", "پایانimath", "پایانindentation", "پایانindentedtext", "پایانinteraction", "پایانinterface", "پایانintermezzotext", "پایانintertext", "پایانitemgroup", "پایانitemgroupcolumns", "پایانitemize", "پایانknockout", "پایانlabeltext", "پایانlayout", "پایانlegend", "پایانlinealignment", "پایانlinecorrection", "پایانlinefiller", "پایانlinenumbering", "پایانlines", "پایانlinetable", "پایانlinetablebody", "پایانlinetablecell", "پایانlinetablehead", "پایانlocalfootnotes", "پایانlocalheadsetup", "پایانlocallinecorrection", "پایانlocalnotes", "پایانlocalsetups", "پایانlua", "پایانluacode", "پایانluaparameterset", "پایانluasetups", "پایانmakeup", "پایانmarginblock", "پایانmarkedcontent", "پایانmathalignment", "پایانmathcases", "پایانmathlabeltext", "پایانmathmatrix", "پایانmathmode", "پایانmathstyle", "پایانmatrices", "پایانmatrix", "پایانmaxaligned", "پایانmdformula", "پایانmiddlealigned", "پایانmiddlemakeup", "پایانmixedcolumns", "پایانmode", "پایانmodeset", "پایانmodule", "پایانmoduletestsection", "پایانmpformula", "پایانnamedsection", "پایانnamedsubformulas", "پایانnarrow", "پایانnarrower", "پایانnegative", "پایانnicelyfilledbox", "پایانnointerference", "پایانnotallmodes", "پایانnotext", "پایانnotmode", "پایانoperatortext", "پایانopposite", "پایانoutputstream", "پایانoverlay", "پایانoverprint", "پایانpagecomment", "پایانpagefigure", "پایانpagegrid", "پایانpagegridspan", "پایانpagelayout", "پایانpagemakeup", "پایانpar", "پایانparagraph", "پایانparagraphs", "پایانparagraphscell", "پایانparbuilder", "پایانpart", "پایانpath", "پایانplacechemical", "پایانplacefigure", "پایانplacegraphic", "پایانplaceintermezzo", "پایانplacelegend", "پایانplacepairedbox", "پایانplacetable", "پایانpositioning", "پایانpositionoverlay", "پایانpositive", "پایانpostponing", "پایانprefixtext", "پایانprocessassignmentcommand", "پایانprocessassignmentlist", "پایانprocesscommacommand", "پایانprocesscommalist", "پایانprotect", "پایانprotectedcolors", "پایانpunctuation", "پایانquotation", "پایانquote", "پایانrandomized", "پایانrandomseed", "پایانrawsetups", "پایانreadingfile", "پایانreferenceprefix", "پایانregime", "پایانreusableMPgraphic", "پایانscript", "پایانsdformula", "پایانsection", "پایانsectionblock", "پایانsectionblockenvironment", "پایانsectionlevel", "پایانsetups", "پایانshapebox", "پایانshift", "پایانsidebar", "پایانsimplecolumns", "پایانspecialitem", "پایانspeech", "پایانspformula", "پایانsplitformula", "پایانspread", "پایانstandardmakeup", "پایانstartstop", "پایانstaticMPfigure", "پایانstaticMPgraphic", "پایانstrictinspectnextcharacter", "پایانstrut", "پایانstyle", "پایانsubformulas", "پایانsubject", "پایانsubjectlevel", "پایانsubsection", "پایانsubsentence", "پایانsubstack", "پایانsubsubject", "پایانsubsubsection", "پایانsubsubsubject", "پایانsubsubsubsection", "پایانsubsubsubsubject", "پایانsubsubsubsubsection", "پایانsubsubsubsubsubject", "پایانsuffixtext", "پایانsymbolset", "پایانtable", "پایانtablehead", "پایانtables", "پایانtabletail", "پایانtabletext", "پایانtabulate", "پایانtabulatehead", "پایانtabulatetail", "پایانtagged", "پایانtaglabeltext", "پایانtexcode", "پایانtexdefinition", "پایانtext", "پایانtextbackground", "پایانtextbackgroundmanual", "پایانtextcolor", "پایانtextcolorintent", "پایانtextflow", "پایانtextmakeup", "پایانtitle", "پایانtokens", "پایانtransparent", "پایانtypescript", "پایانtypescriptcollection", "پایانtyping", "پایانuniqueMPgraphic", "پایانuniqueMPpagegraphic", "پایانunittext", "پایانunpacked", "پایانusableMPgraphic", "پایانuseMPgraphic", "پایانusemathstyleparameter", "پایانusingbtxspecification", "پایانvbox", "پایانvboxregister", "پایانvboxtohbox", "پایانvboxtohboxseparator", "پایانviewerlayer", "پایانvtop", "پایانvtopregister", "پایانxcell", "پایانxcellgroup", "پایانxgroup", "پایانxmldisplayverbatim", "پایانxmlinlineverbatim", "پایانxmlraw", "پایانxmlsetups", "پایانxrow", "پایانxrowgroup", "پایانxtable", "پایانxtablebody", "پایانxtablefoot", "پایانxtablehead", "پایانxtablenext", "پایانآیتم", "پایانبروبه", "پایانتنظیم‌راست", "پایانتنظیم‌وسط", "پایانتولید", "پایانخط‌حاشیه", "پایانخط‌متن", "پایاندرج‌شناور", "پایاندرج‌فرمول", "پایانرنگ", "پایانسر", "پایانفشرده", "پایانقالبی", "پایانمحیط", "پایانمنوی‌پانل", "پایانمولفه", "پایاننشر", "پایانپروژه", "پایانپس‌زمینه", "پایانچپ‌چین", "پایان‌خط", "پایین", "پرده", "پروژه", "پرکردن‌میدان", "پس‌زمینه", "چوبخط", "چپ‌چین", "کشیده", "کلمه‌راست", "گیره", "یادداشت", "یک‌جا", "یک‌خط" },
- ["ro"]={ "CUVANT", "CUVINTE", "Cuvant", "Cuvinte", "Kap", "LUNA", "Litera", "Litere", "Numere", "Numereromane", "ZIDINSAPTAMANA", "adapteazaaspect", "adubuffer", "adumarcaje", "afiseazaaspect", "afiseazaculoare", "afiseazafonttext", "afiseazagrid", "afiseazagrupculoare", "afiseazamakeup", "afiseazamediufonttext", "afiseazapaleta", "afiseazarama", "afiseazasetari", "afiseazasetsimboluri", "afiseazastruts", "afiseazatiparire", "aliniatcentru", "aliniatdreapta", "aliniatstanga", "ascundeblocuri", "baraculoare", "barainteractiune", "blanc", "butoaneinteractiune", "buton", "butonmeniu", "camp", "cloneazacamp", "coloana", "comparagrupculoare", "comparapaleta", "completeazanumarpagina", "componenta", "convertestenumar", "copiazacamp", "corecteazaspatiualb", "culoare", "culoaregri", "cuvantdreapta", "data", "datacurenta", "defineste", "definesteaccent", "definesteantet", "definestebloc", "definesteblocsectiune", "definestebuffer", "definestecamp", "definestecaracter", "definestecomanda", "definesteconversie", "definesteculoare", "definestedescriere", "definestedimensiunehartie", "definesteenumerare", "definesteeticheta", "definestefloat", "definestefont", "definestefonttext", "definesteformatreferinte", "definestegrupculori", "definestehbox", "definesteinconjurare", "definestelista", "definestelistacombinata", "definestemakeup", "definestemarcaje", "definestemediulfonttext", "definestemeniuinteractiune", "definesteoverlay", "definestepaleta", "definesteparagraf", "definesteprofil", "definesteprogram", "definestereferinte", "definesteregistru", "definestesablontabel", "definestesectiune", "definestesimbol", "definestesimbolfigura", "definestesinonim", "definestesinonimfont", "definestesortare", "definestestartstop", "definestestil", "definestestilfont", "definestestivacampuri", "definestesubcamp", "definestetabulatori", "definestetext", "definestetexteinconjurate", "definestetextinconjurat", "definestetyping", "despre", "determinacaracteristicilelistei", "determinacaracteristiciregistru", "determinanumartitlu", "din", "dute", "dutebox", "dutepagina", "ecran", "element", "faraliniiantetsisubsol", "faraliniisussijos", "faraspatiu", "figuraexterna", "firdepar", "folosesteURL", "folosestebloc", "folosestedirector", "folosestedocumentextern", "folosestefiguraexterna", "folosestemodul", "folosestemuzicaexterna", "folosestescriptJS", "folosestesimboluri", "folosesteurl", "fundal", "grosimelinie", "impartefloat", "inalt", "injos", "inlinie", "instalarelimba", "intins", "jos", "jossus", "la", "lapagina", "limba", "limbaprincipala", "linieneagra", "liniesubtire", "linieumplere", "liniinegre", "liniisubtiri", "litera", "litere", "luna", "lungimelista", "marcaje", "matematica", "mediu", "meniuinteractiune", "necunoscut", "nokap", "nota", "numarformula", "numarpagina", "numartitlu", "numartitlucurent", "numere", "numereromane", "olinie", "pagina", "pastreazablocuri", "pelung", "plaseazapegrid", "plaseazasemnecarte", "potrivestecamp", "pozitie", "proceseazabloc", "produs", "proiect", "puncte", "punedeasuprafiecareia", "punefatainfata", "puneformula", "punelista", "punelistacombinata", "punenotesubsol", "punenotesubsollocale", "punenumarpagina", "puneregistru", "punesubformula", "referinta", "referintapagina", "referintatext", "reflexie", "remarca", "reseteazamarcaje", "riglatext", "rigleumplere", "roteste", "scala", "scriebuffer", "scrieinlista", "scrieintreliste", "selecteazablocuri", "semncarte", "setareitemization", "setarelimba", "setarepozitie", "seteazaaliniat", "seteazaalinierea", "seteazaantet", "seteazaaranjareapag", "seteazaaspect", "seteazabarainteractiune", "seteazablanc", "seteazabloc", "seteazablocsectiune", "seteazabuffer", "seteazacamp", "seteazacampuri", "seteazaclipping", "seteazacoloane", "seteazacomentariu", "seteazacomentariupagina", "seteazaculoare", "seteazaculori", "seteazadimensiunihartie", "seteazaecraninteractiune", "seteazaelemente", "seteazaenumerare", "seteazafloat", "seteazafloats", "seteazafonttext", "seteazaformulare", "seteazaformule", "seteazafundal", "seteazafundaluri", "seteazagrosimelinie", "seteazaimpartireafloat", "seteazainconjurat", "seteazaingust", "seteazainteractiunea", "seteazajos", "seteazalegenda", "seteazalegendele", "seteazaliniesilabe", "seteazaliniesubtire", "seteazalinii", "seteazaliniimargine", "seteazaliniinegre", "seteazaliniiumplere", "seteazalista", "seteazalistacombinata", "seteazamajuscule", "seteazamakeup", "seteazamarcaje", "seteazameniuinteractiune", "seteazaminicitat", "seteazanumarpagina", "seteazanumarsubpagina", "seteazanumartitlu", "seteazanumerotarelinii", "seteazanumerotarepagina", "seteazanumerotareparagrafe", "seteazapaleta", "seteazaparagrafe", "seteazaplasareaopozita", "seteazaprograme", "seteazareferinte", "seteazaregistru", "seteazarigletext", "seteazarigleumplere", "seteazarotare", "seteazasimbol", "seteazasinonime", "seteazasortare", "seteazaspatiu", "seteazaspatiualb", "seteazaspatiuinterliniar", "seteazasubsol", "seteazasus", "seteazatabele", "seteazatabulatori", "seteazatext", "seteazatexteantet", "seteazatextejos", "seteazatextesubsol", "seteazatextesus", "seteazatextetext", "seteazatitlu", "seteazatitluri", "seteazatoleranta", "seteazatranzitiepagina", "seteazatype", "seteazatyping", "seteazaurl", "simbol", "spatiifixate", "spatiu", "spatiufixat", "startaliniatcentru", "startaliniatdreapta", "startaliniatstanga", "startcomponenta", "startculoare", "startdute", "startfundal", "startimpachetat", "startlinie", "startliniemargine", "startmediu", "startmeniuinteractiune", "startprodus", "startproiect", "startpublicatie", "startpuneformula", "startriglatext", "starttitlu", "stivacampuri", "stopaliniatcentru", "stopaliniatdreapta", "stopaliniatstanga", "stopcomponenta", "stopculoare", "stopdute", "stopfundal", "stopimpachetat", "stoplinie", "stopliniemargine", "stopmediu", "stopmeniuinteractiune", "stopprodus", "stopproiect", "stoppublicatie", "stoppuneformula", "stopriglatext", "stoptitlu", "textumplere", "traduce", "trecilafonttext", "undeva", "valoareculoare", "versiune", "zidinsaptamana" },
+ ["fr"]={ "Caractere", "Caracteres", "Chiffresromains", "JOURSEMAINE", "MOIS", "MOT", "MOTS", "Mot", "Mots", "Numeros", "a", "adaptedisposition", "ajustechamp", "alaligne", "alapage", "aligneadroite", "aligneagauche", "aligneaumilieu", "arriereplan", "baha", "barrecouleur", "barreinteraction", "bas", "bouton", "boutonmenu", "boutonsinteraction", "cacheblocs", "caractere", "caracteres", "champ", "changepolicecorps", "chiffresromains", "clonechamp", "colonne", "commentaire", "comparegroupecouleur", "comparepalette", "completenumeropage", "completeregistre", "composant", "concernant", "convertitnumero", "copitchamp", "corrigeespaceblanc", "couleur", "couleurgrise", "dactylographier", "dans", "datecourante", "de", "definicaractere", "definit", "definitaccent", "definitbloc", "definitblocsection", "definitbuffer", "definitcalque", "definitchamp", "definitcommande", "definitconversion", "definitcouleur", "definitdactylo", "definitdemarrestoppe", "definitdescription", "definitdisposition", "definitenumeration", "definitenvironnementpolicecorps", "definitetiquette", "definitflottant", "definitformatreference", "definitgroupecouleur", "definithbox", "definitjeucolonne", "definitliste", "definitlisteimbriquee", "definitmakeup", "definitmarquage", "definitmenuinteraction", "definitpalette", "definitparagraphes", "definitpilechamp", "definitpolice", "definitpolicecorps", "definitprofil", "definitprogramme", "definitreference", "definitregistre", "definitrevetement", "definitsautdecolonne", "definitsautdepage", "definitsection", "definitsouschamp", "definitstyle", "definitstylepolice", "definitsymbole", "definitsymbolefigure", "definitsynonymepolice", "definitsynonymes", "definittabulation", "definittaillepapier", "definittete", "definittexte", "definittrametableau", "definittri", "definittype", "definitvide", "demarreJScode", "demarreJSpreamble", "demarreLUA", "demarreMP", "demarreMPclip", "demarreMPcode", "demarreMPdefinitions", "demarreMPdrawing", "demarreMPenvironment", "demarreMPextensions", "demarreMPinclusions", "demarreMPinitializations", "demarreMPpage", "demarreMPpositiongraphic", "demarreMPpositionmethod", "demarreMPrun", "demarrePARSEDXML", "demarreTABLE", "demarreTABLEbody", "demarreTABLEfoot", "demarreTABLEhead", "demarreTABLEnext", "demarreTC", "demarreTD", "demarreTDs", "demarreTEX", "demarreTEXpage", "demarreTH", "demarreTN", "demarreTR", "demarreTRs", "demarreTX", "demarreTY", "demarreXML", "demarrealign", "demarrealigneadroite", "demarrealigneagauche", "demarrealigneaumilieu", "demarrealignment", "demarreallmodes", "demarreappendices", "demarrearrangedpages", "demarrearriereplan", "demarreaside", "demarreattachment", "demarrebackmatter", "demarrebar", "demarrebbordermatrix", "demarrebitmapimage", "demarreblockquote", "demarrebodymatter", "demarrebordermatrix", "demarreboxedcolumns", "demarrebtxlabeltext", "demarrebtxrenderingdefinitions", "demarrebuffer", "demarrecases", "demarrecatcodetable", "demarrecenteraligned", "demarrechapter", "demarrecharacteralign", "demarrecheckedfences", "demarrechemical", "demarrechemicaltext", "demarreciter", "demarrecollect", "demarrecollecting", "demarrecolorintent", "demarrecoloronly", "demarrecolorset", "demarrecolumns", "demarrecolumnset", "demarrecolumnsetspan", "demarrecolumnspan", "demarrecombination", "demarrecomment", "demarrecomposant", "demarrecontextcode", "demarrecontextdefinitioncode", "demarrecouleur", "demarrectxfunction", "demarrectxfunctiondefinition", "demarrecurrentcolor", "demarrecurrentlistentrywrapper", "demarredelimited", "demarredelimitedtext", "demarredisplaymath", "demarredmath", "demarredocument", "demarreeffect", "demarreelement", "demarreembeddedxtable", "demarreendnote", "demarreendofline", "demarreenvironement", "demarreexceptions", "demarreexpanded", "demarreexpandedcollect", "demarreextendedcatcodetable", "demarreexternalfigurecollection", "demarrefacingfloat", "demarrefact", "demarrefigure", "demarrefiguretext", "demarrefittingpage", "demarrefixed", "demarrefloatcombination", "demarrefont", "demarrefontclass", "demarrefontsolution", "demarrefootnote", "demarreformula", "demarreformulas", "demarreframed", "demarreframedcell", "demarreframedcontent", "demarreframedrow", "demarreframedtable", "demarreframedtext", "demarrefrontmatter", "demarregraphictext", "demarregridsnapping", "demarregroupe", "demarrehanging", "demarrehbox", "demarrehboxestohbox", "demarrehboxregister", "demarreheadtext", "demarrehelptext", "demarrehiding", "demarrehighlight", "demarrehyphenation", "demarreimath", "demarreindentation", "demarreindentedtext", "demarreinteraction", "demarreinterface", "demarreintermezzotext", "demarreintertext", "demarreitemgroup", "demarreitemgroupcolumns", "demarreitemize", "demarreknockout", "demarrelabeltext", "demarrelangue", "demarrelayout", "demarrelegend", "demarreligne", "demarreligneregleetexte", "demarrelinealignment", "demarrelinecorrection", "demarrelinefiller", "demarrelinenumbering", "demarrelines", "demarrelinetable", "demarrelinetablebody", "demarrelinetablecell", "demarrelinetablehead", "demarrelocalfootnotes", "demarrelocalheadsetup", "demarrelocallinecorrection", "demarrelocalnotes", "demarrelocalsetups", "demarrelua", "demarreluacode", "demarreluaparameterset", "demarreluasetups", "demarremakeup", "demarremargereglee", "demarremarginblock", "demarremarkedcontent", "demarremarkpages", "demarremathalignment", "demarremathcases", "demarremathlabeltext", "demarremathmatrix", "demarremathmode", "demarremathstyle", "demarrematrices", "demarrematrix", "demarremaxaligned", "demarremdformula", "demarremenuinteraction", "demarremiddlealigned", "demarremiddlemakeup", "demarremixedcolumns", "demarremode", "demarremodeset", "demarremodule", "demarremoduletestsection", "demarrempformula", "demarrenamedsection", "demarrenamedsubformulas", "demarrenarrow", "demarrenarrower", "demarrenegative", "demarrenicelyfilledbox", "demarrenointerference", "demarrenotallmodes", "demarrenotext", "demarrenotmode", "demarreoperatortext", "demarreopposite", "demarreoutputstream", "demarreoverlay", "demarreoverprint", "demarrepagecolumns", "demarrepagecomment", "demarrepagefigure", "demarrepagelayout", "demarrepagemakeup", "demarrepar", "demarreparagraph", "demarreparagraphs", "demarreparagraphscell", "demarreparbuilder", "demarrepart", "demarrepath", "demarreplacechemical", "demarreplacefigure", "demarreplaceflottant", "demarreplaceformule", "demarreplacegraphic", "demarreplaceintermezzo", "demarreplacelegend", "demarreplacepairedbox", "demarreplacetable", "demarrepositioning", "demarrepositionoverlay", "demarrepositive", "demarrepostponing", "demarrepostponingnotes", "demarreprefixtext", "demarreprocessassignmentcommand", "demarreprocessassignmentlist", "demarreprocesscommacommand", "demarreprocesscommalist", "demarreproduit", "demarreprojet", "demarreprotect", "demarreprotectedcolors", "demarrepublication", "demarrepunctuation", "demarrequotation", "demarrequote", "demarrerandomized", "demarrerandomseed", "demarrerawsetups", "demarrereadingfile", "demarrereferenceprefix", "demarreregime", "demarrereusableMPgraphic", "demarreruby", "demarrescript", "demarresdformula", "demarresection", "demarresectionblock", "demarresectionblockenvironment", "demarresectionlevel", "demarresetups", "demarreshapebox", "demarreshift", "demarresidebar", "demarresimplecolumns", "demarrespecialitem", "demarrespeech", "demarrespformula", "demarresplitformula", "demarresplittext", "demarrespread", "demarrestandardmakeup", "demarrestaticMPfigure", "demarrestaticMPgraphic", "demarrestrictinspectnextcharacter", "demarrestrut", "demarrestyle", "demarresubformulas", "demarresubject", "demarresubjectlevel", "demarresubsection", "demarresubsentence", "demarresubstack", "demarresubsubject", "demarresubsubsection", "demarresubsubsubject", "demarresubsubsubsection", "demarresubsubsubsubject", "demarresubsubsubsubsection", "demarresubsubsubsubsubject", "demarresuffixtext", "demarresymbolset", "demarretable", "demarretablehead", "demarretables", "demarretabletail", "demarretabletext", "demarretabulate", "demarretabulatehead", "demarretabulatetail", "demarretagged", "demarretaglabeltext", "demarretete", "demarretexcode", "demarretexdefinition", "demarretext", "demarretextbackground", "demarretextbackgroundmanual", "demarretextcolor", "demarretextcolorintent", "demarretextflow", "demarretextmakeup", "demarretitle", "demarretokenlist", "demarretokens", "demarretransparent", "demarretypescript", "demarretypescriptcollection", "demarretyping", "demarreuniqueMPgraphic", "demarreuniqueMPpagegraphic", "demarreunittext", "demarreunpacked", "demarreusableMPgraphic", "demarreuseMPgraphic", "demarreusemathstyleparameter", "demarreuserdata", "demarreusingbtxspecification", "demarreva", "demarrevbox", "demarrevboxregister", "demarrevboxtohbox", "demarrevboxtohboxseparator", "demarreviewerlayer", "demarrevtop", "demarrevtopregister", "demarrexcell", "demarrexcellgroup", "demarrexcolumn", "demarrexgroup", "demarrexmldisplayverbatim", "demarrexmlinlineverbatim", "demarrexmlraw", "demarrexmlsetups", "demarrexrow", "demarrexrowgroup", "demarrextable", "demarrextablebody", "demarrextablefoot", "demarrextablehead", "demarrextablenext", "determinecaracteristiqueliste", "determinecaracteristiquesregistre", "determinenumerotete", "echelle", "ecran", "ecritdansliste", "ecritentreliste", "element", "elements", "environement", "espace", "espacefixe", "espacesfixes", "etire", "faitreference", "fichierdactylo", "figureexterne", "gardeblocs", "grille", "haut", "inconnu", "installelangue", "joursemaine", "langue", "langueprincipale", "largeurligne", "ligneh", "lignenoire", "ligneregleetexte", "lignesnoires", "llongueurliste", "marquage", "marquepage", "mathematique", "menuinteraction", "mois", "montrecadre", "montrecouleur", "montredisposition", "montreedition", "montreenvironnementpolicecorps", "montregrille", "montregroupecouleur", "montrejeusymboles", "montremakeup", "montrepalette", "montrepolicecorps", "montrereglages", "montrestruts", "motdroit", "numeroformule", "numeropage", "numeros", "numerotete", "numerotetecourant", "obtientmarquage", "oriente", "periodes", "pilechamp", "placecoteacote", "placeflottant", "placeformule", "placelesunsaudessusdesautres", "placeliste", "placelisteinmbriquee", "placemarquespages", "placenotespdp", "placenotespdplocales", "placenumeropage", "placenumerotete", "placeregistre", "placesousformule", "placesurgrille", "placetextetete", "prendbuffer", "produit", "programme", "projet", "qqpart", "razmarquage", "referencepage", "referencetexte", "reflete", "reglealignement", "reglearrangement", "reglearriereplan", "reglearriereplans", "reglebarreinteraction", "reglebloc", "regleblocsection", "reglebuffer", "reglecapitales", "reglechamp", "reglechamps", "regleclipping", "reglecolonnes", "reglecommentaire", "reglecommentairepage", "reglecompoetroite", "reglecomposeenalinea", "reglecouleur", "reglecouleurs", "regledactylo", "regledemarrestoppe", "regledisposition", "regleecraninteraction", "regleelements", "regleencadre", "regleentete", "regleenumerations", "regleepaisseurligne", "regleespaceblanc", "regleespacement", "regleespacementinterligne", "regleflottant", "regleflottants", "regleformulaires", "regleformules", "reglegroupeselements", "regleinf", "regleinteraction", "regleintitule", "regleintitules", "reglejeucolonne", "reglejeusymboles", "reglelangue", "reglelignes", "reglelignesnoires", "reglelignesreglestexte", "regleliste", "reglelisteimbriquee", "reglemakeup", "reglemargereglee", "reglemarquage", "reglemarquagehyphenation", "reglemenuinteraction", "reglenumeropage", "reglenumerotationligne", "reglenumerotationpage", "reglenumerotationparagraphe", "reglenumerotete", "regleoriente", "reglepalette", "reglepapier", "regleparagraphes", "reglepdp", "regleplacementopposition", "reglepolicecorps", "reglepositionnement", "regleprogrammes", "reglereferencage", "regleregistre", "regleremplitligne", "regleremplitlignesreglees", "regleseparationflottant", "reglesousnumeropage", "reglesup", "reglesynonymes", "regletableaux", "regletabulation", "regletaillepapier", "regletete", "regletetes", "regletexte", "regletextesentete", "regletextesinf", "regletextespdp", "regletextessup", "regletextestexte", "regletolerance", "regletraitsfins", "regletransitionspage", "regletri", "regletype", "regleurl", "remplitligne", "remplitlignesreglees", "remplittexte", "sansespace", "sanslignesenteteetpdp", "sanslignessupetinf", "selectionneblocs", "separeflottant", "settext", "sousnumeropage", "stoppeJScode", "stoppeJSpreamble", "stoppeLUA", "stoppeMP", "stoppeMPclip", "stoppeMPcode", "stoppeMPdefinitions", "stoppeMPdrawing", "stoppeMPenvironment", "stoppeMPextensions", "stoppeMPinclusions", "stoppeMPinitializations", "stoppeMPpage", "stoppeMPpositiongraphic", "stoppeMPpositionmethod", "stoppeMPrun", "stoppePARSEDXML", "stoppeTABLE", "stoppeTABLEbody", "stoppeTABLEfoot", "stoppeTABLEhead", "stoppeTABLEnext", "stoppeTC", "stoppeTD", "stoppeTDs", "stoppeTEX", "stoppeTEXpage", "stoppeTH", "stoppeTN", "stoppeTR", "stoppeTRs", "stoppeTX", "stoppeTY", "stoppeXML", "stoppealign", "stoppealigneadroite", "stoppealigneagauche", "stoppealigneaumilieu", "stoppealignment", "stoppeallmodes", "stoppeappendices", "stoppearrangedpages", "stoppearriereplan", "stoppeaside", "stoppeattachment", "stoppebackmatter", "stoppebar", "stoppebbordermatrix", "stoppebitmapimage", "stoppeblockquote", "stoppebodymatter", "stoppebordermatrix", "stoppeboxedcolumns", "stoppebtxlabeltext", "stoppebtxrenderingdefinitions", "stoppebuffer", "stoppecases", "stoppecatcodetable", "stoppecenteraligned", "stoppechapter", "stoppecharacteralign", "stoppecheckedfences", "stoppechemical", "stoppechemicaltext", "stoppecollect", "stoppecollecting", "stoppecolorintent", "stoppecoloronly", "stoppecolorset", "stoppecolumns", "stoppecolumnset", "stoppecolumnsetspan", "stoppecolumnspan", "stoppecombination", "stoppecomment", "stoppecomposant", "stoppecontextcode", "stoppecontextdefinitioncode", "stoppecouleur", "stoppectxfunction", "stoppectxfunctiondefinition", "stoppecurrentcolor", "stoppecurrentlistentrywrapper", "stoppedelimited", "stoppedelimitedtext", "stoppedisplaymath", "stoppedmath", "stoppedocument", "stoppeeffect", "stoppeelement", "stoppeembeddedxtable", "stoppeendnote", "stoppeendofline", "stoppeenvironement", "stoppeexceptions", "stoppeexpanded", "stoppeexpandedcollect", "stoppeextendedcatcodetable", "stoppeexternalfigurecollection", "stoppefacingfloat", "stoppefact", "stoppefigure", "stoppefiguretext", "stoppefittingpage", "stoppefixed", "stoppefloatcombination", "stoppefont", "stoppefontclass", "stoppefontsolution", "stoppefootnote", "stoppeformula", "stoppeformulas", "stoppeframed", "stoppeframedcell", "stoppeframedcontent", "stoppeframedrow", "stoppeframedtable", "stoppeframedtext", "stoppefrontmatter", "stoppegraphictext", "stoppegridsnapping", "stoppegroupe", "stoppehanging", "stoppehbox", "stoppehboxestohbox", "stoppehboxregister", "stoppeheadtext", "stoppehelptext", "stoppehiding", "stoppehighlight", "stoppehyphenation", "stoppeimath", "stoppeindentation", "stoppeindentedtext", "stoppeinteraction", "stoppeinterface", "stoppeintermezzotext", "stoppeintertext", "stoppeitemgroup", "stoppeitemgroupcolumns", "stoppeitemize", "stoppeknockout", "stoppelabeltext", "stoppelangue", "stoppelayout", "stoppelegend", "stoppeligne", "stoppeligneregleetexte", "stoppelinealignment", "stoppelinecorrection", "stoppelinefiller", "stoppelinenumbering", "stoppelines", "stoppelinetable", "stoppelinetablebody", "stoppelinetablecell", "stoppelinetablehead", "stoppelocalfootnotes", "stoppelocalheadsetup", "stoppelocallinecorrection", "stoppelocalnotes", "stoppelocalsetups", "stoppelua", "stoppeluacode", "stoppeluaparameterset", "stoppeluasetups", "stoppemakeup", "stoppemargereglee", "stoppemarginblock", "stoppemarkedcontent", "stoppemarkpages", "stoppemathalignment", "stoppemathcases", "stoppemathlabeltext", "stoppemathmatrix", "stoppemathmode", "stoppemathstyle", "stoppematrices", "stoppematrix", "stoppemaxaligned", "stoppemdformula", "stoppemenuinteraction", "stoppemiddlealigned", "stoppemiddlemakeup", "stoppemixedcolumns", "stoppemode", "stoppemodeset", "stoppemodule", "stoppemoduletestsection", "stoppempformula", "stoppenamedsection", "stoppenamedsubformulas", "stoppenarrow", "stoppenarrower", "stoppenegative", "stoppenicelyfilledbox", "stoppenointerference", "stoppenotallmodes", "stoppenotext", "stoppenotmode", "stoppeoperatortext", "stoppeopposite", "stoppeoutputstream", "stoppeoverlay", "stoppeoverprint", "stoppepagecolumns", "stoppepagecomment", "stoppepagefigure", "stoppepagelayout", "stoppepagemakeup", "stoppepar", "stoppeparagraph", "stoppeparagraphs", "stoppeparagraphscell", "stoppeparbuilder", "stoppepart", "stoppepath", "stoppeplacechemical", "stoppeplacefigure", "stoppeplaceflottant", "stoppeplaceformule", "stoppeplacegraphic", "stoppeplaceintermezzo", "stoppeplacelegend", "stoppeplacepairedbox", "stoppeplacetable", "stoppepositioning", "stoppepositionoverlay", "stoppepositive", "stoppepostponing", "stoppepostponingnotes", "stoppeprefixtext", "stoppeprocessassignmentcommand", "stoppeprocessassignmentlist", "stoppeprocesscommacommand", "stoppeprocesscommalist", "stoppeproduit", "stoppeprojet", "stoppeprotect", "stoppeprotectedcolors", "stoppepublication", "stoppepunctuation", "stoppequotation", "stoppequote", "stopperandomized", "stopperandomseed", "stopperawsetups", "stoppereadingfile", "stoppereferenceprefix", "stopperegime", "stoppereusableMPgraphic", "stopperuby", "stoppescript", "stoppesdformula", "stoppesection", "stoppesectionblock", "stoppesectionblockenvironment", "stoppesectionlevel", "stoppesetups", "stoppeshapebox", "stoppeshift", "stoppesidebar", "stoppesimplecolumns", "stoppespecialitem", "stoppespeech", "stoppespformula", "stoppesplitformula", "stoppesplittext", "stoppespread", "stoppestandardmakeup", "stoppestaticMPfigure", "stoppestaticMPgraphic", "stoppestrictinspectnextcharacter", "stoppestrut", "stoppestyle", "stoppesubformulas", "stoppesubject", "stoppesubjectlevel", "stoppesubsection", "stoppesubsentence", "stoppesubstack", "stoppesubsubject", "stoppesubsubsection", "stoppesubsubsubject", "stoppesubsubsubsection", "stoppesubsubsubsubject", "stoppesubsubsubsubsection", "stoppesubsubsubsubsubject", "stoppesuffixtext", "stoppesymbolset", "stoppetable", "stoppetablehead", "stoppetables", "stoppetabletail", "stoppetabletext", "stoppetabulate", "stoppetabulatehead", "stoppetabulatetail", "stoppetagged", "stoppetaglabeltext", "stoppetete", "stoppetexcode", "stoppetexdefinition", "stoppetext", "stoppetextbackground", "stoppetextbackgroundmanual", "stoppetextcolor", "stoppetextcolorintent", "stoppetextflow", "stoppetextmakeup", "stoppetitle", "stoppetokenlist", "stoppetokens", "stoppetransparent", "stoppetypescript", "stoppetypescriptcollection", "stoppetyping", "stoppeuniqueMPgraphic", "stoppeuniqueMPpagegraphic", "stoppeunittext", "stoppeunpacked", "stoppeusableMPgraphic", "stoppeuseMPgraphic", "stoppeusemathstyleparameter", "stoppeuserdata", "stoppeusingbtxspecification", "stoppeva", "stoppevbox", "stoppevboxregister", "stoppevboxtohbox", "stoppevboxtohboxseparator", "stoppeviewerlayer", "stoppevtop", "stoppevtopregister", "stoppexcell", "stoppexcellgroup", "stoppexcolumn", "stoppexgroup", "stoppexmldisplayverbatim", "stoppexmlinlineverbatim", "stoppexmlraw", "stoppexmlsetups", "stoppexrow", "stoppexrowgroup", "stoppextable", "stoppextablebody", "stoppextablefoot", "stoppextablehead", "stoppextablenext", "symbole", "tapebuffer", "textenotepdp", "traduire", "traiteblocs", "traitfin", "traitsfins", "uneligne", "utiliseJSscripts", "utiliseURL", "utiliseblocs", "utilisechemin", "utilisedocumentexterne", "utilisefigureexterne", "utilisemodule", "utilisepsiteaudioexterne", "utilisesymboles", "utiliseurl", "va", "vaalaboite", "vaalapage", "vaenbas", "valeurcouleur", "vide" },
+ ["it"]={ "GIORNOSETTIMANA", "Lettera", "Lettere", "MESE", "Numeri", "Numeriromani", "PAROLA", "PAROLE", "Parola", "Parole", "adattacampo", "adattalayout", "al", "allineacentro", "allineadestra", "allineasinistra", "ambiente", "ap", "apagina", "barracolori", "barrainterazione", "cambiaafontdeltesto", "campi", "capello", "chim", "circondato", "clonacampo", "colonna", "colore", "coloregrigio", "commento", "componenet", "confrontagruppocolori", "confrontatavolozza", "convertinumero", "copiacampo", "correggispaziobianco", "da", "daqualcheparte", "data", "datadioggi", "definisci", "definisciaccento", "definisciambientefontdeltesto", "definisciblocco", "definiscibloccosezione", "definiscibuffer", "definiscicampo", "definiscicapoversi", "definiscicarattere", "definiscicolore", "definiscicomando", "definisciconversione", "definiscidescrizione", "definiscidimensionicarta", "definiscielenco", "definiscielencocombinato", "definiscienumerazione", "definiscietichetta", "definiscifigurasimbolo", "definiscifont", "definiscifontdeltesto", "definisciformatoriferimento", "definiscigruppocolonne", "definiscigruppocolori", "definiscihbox", "definisciincorniciato", "definisciiniziatermina", "definiscilayout", "definiscimakeup", "definiscimarcatura", "definiscimenuinterazione", "definiscimodellotabella", "definiscioggettomobile", "definisciordinamento", "definisciprofilo", "definisciprogramma", "definisciregistro", "definisciriferimento", "definiscisezione", "definiscisimbolo", "definiscisinonimi", "definiscisinonimofont", "definiscisottocampo", "definiscisovrapposizione", "definiscistackcampi", "definiscistile", "definiscistilefont", "definiscitabulato", "definiscitavolozza", "definiscitesta", "definiscitesto", "definiscitestoincorniciato", "definiscitype", "definiscityping", "determinacaratteristicheregistro", "determinacarattersticheelenco", "determinanumerotesta", "elaborablocchi", "elementi", "elemento", "figuraesterna", "giornosettimana", "griglia", "ignoto", "impostaallineamento", "impostaampiezzariga", "impostabarrainterazione", "impostablocco", "impostabloccosezione", "impostabuffer", "impostacampi", "impostacampo", "impostacapoversi", "impostacaption", "impostacaptions", "impostacima", "impostaclippling", "impostacolonne", "impostacolore", "impostacolori", "impostacommento", "impostacommentopagina", "impostadimensionicarta", "impostaelementi", "impostaelencazioni", "impostaelenco", "impostaelencocombinato", "impostaenumerazioni", "impostafondo", "impostafontdeltesto", "impostaforms", "impostaformule", "impostagruppocolonne", "impostaincorniciato", "impostainiziatermina", "impostainstestazione", "impostainterazione", "impostainterlinea", "impostalayout", "impostalineemargine", "impostalineenere", "impostalineeriempimento", "impostalineesottili", "impostalineetesto", "impostalingua", "impostamaiuscole", "impostamakeup", "impostamarcatura", "impostamenuinterazione", "impostamenzione", "impostanumerazionecapoversi", "impostanumerazionepagina", "impostanumerazionerighe", "impostanumeropagina", "impostanumerosottopagina", "impostanumerotesta", "impostaoggettimobili", "impostaoggettomobile", "impostaordinamento", "impostaparranging", "impostapdp", "impostapiustretto", "impostaposizionamento", "impostaposizionamentoopposti", "impostaprogrammi", "impostaregistro", "impostarientro", "impostariferimento", "impostarighe", "impostarigheriempimento", "impostarigovuoto", "impostarotazione", "impostaschermointerazione", "impostasegnosillabazione", "impostasetsimboli", "impostasfondi", "impostasfondo", "impostasinonimi", "impostaspaziatura", "impostaspaziobianco", "impostaspezzamentooggettomobile", "impostatabelle", "impostatabulato", "impostatavolozza", "impostatesta", "impostateste", "impostatesticima", "impostatestifondo", "impostatestiincorniciati", "impostatestiintestazioni", "impostatestipdp", "impostatesto", "impostatestotesti", "impostatolleranza", "impostatransizionepagina", "impostatype", "impostatyping", "impostaurl", "incorniciato", "iniziaJScode", "iniziaJSpreamble", "iniziaLUA", "iniziaMP", "iniziaMPclip", "iniziaMPcode", "iniziaMPdefinitions", "iniziaMPdrawing", "iniziaMPenvironment", "iniziaMPextensions", "iniziaMPinclusions", "iniziaMPinitializations", "iniziaMPpage", "iniziaMPpositiongraphic", "iniziaMPpositionmethod", "iniziaMPrun", "iniziaPARSEDXML", "iniziaTABLE", "iniziaTABLEbody", "iniziaTABLEfoot", "iniziaTABLEhead", "iniziaTABLEnext", "iniziaTC", "iniziaTD", "iniziaTDs", "iniziaTEX", "iniziaTEXpage", "iniziaTH", "iniziaTN", "iniziaTR", "iniziaTRs", "iniziaTX", "iniziaTY", "iniziaXML", "iniziaalign", "iniziaalignment", "iniziaallineacentro", "iniziaallineadestra", "iniziaallineasinistra", "iniziaallmodes", "iniziaambiente", "iniziaappendices", "iniziaarrangedpages", "iniziaaside", "iniziaattachment", "iniziabackmatter", "iniziabar", "iniziabbordermatrix", "iniziabitmapimage", "iniziablockquote", "iniziabodymatter", "iniziabordermatrix", "iniziaboxedcolumns", "iniziabtxlabeltext", "iniziabtxrenderingdefinitions", "iniziabuffer", "iniziacases", "iniziacatcodetable", "iniziacenteraligned", "iniziachapter", "iniziacharacteralign", "iniziacheckedfences", "iniziachemical", "iniziachemicaltext", "iniziacollect", "iniziacollecting", "iniziacolore", "iniziacolorintent", "iniziacoloronly", "iniziacolorset", "iniziacolumns", "iniziacolumnset", "iniziacolumnsetspan", "iniziacolumnspan", "iniziacombination", "iniziacomment", "iniziacomponenet", "iniziacontextcode", "iniziacontextdefinitioncode", "iniziactxfunction", "iniziactxfunctiondefinition", "iniziacurrentcolor", "iniziacurrentlistentrywrapper", "iniziadelimited", "iniziadelimitedtext", "iniziadisplaymath", "iniziadmath", "iniziadocument", "iniziaeffect", "iniziaelement", "iniziaelemento", "iniziaembeddedxtable", "iniziaendnote", "iniziaendofline", "iniziaexceptions", "iniziaexpanded", "iniziaexpandedcollect", "iniziaextendedcatcodetable", "iniziaexternalfigurecollection", "iniziafacingfloat", "iniziafact", "iniziafigure", "iniziafiguretext", "iniziafittingpage", "iniziafixed", "iniziafloatcombination", "iniziafont", "iniziafontclass", "iniziafontsolution", "iniziafootnote", "iniziaformula", "iniziaformulas", "iniziaframedcell", "iniziaframedcontent", "iniziaframedrow", "iniziaframedtable", "iniziaframedtext", "iniziafrontmatter", "iniziagraphictext", "iniziagridsnapping", "iniziahanging", "iniziahbox", "iniziahboxestohbox", "iniziahboxregister", "iniziaheadtext", "iniziahelptext", "iniziahiding", "iniziahighlight", "iniziahyphenation", "iniziaimath", "iniziaimpaccato", "iniziaincorniciato", "iniziaindentation", "iniziaindentedtext", "iniziainteraction", "iniziainterface", "iniziaintermezzotext", "iniziaintertext", "iniziaitemgroup", "iniziaitemgroupcolumns", "iniziaitemize", "iniziaknockout", "inizialabeltext", "inizialayout", "inizialegend", "inizialinealignment", "inizialineamargine", "inizialineatesto", "inizialinecorrection", "inizialinefiller", "inizialinenumbering", "inizialines", "inizialinetable", "inizialinetablebody", "inizialinetablecell", "inizialinetablehead", "inizialingua", "inizialocalfootnotes", "inizialocalheadsetup", "inizialocallinecorrection", "inizialocalnotes", "inizialocalsetups", "inizialua", "inizialuacode", "inizialuaparameterset", "inizialuasetups", "iniziamakeup", "iniziamarginblock", "iniziamarkedcontent", "iniziamarkpages", "iniziamathalignment", "iniziamathcases", "iniziamathlabeltext", "iniziamathmatrix", "iniziamathmode", "iniziamathstyle", "iniziamatrices", "iniziamatrix", "iniziamaxaligned", "iniziamdformula", "iniziamenuinterattivo", "iniziamettiformula", "iniziamiddlealigned", "iniziamiddlemakeup", "iniziamixedcolumns", "iniziamode", "iniziamodeset", "iniziamodule", "iniziamoduletestsection", "iniziampformula", "inizianamedsection", "inizianamedsubformulas", "inizianarrow", "inizianarrower", "inizianegative", "inizianicelyfilledbox", "inizianointerference", "inizianotallmodes", "inizianotext", "inizianotmode", "iniziaoperatortext", "iniziaopposite", "iniziaoutputstream", "iniziaoverlay", "iniziaoverprint", "iniziapagecolumns", "iniziapagecomment", "iniziapagefigure", "iniziapagelayout", "iniziapagemakeup", "iniziapar", "iniziaparagraph", "iniziaparagraphs", "iniziaparagraphscell", "iniziaparbuilder", "iniziapart", "iniziapath", "iniziaplacechemical", "iniziaplacefigure", "iniziaplacefloat", "iniziaplacegraphic", "iniziaplaceintermezzo", "iniziaplacelegend", "iniziaplacepairedbox", "iniziaplacetable", "iniziapositioning", "iniziapositionoverlay", "iniziapositive", "iniziapostponing", "iniziapostponingnotes", "iniziaprefixtext", "iniziaprocessassignmentcommand", "iniziaprocessassignmentlist", "iniziaprocesscommacommand", "iniziaprocesscommalist", "iniziaprodotto", "iniziaprogetto", "iniziaprotect", "iniziaprotectedcolors", "iniziapubblicazione", "iniziapunctuation", "iniziaquotation", "iniziaquote", "iniziarandomized", "iniziarandomseed", "iniziarawsetups", "iniziareadingfile", "iniziareferenceprefix", "iniziaregime", "iniziareusableMPgraphic", "iniziariga", "iniziaruby", "iniziascript", "iniziasdformula", "iniziasection", "iniziasectionblock", "iniziasectionblockenvironment", "iniziasectionlevel", "iniziasetups", "iniziasfondo", "iniziashapebox", "iniziashift", "iniziasidebar", "iniziasimplecolumns", "iniziaspecialitem", "iniziaspeech", "iniziaspformula", "iniziasplitformula", "iniziasplittext", "iniziaspread", "iniziastandardmakeup", "iniziastaticMPfigure", "iniziastaticMPgraphic", "iniziastrictinspectnextcharacter", "iniziastrut", "iniziastyle", "iniziasubformulas", "iniziasubject", "iniziasubjectlevel", "iniziasubsection", "iniziasubsentence", "iniziasubstack", "iniziasubsubject", "iniziasubsubsection", "iniziasubsubsubject", "iniziasubsubsubsection", "iniziasubsubsubsubject", "iniziasubsubsubsubsection", "iniziasubsubsubsubsubject", "iniziasuffixtext", "iniziasymbolset", "iniziatable", "iniziatablehead", "iniziatables", "iniziatabletail", "iniziatabletext", "iniziatabulate", "iniziatabulatehead", "iniziatabulatetail", "iniziatagged", "iniziataglabeltext", "iniziatesta", "iniziatexcode", "iniziatexdefinition", "iniziatext", "iniziatextbackground", "iniziatextbackgroundmanual", "iniziatextcolor", "iniziatextcolorintent", "iniziatextflow", "iniziatextmakeup", "iniziatitle", "iniziatokenlist", "iniziatokens", "iniziatransparent", "iniziatypescript", "iniziatypescriptcollection", "iniziatyping", "iniziauniqueMPgraphic", "iniziauniqueMPpagegraphic", "iniziaunittext", "iniziaunpacked", "iniziausableMPgraphic", "iniziauseMPgraphic", "iniziausemathstyleparameter", "iniziauserdata", "iniziausingbtxspecification", "iniziavaia", "iniziavbox", "iniziavboxregister", "iniziavboxtohbox", "iniziavboxtohboxseparator", "iniziaviewerlayer", "iniziavtop", "iniziavtopregister", "iniziaxcell", "iniziaxcellgroup", "iniziaxcolumn", "iniziaxgroup", "iniziaxmldisplayverbatim", "iniziaxmlinlineverbatim", "iniziaxmlraw", "iniziaxmlsetups", "iniziaxrow", "iniziaxrowgroup", "iniziaxtable", "iniziaxtablebody", "iniziaxtablefoot", "iniziaxtablehead", "iniziaxtablenext", "inriga", "installalingua", "intorno", "lettera", "lettere", "lineanera", "lineasottile", "lineatesto", "lineenere", "lineeriempimento", "lineesottili", "lingua", "linguaprincipale", "lunghezzaelenco", "marcatura", "matematica", "menuinterattivo", "mese", "mettielenco", "mettielencocombinato", "mettifiancoafianco", "mettiformula", "mettiingriglia", "mettinotepdp", "mettinotepdplocali", "mettinumeropagina", "mettiregistro", "mettisegnalibro", "mettisottoformula", "mettiunosullaltro", "mostraambientefontdeltesto", "mostracolore", "mostracornice", "mostrafontdeltesto", "mostragriglia", "mostragruppocolori", "mostraimpostazioni", "mostralyout", "mostramakeup", "mostrasetsimboli", "mostrastampa", "mostrastruts", "mostratavolozza", "nascondiblocchi", "nientelineecimafondo", "nientelineintestazionepdp", "nientespazio", "nota", "numeri", "numeriromani", "numeroformula", "numeropagina", "numeropaginacompleto", "numerotesta", "numerotestacorrente", "pagina", "paroladestra", "ped", "pedap", "perlungo", "posizionanumerotesta", "posizionatestotesta", "posizione", "prendibuffer", "prendimarcatura", "prodotto", "progetto", "programma", "pulsante", "pulsantemenu", "pulsantinterazione", "punti", "qualcheriga", "reimpostamarcatura", "rif", "riferimento", "riferimentopagina", "riferimentotesto", "riflessione", "rigariempimento", "rigovuoto", "ruota", "scala", "schermo", "scrividentroelenco", "scriviinelenco", "segnalibro", "selezionablocchi", "settext", "sfondo", "simbolo", "spazifissi", "spazio", "spaziofisso", "spessoreriga", "spezzaoggettomobile", "stackcampi", "stirato", "terminaJScode", "terminaJSpreamble", "terminaLUA", "terminaMP", "terminaMPclip", "terminaMPcode", "terminaMPdefinitions", "terminaMPdrawing", "terminaMPenvironment", "terminaMPextensions", "terminaMPinclusions", "terminaMPinitializations", "terminaMPpage", "terminaMPpositiongraphic", "terminaMPpositionmethod", "terminaMPrun", "terminaPARSEDXML", "terminaTABLE", "terminaTABLEbody", "terminaTABLEfoot", "terminaTABLEhead", "terminaTABLEnext", "terminaTC", "terminaTD", "terminaTDs", "terminaTEX", "terminaTEXpage", "terminaTH", "terminaTN", "terminaTR", "terminaTRs", "terminaTX", "terminaTY", "terminaXML", "terminaalign", "terminaalignment", "terminaallineacentro", "terminaallineadestra", "terminaallineasinistra", "terminaallmodes", "terminaambiente", "terminaappendices", "terminaarrangedpages", "terminaaside", "terminaattachment", "terminabackmatter", "terminabar", "terminabbordermatrix", "terminabitmapimage", "terminablockquote", "terminabodymatter", "terminabordermatrix", "terminaboxedcolumns", "terminabtxlabeltext", "terminabtxrenderingdefinitions", "terminabuffer", "terminacases", "terminacatcodetable", "terminacenteraligned", "terminachapter", "terminacharacteralign", "terminacheckedfences", "terminachemical", "terminachemicaltext", "terminacollect", "terminacollecting", "terminacolore", "terminacolorintent", "terminacoloronly", "terminacolorset", "terminacolumns", "terminacolumnset", "terminacolumnsetspan", "terminacolumnspan", "terminacombination", "terminacomment", "terminacomponenet", "terminacontextcode", "terminacontextdefinitioncode", "terminactxfunction", "terminactxfunctiondefinition", "terminacurrentcolor", "terminacurrentlistentrywrapper", "terminadelimited", "terminadelimitedtext", "terminadisplaymath", "terminadmath", "terminadocument", "terminaeffect", "terminaelement", "terminaelemento", "terminaembeddedxtable", "terminaendnote", "terminaendofline", "terminaexceptions", "terminaexpanded", "terminaexpandedcollect", "terminaextendedcatcodetable", "terminaexternalfigurecollection", "terminafacingfloat", "terminafact", "terminafigure", "terminafiguretext", "terminafittingpage", "terminafixed", "terminafloatcombination", "terminafont", "terminafontclass", "terminafontsolution", "terminafootnote", "terminaformula", "terminaformulas", "terminaframedcell", "terminaframedcontent", "terminaframedrow", "terminaframedtable", "terminaframedtext", "terminafrontmatter", "terminagraphictext", "terminagridsnapping", "terminahanging", "terminahbox", "terminahboxestohbox", "terminahboxregister", "terminaheadtext", "terminahelptext", "terminahiding", "terminahighlight", "terminahyphenation", "terminaimath", "terminaimpaccato", "terminaincorniciato", "terminaindentation", "terminaindentedtext", "terminainteraction", "terminainterface", "terminaintermezzotext", "terminaintertext", "terminaitemgroup", "terminaitemgroupcolumns", "terminaitemize", "terminaknockout", "terminalabeltext", "terminalayout", "terminalegend", "terminalinealignment", "terminalineamargine", "terminalineatesto", "terminalinecorrection", "terminalinefiller", "terminalinenumbering", "terminalines", "terminalinetable", "terminalinetablebody", "terminalinetablecell", "terminalinetablehead", "terminalingua", "terminalocalfootnotes", "terminalocalheadsetup", "terminalocallinecorrection", "terminalocalnotes", "terminalocalsetups", "terminalua", "terminaluacode", "terminaluaparameterset", "terminaluasetups", "terminamakeup", "terminamarginblock", "terminamarkedcontent", "terminamarkpages", "terminamathalignment", "terminamathcases", "terminamathlabeltext", "terminamathmatrix", "terminamathmode", "terminamathstyle", "terminamatrices", "terminamatrix", "terminamaxaligned", "terminamdformula", "terminamenuinterattivo", "terminamettiformula", "terminamiddlealigned", "terminamiddlemakeup", "terminamixedcolumns", "terminamode", "terminamodeset", "terminamodule", "terminamoduletestsection", "terminampformula", "terminanamedsection", "terminanamedsubformulas", "terminanarrow", "terminanarrower", "terminanegative", "terminanicelyfilledbox", "terminanointerference", "terminanotallmodes", "terminanotext", "terminanotmode", "terminaoperatortext", "terminaopposite", "terminaoutputstream", "terminaoverlay", "terminaoverprint", "terminapagecolumns", "terminapagecomment", "terminapagefigure", "terminapagelayout", "terminapagemakeup", "terminapar", "terminaparagraph", "terminaparagraphs", "terminaparagraphscell", "terminaparbuilder", "terminapart", "terminapath", "terminaplacechemical", "terminaplacefigure", "terminaplacefloat", "terminaplacegraphic", "terminaplaceintermezzo", "terminaplacelegend", "terminaplacepairedbox", "terminaplacetable", "terminapositioning", "terminapositionoverlay", "terminapositive", "terminapostponing", "terminapostponingnotes", "terminaprefixtext", "terminaprocessassignmentcommand", "terminaprocessassignmentlist", "terminaprocesscommacommand", "terminaprocesscommalist", "terminaprodotto", "terminaprogetto", "terminaprotect", "terminaprotectedcolors", "terminapubblicazione", "terminapunctuation", "terminaquotation", "terminaquote", "terminarandomized", "terminarandomseed", "terminarawsetups", "terminareadingfile", "terminareferenceprefix", "terminaregime", "terminareusableMPgraphic", "terminariga", "terminaruby", "terminascript", "terminasdformula", "terminasection", "terminasectionblock", "terminasectionblockenvironment", "terminasectionlevel", "terminasetups", "terminasfondo", "terminashapebox", "terminashift", "terminasidebar", "terminasimplecolumns", "terminaspecialitem", "terminaspeech", "terminaspformula", "terminasplitformula", "terminasplittext", "terminaspread", "terminastandardmakeup", "terminastaticMPfigure", "terminastaticMPgraphic", "terminastrictinspectnextcharacter", "terminastrut", "terminastyle", "terminasubformulas", "terminasubject", "terminasubjectlevel", "terminasubsection", "terminasubsentence", "terminasubstack", "terminasubsubject", "terminasubsubsection", "terminasubsubsubject", "terminasubsubsubsection", "terminasubsubsubsubject", "terminasubsubsubsubsection", "terminasubsubsubsubsubject", "terminasuffixtext", "terminasymbolset", "terminatable", "terminatablehead", "terminatables", "terminatabletail", "terminatabletext", "terminatabulate", "terminatabulatehead", "terminatabulatetail", "terminatagged", "terminataglabeltext", "terminatesta", "terminatexcode", "terminatexdefinition", "terminatext", "terminatextbackground", "terminatextbackgroundmanual", "terminatextcolor", "terminatextcolorintent", "terminatextflow", "terminatextmakeup", "terminatitle", "terminatokenlist", "terminatokens", "terminatransparent", "terminatypescript", "terminatypescriptcollection", "terminatyping", "terminauniqueMPgraphic", "terminauniqueMPpagegraphic", "terminaunittext", "terminaunpacked", "terminausableMPgraphic", "terminauseMPgraphic", "terminausemathstyleparameter", "terminauserdata", "terminausingbtxspecification", "terminavaia", "terminavbox", "terminavboxregister", "terminavboxtohbox", "terminavboxtohboxseparator", "terminaviewerlayer", "terminavtop", "terminavtopregister", "terminaxcell", "terminaxcellgroup", "terminaxcolumn", "terminaxgroup", "terminaxmldisplayverbatim", "terminaxmlinlineverbatim", "terminaxmlraw", "terminaxmlsetups", "terminaxrow", "terminaxrowgroup", "terminaxtable", "terminaxtablebody", "terminaxtablefoot", "terminaxtablehead", "terminaxtablenext", "testonotapdp", "testoriempimento", "tieniblocchi", "traduci", "usaJSscripts", "usaURL", "usablocco", "usacartella", "usacolonnasonoraesterna", "usadocumentoesterno", "usafiguraesterna", "usamodulo", "usasimboli", "usaurl", "vaia", "vaiabox", "vaiapagina", "vaigiu", "valorecolore", "versione" },
+ ["nl"]={ "Cijfers", "Kap", "Letter", "Letters", "MAAND", "Romeins", "WEEKDAG", "WOORD", "WOORDEN", "Woord", "Woorden", "achtergrond", "bepaalkopnummer", "bepaallijstkenmerken", "bepaalregisterkenmerken", "bewaarbuffer", "blanko", "blokje", "blokjes", "cijfers", "converteernummer", "copieerveld", "corrigeerwitruimte", "datum", "definieer", "definieeraccent", "definieeralineas", "definieerblok", "definieerbuffer", "definieercombinatie", "definieercommando", "definieerconversie", "definieerfiguursymbool", "definieerfont", "definieerfontstijl", "definieerfontsynoniem", "definieerhbox", "definieeringesprongentext", "definieerinteractiemenu", "definieeritemgroep", "definieerkadertekst", "definieerkarakter", "definieerkleur", "definieerkleurgroep", "definieerkolomgroep", "definieerkolomovergang", "definieerkop", "definieerkorps", "definieerkorpsomgeving", "definieerlayer", "definieerlayout", "definieerletter", "definieerlijst", "definieermarkering", "definieeromlijnd", "definieeropmaak", "definieeroverlay", "definieerpaginaovergang", "definieerpalet", "definieerpapierformaat", "definieerplaats", "definieerplaatsblok", "definieerprofiel", "definieerprogramma", "definieerreferentie", "definieerreferentieformaat", "definieerregister", "definieersamengesteldelijst", "definieersectie", "definieersectieblok", "definieersorteren", "definieerstartstop", "definieersubveld", "definieersymbool", "definieersynoniemen", "definieertabelvorm", "definieertabulatie", "definieertekst", "definieertekstachtergrond", "definieertype", "definieertypen", "definieerveld", "definieerveldstapel", "definieerwiskundeuitlijnen", "doordefinieren", "doorlabelen", "doornummeren", "dunnelijn", "dunnelijnen", "eenregel", "ergens", "externfiguur", "formulenummer", "gebruikJSscripts", "gebruikURL", "gebruikblokken", "gebruikexterndocument", "gebruikexternfiguur", "gebruikexterngeluidsfragment", "gebruikmodule", "gebruikpad", "gebruiksymbolen", "gebruiktypescript", "gebruiktypescriptfile", "gebruikurl", "geenbovenenonderregels", "geenhoofdenvoetregels", "geenspatie", "grijskleur", "haalbuffer", "haalmarkering", "haarlijn", "handhaafblokken", "hoofdtaal", "hoog", "huidigedatum", "huidigekopnummer", "inlijnd", "inregel", "installeertaal", "interactiebalk", "interactiebuttons", "interactiemenu", "invullijnen", "invulregel", "invultekst", "kleur", "kleurenbalk", "kleurwaarde", "kloonveld", "kolom", "kopnummer", "laag", "laho", "legeregels", "letter", "letters", "lijndikte", "lijstlengte", "maand", "markeer", "naar", "naarbox", "naarpagina", "nokap", "noot", "omgeving", "omlaag", "omlijnd", "onbekend", "onderdeel", "op", "oppagina", "pagina", "paginanummer", "paginareferentie", "paslayoutaan", "passendveld", "plaatsbookmarks", "plaatsformule", "plaatskopnummer", "plaatskoptekst", "plaatslijst", "plaatslijstmetsynoniemen", "plaatslokalevoetnoten", "plaatsnaastelkaar", "plaatsonderelkaar", "plaatsopgrid", "plaatspaginanummer", "plaatsplaatsblok", "plaatsregister", "plaatsruwelijst", "plaatssamengesteldelijst", "plaatssubformule", "plaatsvoetnoten", "positioneer", "produkt", "programma", "projekt", "punten", "refereer", "referentie", "regellinks", "regelmidden", "regelrechts", "resetmarkering", "romeins", "rooster", "roteer", "schaal", "scherm", "schrijfnaarlijst", "schrijftussenlijst", "selecteerblokken", "som", "spatie", "spiegel", "splitsplaatsblok", "startachtergrond", "startinteractiemenu", "startkantlijn", "startkleur", "startkop", "startlokalevoetnoten", "startmargeblok", "startnaar", "startomgeving", "startomlijnd", "startonderdeel", "startopelkaar", "startplaatsformule", "startplaatsplaatsblok", "startprodukt", "startprojekt", "startpublicatie", "startregel", "startregelcorrectie", "startregellinks", "startregelmidden", "startregelrechts", "startsom", "starttaal", "starttekstachtergrond", "starttekstlijn", "startuitlijnen", "stelachtergrondenin", "stelachtergrondin", "stelalineasin", "stelarrangerenin", "stelblankoin", "stelblokin", "stelblokjesin", "stelblokkopjein", "stelblokkopjesin", "stelbovenin", "stelboventekstenin", "stelbufferin", "stelciterenin", "stelclipin", "stelcommentaarin", "steldoordefinierenin", "steldoornummerenin", "steldunnelijnenin", "stelformulein", "stelformulesin", "stelformulierenin", "stelhoofdin", "stelhoofdtekstenin", "stelingesprongentextin", "stelinmargein", "stelinspringenin", "stelinteractiebalkin", "stelinteractiein", "stelinteractiemenuin", "stelinteractieschermin", "stelinterliniein", "stelinvullijnenin", "stelinvulregelsin", "stelitemgroepin", "stelitemsin", "stelkadertekstenin", "stelkadertekstin", "stelkantlijnin", "stelkapitalenin", "stelkleurenin", "stelkleurin", "stelkolomgroepin", "stelkolomgroepregelsin", "stelkolomgroepstartin", "stelkolommenin", "stelkopin", "stelkopnummerin", "stelkoppeltekenin", "stelkoppenin", "stelkorpsin", "stellayoutin", "stellijndiktein", "stellijstin", "stelmargeblokkenin", "stelmarkeringin", "stelnaastplaatsenin", "stelomlijndin", "stelonderin", "stelondertekstenin", "stelopmaakin", "stelopsommingenin", "stelpaginacommentaarin", "stelpaginanummerin", "stelpaginanummeringin", "stelpaginaovergangenin", "stelpaletin", "stelpapierformaatin", "stelpapierin", "stelparagraafnummerenin", "stelplaatsblokin", "stelplaatsblokkenin", "stelplaatsbloksplitsenin", "stelplaatsin", "stelpositionerenin", "stelprogrammasin", "stelrefererenin", "stelregelnummerenin", "stelregelsin", "stelregisterin", "stelroterenin", "stelsamengesteldelijstin", "stelsectieblokin", "stelsmallerin", "stelsorterenin", "stelspatieringin", "stelstartstopin", "stelsubpaginanummerin", "stelsymboolsetin", "stelsynoniemenin", "steltaalin", "steltabellenin", "steltabulatiein", "steltekstachtergrondin", "steltekstin", "steltekstinhoudin", "steltekstlijnenin", "stelteksttekstenin", "steltolerantiein", "steltypein", "steltypenin", "steluitlijnenin", "stelurlin", "stelveldenin", "stelveldin", "stelvoetin", "stelvoettekstenin", "stelwiskundeuitlijnenin", "stelwitruimtein", "stopachtergrond", "stopinteractiemenu", "stopkantlijn", "stopkleur", "stopkop", "stoplokalevoetnoten", "stopmargeblok", "stopnaar", "stopomgeving", "stopomlijnd", "stoponderdeel", "stopopelkaar", "stopplaatsformule", "stopplaatsplaatsblok", "stopprodukt", "stopprojekt", "stoppublicatie", "stopregel", "stopregelcorrectie", "stopregellinks", "stopregelmidden", "stopregelrechts", "stopsom", "stoptaal", "stoptekstachtergrond", "stoptekstlijn", "stopuitlijnen", "subpaginanummer", "switchnaarkorps", "symbool", "taal", "tekstlijn", "tekstreferentie", "testkolom", "testpagina", "toelichting", "toongrid", "tooninstellingen", "toonkader", "toonkleur", "toonkleurgroep", "toonkorps", "toonkorpsomgeving", "toonlayout", "toonopmaak", "toonpalet", "toonprint", "toonstruts", "toonsymboolset", "uit", "uitgerekt", "vastespatie", "vastespaties", "veld", "veldstapel", "verbergblokken", "vergelijkkleurgroep", "vergelijkpalet", "versie", "vertaal", "verwerkblokken", "voetnoottekst", "volledigepaginanummer", "volledigregister", "voluit", "weekdag", "wiskunde", "woordrechts" },
+ ["pe"]={ "آیتم", "آیتمها", "آینه", "از", "استفاده‌بلوکها", "استفاده‌دستخط‌تایپ", "استفاده‌شکل‌خارجی", "استفاده‌قطعه‌موزیک‌خارجی", "استفاده‌مدول", "استفاده‌مسیر", "استفاده‌نمادها", "استفاده‌نوشتارخارجی", "استفاده‌پرونده‌دستخط‌تایپ", "اعدادلاتین", "افزودن", "انتخاب‌بلوکها", "بارگذاری‌آرایش", "بارگذاری‌آیتمها", "بارگذاری‌ارجاع", "بارگذاری‌اندازه‌برگ", "بارگذاری‌باریکتر", "بارگذاری‌بافر", "بارگذاری‌بالا", "بارگذاری‌بردباری", "بارگذاری‌برنامه‌ها", "بارگذاری‌برگ", "بارگذاری‌بلوک", "بارگذاری‌بلوک‌بخش", "بارگذاری‌تایپ", "بارگذاری‌تایپ‌کردن", "بارگذاری‌ترتیب", "بارگذاری‌تنظیم", "بارگذاری‌تنظیم‌ریاضی", "بارگذاری‌ته‌برگ", "بارگذاری‌تورفتگی", "بارگذاری‌توضیح", "بارگذاری‌توضیح‌صفحه", "بارگذاری‌ثبت", "بارگذاری‌جانشانی", "بارگذاری‌جدولها", "بارگذاری‌جدول‌بندی", "بارگذاری‌خالی", "بارگذاری‌خطها", "بارگذاری‌خطهای‌حاشیه", "بارگذاری‌خطهای‌سیاه", "بارگذاری‌خطهای‌متن", "بارگذاری‌خطهای‌مجموعه‌ستون", "بارگذاری‌خطها‌ی‌نازک", "بارگذاری‌درج‌درخطها", "بارگذاری‌درج‌مخالف", "بارگذاری‌دوران", "بارگذاری‌رنگ", "بارگذاری‌رنگها", "بارگذاری‌زبان", "بارگذاری‌ستونها", "بارگذاری‌سر", "بارگذاری‌سربرگ", "بارگذاری‌سرها", "بارگذاری‌شرح", "بارگذاری‌شرحها", "بارگذاری‌شروع‌مجموعه‌ستون", "بارگذاری‌شروع‌پایان", "بارگذاری‌شماره‌زیرصفحه", "بارگذاری‌شماره‌سر", "بارگذاری‌شماره‌صفحه", "بارگذاری‌شماره‌گذاریها", "بارگذاری‌شماره‌گذاری‌صفحه", "بارگذاری‌شماره‌گذاری‌پاراگراف", "بارگذاری‌شماره‌‌گذاری‌خط", "بارگذاری‌شناور", "بارگذاری‌شناورها", "بارگذاری‌شکافتن‌شناورها", "بارگذاری‌طرح", "بارگذاری‌طرح‌بندی", "بارگذاری‌عرض‌خط", "بارگذاری‌فاصله‌بین‌خط", "بارگذاری‌فرمولها", "بارگذاری‌فضای‌سفید", "بارگذاری‌فضا‌گذاری", "بارگذاری‌قالبی", "بارگذاری‌قلم‌متن", "بارگذاری‌لوح", "بارگذاری‌لیست", "بارگذاری‌لیست‌ترکیبی", "بارگذاری‌مترادفها", "بارگذاری‌متن", "بارگذاری‌متنهای‌بالا", "بارگذاری‌متن‌سربرگ", "بارگذاری‌متن‌قالبی", "بارگذاری‌متن‌متنها", "بارگذاری‌متن‌پانوشت", "بارگذاری‌متن‌پایین", "بارگذاری‌مجموعه‌ستون", "بارگذاری‌مجموعه‌نماد", "بارگذاری‌منوی‌پانل", "بارگذاری‌مکان‌گذاری", "بارگذاری‌میدان", "بارگذاری‌میدانها", "بارگذاری‌میله‌پانل", "بارگذاری‌نشانه‌شکستن", "بارگذاری‌نشانه‌گذاری", "بارگذاری‌نقل", "بارگذاری‌پاراگرافها", "بارگذاری‌پانل", "بارگذاری‌پایین", "بارگذاری‌پرده‌پانل", "بارگذاری‌پرکردن‌خطها", "بارگذاری‌پس‌زمینه", "بارگذاری‌پس‌زمینه‌ها", "بارگذاری‌چیدن", "بارگذاری‌گذارصفحه", "بارگذاری‌گروههای‌آیتم", "بارگذاری‌گروه‌آیتم", "بازنشانی‌نشانه‌گذاری", "بدون‌خط‌بالاوپایین", "بدون‌خط‌سروته‌برگ", "بدون‌فضا", "برنامه", "بروبه", "بروبه‌جعبه", "بروبه‌صفحه", "بروپایین", "بلند", "بلوکهای‌پردازش", "بلوکها‌پنهان", "بنویس‌بین‌لیست", "بنویس‌در‌لیست", "تاریخ", "تاریخ‌جاری", "تایپ", "تایپ‌بافر", "تایپ‌پرونده", "ترجمه", "تعریف", "تعریف‌آرایش", "تعریف‌الگوی‌جدول", "تعریف‌اندازه‌برگ", "تعریف‌بافر", "تعریف‌بخش", "تعریف‌برنامه", "تعریف‌برچسب", "تعریف‌بلوک", "تعریف‌بلوک‌بخش", "تعریف‌تایپ", "تعریف‌تایپ‌کردن", "تعریف‌تبدیل", "تعریف‌ترتیب", "تعریف‌ترکیب", "تعریف‌تنظیم‌ریاضی", "تعریف‌توده‌میدان", "تعریف‌ثبت", "تعریف‌جانشانی", "تعریف‌جدول‌بندی", "تعریف‌جعبه‌‌افقی", "تعریف‌حرف", "تعریف‌رنگ", "تعریف‌زیرمیدان", "تعریف‌سبک", "تعریف‌سبک‌قلم", "تعریف‌سر", "تعریف‌شرح", "تعریف‌شروع‌پایان", "تعریف‌شماره‌بندی", "تعریف‌شمایل‌مرجع", "تعریف‌شناور", "تعریف‌شکستن‌ستون", "تعریف‌شکست‌صفحه", "تعریف‌طرح‌بندی", "تعریف‌فرمان", "تعریف‌قالبی", "تعریف‌قلم", "تعریف‌قلم‌متن", "تعریف‌لایه", "تعریف‌لهجه", "تعریف‌لوح", "تعریف‌لیست", "تعریف‌لیست‌ترکیبی", "تعریف‌مترادفها", "تعریف‌مترادف‌قلم", "تعریف‌متن", "تعریف‌متن‌قالبی", "تعریف‌مجموعه‌ستون", "تعریف‌محیط‌قلم‌بدنه", "تعریف‌مرجع", "تعریف‌منوی‌پانل", "تعریف‌میدان", "تعریف‌نشانه‌گذاری", "تعریف‌نماد", "تعریف‌نمادشکل", "تعریف‌پاراگرافها", "تعریف‌پروفایل", "تعریف‌پوشش", "تعریف‌گروه‌آیتم", "تعریف‌گروه‌رنگ", "تعیین‌شماره‌سر", "تعیین‌محتوای‌متن", "تعیین‌مشخصات‌ثبت", "تعیین‌مشخصات‌لیست", "تغییربه‌قلم‌بدنه", "تنظیم‌راست", "تنظیم‌طرح‌بندی", "تنظیم‌وسط", "توجه", "توری", "تولید", "تک", "ثبت‌کامل", "حرف", "حرفها", "حفظ‌بلوکها", "خالی", "خطهای‌سیاه", "خطهای‌نازک", "خطها‌خالی", "خط‌سیاه", "خط‌متن", "خط‌مو", "خط‌نازک", "خ‌ا", "خ‌ع", "در", "درج‌ثبت", "درج‌درخط", "درج‌درخطها", "درج‌درمتن", "درج‌در‌بالای‌یکدیگر", "درج‌در‌توری", "درج‌زیرفرمول", "درج‌شماره‌سر", "درج‌شماره‌صفحه", "درج‌شناور", "درج‌فرمول", "درج‌لیست", "درج‌لیست‌خام", "درج‌لیست‌مختلط", "درج‌متن‌سر", "درج‌پانوشتها", "درج‌پانوشتهای‌موضعی", "درج‌چوب‌خط", "درج‌کنار‌به‌کنار", "درخط", "درصفحه", "درقالبی", "درمورد", "درون", "درپر", "دریافت‌بافر", "دریافت‌نشانه", "دوران", "دکمه", "دکمه‌منو", "دکمه‌پانل", "رج", "رنگ", "رنگ‌خاکستری", "روزهفته", "ریاضی", "زبان", "زبان‌اصلی", "ستون", "ستون‌امتحان", "سرپوش‌کوچک‌نه", "شروعJScode", "شروعJSpreamble", "شروعLUA", "شروعMP", "شروعMPclip", "شروعMPcode", "شروعMPdefinitions", "شروعMPdrawing", "شروعMPenvironment", "شروعMPextensions", "شروعMPinclusions", "شروعMPinitializations", "شروعMPpage", "شروعMPpositiongraphic", "شروعMPpositionmethod", "شروعMPrun", "شروعPARSEDXML", "شروعTABLE", "شروعTABLEbody", "شروعTABLEfoot", "شروعTABLEhead", "شروعTABLEnext", "شروعTC", "شروعTD", "شروعTDs", "شروعTEX", "شروعTEXpage", "شروعTH", "شروعTN", "شروعTR", "شروعTRs", "شروعTX", "شروعTY", "شروعXML", "شروعalign", "شروعalignment", "شروعallmodes", "شروعappendices", "شروعarrangedpages", "شروعaside", "شروعattachment", "شروعbackmatter", "شروعbar", "شروعbbordermatrix", "شروعbitmapimage", "شروعblockquote", "شروعbodymatter", "شروعbordermatrix", "شروعboxedcolumns", "شروعbtxlabeltext", "شروعbtxrenderingdefinitions", "شروعbuffer", "شروعcases", "شروعcatcodetable", "شروعcenteraligned", "شروعchapter", "شروعcharacteralign", "شروعcheckedfences", "شروعchemical", "شروعchemicaltext", "شروعcollect", "شروعcollecting", "شروعcolorintent", "شروعcoloronly", "شروعcolorset", "شروعcolumns", "شروعcolumnset", "شروعcolumnsetspan", "شروعcolumnspan", "شروعcombination", "شروعcomment", "شروعcontextcode", "شروعcontextdefinitioncode", "شروعctxfunction", "شروعctxfunctiondefinition", "شروعcurrentcolor", "شروعcurrentlistentrywrapper", "شروعdelimited", "شروعdelimitedtext", "شروعdisplaymath", "شروعdmath", "شروعdocument", "شروعeffect", "شروعelement", "شروعembeddedxtable", "شروعendnote", "شروعendofline", "شروعexceptions", "شروعexpanded", "شروعexpandedcollect", "شروعextendedcatcodetable", "شروعexternalfigurecollection", "شروعfacingfloat", "شروعfact", "شروعfigure", "شروعfiguretext", "شروعfittingpage", "شروعfixed", "شروعfloatcombination", "شروعfont", "شروعfontclass", "شروعfontsolution", "شروعfootnote", "شروعformula", "شروعformulas", "شروعframedcell", "شروعframedcontent", "شروعframedrow", "شروعframedtable", "شروعframedtext", "شروعfrontmatter", "شروعgraphictext", "شروعgridsnapping", "شروعhanging", "شروعhbox", "شروعhboxestohbox", "شروعhboxregister", "شروعheadtext", "شروعhelptext", "شروعhiding", "شروعhighlight", "شروعhyphenation", "شروعimath", "شروعindentation", "شروعindentedtext", "شروعinteraction", "شروعinterface", "شروعintermezzotext", "شروعintertext", "شروعitemgroup", "شروعitemgroupcolumns", "شروعitemize", "شروعknockout", "شروعlabeltext", "شروعlayout", "شروعlegend", "شروعlinealignment", "شروعlinecorrection", "شروعlinefiller", "شروعlinenumbering", "شروعlines", "شروعlinetable", "شروعlinetablebody", "شروعlinetablecell", "شروعlinetablehead", "شروعlocalfootnotes", "شروعlocalheadsetup", "شروعlocallinecorrection", "شروعlocalnotes", "شروعlocalsetups", "شروعlua", "شروعluacode", "شروعluaparameterset", "شروعluasetups", "شروعmakeup", "شروعmarginblock", "شروعmarkedcontent", "شروعmarkpages", "شروعmathalignment", "شروعmathcases", "شروعmathlabeltext", "شروعmathmatrix", "شروعmathmode", "شروعmathstyle", "شروعmatrices", "شروعmatrix", "شروعmaxaligned", "شروعmdformula", "شروعmiddlealigned", "شروعmiddlemakeup", "شروعmixedcolumns", "شروعmode", "شروعmodeset", "شروعmodule", "شروعmoduletestsection", "شروعmpformula", "شروعnamedsection", "شروعnamedsubformulas", "شروعnarrow", "شروعnarrower", "شروعnegative", "شروعnicelyfilledbox", "شروعnointerference", "شروعnotallmodes", "شروعnotext", "شروعnotmode", "شروعoperatortext", "شروعopposite", "شروعoutputstream", "شروعoverlay", "شروعoverprint", "شروعpagecolumns", "شروعpagecomment", "شروعpagefigure", "شروعpagelayout", "شروعpagemakeup", "شروعpar", "شروعparagraph", "شروعparagraphs", "شروعparagraphscell", "شروعparbuilder", "شروعpart", "شروعpath", "شروعplacechemical", "شروعplacefigure", "شروعplacegraphic", "شروعplaceintermezzo", "شروعplacelegend", "شروعplacepairedbox", "شروعplacetable", "شروعpositioning", "شروعpositionoverlay", "شروعpositive", "شروعpostponing", "شروعpostponingnotes", "شروعprefixtext", "شروعprocessassignmentcommand", "شروعprocessassignmentlist", "شروعprocesscommacommand", "شروعprocesscommalist", "شروعprotect", "شروعprotectedcolors", "شروعpunctuation", "شروعquotation", "شروعquote", "شروعrandomized", "شروعrandomseed", "شروعrawsetups", "شروعreadingfile", "شروعreferenceprefix", "شروعregime", "شروعreusableMPgraphic", "شروعruby", "شروعscript", "شروعsdformula", "شروعsection", "شروعsectionblock", "شروعsectionblockenvironment", "شروعsectionlevel", "شروعsetups", "شروعshapebox", "شروعshift", "شروعsidebar", "شروعsimplecolumns", "شروعspecialitem", "شروعspeech", "شروعspformula", "شروعsplitformula", "شروعsplittext", "شروعspread", "شروعstandardmakeup", "شروعstaticMPfigure", "شروعstaticMPgraphic", "شروعstrictinspectnextcharacter", "شروعstrut", "شروعstyle", "شروعsubformulas", "شروعsubject", "شروعsubjectlevel", "شروعsubsection", "شروعsubsentence", "شروعsubstack", "شروعsubsubject", "شروعsubsubsection", "شروعsubsubsubject", "شروعsubsubsubsection", "شروعsubsubsubsubject", "شروعsubsubsubsubsection", "شروعsubsubsubsubsubject", "شروعsuffixtext", "شروعsymbolset", "شروعtable", "شروعtablehead", "شروعtables", "شروعtabletail", "شروعtabletext", "شروعtabulate", "شروعtabulatehead", "شروعtabulatetail", "شروعtagged", "شروعtaglabeltext", "شروعtexcode", "شروعtexdefinition", "شروعtext", "شروعtextbackground", "شروعtextbackgroundmanual", "شروعtextcolor", "شروعtextcolorintent", "شروعtextflow", "شروعtextmakeup", "شروعtitle", "شروعtokenlist", "شروعtokens", "شروعtransparent", "شروعtypescript", "شروعtypescriptcollection", "شروعtyping", "شروعuniqueMPgraphic", "شروعuniqueMPpagegraphic", "شروعunittext", "شروعunpacked", "شروعusableMPgraphic", "شروعuseMPgraphic", "شروعusemathstyleparameter", "شروعuserdata", "شروعusingbtxspecification", "شروعvbox", "شروعvboxregister", "شروعvboxtohbox", "شروعvboxtohboxseparator", "شروعviewerlayer", "شروعvtop", "شروعvtopregister", "شروعxcell", "شروعxcellgroup", "شروعxcolumn", "شروعxgroup", "شروعxmldisplayverbatim", "شروعxmlinlineverbatim", "شروعxmlraw", "شروعxmlsetups", "شروعxrow", "شروعxrowgroup", "شروعxtable", "شروعxtablebody", "شروعxtablefoot", "شروعxtablehead", "شروعxtablenext", "شروعآیتم", "شروعبروبه", "شروعتنظیم‌راست", "شروعتنظیم‌وسط", "شروعتولید", "شروعخط‌حاشیه", "شروعخط‌متن", "شروعدرج‌شناور", "شروعدرج‌فرمول", "شروعرنگ", "شروعزبان", "شروعسر", "شروعفشرده", "شروعقالبی", "شروعمحیط", "شروعمنوی‌پانل", "شروعمولفه", "شروعنشر", "شروعپروژه", "شروعپس‌زمینه", "شروعچپ‌چین", "شروع‌خط", "شماره‌زیرصفحه", "شماره‌سر", "شماره‌سرجاری", "شماره‌صفحه", "شماره‌صفحه‌کامل", "شماره‌فرمول", "شماره‌مبدل", "شماره‌ها", "شکافتن‌شناور", "شکل‌خارجی", "صفحه", "صفحه‌تست", "طول‌لیست", "عرض‌خط", "فضا", "فضاهای‌ثابت", "فضای‌ثابت", "فضای‌سفیدصحیح", "قالبی", "لوح‌مقایسه", "ماه", "متن‌پانوشت", "محیط", "مراجعه", "مرجع", "مرجع‌صفحه", "مرجع‌متن", "مقایسه‌گروه‌رنگ", "مقداررنگ", "مقیاس", "منوی‌پانل", "مولفه", "مکان", "میدان", "میدان‌شبیه‌سازی", "میدان‌پشته", "میدان‌کپی", "میله‌رنگ", "میله‌پانل", "ناشناس", "نسخه", "نشانه‌گذاری", "نصب‌زبان", "نقطه‌ها", "نماد", "نمایش‌آرایش", "نمایش‌بارگذاریها", "نمایش‌بستها", "نمایش‌توری", "نمایش‌رنگ", "نمایش‌طرح‌بندی", "نمایش‌قالب", "نمایش‌قلم‌بدنه", "نمایش‌لوح", "نمایش‌مجموعه‌علامت", "نمایش‌محیط‌قلم‌بدنه", "نمایش‌چاپ", "نمایش‌گروه‌رنگ", "پابا", "پایانJScode", "پایانJSpreamble", "پایانLUA", "پایانMP", "پایانMPclip", "پایانMPcode", "پایانMPdefinitions", "پایانMPdrawing", "پایانMPenvironment", "پایانMPextensions", "پایانMPinclusions", "پایانMPinitializations", "پایانMPpage", "پایانMPpositiongraphic", "پایانMPpositionmethod", "پایانMPrun", "پایانPARSEDXML", "پایانTABLE", "پایانTABLEbody", "پایانTABLEfoot", "پایانTABLEhead", "پایانTABLEnext", "پایانTC", "پایانTD", "پایانTDs", "پایانTEX", "پایانTEXpage", "پایانTH", "پایانTN", "پایانTR", "پایانTRs", "پایانTX", "پایانTY", "پایانXML", "پایانalign", "پایانalignment", "پایانallmodes", "پایانappendices", "پایانarrangedpages", "پایانaside", "پایانattachment", "پایانbackmatter", "پایانbar", "پایانbbordermatrix", "پایانbitmapimage", "پایانblockquote", "پایانbodymatter", "پایانbordermatrix", "پایانboxedcolumns", "پایانbtxlabeltext", "پایانbtxrenderingdefinitions", "پایانbuffer", "پایانcases", "پایانcatcodetable", "پایانcenteraligned", "پایانchapter", "پایانcharacteralign", "پایانcheckedfences", "پایانchemical", "پایانchemicaltext", "پایانcollect", "پایانcollecting", "پایانcolorintent", "پایانcoloronly", "پایانcolorset", "پایانcolumns", "پایانcolumnset", "پایانcolumnsetspan", "پایانcolumnspan", "پایانcombination", "پایانcomment", "پایانcontextcode", "پایانcontextdefinitioncode", "پایانctxfunction", "پایانctxfunctiondefinition", "پایانcurrentcolor", "پایانcurrentlistentrywrapper", "پایانdelimited", "پایانdelimitedtext", "پایانdisplaymath", "پایانdmath", "پایانdocument", "پایانeffect", "پایانelement", "پایانembeddedxtable", "پایانendnote", "پایانendofline", "پایانexceptions", "پایانexpanded", "پایانexpandedcollect", "پایانextendedcatcodetable", "پایانexternalfigurecollection", "پایانfacingfloat", "پایانfact", "پایانfigure", "پایانfiguretext", "پایانfittingpage", "پایانfixed", "پایانfloatcombination", "پایانfont", "پایانfontclass", "پایانfontsolution", "پایانfootnote", "پایانformula", "پایانformulas", "پایانframedcell", "پایانframedcontent", "پایانframedrow", "پایانframedtable", "پایانframedtext", "پایانfrontmatter", "پایانgraphictext", "پایانgridsnapping", "پایانhanging", "پایانhbox", "پایانhboxestohbox", "پایانhboxregister", "پایانheadtext", "پایانhelptext", "پایانhiding", "پایانhighlight", "پایانhyphenation", "پایانimath", "پایانindentation", "پایانindentedtext", "پایانinteraction", "پایانinterface", "پایانintermezzotext", "پایانintertext", "پایانitemgroup", "پایانitemgroupcolumns", "پایانitemize", "پایانknockout", "پایانlabeltext", "پایانlayout", "پایانlegend", "پایانlinealignment", "پایانlinecorrection", "پایانlinefiller", "پایانlinenumbering", "پایانlines", "پایانlinetable", "پایانlinetablebody", "پایانlinetablecell", "پایانlinetablehead", "پایانlocalfootnotes", "پایانlocalheadsetup", "پایانlocallinecorrection", "پایانlocalnotes", "پایانlocalsetups", "پایانlua", "پایانluacode", "پایانluaparameterset", "پایانluasetups", "پایانmakeup", "پایانmarginblock", "پایانmarkedcontent", "پایانmarkpages", "پایانmathalignment", "پایانmathcases", "پایانmathlabeltext", "پایانmathmatrix", "پایانmathmode", "پایانmathstyle", "پایانmatrices", "پایانmatrix", "پایانmaxaligned", "پایانmdformula", "پایانmiddlealigned", "پایانmiddlemakeup", "پایانmixedcolumns", "پایانmode", "پایانmodeset", "پایانmodule", "پایانmoduletestsection", "پایانmpformula", "پایانnamedsection", "پایانnamedsubformulas", "پایانnarrow", "پایانnarrower", "پایانnegative", "پایانnicelyfilledbox", "پایانnointerference", "پایانnotallmodes", "پایانnotext", "پایانnotmode", "پایانoperatortext", "پایانopposite", "پایانoutputstream", "پایانoverlay", "پایانoverprint", "پایانpagecolumns", "پایانpagecomment", "پایانpagefigure", "پایانpagelayout", "پایانpagemakeup", "پایانpar", "پایانparagraph", "پایانparagraphs", "پایانparagraphscell", "پایانparbuilder", "پایانpart", "پایانpath", "پایانplacechemical", "پایانplacefigure", "پایانplacegraphic", "پایانplaceintermezzo", "پایانplacelegend", "پایانplacepairedbox", "پایانplacetable", "پایانpositioning", "پایانpositionoverlay", "پایانpositive", "پایانpostponing", "پایانpostponingnotes", "پایانprefixtext", "پایانprocessassignmentcommand", "پایانprocessassignmentlist", "پایانprocesscommacommand", "پایانprocesscommalist", "پایانprotect", "پایانprotectedcolors", "پایانpunctuation", "پایانquotation", "پایانquote", "پایانrandomized", "پایانrandomseed", "پایانrawsetups", "پایانreadingfile", "پایانreferenceprefix", "پایانregime", "پایانreusableMPgraphic", "پایانruby", "پایانscript", "پایانsdformula", "پایانsection", "پایانsectionblock", "پایانsectionblockenvironment", "پایانsectionlevel", "پایانsetups", "پایانshapebox", "پایانshift", "پایانsidebar", "پایانsimplecolumns", "پایانspecialitem", "پایانspeech", "پایانspformula", "پایانsplitformula", "پایانsplittext", "پایانspread", "پایانstandardmakeup", "پایانstaticMPfigure", "پایانstaticMPgraphic", "پایانstrictinspectnextcharacter", "پایانstrut", "پایانstyle", "پایانsubformulas", "پایانsubject", "پایانsubjectlevel", "پایانsubsection", "پایانsubsentence", "پایانsubstack", "پایانsubsubject", "پایانsubsubsection", "پایانsubsubsubject", "پایانsubsubsubsection", "پایانsubsubsubsubject", "پایانsubsubsubsubsection", "پایانsubsubsubsubsubject", "پایانsuffixtext", "پایانsymbolset", "پایانtable", "پایانtablehead", "پایانtables", "پایانtabletail", "پایانtabletext", "پایانtabulate", "پایانtabulatehead", "پایانtabulatetail", "پایانtagged", "پایانtaglabeltext", "پایانtexcode", "پایانtexdefinition", "پایانtext", "پایانtextbackground", "پایانtextbackgroundmanual", "پایانtextcolor", "پایانtextcolorintent", "پایانtextflow", "پایانtextmakeup", "پایانtitle", "پایانtokenlist", "پایانtokens", "پایانtransparent", "پایانtypescript", "پایانtypescriptcollection", "پایانtyping", "پایانuniqueMPgraphic", "پایانuniqueMPpagegraphic", "پایانunittext", "پایانunpacked", "پایانusableMPgraphic", "پایانuseMPgraphic", "پایانusemathstyleparameter", "پایانuserdata", "پایانusingbtxspecification", "پایانvbox", "پایانvboxregister", "پایانvboxtohbox", "پایانvboxtohboxseparator", "پایانviewerlayer", "پایانvtop", "پایانvtopregister", "پایانxcell", "پایانxcellgroup", "پایانxcolumn", "پایانxgroup", "پایانxmldisplayverbatim", "پایانxmlinlineverbatim", "پایانxmlraw", "پایانxmlsetups", "پایانxrow", "پایانxrowgroup", "پایانxtable", "پایانxtablebody", "پایانxtablefoot", "پایانxtablehead", "پایانxtablenext", "پایانآیتم", "پایانبروبه", "پایانتنظیم‌راست", "پایانتنظیم‌وسط", "پایانتولید", "پایانخط‌حاشیه", "پایانخط‌متن", "پایاندرج‌شناور", "پایاندرج‌فرمول", "پایانرنگ", "پایانزبان", "پایانسر", "پایانفشرده", "پایانقالبی", "پایانمحیط", "پایانمنوی‌پانل", "پایانمولفه", "پایاننشر", "پایانپروژه", "پایانپس‌زمینه", "پایانچپ‌چین", "پایان‌خط", "پایین", "پرده", "پروژه", "پرکردن‌میدان", "پس‌زمینه", "چوبخط", "چپ‌چین", "کشیده", "کلمه‌راست", "گیره", "یادداشت", "یک‌جا", "یک‌خط" },
+ ["ro"]={ "CUVANT", "CUVINTE", "Cuvant", "Cuvinte", "Kap", "LUNA", "Litera", "Litere", "Numere", "Numereromane", "ZIDINSAPTAMANA", "adapteazaaspect", "adubuffer", "adumarcaje", "afiseazaaspect", "afiseazaculoare", "afiseazafonttext", "afiseazagrid", "afiseazagrupculoare", "afiseazamakeup", "afiseazamediufonttext", "afiseazapaleta", "afiseazarama", "afiseazasetari", "afiseazasetsimboluri", "afiseazastruts", "afiseazatiparire", "aliniatcentru", "aliniatdreapta", "aliniatstanga", "ascundeblocuri", "baraculoare", "barainteractiune", "blanc", "butoaneinteractiune", "buton", "butonmeniu", "camp", "cloneazacamp", "coloana", "comparagrupculoare", "comparapaleta", "completeazanumarpagina", "componenta", "convertestenumar", "copiazacamp", "corecteazaspatiualb", "culoare", "culoaregri", "cuvantdreapta", "data", "datacurenta", "defineste", "definesteaccent", "definesteantet", "definestebloc", "definesteblocsectiune", "definestebuffer", "definestecamp", "definestecaracter", "definestecomanda", "definesteconversie", "definesteculoare", "definestedescriere", "definestedimensiunehartie", "definesteenumerare", "definesteeticheta", "definestefloat", "definestefont", "definestefonttext", "definesteformatreferinte", "definestegrupculori", "definestehbox", "definesteinconjurare", "definestelista", "definestelistacombinata", "definestemakeup", "definestemarcaje", "definestemediulfonttext", "definestemeniuinteractiune", "definesteoverlay", "definestepaleta", "definesteparagraf", "definesteprofil", "definesteprogram", "definestereferinte", "definesteregistru", "definestesablontabel", "definestesectiune", "definestesimbol", "definestesimbolfigura", "definestesinonim", "definestesinonimfont", "definestesortare", "definestestartstop", "definestestil", "definestestilfont", "definestestivacampuri", "definestesubcamp", "definestetabulatori", "definestetext", "definestetexteinconjurate", "definestetextinconjurat", "definestetyping", "despre", "determinacaracteristicilelistei", "determinacaracteristiciregistru", "determinanumartitlu", "din", "dute", "dutebox", "dutepagina", "ecran", "element", "faraliniiantetsisubsol", "faraliniisussijos", "faraspatiu", "figuraexterna", "firdepar", "folosesteURL", "folosestebloc", "folosestedirector", "folosestedocumentextern", "folosestefiguraexterna", "folosestemodul", "folosestemuzicaexterna", "folosestescriptJS", "folosestesimboluri", "folosesteurl", "fundal", "grosimelinie", "impartefloat", "inalt", "injos", "inlinie", "instalarelimba", "intins", "jos", "jossus", "la", "lapagina", "limba", "limbaprincipala", "linieneagra", "liniesubtire", "linieumplere", "liniinegre", "liniisubtiri", "litera", "litere", "luna", "lungimelista", "marcaje", "matematica", "mediu", "meniuinteractiune", "necunoscut", "nokap", "nota", "numarformula", "numarpagina", "numartitlu", "numartitlucurent", "numere", "numereromane", "olinie", "pagina", "pastreazablocuri", "pelung", "plaseazapegrid", "plaseazasemnecarte", "potrivestecamp", "pozitie", "proceseazabloc", "produs", "proiect", "puncte", "punedeasuprafiecareia", "punefatainfata", "puneformula", "punelista", "punelistacombinata", "punenotesubsol", "punenotesubsollocale", "punenumarpagina", "puneregistru", "punesubformula", "referinta", "referintapagina", "referintatext", "reflexie", "remarca", "reseteazamarcaje", "riglatext", "rigleumplere", "roteste", "scala", "scriebuffer", "scrieinlista", "scrieintreliste", "selecteazablocuri", "semncarte", "setareitemization", "setarelimba", "setarepozitie", "seteazaaliniat", "seteazaalinierea", "seteazaantet", "seteazaaranjareapag", "seteazaaspect", "seteazabarainteractiune", "seteazablanc", "seteazabloc", "seteazablocsectiune", "seteazabuffer", "seteazacamp", "seteazacampuri", "seteazaclipping", "seteazacoloane", "seteazacomentariu", "seteazacomentariupagina", "seteazaculoare", "seteazaculori", "seteazadimensiunihartie", "seteazaecraninteractiune", "seteazaelemente", "seteazaenumerare", "seteazafloat", "seteazafloats", "seteazafonttext", "seteazaformulare", "seteazaformule", "seteazafundal", "seteazafundaluri", "seteazagrosimelinie", "seteazaimpartireafloat", "seteazainconjurat", "seteazaingust", "seteazainteractiunea", "seteazajos", "seteazalegenda", "seteazalegendele", "seteazaliniesilabe", "seteazaliniesubtire", "seteazalinii", "seteazaliniimargine", "seteazaliniinegre", "seteazaliniiumplere", "seteazalista", "seteazalistacombinata", "seteazamajuscule", "seteazamakeup", "seteazamarcaje", "seteazameniuinteractiune", "seteazaminicitat", "seteazanumarpagina", "seteazanumarsubpagina", "seteazanumartitlu", "seteazanumerotarelinii", "seteazanumerotarepagina", "seteazanumerotareparagrafe", "seteazapaleta", "seteazaparagrafe", "seteazaplasareaopozita", "seteazaprograme", "seteazareferinte", "seteazaregistru", "seteazarigletext", "seteazarigleumplere", "seteazarotare", "seteazasimbol", "seteazasinonime", "seteazasortare", "seteazaspatiu", "seteazaspatiualb", "seteazaspatiuinterliniar", "seteazasubsol", "seteazasus", "seteazatabele", "seteazatabulatori", "seteazatext", "seteazatexteantet", "seteazatextejos", "seteazatextesubsol", "seteazatextesus", "seteazatextetext", "seteazatitlu", "seteazatitluri", "seteazatoleranta", "seteazatranzitiepagina", "seteazatype", "seteazatyping", "seteazaurl", "simbol", "spatiifixate", "spatiu", "spatiufixat", "startaliniatcentru", "startaliniatdreapta", "startaliniatstanga", "startcomponenta", "startculoare", "startdute", "startfundal", "startimpachetat", "startlimba", "startlinie", "startliniemargine", "startmediu", "startmeniuinteractiune", "startprodus", "startproiect", "startpublicatie", "startpuneformula", "startriglatext", "starttitlu", "stivacampuri", "stopaliniatcentru", "stopaliniatdreapta", "stopaliniatstanga", "stopcomponenta", "stopculoare", "stopdute", "stopfundal", "stopimpachetat", "stoplimba", "stoplinie", "stopliniemargine", "stopmediu", "stopmeniuinteractiune", "stopprodus", "stopproiect", "stoppublicatie", "stoppuneformula", "stopriglatext", "stoptitlu", "textumplere", "traduce", "trecilafonttext", "undeva", "valoareculoare", "versiune", "zidinsaptamana" },
} \ No newline at end of file
diff --git a/context/data/scite/context/lexers/data/scite-context-data-metafun.lua b/context/data/scite/context/lexers/data/scite-context-data-metafun.lua
index b577c8aee..4d18d3081 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-metafun.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-metafun.lua
@@ -1,4 +1,4 @@
return {
- ["commands"]={ "loadfile", "loadimage", "loadmodule", "dispose", "nothing", "transparency", "tolist", "topath", "tocycle", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "tanh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "perpendicular", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "drawdoublearrows", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "boundingradius", "boundingcircle", "boundingpoint", "crossingunder", "insideof", "outsideof", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", "withshadestep", "withshadefraction", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "colordecimalslist", "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "istextext", "verbatim", "thelabel", "label", "autoalign", "transparent", "withtransparency", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "colorlike", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "resetarrows", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "pencilled", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "topair", "format", "formatted", "quotation", "quote", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "fillup", "eofillup", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright", "sortlist", "copylist", "shapedlist", "listtocurves", "listtolines", "listsize", "listlast", "uniquelist", "circularpath", "squarepath", "linearpath" },
- ["internals"]={ "nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel", "shadefactor", "textextoffset", "normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent", "softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent", "darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent", "huetransparent", "saturationtransparent", "colortransparent", "luminositytransparent", "ahvariant", "ahdimple", "ahfactor", "ahscale", "metapostversion", "maxdimensions", "drawoptionsfactor", "dq", "sq", "crossingscale", "crossingoption" },
+ ["commands"]={ "loadfile", "loadimage", "loadmodule", "dispose", "nothing", "transparency", "tolist", "topath", "tocycle", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "tanh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "perpendicular", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "drawdoublearrows", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "boundingradius", "boundingcircle", "boundingpoint", "crossingunder", "insideof", "outsideof", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", "withshadestep", "withshadefraction", "withshadeorigin", "shownshadevector", "shownshadeorigin", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "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", "transparent", "withtransparency", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "colorlike", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "resetarrows", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "pencilled", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "topair", "format", "formatted", "quotation", "quote", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "fillup", "eofillup", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright", "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" },
+ ["internals"]={ "nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel", "shadefactor", "textextoffset", "textextanchor", "normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent", "softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent", "darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent", "huetransparent", "saturationtransparent", "colortransparent", "luminositytransparent", "ahvariant", "ahdimple", "ahfactor", "ahscale", "metapostversion", "maxdimensions", "drawoptionsfactor", "dq", "sq", "crossingscale", "crossingoption" },
} \ No newline at end of file
diff --git a/context/data/scite/context/lexers/data/scite-context-data-tex.lua b/context/data/scite/context/lexers/data/scite-context-data-tex.lua
index 31cb6e4fb..473c64499 100644
--- a/context/data/scite/context/lexers/data/scite-context-data-tex.lua
+++ b/context/data/scite/context/lexers/data/scite-context-data-tex.lua
@@ -1,9 +1,9 @@
return {
["aleph"]={ "Alephminorversion", "Alephrevision", "Alephversion" },
["etex"]={ "botmarks", "clubpenalties", "currentgrouplevel", "currentgrouptype", "currentifbranch", "currentiflevel", "currentiftype", "detokenize", "dimexpr", "displaywidowpenalties", "eTeXVersion", "eTeXminorversion", "eTeXrevision", "eTeXversion", "everyeof", "firstmarks", "fontchardp", "fontcharht", "fontcharic", "fontcharwd", "glueexpr", "glueshrink", "glueshrinkorder", "gluestretch", "gluestretchorder", "gluetomu", "ifcsname", "ifdefined", "iffontchar", "interactionmode", "interlinepenalties", "lastlinefit", "lastnodetype", "marks", "muexpr", "mutoglue", "numexpr", "pagediscards", "parshapedimen", "parshapeindent", "parshapelength", "predisplaydirection", "protected", "readline", "savinghyphcodes", "savingvdiscards", "scantokens", "showgroups", "showifs", "showtokens", "splitbotmarks", "splitdiscards", "splitfirstmarks", "topmarks", "tracingassigns", "tracinggroups", "tracingifs", "tracingnesting", "tracingscantokens", "unexpanded", "unless", "widowpenalties" },
- ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Unosubscript", "Unosuperscript", "Uoverdelimiter", "Uradical", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "alignmark", "aligntab", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenmode", "automatichyphenpenalty", "begincsname", "bodydir", "bodydirection", "boxdir", "boxdirection", "breakafterdirmode", "catcodetable", "clearmarks", "copyfont", "compoundhyphenmode", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "draftmode", "dviextension", "dvifeedback", "dvivariable", "efcode", "etoksapp", "etokspre", "expanded", "expandglyphsinfont", "explicitdiscretionary", "explicithyphenpenalty", "fontid", "formatname", "gleaders", "hjcode", "hyphenationbounds", "hyphenationmin", "hyphenpenaltymode", "ifabsdim", "ifabsnum", "ifincsname", "ifprimitive", "ignoreligaturesinfont", "initcatcodetable", "insertht", "lastnamedcs", "lastsavedboxresourceindex", "lastsavedimageresourceindex", "lastsavedimageresourcepages", "lastxpos", "lastypos", "latelua", "leftghost", "leftmarginkern", "letcharcode", "letterspacefont", "linedir", "linedirection", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "lpcode", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathdelimitersmode", "mathdir", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathitalicsmode", "mathnolimitsmode", "mathoption", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathscriptsmode", "mathscriptboxmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "nohrule", "nokerns", "noligs", "normaldeviate", "nospaces", "novrule", "outputbox", "outputmode", "pagebottomoffset", "pagedir", "pagedirection", "pageheight", "pageleftoffset", "pagerightoffset", "pagetopoffset", "pagewidth", "pardir", "pardirection", "pdfextension", "pdffeedback", "pdfvariable", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "primitive", "protrudechars", "pxdimen", "quitvmode", "randomseed", "rightghost", "rightmarginkern", "rpcode", "saveboxresource", "savecatcodetable", "saveimageresource", "savepos", "scantextokens", "setfontid", "setrandomseed", "shapemode", "suppressfontnotfounderror", "suppressifcsnameerror", "suppresslongerror", "suppressmathparerror", "suppressoutererror", "suppressprimitiveerror", "synctex", "tagcode", "textdir", "textdirection", "toksapp", "tokspre", "tracingfonts", "uniformdeviate", "useboxresource", "useimageresource" },
+ ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Unosubscript", "Unosuperscript", "Uoverdelimiter", "Uradical", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "alignmark", "aligntab", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenmode", "automatichyphenpenalty", "begincsname", "bodydir", "bodydirection", "boxdir", "boxdirection", "breakafterdirmode", "catcodetable", "clearmarks", "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", "lastsavedboxresourceindex", "lastsavedimageresourceindex", "lastsavedimageresourcepages", "lastxpos", "lastypos", "latelua", "lateluafunction", "leftghost", "leftmarginkern", "letcharcode", "letterspacefont", "linedir", "linedirection", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathdelimitersmode", "mathdir", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathflattenmode", "mathitalicsmode", "mathnolimitsmode", "mathoption", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathrulethicknessmode", "mathscriptboxmode", "mathscriptcharmode", "mathscriptsmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "nohrule", "nokerns", "noligs", "normaldeviate", "nospaces", "novrule", "outputbox", "outputmode", "pagebottomoffset", "pagedir", "pagedirection", "pageheight", "pageleftoffset", "pagerightoffset", "pagetopoffset", "pagewidth", "pardir", "pardirection", "pdfextension", "pdffeedback", "pdfvariable", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "primitive", "protrudechars", "pxdimen", "quitvmode", "randomseed", "rightghost", "rightmarginkern", "rpcode", "saveboxresource", "savecatcodetable", "saveimageresource", "savepos", "scantextokens", "setfontid", "setrandomseed", "shapemode", "suppressfontnotfounderror", "suppressifcsnameerror", "suppresslongerror", "suppressmathparerror", "suppressoutererror", "suppressprimitiveerror", "synctex", "tagcode", "textdir", "textdirection", "toksapp", "tokspre", "tracingfonts", "uniformdeviate", "useboxresource", "useimageresource", "xtoksapp", "xtokspre" },
["omega"]={ "Omegaminorversion", "Omegarevision", "Omegaversion" },
- ["pdftex"]={ "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfignoreunknownimages", "pdfimageaddfilename", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinfoomitdate", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmapfile", "pdfmapline", "pdfmajorversion", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdfsuppressoptionalinfo", "pdfsuppressptexinfo", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage" },
- ["tex"]={ " ", "-", "/", "Uleft", "Umiddle", "Uright", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "botmark", "boundary", "box", "boxmaxdepth", "brokenpenalty", "catcode", "char", "chardef", "cleaders", "closein", "closeout", "clubpenalty", "copy", "count", "countdef", "cr", "crcr", "csname", "csstring", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "dimen", "dimendef", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "firstvalidlanguage", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hpack", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifcase", "ifcat", "ifdim", "ifeof", "iffalse", "ifhbox", "ifhmode", "ifinner", "ifmmode", "ifnum", "ifodd", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "immediate", "indent", "input", "inputlineno", "insert", "insertpenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastpenalty", "lastskip", "lccode", "leaders", "left", "lefthyphenmin", "leftskip", "leqno", "let", "limits", "linepenalty", "lineskip", "lineskiplimit", "long", "looseness", "lower", "lowercase", "mag", "mark", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "muskip", "muskipdef", "newlinechar", "noalign", "noboundary", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "openin", "openout", "or", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillskip", "parindent", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "protrusionboundary", "radical", "raise", "read", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "special", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tpack", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vpack", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "wordboundary", "write", "xdef", "xleaders", "xspaceskip", "year" },
+ ["pdftex"]={ "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfignoreunknownimages", "pdfimageaddfilename", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinfoomitdate", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmajorversion", "pdfmapfile", "pdfmapline", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfomitcharset", "pdfomitcidset", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrecompress", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdfsuppressoptionalinfo", "pdfsuppressptexinfo", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage" },
+ ["tex"]={ " ", "-", "/", "Uleft", "Umiddle", "Uright", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "botmark", "boundary", "box", "boxmaxdepth", "brokenpenalty", "catcode", "char", "chardef", "cleaders", "closein", "closeout", "clubpenalty", "copy", "count", "countdef", "cr", "crcr", "csname", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "dimen", "dimendef", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "firstvalidlanguage", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "glet", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hpack", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifcase", "ifcat", "ifdim", "ifeof", "iffalse", "ifhbox", "ifhmode", "ifinner", "ifmmode", "ifnum", "ifodd", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "immediate", "indent", "input", "inputlineno", "insert", "insertpenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastpenalty", "lastskip", "lccode", "leaders", "left", "lefthyphenmin", "leftskip", "leqno", "let", "limits", "linepenalty", "lineskip", "lineskiplimit", "long", "looseness", "lower", "lowercase", "mag", "mark", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "muskip", "muskipdef", "newlinechar", "noalign", "noboundary", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "openin", "openout", "or", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillskip", "parindent", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "protrusionboundary", "radical", "raise", "read", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "special", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tpack", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vpack", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "wordboundary", "write", "xdef", "xleaders", "xspaceskip", "year" },
["xetex"]={ "XeTeXversion" },
} \ No newline at end of file
diff --git a/context/data/scite/context/lexers/scite-context-lexer-json.lua b/context/data/scite/context/lexers/scite-context-lexer-json.lua
new file mode 100644
index 000000000..20a2d1d12
--- /dev/null
+++ b/context/data/scite/context/lexers/scite-context-lexer-json.lua
@@ -0,0 +1,100 @@
+local info = {
+ version = 1.002,
+ comment = "scintilla lpeg lexer for json",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+local global, string, table, lpeg = _G, string, table, lpeg
+local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V
+local type = type
+
+local lexer = require("scite-context-lexer")
+local context = lexer.context
+local patterns = context.patterns
+
+local token = lexer.token
+local exact_match = lexer.exact_match
+
+local jsonlexer = lexer.new("json","scite-context-lexer-json")
+local whitespace = jsonlexer.whitespace
+
+local anything = patterns.anything
+local comma = P(",")
+local colon = P(":")
+local escape = P("\\")
+----- single = P("'")
+local double = P('"')
+local openarray = P('[')
+local closearray = P(']')
+local openhash = P('{')
+local closehash = P('}')
+----- lineending = S("\n\r")
+local space = S(" \t\n\r\f")
+local spaces = space^1
+local operator = S(':,{}[]')
+local fence = openarray + closearray + openhash + closehash
+
+local escape_un = P("\\u") / "0x" * S("09","AF","af")
+local escape_bs = P([[\]]) * P(1)
+local content = (escape_un + escape_bs + (1-double))^0
+
+local reserved = P("true")
+ + P("false")
+ + P("null")
+
+local integer = P("-")^-1 * (patterns.hexadecimal + patterns.decimal)
+local float = patterns.float
+
+local t_number = token("number", float + integer)
+ * (token("error",R("AZ","az","__")^1))^0
+
+local t_spacing = token(whitespace, space^1)
+local t_optionalws = token("default", space^1)^0
+
+local t_operator = token("special", operator)
+
+local t_string = token("operator",double)
+ * token("string",content)
+ * token("operator",double)
+
+local t_key = token("operator",double)
+ * token("text",content)
+ * token("operator",double)
+ * t_optionalws
+ * token("operator",colon)
+
+local t_fences = token("operator",fence) -- grouping
+
+local t_reserved = token("primitive",reserved)
+
+local t_rest = token("default",anything)
+
+jsonlexer._rules = {
+ { "whitespace", t_spacing },
+ { "reserved", t_reserved },
+ { "key", t_key },
+ { "number", t_number },
+ { "string", t_string },
+ { "fences", t_fences },
+ { "operator", t_operator },
+ { "rest", t_rest },
+}
+
+jsonlexer._tokenstyles = context.styleset
+
+jsonlexer._foldpattern = fence
+
+jsonlexer._foldsymbols = {
+ _patterns = {
+ "{", "}",
+ "[", "]",
+ },
+ ["grouping"] = {
+ ["{"] = 1, ["}"] = -1,
+ ["["] = 1, ["]"] = -1,
+ },
+}
+
+return jsonlexer
diff --git a/context/data/scite/context/lexers/scite-context-lexer-mps.lua b/context/data/scite/context/lexers/scite-context-lexer-mps.lua
index 1c87ea6d0..4bbfae03c 100644
--- a/context/data/scite/context/lexers/scite-context-lexer-mps.lua
+++ b/context/data/scite/context/lexers/scite-context-lexer-mps.lua
@@ -91,9 +91,12 @@ local plain = token("plain", exact_match(metapostcommands))
local quoted = token("quote", dquote)
* token("string", P(1-dquote)^0)
* token("quote", dquote)
-local texstuff = token("quote", P("btex ") + P("verbatimtex "))
- * token("string", P(1-P(" etex"))^0)
- * token("quote", P(" etex"))
+local separator = P(" ") + S("\n\r")^1
+local btex = (P("btex") + P("verbatimtex")) * separator
+local etex = separator * P("etex")
+local texstuff = token("quote", btex)
+ * token("string", (1-etex)^0)
+ * token("quote", etex)
local primitive = token("primitive", exact_match(metapostprimitives))
local identifier = token("default", cstoken^1)
local number = token("number", number)
@@ -130,10 +133,10 @@ metafunlexer._rules = {
{ "comment", comment },
{ "internal", internal },
{ "shortcut", shortcut },
+ { "luacall", luacall },
{ "helper", helper },
{ "plain", plain },
{ "primitive", primitive },
- { "luacall", luacall },
{ "texstuff", texstuff },
{ "suffix", suffix },
{ "identifier", identifier },
diff --git a/context/data/scite/context/lexers/scite-context-lexer-pdf.lua b/context/data/scite/context/lexers/scite-context-lexer-pdf.lua
index 0fd238d63..1956071b7 100644
--- a/context/data/scite/context/lexers/scite-context-lexer-pdf.lua
+++ b/context/data/scite/context/lexers/scite-context-lexer-pdf.lua
@@ -90,7 +90,7 @@ local t_number = token("number", real)
-- t_reference = token("number", cardinal)
-- * t_spacing
-- * token("number", cardinal)
-local t_reserved = token("number", P("true") + P("false") + P("NULL"))
+local t_reserved = token("number", P("true") + P("false") + P("null"))
-- t_reference = token("warning", cardinal * spacing * cardinal * spacing)
-- * token("keyword", p_reference)
local t_reference = token("warning", cardinal)
@@ -121,17 +121,31 @@ local t_stream = token("keyword", p_stream)
* token("text", (1 - p_endstream)^1)
* token("keyword", p_endstream)
+local t_other = t_constant + t_reference + t_string + t_unicode + t_number + t_reserved + t_whatsit
+
local t_dictionary = { "dictionary",
- dictionary = t_opendictionary * (t_spaces * t_keyword * t_spaces * V("whatever"))^0 * t_spaces * t_closedictionary,
- array = t_openarray * (t_spaces * V("whatever"))^0 * t_spaces * t_closearray,
- whatever = V("dictionary") + V("array") + t_constant + t_reference + t_string + t_unicode + t_number + t_reserved + t_whatsit,
+ dictionary = t_opendictionary
+ * (t_spaces * t_keyword * t_spaces * V("whatever"))^0
+ * t_spaces
+ * t_closedictionary,
+ array = t_openarray
+ * (t_spaces * V("whatever"))^0
+ * t_spaces
+ * t_closearray,
+ whatever = V("dictionary")
+ + V("array")
+ + t_other,
}
local t_object = { "object", -- weird that we need to catch the end here (probably otherwise an invalid lpeg)
dictionary = t_dictionary.dictionary,
array = t_dictionary.array,
whatever = t_dictionary.whatever,
- object = t_openobject * t_spaces * (V("dictionary")^-1 * t_spaces * t_stream^-1 + V("array") + V("number") + t_spaces) * t_spaces * t_closeobject,
+ object = t_openobject
+ * t_spaces
+ * (V("dictionary") * t_spaces * t_stream^-1 + V("array") + t_other)
+ * t_spaces
+ * t_closeobject,
number = t_number,
}
diff --git a/context/data/scite/context/lexers/scite-context-lexer-tex.lua b/context/data/scite/context/lexers/scite-context-lexer-tex.lua
index 2c2421d2f..d4e28f99b 100644
--- a/context/data/scite/context/lexers/scite-context-lexer-tex.lua
+++ b/context/data/scite/context/lexers/scite-context-lexer-tex.lua
@@ -411,7 +411,7 @@ contextlexer._reset_parser = function()
lualevel = 0
end
-local luaenvironment = P("lua") * (P("setups") + P("code") + P(true))
+local luaenvironment = P("lua") * (P("setups") + P("code") + P("parameterset") + P(true))
+ P("ctxfunction") * (P("definition") + P(true))
local inlinelua = P("\\") * (
diff --git a/context/data/scite/context/lexers/scite-context-lexer.lua b/context/data/scite/context/lexers/scite-context-lexer.lua
index fc16e261a..234b03c05 100644
--- a/context/data/scite/context/lexers/scite-context-lexer.lua
+++ b/context/data/scite/context/lexers/scite-context-lexer.lua
@@ -8,6 +8,10 @@ local info = {
}
+-- We need a copy of this file to lexer.lua in the same path. This was not needed
+-- before version 10 but I can't figure out what else to do. It looks like there
+-- is some loading of lexer.lua but I can't see where.
+
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
local log = false
@@ -19,10 +23,6 @@ local inspect = false -- can save some 15% (maybe easier on scintilla)
-- local log = true
-- local trace = true
--- local f = io.open("e:/tmp/lexers.log","w")
--- print = function(...)
--- f:write(...,"\n")
--- end
-- GET GOING
--
@@ -236,6 +236,17 @@ local inspect = false -- can save some 15% (maybe easier on scintilla)
-- is still not perfect (sometimes hangs) but it was enough reason to spend time on
-- making our lexer work with TextAdept and create a setup.
--
+-- Some bad news. The interface changed (again) in textadept 10, some for the better
+-- (but a bit different from what happens here) and some for the worse, especially
+-- moving some code to the init file so we now need some bad hacks. I decided to
+-- stay with the old method of defining lexers and because the lexer cannot be run
+-- in parallel any more (some change in the binary?) I will probably also cleanup
+-- code below as we no longer need to be compatible. Unfortunately textadept is too
+-- much a moving target to simply kick in some (tex related) production flow (apart
+-- from the fact that it doesn't yet have the scite like realtime console). I'll
+-- keep an eye on it. Because we don't need many added features I might as well decide
+-- to make a lean and mean instance (after all the license permits forking).
+
-- TRACING
--
-- The advantage is that we now can check more easily with regular Lua(TeX). We can
@@ -247,8 +258,8 @@ local inspect = false -- can save some 15% (maybe easier on scintilla)
--
-- TODO
--
--- It would be nice if we could lods some ConTeXt Lua modules (the basic set) and
--- then use resolvers and such.
+-- It would be nice if we could load some ConTeXt Lua modules (the basic set) and
+-- then use resolvers and such. But it might not work well with scite.
--
-- The current lexer basics are still a mix between old and new. Maybe I should redo
-- some more. This is probably easier in TextAdept than in SciTE.
@@ -304,7 +315,17 @@ local lpegmatch = lpeg.match
local usage = (textadept and "textadept") or (resolvers and "context") or "scite"
local nesting = 0
-local print = textadept and ui and ui.print or print
+local output = nil
+
+----- print = textadept and ui and ui.print or print -- crashes when ui is not yet defined
+
+local function print(...)
+ if not output then
+ output = io.open("lexer.log","w")
+ end
+ output:write(...,"\n")
+ output:flush()
+end
local function report(fmt,str,...)
if log then
@@ -323,6 +344,36 @@ end
inform("loading context lexer module (global table: %s)",tostring(global))
+do
+
+ local floor = math and math.floor
+ local format = format
+ local tonumber = tonumber
+
+ if not floor then
+
+ if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then
+ floor = function(n)
+ return tonumber(format("%d",n))
+ end
+ else
+ -- 5.3 has a mixed number system and format %d doesn't work with
+ -- floats any longer ... no fun
+ floor = function(n)
+ return (n - n % 1)
+ end
+ end
+
+ math = math or { }
+
+ math.floor = floor
+
+ end
+
+end
+
+local floor = math.floor
+
if not package.searchpath then
-- Unfortunately the io library is only available when we end up
@@ -416,7 +467,9 @@ local default = {
local predefined = {
"default", "linenumber", "bracelight", "bracebad", "controlchar",
- "indentguide", "calltip"
+ "indentguide", "calltip",
+ -- seems new
+ "folddisplaytext"
}
-- Bah ... ugly ... nicer would be a proper hash .. we now have properties
@@ -514,9 +567,16 @@ lexers.property_expanded = setmetatable({ }, {
check_main_properties()
end
--
- return gsub(property[k],"[$%%]%b()", function(k)
- return t[sub(k,3,-2)]
- end)
+-- return gsub(property[k],"[$%%]%b()", function(k)
+-- return t[sub(k,3,-2)]
+-- end)
+ local v = property[k]
+ if v then
+ v = gsub(v,"[$%%]%b()", function(k)
+ return t[sub(k,3,-2)]
+ end)
+ end
+ return v
end,
__newindex = function(t,k,v)
report("properties are read-only, '%s' is not changed",k)
@@ -839,32 +899,42 @@ function context.loaddefinitions(name)
return type(data) == "table" and data
end
+-- A bit of regression in textadept > 10 so updated ... done a bit different.
+-- We don't use this in the context lexers anyway.
+
function context.word_match(words,word_chars,case_insensitive)
- local chars = "%w_" -- maybe just "" when word_chars
- if word_chars then
- chars = "^([" .. chars .. gsub(word_chars,"([%^%]%-])", "%%%1") .."]+)"
- else
- chars = "^([" .. chars .."]+)"
+ -- used to be proper tables ...
+ if type(words) == "string" then
+ local clean = gsub(words,"%-%-[^\n]+","")
+ local split = { }
+ for s in gmatch(clean,"%S+") do
+ split[#split+1] = s
+ end
+ words = split
+ end
+ local list = { }
+ for i=1,#words do
+ list[words[i]] = true
end
if case_insensitive then
- local word_list = { }
- for i=1,#words do
- word_list[lower(words[i])] = true
- end
- return P(function(input, index)
- local s, e, word = find(input,chars,index)
- return word and word_list[lower(word)] and e + 1 or nil
- end)
- else
- local word_list = { }
for i=1,#words do
- word_list[words[i]] = true
+ list[lower(words[i])] = true
end
- return P(function(input, index)
- local s, e, word = find(input,chars,index)
- return word and word_list[word] and e + 1 or nil
- end)
end
+ local chars = S(word_chars or "")
+ for i=1,#words do
+ chars = chars + S(words[i])
+ end
+ local match = case_insensitive and
+ function(input,index,word)
+ -- We can speed mixed case if needed.
+ return (list[word] or list[lower(word)]) and index or nil
+ end
+ or
+ function(input,index,word)
+ return list[word] and index or nil
+ end
+ return Cmt(chars^1,match)
end
-- Patterns are grouped in a separate namespace but the regular lexers expect
@@ -892,6 +962,11 @@ do
local hexadecimal = P("0") * S("xX")
* (hexdigit^0 * period * hexdigit^1 + hexdigit^1 * period * hexdigit^0 + hexdigit^1)
* (S("pP") * sign^-1 * hexdigit^1)^-1 -- *
+ local integer = sign^-1
+ * (hexadecimal + octal + decimal)
+ local float = sign^-1
+ * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1)
+ * S("eE") * sign^-1 * digit^1 -- *
patterns.idtoken = idtoken
patterns.digit = digit
@@ -908,15 +983,13 @@ do
patterns.decimal = decimal
patterns.octal = octal
patterns.hexadecimal = hexadecimal
- patterns.float = sign^-1
- * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1)
- * S("eE") * sign^-1 * digit^1 -- *
+ patterns.float = float
patterns.cardinal = decimal
patterns.signeddecimal = sign^-1 * decimal
patterns.signedoctal = sign^-1 * octal
patterns.signedhexadecimal = sign^-1 * hexadecimal
- patterns.integer = sign^-1 * (hexadecimal + octal + decimal)
+ patterns.integer = integer
patterns.real =
sign^-1 * ( -- at most one
digit^1 * period * digit^0 -- 10.0 10.
@@ -932,6 +1005,7 @@ do
patterns.nospacing = (1-space)^1
patterns.eol = eol
patterns.newline = P("\r\n") + eol
+ patterns.backslash = backslash
local endof = S("\n\r\f")
@@ -947,7 +1021,7 @@ do
lexers.extend = extend
lexers.alpha = alpha
lexers.digit = digit
- lexers.alnum = alnum
+ lexers.alnum = alpha + digit
lexers.lower = lower
lexers.upper = upper
lexers.xdigit = hexdigit
@@ -1136,6 +1210,8 @@ local p_nop = newline
local folders = { }
+-- Snippets from the > 10 code .. but we do things different so ...
+
local function fold_by_parsing(text,start_pos,start_line,start_level,lexer)
local folder = folders[lexer]
if not folder then
@@ -1145,6 +1221,12 @@ local function fold_by_parsing(text,start_pos,start_line,start_level,lexer)
local fold_symbols = lexer._foldsymbols
local fold_pattern = lexer._foldpattern -- use lpeg instead (context extension)
--
+ -- textadept >= 10
+ --
+ -- local zerosumlines = lexer.property_int["fold.on.zero.sum.lines"] > 0 -- not done
+ -- local compact = lexer.property_int['fold.compact'] > 0 -- not done
+ -- local lowercase = lexer._CASEINSENSITIVEFOLDPOINTS -- useless (utf will distort)
+ --
if fold_pattern then
-- if no functions are found then we could have a faster one
fold_pattern = Cp() * C(fold_pattern) / function(s,match)
@@ -1177,7 +1259,7 @@ local function fold_by_parsing(text,start_pos,start_line,start_level,lexer)
-- the traditional one but a bit optimized
local fold_symbols_patterns = fold_symbols._patterns
local action_y = function(pos,line)
- for j = 1, #fold_symbols_patterns do
+ for j=1, #fold_symbols_patterns do
for s, match in gmatch(line,fold_symbols_patterns[j]) do -- "()(" .. patterns[i] .. ")"
local symbols = fold_symbols[style_at[start_pos + pos + s - 1]]
local l = symbols and symbols[match]
@@ -1320,11 +1402,11 @@ function context.fold(lexer,text,start_pos,start_line,start_level) -- hm, we had
if filesize <= threshold_by_parsing then
return fold_by_parsing(text,start_pos,start_line,start_level,lexer)
end
- elseif lexer.properties("fold.by.indentation",1) > 0 then
+ elseif lexer._FOLDBYINDENTATION or lexer.properties("fold.by.indentation",1) > 0 then
if filesize <= threshold_by_indentation then
return fold_by_indentation(text,start_pos,start_line,start_level,lexer)
end
- elseif lexer.properties("fold.by.line",1) > 0 then
+ elseif lexer._FOLDBYLINE or lexer.properties("fold.by.line",1) > 0 then
if filesize <= threshold_by_line then
return fold_by_line(text,start_pos,start_line,start_level,lexer)
end
@@ -1343,6 +1425,20 @@ local function add_rule(lexer,id,rule) -- unchanged
lexer._RULEORDER[#lexer._RULEORDER + 1] = id
end
+local function modify_rule(lexer,id,rule) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ lexer._RULES[id] = rule
+end
+
+local function get_rule(lexer,id) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ return lexer._RULES[id]
+end
+
-- I finally figured out that adding more styles was an issue because of several
-- reasons:
--
@@ -1366,12 +1462,20 @@ local function add_style(lexer,token_name,style) -- changed a bit around 3.41
if trace and detail then
report("default style '%s' is ignored as extra style",token_name)
end
- return
+ if textadept then
+ -- go on, stored per buffer
+ else
+ return
+ end
elseif predefinedstyles[token_name] then
if trace and detail then
report("predefined style '%s' is ignored as extra style",token_name)
end
- return
+ if textadept then
+ -- go on, stored per buffer
+ else
+ return
+ end
else
if trace and detail then
report("adding extra style '%s' as '%s'",token_name,style)
@@ -1388,6 +1492,7 @@ local function add_style(lexer,token_name,style) -- changed a bit around 3.41
lexer._TOKENSTYLES[token_name] = num_styles
lexer._EXTRASTYLES[token_name] = style
lexer._numstyles = num_styles + 1
+ -- hm, the original (now) also copies to the parent ._lexer
end
local function check_styles(lexer)
@@ -1437,6 +1542,8 @@ local function join_tokens(lexer) -- slightly different from the original (no 'a
end
end
+-- hm, maybe instead of a grammer just a flat one
+
local function add_lexer(grammar, lexer) -- mostly the same as the original
local token_rule = join_tokens(lexer)
local lexer_name = lexer._NAME
@@ -1466,6 +1573,10 @@ local function build_grammar(lexer,initial_rule) -- same as the original
local children = lexer._CHILDREN
local lexer_name = lexer._NAME
local preamble = lexer._preamble
+ local grammar = lexer._grammar
+ -- if grammar then
+ -- -- experiment
+ -- elseif children then
if children then
if not initial_rule then
initial_rule = lexer_name
@@ -1539,17 +1650,17 @@ local function matched(lexer,grammar,text)
else
txt = "!no text!"
end
- report("%4i : %s > %s (%s) (%s)",n/2,ti,tn,s[ti] or "!unset!",txt)
+ report("%4i : %s > %s (%s) (%s)",floor(n/2),ti,tn,s[ti] or "!unset!",txt)
p = tn
else
break
end
end
end
- report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,#t/2)
+ report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2))
if collapse then
t = collapsed(t)
- report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,#t/2)
+ report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2))
end
elseif collapse then
t = collapsed(t)
@@ -1559,6 +1670,9 @@ end
-- Todo: make nice generic lexer (extra argument with start/stop commands) for
-- context itself.
+--
+-- In textadept >= 10 grammar building seem to have changed a bit. So, in retrospect
+-- I could better have just dropped compatibility and stick to ctx lexers only.
function context.lex(lexer,text,init_style)
-- local lexer = global._LEXER
@@ -1629,30 +1743,9 @@ function context.lex(lexer,text,init_style)
hash[init_style] = grammar
end
if trace then
- report("lexing '%s' with initial style '%s' and %s children",lexer._NAME,#lexer._CHILDREN or 0,init_style)
+ report("lexing '%s' with initial style '%s' and %s children", lexer._NAME,init_style,#lexer._CHILDREN or 0)
end
return matched(lexer,grammar,text)
--- local result = matched(lexer,grammar,text)
--- local fil = io.open("e:/tmp/foo.log","w")
--- local len = #text
--- local old = 1
--- local txt = false
--- for i=1,#result,2 do
--- local tag = result[i]
--- local pos = result[i+1]
--- if nxt and tag == "text" then
--- local wrd = sub(text,old,pos-1)
--- fil:write(tag,"\t",wrd,"\n")
--- if txt then
--- result[i] = "internal"
--- txt = false
--- else
--- txt = true
--- end
--- end
--- old = pos
--- end
--- fil:close()
else
if trace then
report("lexing '%s' with initial style '%s'",lexer._NAME,init_style)
@@ -1661,7 +1754,8 @@ function context.lex(lexer,text,init_style)
end
end
--- hm, changed in 3.24 .. no longer small table but one table:
+-- hm, changed in 3.24 .. no longer small table but one table (so we could remove our
+-- agressive optimization which worked quite well)
function context.token(name, patt)
return patt * Cc(name) * Cp()
@@ -1721,6 +1815,7 @@ function context.new(name,filename)
check_whitespace(lexer)
check_styles(lexer)
check_properties(lexer)
+ lexer._tokenstyles = context.styleset
return lexer
end
@@ -1826,7 +1921,36 @@ end
-- namespace can be automatic: if parent then use name of parent (chain)
+-- The original lexer framework had a rather messy user uinterface (e.g. moving
+-- stuff from _rules to _RULES at some point but I could live with that. Now it uses
+-- add_ helpers. But the subsystem is still not clean and pretty. Now, I can move to
+-- the add_ but there is no gain in it so we support a mix which gives somewhat ugly
+-- code. In fact, there should be proper subtables for this. I might actually do
+-- this because we now always overload the normal lexer (parallel usage seems no
+-- longer possible). For SciTE we can actually do a conceptual upgrade (more the
+-- context way) because there is no further development there. That way we could
+-- make even more advanced lexers.
+
+local savedrequire = require
+
+local escapes = {
+ ["%"] = "%%",
+ ["."] = "%.",
+ ["+"] = "%+", ["-"] = "%-", ["*"] = "%*",
+ ["["] = "%[", ["]"] = "%]",
+ ["("] = "%(", [")"] = "%)",
+ -- ["{"] = "%{", ["}"] = "%}"
+ -- ["^"] = "%^", ["$"] = "%$",
+}
+
function context.loadlexer(filename,namespace)
+
+ if textadept then
+ require = function(name)
+ return savedrequire(name == "lexer" and "scite-context-lexer" or name)
+ end
+ end
+
nesting = nesting + 1
if not namespace then
namespace = filename
@@ -1851,7 +1975,7 @@ function context.loadlexer(filename,namespace)
lexer = load_lexer(filename,namespace) or nolexer(filename,namespace)
usedlexers[filename] = lexer
--
- if not lexer._rules and not lexer._lexer then
+ if not lexer._rules and not lexer._lexer and not lexer_grammar then -- hmm should be lexer._grammar
lexer._lexer = parent_lexer
end
--
@@ -1883,6 +2007,8 @@ function context.loadlexer(filename,namespace)
end
--
local _r = lexer._rules
+ local _g = lexer._grammar
+ -- if _r or _g then
if _r then
local _s = lexer._tokenstyles
if _s then
@@ -1897,6 +2023,9 @@ function context.loadlexer(filename,namespace)
end
end
build_grammar(lexer)
+ else
+ -- other lexers
+ build_grammar(lexer)
end
--
add_style(lexer, lexer.whitespace, lexers.STYLE_WHITESPACE)
@@ -1906,7 +2035,7 @@ function context.loadlexer(filename,namespace)
local patterns = foldsymbols._patterns
if patterns then
for i = 1, #patterns do
- patterns[i] = "()(" .. patterns[i] .. ")"
+ patterns[i] = "()(" .. gsub(patterns[i],".",escapes) .. ")"
end
end
end
@@ -1920,6 +2049,10 @@ function context.loadlexer(filename,namespace)
context.inspect(lexer)
end
--
+ if textadept then
+ require = savedrequire
+ end
+ --
return lexer
end
@@ -2019,8 +2152,8 @@ lexers.inspect = context.inspect
lexers.report = context.report
lexers.inform = context.inform
--- helper .. alas ... the lexer's lua instance is rather crippled .. not even
--- math is part of it
+-- helper .. alas ... in scite the lexer's lua instance is rather crippled .. not
+-- even math is part of it
do
@@ -2029,26 +2162,6 @@ do
local format = format
local tonumber = tonumber
- if not floor then
-
- if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then
- floor = function(n)
- return tonumber(format("%d",n))
- end
- else
- -- 5.3 has a mixed number system and format %d doesn't work with
- -- floats any longer ... no fun
- floor = function(n)
- return (n - n % 1)
- end
- end
-
- math = math or { }
-
- math.floor = floor
-
- end
-
local function utfchar(n)
if n < 0x80 then
return char(n)
@@ -2424,6 +2537,128 @@ function lexers.fold_line_comments(prefix)
end
end
+-- There are some fundamental changes in textadept version 10 and I don't want to
+-- adapt again so we go the reverse route: map new to old. This is needed because
+-- we need to load other lexers which is teh result of not being able to load the
+-- lexer framework in parallel. Something happened in 10 that makes the main lexer
+-- always enforced so now we need to really replace that one (and even then it loads
+-- twice (i can probably sort that out). Maybe there's now some hard coded magic
+-- in the binary.
+
+if textadept then
+
+ -- Folds are still somewhat weak because of the end condition not being
+ -- bound to a start .. probably to complex and it seems to work anyhow. As
+ -- we have extended thinsg we just remap.
+
+ local function add_fold_point(lexer,token_name,start_symbol,end_symbol)
+ if type(start_symbol) == "string" then
+ local foldsymbols = lexer._foldsymbols
+ if not foldsymbols then
+ foldsymbols = { }
+ lexer._foldsymbols = foldsymbols
+ end
+ local patterns = foldsymbols._patterns
+ if not patterns then
+ patterns = { }
+ usedpatt = { } -- > 10 uses a mixed index/hash (we don't use patterns)
+ foldsymbols._patterns = patterns
+ foldsymbols._usedpatt = usedpatt
+ end
+ local foldsymbol = foldsymbols[token_name]
+ if not foldsymbol then
+ foldsymbol = { }
+ foldsymbols[token_name] = foldsymbol
+ end
+ if not usedpatt[start_symbol] then
+ patterns[#patterns+1] = start_symbol
+ usedpatt[start_symbol] = true
+ end
+ if type(end_symbol) == "string" then
+ foldsymbol[start_symbol] = 1
+ foldsymbol[end_symbol] = -1
+ if not usedpatt[end_symbol] then
+ patterns[#patterns+1] = end_symbol
+ usedpatt[end_symbol] = true
+ end
+ else
+ foldsymbol[start_symbol] = end_symbol
+ end
+ end
+ end
+
+ local function add_style(lexer,name,style)
+ local tokenstyles = lexer._tokenstyles
+ if not tokenstyles then
+ tokenstyles = { }
+ lexer._tokenstyles = tokenstyles
+ end
+ tokenstyles[name] = style
+ end
+
+ local function add_rule(lexer,id,rule)
+ local rules = lexer._rules
+ if not rules then
+ rules = { }
+ lexer._rules = rules
+ end
+ rules[#rules+1] = { id, rule }
+ end
+
+ local function modify_rule(lexer,id,rule) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ local RULES = lexer._RULES
+ if RULES then
+ RULES[id] = rule
+ end
+ end
+
+ local function get_rule(lexer,id) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ local RULES = lexer._RULES
+ if RULES then
+ return RULES[id]
+ end
+ end
+
+ local new = context.new
+ local lmt = {
+ __index = {
+
+ add_rule = add_rule,
+ modify_rule = modify_rule,
+ get_rule = get_rule,
+ add_style = add_style,
+ add_fold_point = add_fold_point,
+
+ join_tokens = join_tokens,
+ build_grammar = build_grammar,
+
+ embed = lexers.embed,
+ lex = lexers.lex,
+ fold = lexers.fold
+
+ }
+ }
+
+ function lexers.new(name,options)
+ local lexer = new(name)
+ if options then
+ lexer._LEXBYLINE = options['lex_by_line']
+ lexer._FOLDBYINDENTATION = options['fold_by_indentation']
+ lexer._CASEINSENSITIVEFOLDPOINTS = options['case_insensitive_fold_points']
+ lexer._lexer = options['inherit']
+ end
+ setmetatable(lexer,lmt)
+ return lexer
+ end
+
+end
+
-- done
return lexers
diff --git a/context/data/scite/context/scite-context-data-context.properties b/context/data/scite/context/scite-context-data-context.properties
index 5c089d489..c70aadab2 100644
--- a/context/data/scite/context/scite-context-data-context.properties
+++ b/context/data/scite/context/scite-context-data-context.properties
@@ -2,73 +2,77 @@ keywordclass.context.constants=\
zerocount minusone minustwo plusone \
plustwo plusthree plusfour plusfive plussix \
plusseven pluseight plusnine plusten plussixteen \
-plushundred plustwohundred plusthousand plustenthousand plustwentythousand \
-medcard maxcard maxcardminusone zeropoint onepoint \
-halfapoint onebasepoint maxcount maxdimen scaledpoint \
-thousandpoint points halfpoint zeroskip zeromuskip \
-onemuskip pluscxxvii pluscxxviii pluscclv pluscclvi \
-normalpagebox endoflinetoken outputnewlinechar emptytoks empty \
+plusfifty plushundred plusonehundred plustwohundred plusfivehundred \
+plusthousand plustenthousand plustwentythousand medcard maxcard \
+maxcardminusone zeropoint onepoint halfapoint onebasepoint \
+maxcount maxdimen scaledpoint thousandpoint points \
+halfpoint zeroskip zeromuskip onemuskip pluscxxvii \
+pluscxxviii pluscclv pluscclvi normalpagebox directionlefttoright \
+directionrighttoleft endoflinetoken outputnewlinechar emptytoks empty \
undefined voidbox emptybox emptyvbox emptyhbox \
bigskipamount medskipamount smallskipamount fmtname fmtversion \
texengine texenginename texengineversion texenginefunctionality luatexengine \
-pdftexengine xetexengine unknownengine activecatcode bgroup \
-egroup endline conditionaltrue conditionalfalse attributeunsetvalue \
-uprotationangle rightrotationangle downrotationangle leftrotationangle inicatcodes \
-ctxcatcodes texcatcodes notcatcodes txtcatcodes vrbcatcodes \
-prtcatcodes nilcatcodes luacatcodes tpacatcodes tpbcatcodes \
-xmlcatcodes ctdcatcodes escapecatcode begingroupcatcode endgroupcatcode \
-mathshiftcatcode alignmentcatcode endoflinecatcode parametercatcode superscriptcatcode \
-subscriptcatcode ignorecatcode spacecatcode lettercatcode othercatcode \
-activecatcode commentcatcode invalidcatcode tabasciicode newlineasciicode \
-formfeedasciicode endoflineasciicode endoffileasciicode spaceasciicode hashasciicode \
-dollarasciicode commentasciicode ampersandasciicode colonasciicode backslashasciicode \
-circumflexasciicode underscoreasciicode leftbraceasciicode barasciicode rightbraceasciicode \
-tildeasciicode delasciicode lessthanasciicode morethanasciicode doublecommentsignal \
-atsignasciicode exclamationmarkasciicode questionmarkasciicode doublequoteasciicode singlequoteasciicode \
-forwardslashasciicode primeasciicode hyphenasciicode activemathcharcode activetabtoken \
-activeformfeedtoken activeendoflinetoken batchmodecode nonstopmodecode scrollmodecode \
-errorstopmodecode bottomlevelgroupcode simplegroupcode hboxgroupcode adjustedhboxgroupcode \
-vboxgroupcode vtopgroupcode aligngroupcode noaligngroupcode outputgroupcode \
-mathgroupcode discretionarygroupcode insertgroupcode vcentergroupcode mathchoicegroupcode \
-semisimplegroupcode mathshiftgroupcode mathleftgroupcode vadjustgroupcode charnodecode \
-hlistnodecode vlistnodecode rulenodecode insertnodecode marknodecode \
-adjustnodecode ligaturenodecode discretionarynodecode whatsitnodecode mathnodecode \
-gluenodecode kernnodecode penaltynodecode unsetnodecode mathsnodecode \
-charifcode catifcode numifcode dimifcode oddifcode \
-vmodeifcode hmodeifcode mmodeifcode innerifcode voidifcode \
-hboxifcode vboxifcode xifcode eofifcode trueifcode \
-falseifcode caseifcode definedifcode csnameifcode fontcharifcode \
-fontslantperpoint fontinterwordspace fontinterwordstretch fontinterwordshrink fontexheight \
-fontemwidth fontextraspace slantperpoint mathexheight mathemwidth \
-interwordspace interwordstretch interwordshrink exheight emwidth \
-extraspace mathsupdisplay mathsupnormal mathsupcramped mathsubnormal \
-mathsubcombined mathaxisheight muquad startmode stopmode \
-startnotmode stopnotmode startmodeset stopmodeset doifmode \
-doifelsemode doifmodeelse doifnotmode startmodeset stopmodeset \
-startallmodes stopallmodes startnotallmodes stopnotallmodes doifallmodes \
-doifelseallmodes doifallmodeselse doifnotallmodes startenvironment stopenvironment \
-environment startcomponent stopcomponent component startproduct \
-stopproduct product startproject stopproject project \
-starttext stoptext startnotext stopnotext startdocument \
-stopdocument documentvariable unexpandeddocumentvariable setupdocument presetdocument \
-startmodule stopmodule usemodule usetexmodule useluamodule \
-setupmodule currentmoduleparameter moduleparameter everystarttext everystoptext \
-startTEXpage stopTEXpage enablemode disablemode preventmode \
-definemode globalenablemode globaldisablemode globalpreventmode pushmode \
-popmode typescriptone typescripttwo typescriptthree mathsizesuffix \
-mathordcode mathopcode mathbincode mathrelcode mathopencode \
-mathclosecode mathpunctcode mathalphacode mathinnercode mathnothingcode \
-mathlimopcode mathnolopcode mathboxcode mathchoicecode mathaccentcode \
-mathradicalcode constantnumber constantnumberargument constantdimen constantdimenargument \
-constantemptyargument continueifinputfile luastringsep !!bs !!es \
-lefttorightmark righttoleftmark lrm rlm bidilre \
-bidirle bidipop bidilro bidirlo breakablethinspace \
-nobreakspace nonbreakablespace narrownobreakspace zerowidthnobreakspace ideographicspace \
-ideographichalffillspace twoperemspace threeperemspace fourperemspace fiveperemspace \
-sixperemspace figurespace punctuationspace hairspace enquad \
-emquad zerowidthspace zerowidthnonjoiner zerowidthjoiner zwnj \
-zwj optionalspace asciispacechar softhyphen Ux \
-eUx Umathaccents parfillleftskip parfillrightskip
+pdftexengine xetexengine unknownengine contextformat contextversion \
+contextkind contextlmtxmode contextmark mksuffix activecatcode \
+bgroup egroup endline conditionaltrue conditionalfalse \
+attributeunsetvalue uprotationangle rightrotationangle downrotationangle leftrotationangle \
+inicatcodes ctxcatcodes texcatcodes notcatcodes txtcatcodes \
+vrbcatcodes prtcatcodes nilcatcodes luacatcodes tpacatcodes \
+tpbcatcodes xmlcatcodes ctdcatcodes escapecatcode begingroupcatcode \
+endgroupcatcode mathshiftcatcode alignmentcatcode endoflinecatcode parametercatcode \
+superscriptcatcode subscriptcatcode ignorecatcode spacecatcode lettercatcode \
+othercatcode activecatcode commentcatcode invalidcatcode tabasciicode \
+newlineasciicode formfeedasciicode endoflineasciicode endoffileasciicode spaceasciicode \
+hashasciicode dollarasciicode commentasciicode ampersandasciicode colonasciicode \
+backslashasciicode circumflexasciicode underscoreasciicode leftbraceasciicode barasciicode \
+rightbraceasciicode tildeasciicode delasciicode leftparentasciicode rightparentasciicode \
+lessthanasciicode morethanasciicode doublecommentsignal atsignasciicode exclamationmarkasciicode \
+questionmarkasciicode doublequoteasciicode singlequoteasciicode forwardslashasciicode primeasciicode \
+hyphenasciicode activemathcharcode activetabtoken activeformfeedtoken activeendoflinetoken \
+batchmodecode nonstopmodecode scrollmodecode errorstopmodecode bottomlevelgroupcode \
+simplegroupcode hboxgroupcode adjustedhboxgroupcode vboxgroupcode vtopgroupcode \
+aligngroupcode noaligngroupcode outputgroupcode mathgroupcode discretionarygroupcode \
+insertgroupcode vcentergroupcode mathchoicegroupcode semisimplegroupcode mathshiftgroupcode \
+mathleftgroupcode vadjustgroupcode charnodecode hlistnodecode vlistnodecode \
+rulenodecode insertnodecode marknodecode adjustnodecode ligaturenodecode \
+discretionarynodecode whatsitnodecode mathnodecode gluenodecode kernnodecode \
+penaltynodecode unsetnodecode mathsnodecode charifcode catifcode \
+numifcode dimifcode oddifcode vmodeifcode hmodeifcode \
+mmodeifcode innerifcode voidifcode hboxifcode vboxifcode \
+xifcode eofifcode trueifcode falseifcode caseifcode \
+definedifcode csnameifcode fontcharifcode fontslantperpoint fontinterwordspace \
+fontinterwordstretch fontinterwordshrink fontexheight fontemwidth fontextraspace \
+slantperpoint mathexheight mathemwidth interwordspace interwordstretch \
+interwordshrink exheight emwidth extraspace mathsupdisplay \
+mathsupnormal mathsupcramped mathsubnormal mathsubcombined mathaxisheight \
+muquad startmode stopmode startnotmode stopnotmode \
+startmodeset stopmodeset doifmode doifelsemode doifmodeelse \
+doifnotmode startmodeset stopmodeset startallmodes stopallmodes \
+startnotallmodes stopnotallmodes doifallmodes doifelseallmodes doifallmodeselse \
+doifnotallmodes startenvironment stopenvironment environment startcomponent \
+stopcomponent component startproduct stopproduct product \
+startproject stopproject project starttext stoptext \
+startnotext stopnotext startdocument stopdocument documentvariable \
+unexpandeddocumentvariable setupdocument presetdocument doifelsedocumentvariable doifdocumentvariableelse \
+doifdocumentvariable doifnotdocumentvariable startmodule stopmodule usemodule \
+usetexmodule useluamodule setupmodule currentmoduleparameter moduleparameter \
+everystarttext everystoptext startTEXpage stopTEXpage enablemode \
+disablemode preventmode definemode globalenablemode globaldisablemode \
+globalpreventmode pushmode popmode typescriptone typescripttwo \
+typescriptthree mathsizesuffix mathordcode mathopcode mathbincode \
+mathrelcode mathopencode mathclosecode mathpunctcode mathalphacode \
+mathinnercode mathnothingcode mathlimopcode mathnolopcode mathboxcode \
+mathchoicecode mathaccentcode mathradicalcode constantnumber constantnumberargument \
+constantdimen constantdimenargument constantemptyargument continueifinputfile luastringsep \
+!!bs !!es lefttorightmark righttoleftmark lrm \
+rlm bidilre bidirle bidipop bidilro \
+bidirlo breakablethinspace nobreakspace nonbreakablespace narrownobreakspace \
+zerowidthnobreakspace ideographicspace ideographichalffillspace twoperemspace threeperemspace \
+fourperemspace fiveperemspace sixperemspace figurespace punctuationspace \
+hairspace enquad emquad zerowidthspace zerowidthnonjoiner \
+zerowidthjoiner zwnj zwj optionalspace asciispacechar \
+softhyphen Ux eUx Umathaccents parfillleftskip \
+parfillrightskip
keywordclass.context.helpers=\
startsetups stopsetups startxmlsetups stopxmlsetups \
@@ -77,28 +81,31 @@ stoprawsetups startlocalsetups stoplocalsetups starttexdefinition stoptexdefinit
starttexcode stoptexcode startcontextcode stopcontextcode startcontextdefinitioncode \
stopcontextdefinitioncode texdefinition doifelsesetups doifsetupselse doifsetups \
doifnotsetups setup setups texsetup xmlsetup \
-luasetup directsetup fastsetup doifelsecommandhandler doifcommandhandlerelse \
-doifnotcommandhandler doifcommandhandler newmode setmode resetmode \
-newsystemmode setsystemmode resetsystemmode pushsystemmode popsystemmode \
-booleanmodevalue newcount newdimen newskip newmuskip \
-newbox newtoks newread newwrite newmarks \
-newinsert newattribute newif newlanguage newfamily \
-newfam newhelp then begcsname strippedcsname \
-checkedstrippedcsname firstargumentfalse firstargumenttrue secondargumentfalse secondargumenttrue \
-thirdargumentfalse thirdargumenttrue fourthargumentfalse fourthargumenttrue fifthargumentfalse \
-fifthsargumenttrue sixthargumentfalse sixtsargumenttrue doglobal dodoglobal \
-redoglobal resetglobal donothing dontcomplain forgetall \
-donetrue donefalse foundtrue foundfalse inlineordisplaymath \
-indisplaymath forcedisplaymath startforceddisplaymath stopforceddisplaymath startpickupmath \
-stoppickupmath reqno mathortext htdp unvoidbox \
-hfilll vfilll mathbox mathlimop mathnolop \
-mathnothing mathalpha currentcatcodetable defaultcatcodetable catcodetablename \
-newcatcodetable startcatcodetable stopcatcodetable startextendcatcodetable stopextendcatcodetable \
-pushcatcodetable popcatcodetable restorecatcodes setcatcodetable letcatcodecommand \
-defcatcodecommand uedcatcodecommand hglue vglue hfillneg \
-vfillneg hfilllneg vfilllneg ruledhss ruledhfil \
-ruledhfill ruledhfilneg ruledhfillneg normalhfillneg ruledvss \
-ruledvfil ruledvfill ruledvfilneg ruledvfillneg normalvfillneg \
+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 newlanguage \
+newfamily newfam newhelp then begcsname \
+autorule strippedcsname checkedstrippedcsname firstargumentfalse firstargumenttrue \
+secondargumentfalse secondargumenttrue thirdargumentfalse thirdargumenttrue fourthargumentfalse \
+fourthargumenttrue fifthargumentfalse fifthargumenttrue sixthargumentfalse sixthargumenttrue \
+seventhargumentfalse seventhargumenttrue vkern hkern doglobal \
+dodoglobal redoglobal resetglobal donothing dontcomplain \
+forgetall donetrue donefalse foundtrue foundfalse \
+inlineordisplaymath indisplaymath forcedisplaymath startforceddisplaymath stopforceddisplaymath \
+startpickupmath stoppickupmath reqno mathortext htdp \
+unvoidbox hfilll vfilll mathbox mathlimop \
+mathnolop mathnothing mathalpha currentcatcodetable defaultcatcodetable \
+catcodetablename newcatcodetable startcatcodetable stopcatcodetable startextendcatcodetable \
+stopextendcatcodetable pushcatcodetable popcatcodetable restorecatcodes setcatcodetable \
+letcatcodecommand defcatcodecommand uedcatcodecommand hglue vglue \
+hfillneg vfillneg hfilllneg vfilllneg ruledhss \
+ruledhfil ruledhfill 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 ruledhglue ruledvglue \
@@ -107,34 +114,37 @@ filledhboxg filledhboxc filledhboxm filledhboxy filledhboxk \
scratchcounter globalscratchcounter privatescratchcounter scratchdimen globalscratchdimen \
privatescratchdimen scratchskip globalscratchskip privatescratchskip scratchmuskip \
globalscratchmuskip privatescratchmuskip scratchtoks globalscratchtoks privatescratchtoks \
-scratchbox globalscratchbox privatescratchbox normalbaselineskip normallineskip \
-normallineskiplimit availablehsize localhsize setlocalhsize distributedhsize \
-hsizefraction nextbox dowithnextbox dowithnextboxcs dowithnextboxcontent \
-dowithnextboxcontentcs flushnextbox scratchwidth scratchheight scratchdepth \
-scratchoffset scratchdistance scratchhsize scratchvsize scratchxoffset \
-scratchyoffset scratchhoffset scratchvoffset scratchxposition scratchyposition \
-scratchtopoffset scratchbottomoffset scratchleftoffset scratchrightoffset scratchcounterone \
-scratchcountertwo scratchcounterthree scratchcounterfour scratchcounterfive scratchcountersix \
-scratchdimenone scratchdimentwo scratchdimenthree scratchdimenfour scratchdimenfive \
-scratchdimensix scratchskipone scratchskiptwo scratchskipthree scratchskipfour \
-scratchskipfive scratchskipsix scratchmuskipone scratchmuskiptwo scratchmuskipthree \
-scratchmuskipfour scratchmuskipfive scratchmuskipsix scratchtoksone scratchtokstwo \
-scratchtoksthree scratchtoksfour scratchtoksfive scratchtokssix scratchboxone \
-scratchboxtwo scratchboxthree scratchboxfour scratchboxfive scratchboxsix \
-scratchnx scratchny scratchmx scratchmy scratchunicode \
-scratchmin scratchmax scratchleftskip scratchrightskip scratchtopskip \
-scratchbottomskip doif doifnot doifelse doifinset \
-doifnotinset doifelseinset doifinsetelse doifelsenextchar doifnextcharelse \
-doifelsenextoptional doifnextoptionalelse doifelsenextoptionalcs doifnextoptionalcselse doifelsefastoptionalcheck \
-doiffastoptionalcheckelse doifelsefastoptionalcheckcs doiffastoptionalcheckcselse doifelsenextbgroup doifnextbgroupelse \
-doifelsenextbgroupcs doifnextbgroupcselse doifelsenextparenthesis doifnextparenthesiselse doifelseundefined \
-doifundefinedelse doifelsedefined doifdefinedelse doifundefined doifdefined \
-doifelsevalue doifvalue doifnotvalue doifnothing doifsomething \
-doifelsenothing doifnothingelse doifelsesomething doifsomethingelse doifvaluenothing \
-doifvaluesomething doifelsevaluenothing doifvaluenothingelse doifelsedimension doifdimensionelse \
-doifelsenumber doifnumberelse doifnumber doifnotnumber doifelsecommon \
-doifcommonelse doifcommon doifnotcommon doifinstring doifnotinstring \
-doifelseinstring doifinstringelse doifelseassignment doifassignmentelse docheckassignment \
+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 scratchxoffset scratchyoffset scratchhoffset scratchvoffset \
+scratchxposition scratchyposition scratchtopoffset scratchbottomoffset scratchleftoffset \
+scratchrightoffset scratchcounterone scratchcountertwo scratchcounterthree scratchcounterfour \
+scratchcounterfive scratchcountersix scratchdimenone scratchdimentwo scratchdimenthree \
+scratchdimenfour scratchdimenfive scratchdimensix scratchskipone scratchskiptwo \
+scratchskipthree scratchskipfour scratchskipfive scratchskipsix scratchmuskipone \
+scratchmuskiptwo scratchmuskipthree scratchmuskipfour scratchmuskipfive scratchmuskipsix \
+scratchtoksone scratchtokstwo scratchtoksthree scratchtoksfour scratchtoksfive \
+scratchtokssix scratchboxone scratchboxtwo scratchboxthree scratchboxfour \
+scratchboxfive scratchboxsix scratchnx scratchny scratchmx \
+scratchmy scratchunicode scratchmin scratchmax scratchleftskip \
+scratchrightskip scratchtopskip scratchbottomskip doif doifnot \
+doifelse firstinset doifinset doifnotinset doifelseinset \
+doifinsetelse doifelsenextchar doifnextcharelse doifelsenextoptional doifnextoptionalelse \
+doifelsenextoptionalcs doifnextoptionalcselse doifelsefastoptionalcheck doiffastoptionalcheckelse doifelsefastoptionalcheckcs \
+doiffastoptionalcheckcselse doifelsenextbgroup doifnextbgroupelse doifelsenextbgroupcs doifnextbgroupcselse \
+doifelsenextparenthesis doifnextparenthesiselse doifelseundefined doifundefinedelse doifelsedefined \
+doifdefinedelse doifundefined doifdefined doifelsevalue doifvalue \
+doifnotvalue doifnothing doifsomething doifelsenothing doifnothingelse \
+doifelsesomething doifsomethingelse doifvaluenothing doifvaluesomething doifelsevaluenothing \
+doifvaluenothingelse doifelsedimension doifdimensionelse doifelsenumber doifnumberelse \
+doifnumber doifnotnumber doifelsecommon doifcommonelse doifcommon \
+doifnotcommon doifinstring doifnotinstring doifelseinstring doifinstringelse \
+doifelseassignment doifassignmentelse docheckassignment doifelseassignmentcs doifassignmentelsecs \
doiftext doifelsetext doiftextelse doifnottext tracingall \
tracingnone loggingall removetoks appendtoks prependtoks \
appendtotoks prependtotoks to endgraf endpar \
@@ -144,77 +154,77 @@ nbsp crlf obeyspaces obeylines obeyedspace \
obeyedline obeyedtab obeyedpage normalspace executeifdefined \
singleexpandafter doubleexpandafter tripleexpandafter dontleavehmode removelastspace \
removeunwantedspaces keepunwantedspaces removepunctuation ignoreparskip forcestrutdepth \
-wait writestatus define defineexpandable redefine \
-setmeasure setemeasure setgmeasure setxmeasure definemeasure \
-freezemeasure measure measured installcorenamespace getvalue \
-getuvalue setvalue setevalue setgvalue setxvalue \
-letvalue letgvalue resetvalue undefinevalue ignorevalue \
-setuvalue setuevalue setugvalue setuxvalue globallet \
-glet udef ugdef uedef uxdef \
-checked unique getparameters geteparameters getgparameters \
-getxparameters forgetparameters copyparameters getdummyparameters dummyparameter \
-directdummyparameter setdummyparameter letdummyparameter setexpandeddummyparameter usedummystyleandcolor \
-usedummystyleparameter usedummycolorparameter processcommalist processcommacommand quitcommalist \
-quitprevcommalist processaction processallactions processfirstactioninset processallactionsinset \
-unexpanded expanded startexpanded stopexpanded protected \
-protect unprotect firstofoneargument firstoftwoarguments secondoftwoarguments \
-firstofthreearguments secondofthreearguments thirdofthreearguments firstoffourarguments secondoffourarguments \
-thirdoffourarguments fourthoffourarguments firstoffivearguments secondoffivearguments thirdoffivearguments \
-fourthoffivearguments fifthoffivearguments firstofsixarguments secondofsixarguments thirdofsixarguments \
-fourthofsixarguments fifthofsixarguments sixthofsixarguments firstofoneunexpanded firstoftwounexpanded \
-secondoftwounexpanded firstofthreeunexpanded secondofthreeunexpanded thirdofthreeunexpanded gobbleoneargument \
-gobbletwoarguments gobblethreearguments gobblefourarguments gobblefivearguments gobblesixarguments \
-gobblesevenarguments gobbleeightarguments gobbleninearguments gobbletenarguments gobbleoneoptional \
-gobbletwooptionals gobblethreeoptionals gobblefouroptionals gobblefiveoptionals dorecurse \
-doloop exitloop dostepwiserecurse recurselevel recursedepth \
-dofastloopcs fastloopindex fastloopfinal dowith newconstant \
-setnewconstant setconstant setconstantvalue newconditional settrue \
-setfalse settruevalue setfalsevalue newmacro setnewmacro \
-newfraction newsignal dosingleempty dodoubleempty dotripleempty \
-doquadrupleempty doquintupleempty dosixtupleempty doseventupleempty dosingleargument \
-dodoubleargument dotripleargument doquadrupleargument doquintupleargument dosixtupleargument \
-doseventupleargument dosinglegroupempty dodoublegroupempty dotriplegroupempty doquadruplegroupempty \
-doquintuplegroupempty permitspacesbetweengroups dontpermitspacesbetweengroups nopdfcompression maximumpdfcompression \
-normalpdfcompression modulonumber dividenumber getfirstcharacter doifelsefirstchar \
-doiffirstcharelse startnointerference stopnointerference twodigits threedigits \
-leftorright offinterlineskip oninterlineskip nointerlineskip strut \
-halfstrut quarterstrut depthstrut halflinestrut noheightstrut \
-setstrut strutbox strutht strutdp strutwd \
-struthtdp strutgap begstrut endstrut lineheight \
-leftboundary rightboundary signalcharacter ordordspacing ordopspacing \
-ordbinspacing ordrelspacing ordopenspacing ordclosespacing ordpunctspacing \
-ordinnerspacing opordspacing opopspacing opbinspacing oprelspacing \
-opopenspacing opclosespacing oppunctspacing opinnerspacing binordspacing \
-binopspacing binbinspacing binrelspacing binopenspacing binclosespacing \
-binpunctspacing bininnerspacing relordspacing relopspacing relbinspacing \
-relrelspacing relopenspacing relclosespacing relpunctspacing relinnerspacing \
-openordspacing openopspacing openbinspacing openrelspacing openopenspacing \
-openclosespacing openpunctspacing openinnerspacing closeordspacing closeopspacing \
-closebinspacing closerelspacing closeopenspacing closeclosespacing closepunctspacing \
-closeinnerspacing punctordspacing punctopspacing punctbinspacing punctrelspacing \
-punctopenspacing punctclosespacing punctpunctspacing punctinnerspacing innerordspacing \
-inneropspacing innerbinspacing innerrelspacing inneropenspacing innerclosespacing \
-innerpunctspacing innerinnerspacing normalreqno startimath stopimath \
-normalstartimath normalstopimath startdmath stopdmath normalstartdmath \
-normalstopdmath normalsuperscript normalsubscript normalnosuperscript normalnosubscript \
-superscript subscript nosuperscript nosubscript uncramped \
-cramped triggermathstyle mathstylefont mathsmallstylefont mathstyleface \
-mathsmallstyleface mathstylecommand mathpalette mathstylehbox mathstylevbox \
-mathstylevcenter mathstylevcenteredhbox mathstylevcenteredvbox mathtext setmathsmalltextbox \
-setmathtextbox pushmathstyle popmathstyle triggerdisplaystyle triggertextstyle \
-triggerscriptstyle triggerscriptscriptstyle triggeruncrampedstyle triggercrampedstyle triggersmallstyle \
-triggeruncrampedsmallstyle triggercrampedsmallstyle triggerbigstyle triggeruncrampedbigstyle triggercrampedbigstyle \
-luaexpr expelsedoif expdoif expdoifnot expdoifelsecommon \
-expdoifcommonelse expdoifelseinset expdoifinsetelse ctxdirectlua ctxlatelua \
-ctxsprint ctxwrite ctxcommand ctxdirectcommand ctxlatecommand \
-ctxreport ctxlua luacode lateluacode directluacode \
-registerctxluafile ctxloadluafile luaversion luamajorversion luaminorversion \
-ctxluacode luaconditional luaexpanded startluaparameterset stopluaparameterset \
-luaparameterset definenamedlua obeylualines obeyluatokens startluacode \
-stopluacode startlua stoplua startctxfunction stopctxfunction \
-ctxfunction startctxfunctiondefinition stopctxfunctiondefinition installctxfunction installctxfunctioncall \
-installprotectedctxfunction installprotectedctxfunctioncall installctxscanner installctxscannercall resetctxscanner \
-installprotectedctxscanner installprotectedctxscannercall cldprocessfile cldloadfile cldcontext \
+onlynonbreakablespace wait writestatus define defineexpandable \
+redefine setmeasure setemeasure setgmeasure setxmeasure \
+definemeasure freezemeasure measure measured installcorenamespace \
+getvalue getuvalue setvalue setevalue setgvalue \
+setxvalue letvalue letgvalue resetvalue undefinevalue \
+ignorevalue setuvalue setuevalue setugvalue setuxvalue \
+globallet glet udef ugdef uedef \
+uxdef checked unique getparameters geteparameters \
+getgparameters getxparameters forgetparameters copyparameters getdummyparameters \
+dummyparameter directdummyparameter setdummyparameter letdummyparameter setexpandeddummyparameter \
+usedummystyleandcolor usedummystyleparameter usedummycolorparameter processcommalist processcommacommand \
+quitcommalist quitprevcommalist processaction processallactions processfirstactioninset \
+processallactionsinset unexpanded expanded startexpanded stopexpanded \
+protected protect unprotect firstofoneargument firstoftwoarguments \
+secondoftwoarguments firstofthreearguments secondofthreearguments thirdofthreearguments firstoffourarguments \
+secondoffourarguments thirdoffourarguments fourthoffourarguments firstoffivearguments secondoffivearguments \
+thirdoffivearguments fourthoffivearguments fifthoffivearguments firstofsixarguments secondofsixarguments \
+thirdofsixarguments fourthofsixarguments fifthofsixarguments sixthofsixarguments firstofoneunexpanded \
+firstoftwounexpanded secondoftwounexpanded firstofthreeunexpanded secondofthreeunexpanded thirdofthreeunexpanded \
+gobbleoneargument gobbletwoarguments gobblethreearguments gobblefourarguments gobblefivearguments \
+gobblesixarguments gobblesevenarguments gobbleeightarguments gobbleninearguments gobbletenarguments \
+gobbleoneoptional gobbletwooptionals gobblethreeoptionals gobblefouroptionals gobblefiveoptionals \
+dorecurse doloop exitloop dostepwiserecurse recurselevel \
+recursedepth dofastloopcs fastloopindex fastloopfinal dowith \
+newconstant setnewconstant setconstant setconstantvalue newconditional \
+settrue setfalse settruevalue setfalsevalue newmacro \
+setnewmacro newfraction newsignal dosingleempty dodoubleempty \
+dotripleempty doquadrupleempty doquintupleempty dosixtupleempty doseventupleempty \
+dosingleargument dodoubleargument dotripleargument doquadrupleargument doquintupleargument \
+dosixtupleargument doseventupleargument dosinglegroupempty dodoublegroupempty dotriplegroupempty \
+doquadruplegroupempty doquintuplegroupempty permitspacesbetweengroups dontpermitspacesbetweengroups nopdfcompression \
+maximumpdfcompression normalpdfcompression onlypdfobjectcompression nopdfobjectcompression modulonumber \
+dividenumber getfirstcharacter doifelsefirstchar doiffirstcharelse startnointerference \
+stopnointerference twodigits threedigits leftorright offinterlineskip \
+oninterlineskip nointerlineskip strut halfstrut quarterstrut \
+depthstrut halflinestrut noheightstrut setstrut strutbox \
+strutht strutdp strutwd struthtdp strutgap \
+begstrut endstrut lineheight leftboundary rightboundary \
+signalcharacter ordordspacing ordopspacing ordbinspacing ordrelspacing \
+ordopenspacing ordclosespacing ordpunctspacing ordinnerspacing opordspacing \
+opopspacing opbinspacing oprelspacing opopenspacing opclosespacing \
+oppunctspacing opinnerspacing binordspacing binopspacing binbinspacing \
+binrelspacing binopenspacing binclosespacing binpunctspacing bininnerspacing \
+relordspacing relopspacing relbinspacing relrelspacing relopenspacing \
+relclosespacing relpunctspacing relinnerspacing openordspacing openopspacing \
+openbinspacing openrelspacing openopenspacing openclosespacing openpunctspacing \
+openinnerspacing closeordspacing closeopspacing closebinspacing closerelspacing \
+closeopenspacing closeclosespacing closepunctspacing closeinnerspacing punctordspacing \
+punctopspacing punctbinspacing punctrelspacing punctopenspacing punctclosespacing \
+punctpunctspacing punctinnerspacing innerordspacing inneropspacing innerbinspacing \
+innerrelspacing inneropenspacing innerclosespacing innerpunctspacing innerinnerspacing \
+normalreqno startimath stopimath normalstartimath normalstopimath \
+startdmath stopdmath normalstartdmath normalstopdmath normalsuperscript \
+normalsubscript normalnosuperscript normalnosubscript superscript subscript \
+nosuperscript nosubscript uncramped cramped triggermathstyle \
+mathstylefont mathsmallstylefont mathstyleface mathsmallstyleface mathstylecommand \
+mathpalette mathstylehbox mathstylevbox mathstylevcenter mathstylevcenteredhbox \
+mathstylevcenteredvbox mathtext setmathsmalltextbox setmathtextbox pushmathstyle \
+popmathstyle triggerdisplaystyle triggertextstyle triggerscriptstyle triggerscriptscriptstyle \
+triggeruncrampedstyle triggercrampedstyle triggersmallstyle triggeruncrampedsmallstyle triggercrampedsmallstyle \
+triggerbigstyle triggeruncrampedbigstyle triggercrampedbigstyle luaexpr expelsedoif \
+expdoif expdoifnot expdoifelsecommon expdoifcommonelse expdoifelseinset \
+expdoifinsetelse ctxdirectlua ctxlatelua ctxsprint ctxwrite \
+ctxcommand ctxdirectcommand ctxlatecommand ctxreport ctxlua \
+luacode lateluacode directluacode registerctxluafile ctxloadluafile \
+luaversion luamajorversion luaminorversion ctxluacode luaconditional \
+luaexpanded startluaparameterset stopluaparameterset luaparameterset definenamedlua \
+obeylualines obeyluatokens startluacode stopluacode startlua \
+stoplua startctxfunction stopctxfunction ctxfunction startctxfunctiondefinition \
+stopctxfunctiondefinition installctxfunction installprotectedctxfunction installprotectedctxscanner installctxscanner \
+resetctxscanner cldprocessfile cldloadfile cldloadviafile cldcontext \
cldcommand carryoverpar lastlinewidth assumelongusagecs Umathbotaccent \
righttolefthbox lefttorighthbox righttoleftvbox lefttorightvbox righttoleftvtop \
lefttorightvtop rtlhbox ltrhbox rtlvbox ltrvbox \
@@ -225,6 +235,7 @@ dirlre dirrle dirlro dirrlo lesshyphens \
morehyphens nohyphens dohyphens Ucheckedstartdisplaymath Ucheckedstopdisplaymath \
break nobreak allowbreak goodbreak nospace \
nospacing dospacing naturalhbox naturalvbox naturalvtop \
-naturalhpack naturalvpack frule compoundhyphenpenalty start \
-stop
+naturalhpack naturalvpack naturaltpack reversehbox reversevbox \
+reversevtop reversehpack reversevpack reversetpack frule \
+compoundhyphenpenalty start stop
diff --git a/context/data/scite/context/scite-context-data-interfaces.properties b/context/data/scite/context/scite-context-data-interfaces.properties
index aa5ba4612..73480b187 100644
--- a/context/data/scite/context/scite-context-data-interfaces.properties
+++ b/context/data/scite/context/scite-context-data-interfaces.properties
@@ -123,262 +123,267 @@ assigndimension assignifempty assigntranslation assignvalue assignwidth \
assumelongusagecs ast astype asymp at \
atilde atleftmargin atpage atrightmargin attachment \
autocap autodirhbox autodirvbox autodirvtop autoinsertnextspace \
-autointegral automathematics autosetups availablehsize averagecharwidth \
-backepsilon background backgroundimage backgroundimagefill backgroundline \
-backprime backsim backslash bar barleftarrow \
-barleftarrowrightarrowbar barovernorthwestarrow barwedge basegrid baselinebottom \
-baselineleftbox baselinemiddlebox baselinerightbox bbordermatrix bbox \
-because beforesplitstring beforetestandsplitstring beta beth \
-between bhook big bigbodyfont bigcap \
-bigcirc bigcircle bigcup bigdiamond bigg \
-bigger biggl biggm biggr bigl \
-bigm bigodot bigoplus bigotimes bigr \
-bigskip bigsqcap bigsqcup bigsquare bigstar \
-bigtimes bigtriangledown bigtriangleup bigudot biguplus \
-bigvee bigwedge binom bitmapimage blacklozenge \
-blackrule blackrules blacksquare blacktriangle blacktriangledown \
-blacktriangleleft blacktriangleright blank blap bleed \
-bleedheight bleedwidth blockligatures blockquote blocksynctexfile \
-bodyfontenvironmentlist bodyfontsize bold boldface bolditalic \
-boldslanted bookmark booleanmodevalue bordermatrix bot \
-bottombox bottomleftbox bottomrightbox bowtie boxcursor \
-boxdot boxmarker boxminus boxofsize boxplus \
-boxreference boxtimes bpos breakablethinspace breakhere \
-breve bstroke btxabbreviatedjournal btxaddjournal btxalwayscitation \
-btxauthorfield btxdetail btxdirect btxdoif btxdoifcombiinlistelse \
-btxdoifelse btxdoifelsecombiinlist btxdoifelsesameasprevious btxdoifelsesameaspreviouschecked btxdoifelseuservariable \
-btxdoifnot btxdoifsameaspreviouscheckedelse btxdoifsameaspreviouselse btxdoifuservariableelse btxexpandedjournal \
-btxfield btxfieldname btxfieldtype btxfirstofrange btxflush \
-btxflushauthor btxflushauthorinverted btxflushauthorinvertedshort btxflushauthorname btxflushauthornormal \
-btxflushauthornormalshort btxflushsuffix btxfoundname btxfoundtype btxhiddencitation \
-btxhybridcite btxlabellanguage btxlabeltext btxlistcitation btxloadjournalist \
-btxoneorrange btxremapauthor btxsavejournalist btxsetup btxsingularorplural \
-btxsingularplural btxtextcitation buildmathaccent buildtextaccent buildtextbottomcomma \
-buildtextbottomdot buildtextcedilla buildtextgrave buildtextmacron buildtextognek \
-bullet button cacute calligraphic camel \
-cap carriagereturn catcodetablename cbox ccaron \
-ccedilla ccircumflex ccurl cdot cdotaccent \
-cdotp cdots centeraligned centerbox centerdot \
-centeredbox centeredlastline centerednextbox centerline cfrac \
-chapter character characters chardescription charwidthlanguage \
-check checkcharacteralign checkedchar checkedfiller checkedstrippedcsname \
-checkinjector checkmark checknextindentation checknextinjector checkpage \
-checkparameters checkpreviousinjector checksoundtrack checktwopassdata checkvariables \
-chem chemical chemicalbottext chemicalmidtext chemicalsymbol \
-chemicaltext chemicaltoptext chi chineseallnumerals chinesecapnumerals \
-chinesenumerals chook circ circeq circlearrowleft \
-circlearrowright circledR circledS circledast circledcirc \
-circleddash circledequals circleonrightarrow citation cite \
-clap classfont cldcommand cldcontext cldloadfile \
-cldprocessfile cleftarrow clip clonefield clubsuit \
+autointegral automathematics autopagestaterealpage autopagestaterealpageorder autosetups \
+availablehsize averagecharwidth backepsilon background backgroundimage \
+backgroundimagefill backgroundline backprime backsim backslash \
+bar barleftarrow barleftarrowrightarrowbar barovernorthwestarrow barwedge \
+basegrid baselinebottom baselineleftbox baselinemiddlebox baselinerightbox \
+bbordermatrix bbox because beforesplitstring beforetestandsplitstring \
+beta beth between bhook big \
+bigbodyfont bigcap bigcirc bigcircle bigcup \
+bigdiamond bigg bigger biggl biggm \
+biggr bigl bigm bigodot bigoplus \
+bigotimes bigr bigskip bigsqcap bigsqcup \
+bigsquare bigstar bigtimes bigtriangledown bigtriangleup \
+bigudot biguplus bigvee bigwedge binom \
+bitmapimage blacklozenge blackrule blackrules blacksquare \
+blacktriangle blacktriangledown blacktriangleleft blacktriangleright blank \
+blap bleed bleedheight bleedwidth blockligatures \
+blockquote blocksynctexfile blockuservariable bodyfontenvironmentlist bodyfontsize \
+bold boldface bolditalic boldslanted bookmark \
+booleanmodevalue bordermatrix bot bottombox bottomleftbox \
+bottomrightbox bowtie boxcursor boxdot boxmarker \
+boxminus boxofsize boxplus boxreference boxtimes \
+bpos breakablethinspace breakhere breve bstroke \
+btxabbreviatedjournal btxaddjournal btxalwayscitation btxauthorfield btxdetail \
+btxdirect btxdoif btxdoifcombiinlistelse btxdoifelse btxdoifelsecombiinlist \
+btxdoifelsesameasprevious btxdoifelsesameaspreviouschecked btxdoifelseuservariable btxdoifnot btxdoifsameaspreviouscheckedelse \
+btxdoifsameaspreviouselse btxdoifuservariableelse btxexpandedjournal btxfield btxfieldname \
+btxfieldtype btxfirstofrange btxflush btxflushauthor btxflushauthorinverted \
+btxflushauthorinvertedshort btxflushauthorname btxflushauthornormal btxflushauthornormalshort btxflushsuffix \
+btxfoundname btxfoundtype btxhiddencitation btxhybridcite btxlabellanguage \
+btxlabeltext btxlistcitation btxloadjournalist btxoneorrange btxremapauthor \
+btxsavejournalist btxsetup btxsingularorplural btxsingularplural btxtextcitation \
+buildmathaccent buildtextaccent buildtextbottomcomma buildtextbottomdot buildtextcedilla \
+buildtextgrave buildtextmacron buildtextognek bullet button \
+cacute calligraphic camel cap carriagereturn \
+catcodetablename cbox ccaron ccedilla ccircumflex \
+ccurl cdot cdotaccent cdotp cdots \
+centeraligned centerbox centerdot centeredbox centeredlastline \
+centerednextbox centerline cfrac chapter character \
+characters chardescription charwidthlanguage check checkcharacteralign \
+checkedblank checkedchar checkedfiller checkedstrippedcsname checkinjector \
+checkmark checknextindentation checknextinjector checkpage checkparameters \
+checkpreviousinjector checksoundtrack checktwopassdata checkvariables chem \
+chemical chemicalbottext chemicalmidtext chemicalsymbol chemicaltext \
+chemicaltoptext chi chineseallnumerals chinesecapnumerals chinesenumerals \
+chook circ circeq circlearrowleft circlearrowright \
+circledR circledS circledast circledcirc circleddash \
+circledequals circleonrightarrow citation cite clap \
+classfont cldcommand cldcontext cldloadfile cldprocessfile \
+cleftarrow clip clippedoverlayimage clonefield clubsuit \
collect collectedtext collectexpanded colon coloncolonequals \
colonequals color colorbar colorcomponents colored \
-coloronly colorvalue column columnbreak combinepages \
-commalistelement commalistsentence commalistsize comment comparecolorgroup \
-comparedimension comparedimensioneps comparepalet complement completebtxrendering \
-completecontent completeindex completelist completelistofabbreviations completelistofchemicals \
-completelistoffigures completelistofgraphics completelistofintermezzi completelistoflogos completelistofpublications \
-completelistofsorts completelistofsynonyms completelistoftables completepagenumber completeregister \
-complexes complexorsimple complexorsimpleempty component composedcollector \
-composedlayer compresult cong constantdimen constantdimenargument \
-constantemptyargument constantnumber constantnumberargument contentreference continuednumber \
-continueifinputfile convertargument convertcommand convertedcounter converteddimen \
-convertedsubcounter convertmonth convertnumber convertvalue convertvboxtohbox \
-coprod copyboxfromcache copybtxlabeltext copyfield copyheadtext \
-copylabeltext copymathlabeltext copyoperatortext copypages copyparameters \
-copyposition copyprefixtext copyright copysuffixtext copytaglabeltext \
-copyunittext correctwhitespace countersubs counttoken counttokens \
-cramped crampedclap crampedllap crampedrlap crightarrow \
-crightoverleftarrow cstroke ctop ctxcommand ctxdirectcommand \
-ctxdirectlua ctxfunction ctxlatecommand ctxlatelua ctxloadluafile \
-ctxlua ctxluabuffer ctxluacode ctxreport ctxsprint \
-cup curlyeqprec curlyeqsucc curlyvee curlywedge \
-currentassignmentlistkey currentassignmentlistvalue currentbtxuservariable currentcommalistitem currentcomponent \
-currentdate currentenvironment currentfeaturetest currentheadnumber currentinterface \
-currentlanguage currentlistentrydestinationattribute currentlistentrylimitedtext currentlistentrynumber currentlistentrypagenumber \
-currentlistentryreferenceattribute currentlistentrytitle currentlistentrytitlerendered currentlistsymbol currentmainlanguage \
-currentmessagetext currentmoduleparameter currentoutputstream currentproduct currentproject \
-currentregime currentregisterpageuserdata currentresponses currenttime currentvalue \
-currentxtablecolumn currentxtablerow curvearrowleft curvearrowright cwopencirclearrow \
-cyrillicA cyrillicAE cyrillicAbreve cyrillicAdiaeresis cyrillicB \
-cyrillicBIGYUS cyrillicBIGYUSiotified cyrillicC cyrillicCH cyrillicCHEDC \
-cyrillicCHEDCabkhasian cyrillicCHEabkhasian cyrillicCHEdiaeresis cyrillicCHEkhakassian cyrillicCHEvertstroke \
-cyrillicD cyrillicDASIAPNEUMATA cyrillicDJE cyrillicDZE cyrillicDZEabkhasian \
-cyrillicDZHE cyrillicE cyrillicELtail cyrillicEMtail cyrillicENDC \
-cyrillicENGHE cyrillicENhook cyrillicENtail cyrillicEREV cyrillicERY \
-cyrillicERtick cyrillicEbreve cyrillicEdiaeresis cyrillicEgrave cyrillicEiotified \
-cyrillicF cyrillicFITA cyrillicG cyrillicGHEmidhook cyrillicGHEstroke \
-cyrillicGHEupturn cyrillicGJE cyrillicH cyrillicHA cyrillicHADC \
-cyrillicHRDSN cyrillicI cyrillicIE cyrillicII cyrillicISHRT \
-cyrillicISHRTtail cyrillicIZHITSA cyrillicIZHITSAdoublegrave cyrillicIdiaeresis cyrillicIgrave \
-cyrillicImacron cyrillicJE cyrillicK cyrillicKADC cyrillicKAbashkir \
-cyrillicKAhook cyrillicKAstroke cyrillicKAvertstroke cyrillicKJE cyrillicKOPPA \
-cyrillicKSI cyrillicL cyrillicLITTLEYUS cyrillicLITTLEYUSiotified cyrillicLJE \
-cyrillicM cyrillicN cyrillicNJE cyrillicO cyrillicOMEGA \
-cyrillicOMEGAround cyrillicOMEGAtitlo cyrillicOT cyrillicObarred cyrillicObarreddiaeresis \
-cyrillicOdiaeresis cyrillicP cyrillicPALATALIZATION cyrillicPALOCHKA cyrillicPEmidhook \
-cyrillicPSI cyrillicPSILIPNEUMATA cyrillicR cyrillicS cyrillicSCHWA \
-cyrillicSCHWAdiaeresis cyrillicSDSC cyrillicSEMISOFT cyrillicSFTSN cyrillicSH \
-cyrillicSHCH cyrillicSHHA cyrillicT cyrillicTEDC cyrillicTETSE \
-cyrillicTITLO cyrillicTSHE cyrillicU cyrillicUK cyrillicUSHRT \
-cyrillicUdiaeresis cyrillicUdoubleacute cyrillicUmacron cyrillicV cyrillicYA \
-cyrillicYAT cyrillicYERUdiaeresis cyrillicYI cyrillicYO cyrillicYU \
-cyrillicYstr cyrillicYstrstroke cyrillicZ cyrillicZDSC cyrillicZEdiaeresis \
-cyrillicZH cyrillicZHEbreve cyrillicZHEdescender cyrillicZHEdiaeresis cyrillica \
-cyrillicabreve cyrillicadiaeresis cyrillicae cyrillicb cyrillicbigyus \
-cyrillicbigyusiotified cyrillicc cyrillicch cyrilliccheabkhasian cyrillicchedc \
-cyrillicchedcabkhasian cyrillicchediaeresis cyrillicchekhakassian cyrillicchevertstroke cyrillicd \
-cyrillicdje cyrillicdze cyrillicdzeabkhasian cyrillicdzhe cyrillice \
-cyrillicebreve cyrillicediaeresis cyrillicegrave cyrilliceiotified cyrilliceltail \
-cyrillicemtail cyrillicendc cyrillicenghe cyrillicenhook cyrillicentail \
-cyrillicerev cyrillicertick cyrillicery cyrillicf cyrillicfita \
-cyrillicg cyrillicghemidhook cyrillicghestroke cyrillicgheupturn cyrillicgje \
-cyrillich cyrillicha cyrillichadc cyrillichrdsn cyrillici \
-cyrillicidiaeresis cyrillicie cyrillicigrave cyrillicii cyrillicimacron \
-cyrillicishrt cyrillicishrttail cyrillicizhitsa cyrillicizhitsadoublegrave cyrillicje \
-cyrillick cyrillickabashkir cyrillickadc cyrillickahook cyrillickastroke \
-cyrillickavertstroke cyrillickje cyrillickoppa cyrillicksi cyrillicl \
-cyrilliclittleyus cyrilliclittleyusiotified cyrilliclje cyrillicm cyrillicn \
-cyrillicnje cyrillico cyrillicobarred cyrillicobarreddiaeresis cyrillicodiaeresis \
-cyrillicomega cyrillicomegaround cyrillicomegatitlo cyrillicot cyrillicp \
-cyrillicpemidhook cyrillicpsi cyrillicr cyrillics cyrillicschwa \
-cyrillicschwadiaeresis cyrillicsdsc cyrillicsemisoft cyrillicsftsn cyrillicsh \
-cyrillicshch cyrillicshha cyrillict cyrillictedc cyrillictetse \
-cyrillictshe cyrillicu cyrillicudiaeresis cyrillicudoubleacute cyrillicuk \
-cyrillicumacron cyrillicushrt cyrillicv cyrillicya cyrillicyat \
-cyrillicyerudiaeresis cyrillicyi cyrillicyo cyrillicystr cyrillicystrstroke \
-cyrillicyu cyrillicz cyrilliczdsc cyrilliczediaeresis cyrilliczh \
-cyrilliczhebreve cyrilliczhedescender cyrilliczhediaeresis d dag \
-dagger daleth dasharrow dashedleftarrow dashedrightarrow \
-dashv datasetvariable date dayoftheweek dayspermonth \
-dbinom dcaron dcurl ddag ddagger \
-dddot ddot ddots decrement decrementcounter \
-decrementedcounter decrementpagenumber decrementsubpagenumber decrementvalue defaultinterface \
-defaultobjectpage defaultobjectreference defcatcodecommand defconvertedargument defconvertedcommand \
-defconvertedvalue define defineMPinstance defineTABLEsetup defineaccent \
-defineactivecharacter definealternativestyle defineanchor defineattachment defineattribute \
-definebackground definebar defineblock definebodyfont definebodyfontenvironment \
-definebodyfontswitch definebreakpoint definebreakpoints definebtx definebtxdataset \
-definebtxregister definebtxrendering definebuffer definebutton definecapitals \
-definecharacter definecharacterkerning definecharacterspacing definechemical definechemicals \
-definechemicalsymbol definecollector definecolor definecolorgroup definecolumnbreak \
+coloronly colorvalue column columnbreak columnsetspanwidth \
+combinepages commalistelement commalistsentence commalistsize comment \
+comparecolorgroup comparedimension comparedimensioneps comparepalet complement \
+completebtxrendering completecontent completeindex completelist completelistofabbreviations \
+completelistofchemicals completelistoffigures completelistofgraphics completelistofintermezzi completelistoflogos \
+completelistofpublications completelistofsorts completelistofsynonyms completelistoftables completepagenumber \
+completeregister complexes complexorsimple complexorsimpleempty component \
+composedcollector composedlayer compresult cong constantdimen \
+constantdimenargument constantemptyargument constantnumber constantnumberargument contentreference \
+continuednumber continueifinputfile convertargument convertcommand convertedcounter \
+converteddimen convertedsubcounter convertmonth convertnumber convertvalue \
+convertvboxtohbox coprod copyboxfromcache copybtxlabeltext copyfield \
+copyheadtext copylabeltext copymathlabeltext copyoperatortext copypages \
+copyparameters copyposition copyprefixtext copyright copysetups \
+copysuffixtext copytaglabeltext copyunittext correctwhitespace countersubs \
+counttoken counttokens cramped crampedclap crampedllap \
+crampedrlap crightarrow crightoverleftarrow cstroke ctop \
+ctxcommand ctxdirectcommand ctxdirectlua ctxfunction ctxlatecommand \
+ctxlatelua ctxloadluafile ctxlua ctxluabuffer ctxluacode \
+ctxreport ctxsprint cup curlyeqprec curlyeqsucc \
+curlyvee curlywedge currentassignmentlistkey currentassignmentlistvalue currentbtxuservariable \
+currentcommalistitem currentcomponent currentdate currentenvironment currentfeaturetest \
+currentheadnumber currentinterface currentlanguage currentlistentrydestinationattribute currentlistentrylimitedtext \
+currentlistentrynumber currentlistentrypagenumber currentlistentryreferenceattribute currentlistentrytitle currentlistentrytitlerendered \
+currentlistsymbol currentmainlanguage currentmessagetext currentmoduleparameter currentoutputstream \
+currentproduct currentproject currentregime currentregisterpageuserdata currentresponses \
+currenttime currentvalue currentxtablecolumn currentxtablerow curvearrowleft \
+curvearrowright cwopencirclearrow cyrillicA cyrillicAE cyrillicAbreve \
+cyrillicAdiaeresis cyrillicB cyrillicBIGYUS cyrillicBIGYUSiotified cyrillicC \
+cyrillicCH cyrillicCHEDC cyrillicCHEDCabkhasian cyrillicCHEabkhasian cyrillicCHEdiaeresis \
+cyrillicCHEkhakassian cyrillicCHEvertstroke cyrillicD cyrillicDASIAPNEUMATA cyrillicDJE \
+cyrillicDZE cyrillicDZEabkhasian cyrillicDZHE cyrillicE cyrillicELtail \
+cyrillicEMtail cyrillicENDC cyrillicENGHE cyrillicENhook cyrillicENtail \
+cyrillicEREV cyrillicERY cyrillicERtick cyrillicEbreve cyrillicEdiaeresis \
+cyrillicEgrave cyrillicEiotified cyrillicF cyrillicFITA cyrillicG \
+cyrillicGHEmidhook cyrillicGHEstroke cyrillicGHEupturn cyrillicGJE cyrillicH \
+cyrillicHA cyrillicHADC cyrillicHRDSN cyrillicI cyrillicIE \
+cyrillicII cyrillicISHRT cyrillicISHRTtail cyrillicIZHITSA cyrillicIZHITSAdoublegrave \
+cyrillicIdiaeresis cyrillicIgrave cyrillicImacron cyrillicJE cyrillicK \
+cyrillicKADC cyrillicKAbashkir cyrillicKAhook cyrillicKAstroke cyrillicKAvertstroke \
+cyrillicKJE cyrillicKOPPA cyrillicKSI cyrillicL cyrillicLITTLEYUS \
+cyrillicLITTLEYUSiotified cyrillicLJE cyrillicM cyrillicN cyrillicNJE \
+cyrillicO cyrillicOMEGA cyrillicOMEGAround cyrillicOMEGAtitlo cyrillicOT \
+cyrillicObarred cyrillicObarreddiaeresis cyrillicOdiaeresis cyrillicP cyrillicPALATALIZATION \
+cyrillicPALOCHKA cyrillicPEmidhook cyrillicPSI cyrillicPSILIPNEUMATA cyrillicR \
+cyrillicS cyrillicSCHWA cyrillicSCHWAdiaeresis cyrillicSDSC cyrillicSEMISOFT \
+cyrillicSFTSN cyrillicSH cyrillicSHCH cyrillicSHHA cyrillicT \
+cyrillicTEDC cyrillicTETSE cyrillicTITLO cyrillicTSHE cyrillicU \
+cyrillicUK cyrillicUSHRT cyrillicUdiaeresis cyrillicUdoubleacute cyrillicUmacron \
+cyrillicV cyrillicYA cyrillicYAT cyrillicYERUdiaeresis cyrillicYI \
+cyrillicYO cyrillicYU cyrillicYstr cyrillicYstrstroke cyrillicZ \
+cyrillicZDSC cyrillicZEdiaeresis cyrillicZH cyrillicZHEbreve cyrillicZHEdescender \
+cyrillicZHEdiaeresis cyrillica cyrillicabreve cyrillicadiaeresis cyrillicae \
+cyrillicb cyrillicbigyus cyrillicbigyusiotified cyrillicc cyrillicch \
+cyrilliccheabkhasian cyrillicchedc cyrillicchedcabkhasian cyrillicchediaeresis cyrillicchekhakassian \
+cyrillicchevertstroke cyrillicd cyrillicdje cyrillicdze cyrillicdzeabkhasian \
+cyrillicdzhe cyrillice cyrillicebreve cyrillicediaeresis cyrillicegrave \
+cyrilliceiotified cyrilliceltail cyrillicemtail cyrillicendc cyrillicenghe \
+cyrillicenhook cyrillicentail cyrillicerev cyrillicertick cyrillicery \
+cyrillicf cyrillicfita cyrillicg cyrillicghemidhook cyrillicghestroke \
+cyrillicgheupturn cyrillicgje cyrillich cyrillicha cyrillichadc \
+cyrillichrdsn cyrillici cyrillicidiaeresis cyrillicie cyrillicigrave \
+cyrillicii cyrillicimacron cyrillicishrt cyrillicishrttail cyrillicizhitsa \
+cyrillicizhitsadoublegrave cyrillicje cyrillick cyrillickabashkir cyrillickadc \
+cyrillickahook cyrillickastroke cyrillickavertstroke cyrillickje cyrillickoppa \
+cyrillicksi cyrillicl cyrilliclittleyus cyrilliclittleyusiotified cyrilliclje \
+cyrillicm cyrillicn cyrillicnje cyrillico cyrillicobarred \
+cyrillicobarreddiaeresis cyrillicodiaeresis cyrillicomega cyrillicomegaround cyrillicomegatitlo \
+cyrillicot cyrillicp cyrillicpemidhook cyrillicpsi cyrillicr \
+cyrillics cyrillicschwa cyrillicschwadiaeresis cyrillicsdsc cyrillicsemisoft \
+cyrillicsftsn cyrillicsh cyrillicshch cyrillicshha cyrillict \
+cyrillictedc cyrillictetse cyrillictshe cyrillicu cyrillicudiaeresis \
+cyrillicudoubleacute cyrillicuk cyrillicumacron cyrillicushrt cyrillicv \
+cyrillicya cyrillicyat cyrillicyerudiaeresis cyrillicyi cyrillicyo \
+cyrillicystr cyrillicystrstroke cyrillicyu cyrillicz cyrilliczdsc \
+cyrilliczediaeresis cyrilliczh cyrilliczhebreve cyrilliczhedescender cyrilliczhediaeresis \
+d dag dagger daleth dasharrow \
+dashedleftarrow dashedrightarrow dashv datasetvariable date \
+dayoftheweek dayspermonth dbinom dcaron dcurl \
+ddag ddagger dddot ddot ddots \
+decrement decrementcounter decrementedcounter decrementpagenumber decrementsubpagenumber \
+decrementvalue defaultinterface defaultobjectpage defaultobjectreference defcatcodecommand \
+defconvertedargument defconvertedcommand defconvertedvalue define defineMPinstance \
+defineTABLEsetup defineaccent defineactivecharacter definealternativestyle defineanchor \
+defineattachment defineattribute definebackground definebar defineblock \
+definebodyfont definebodyfontenvironment definebodyfontswitch definebreakpoint definebreakpoints \
+definebtx definebtxdataset definebtxregister definebtxrendering definebuffer \
+definebutton definecapitals definecharacter definecharacterkerning definecharacterspacing \
+definechemical definechemicals definechemicalsymbol definecollector definecolor \
+definecolorgroup definecolumnbreak definecolumnset definecolumnsetarea definecolumnsetspan \
definecombination definecombinedlist definecommand definecomment definecomplexorsimple \
definecomplexorsimpleempty defineconversion defineconversionset definecounter definedataset \
definedelimitedtext definedeq definedescription definedfont defineeffect \
-defineenumeration defineexpandable defineexternalfigure definefallbackfamily definefield \
-definefieldbody definefieldbodyset definefieldcategory definefieldstack definefiguresymbol \
-definefileconstant definefilefallback definefilesynonym definefiller definefirstline \
-definefittingpage definefloat definefont definefontalternative definefontfallback \
-definefontfamily definefontfamilypreset definefontfeature definefontfile definefontsize \
-definefontsolution definefontstyle definefontsynonym defineformula defineformulaalternative \
-defineformulaframed defineframed defineframedcontent defineframedtable defineframedtext \
-definefrozenfont defineglobalcolor definegraphictypesynonym definegridsnapping definehbox \
-definehead defineheadalternative definehelp definehigh definehighlight \
-definehspace definehypenationfeatures defineindentedtext defineindenting defineinitial \
-defineinsertion defineinteraction defineinteractionbar defineinteractionmenu defineinterfaceconstant \
-defineinterfaceelement defineinterfacevariable defineinterlinespace defineintermediatecolor defineitemgroup \
-defineitems definelabel definelabelclass definelayer definelayerpreset \
-definelayout definelinefiller definelinenote definelinenumbering definelines \
-definelist definelistalternative definelistextra definelow definelowhigh \
-definelowmidhigh definemakeup definemarginblock definemargindata definemarker \
-definemarking definemathaccent definemathalignment definemathcases definemathcommand \
-definemathdouble definemathdoubleextensible definemathematics definemathextensible definemathfence \
-definemathfraction definemathframed definemathmatrix definemathornament definemathover \
-definemathoverextensible definemathovertextextensible definemathradical definemathstackers definemathstyle \
-definemathtriplet definemathunder definemathunderextensible definemathundertextextensible definemathunstacked \
-definemeasure definemessageconstant definemixedcolumns definemode definemultitonecolor \
-definenamedcolor definenamespace definenarrower definenote defineornament \
-defineoutputroutine defineoutputroutinecommand defineoverlay definepage definepagebreak \
-definepagechecker definepagegrid definepagegridarea definepagegridspan definepageinjection \
-definepageinjectionalternative definepageshift definepagestate definepairedbox definepalet \
-definepapersize defineparagraph defineparagraphs defineparallel defineparbuilder \
+defineenumeration defineexpandable defineexternalfigure definefacingfloat definefallbackfamily \
+definefield definefieldbody definefieldbodyset definefieldcategory definefieldstack \
+definefiguresymbol definefileconstant definefilefallback definefilesynonym definefiller \
+definefirstline definefittingpage definefloat definefont definefontalternative \
+definefontfallback definefontfamily definefontfamilypreset definefontfeature definefontfile \
+definefontsize definefontsolution definefontstyle definefontsynonym defineformula \
+defineformulaalternative defineformulaframed defineframed defineframedcontent defineframedtable \
+defineframedtext definefrozenfont defineglobalcolor definegraphictypesynonym definegridsnapping \
+definehbox definehead defineheadalternative definehelp definehigh \
+definehighlight definehspace definehypenationfeatures defineindentedtext defineindenting \
+defineinitial defineinsertion defineinteraction defineinteractionbar defineinteractionmenu \
+defineinterfaceconstant defineinterfaceelement defineinterfacevariable defineinterlinespace defineintermediatecolor \
+defineitemgroup defineitems definelabel definelabelclass definelayer \
+definelayerpreset definelayout definelinefiller definelinenote definelinenumbering \
+definelines definelist definelistalternative definelistextra definelow \
+definelowhigh definelowmidhigh definemakeup definemarginblock definemargindata \
+definemarker definemarking definemathaccent definemathalignment definemathcases \
+definemathcommand definemathdouble definemathdoubleextensible definemathematics definemathextensible \
+definemathfence definemathfraction definemathframed definemathmatrix definemathornament \
+definemathover definemathoverextensible definemathovertextextensible definemathradical definemathstackers \
+definemathstyle definemathtriplet definemathunder definemathunderextensible definemathundertextextensible \
+definemathunstacked definemeasure definemessageconstant definemixedcolumns definemode \
+definemultitonecolor definenamedcolor definenamespace definenarrower definenote \
+defineornament defineoutputroutine defineoutputroutinecommand defineoverlay definepage \
+definepagebreak definepagechecker definepagecolumns definepageinjection definepageinjectionalternative \
+definepageshift definepagestate definepairedbox definepalet definepapersize \
+defineparagraph defineparagraphs defineparallel defineparbuilder defineperiodkerning \
defineplacement definepositioning defineprefixset defineprocesscolor defineprocessor \
defineprofile defineprogram definepushbutton definepushsymbol definereference \
-definereferenceformat defineregister definerenderingwindow defineresetset definescale \
-definescript definesection definesectionblock definesectionlevels defineselector \
-defineseparatorset defineshift definesidebar definesort definesorting \
-definespotcolor definestartstop definestyle definestyleinstance definesubfield \
-definesubformula definesymbol definesynonym definesynonyms definesystemattribute \
-definesystemconstant definesystemvariable definetabletemplate definetabulate definetabulation \
-definetext definetextbackground definetextflow definetooltip definetransparency \
-definetwopasslist definetype definetypeface definetypescriptprefix definetypescriptsynonym \
-definetypesetting definetyping defineunit defineviewerlayer definevspace \
-definevspacing definevspacingamount definextable delimited delimitedtext \
-delta depthofstring depthonlybox depthspanningtext depthstrut \
-determineheadnumber determinelistcharacteristics determinenoflines determineregistercharacteristics devanagarinumerals \
-dfrac dhook diameter diamond diamondsuit \
-differentialD differentiald digamma digits dimensiontocount \
-directboxfromcache directcolor directcolored directconvertedcounter directcopyboxfromcache \
-directdummyparameter directgetboxllx directgetboxlly directhighlight directlocalframed \
-directluacode directselect directsetbar directsetup directsymbol \
-directvspacing dis disabledirectives disableexperiments disablemode \
-disableoutputstream disableparpositions disableregime disabletrackers displaymath \
-displaymathematics displaymessage distributedhsize div dividedsize \
-divideontimes divides doadaptleftskip doadaptrightskip doaddfeature \
-doassign doassignempty doboundtext docheckassignment docheckedpagestate \
-docheckedpair documentvariable dodoubleargument dodoubleargumentwithset dodoubleempty \
-dodoubleemptywithset dodoublegroupempty doeassign doexpandedrecurse dofastloopcs \
-dogetattribute dogetattributeid dogetcommacommandelement dogobbledoubleempty dogobblesingleempty \
-doif doifMPgraphicelse doifallcommon doifallcommonelse doifalldefinedelse \
-doifallmodes doifallmodeselse doifassignmentelse doifblackelse doifbothsides \
+definereferenceformat defineregister definerenderingwindow defineresetset defineruby \
+definescale definescript definesection definesectionblock definesectionlevels \
+defineselector defineseparatorset defineshift definesidebar definesort \
+definesorting definespotcolor definestartstop definestyle definestyleinstance \
+definesubfield definesubformula definesymbol definesynonym definesynonyms \
+definesystemattribute definesystemconstant definesystemvariable definetabletemplate definetabulate \
+definetabulation definetext definetextbackground definetextflow definetokenlist \
+definetooltip definetransparency definetwopasslist definetype definetypeface \
+definetypescriptprefix definetypescriptsynonym definetypesetting definetyping defineunit \
+defineuserdata defineuserdataalternative defineviewerlayer definevspace definevspacing \
+definevspacingamount definextable delimited delimitedtext delta \
+depthofstring depthonlybox depthspanningtext depthstrut determineheadnumber \
+determinelistcharacteristics determinenoflines determineregistercharacteristics devanagarinumerals dfrac \
+dhook diameter diamond diamondsuit differentialD \
+differentiald digamma digits dimensiontocount directboxfromcache \
+directcolor directcolored directconvertedcounter directcopyboxfromcache directdummyparameter \
+directgetboxllx directgetboxlly directhighlight directlocalframed directluacode \
+directselect directsetbar directsetup directsymbol directvspacing \
+dis disabledirectives disableexperiments disablemode disableoutputstream \
+disableparpositions disableregime disabletrackers displaymath displaymathematics \
+displaymessage distributedhsize div dividedsize divideontimes \
+divides doadaptleftskip doadaptrightskip doaddfeature doassign \
+doassignempty doboundtext docheckassignment docheckedpagestate docheckedpair \
+documentvariable dodoubleargument dodoubleargumentwithset dodoubleempty dodoubleemptywithset \
+dodoublegroupempty doeassign doexpandedrecurse dofastloopcs dogetattribute \
+dogetattributeid dogetcommacommandelement dogobbledoubleempty dogobblesingleempty doif \
+doifMPgraphicelse doifallcommon doifallcommonelse doifalldefinedelse doifallmodes \
+doifallmodeselse doifassignmentelse doifassignmentelsecs doifblackelse doifbothsides \
doifbothsidesoverruled doifboxelse doifbufferelse doifcolor doifcolorelse \
doifcommandhandler doifcommandhandlerelse doifcommon doifcommonelse doifcontent \
doifconversiondefinedelse doifconversionnumberelse doifcounter doifcounterelse doifcurrentfonthasfeatureelse \
doifdefined doifdefinedcounter doifdefinedcounterelse doifdefinedelse doifdimensionelse \
doifdimenstringelse doifdocumentargument doifdocumentargumentelse doifdocumentfilename doifdocumentfilenameelse \
-doifdrawingblackelse doifelse doifelseMPgraphic doifelseallcommon doifelsealldefined \
-doifelseallmodes doifelseassignment doifelseblack doifelsebox doifelseboxincache \
-doifelsebuffer doifelsecolor doifelsecommandhandler doifelsecommon doifelseconversiondefined \
-doifelseconversionnumber doifelsecounter doifelsecurrentfonthasfeature doifelsecurrentsortingused doifelsecurrentsynonymshown \
-doifelsecurrentsynonymused doifelsedefined doifelsedefinedcounter doifelsedimension doifelsedimenstring \
-doifelsedocumentargument doifelsedocumentfilename doifelsedrawingblack doifelseempty doifelseemptyvalue \
-doifelseemptyvariable doifelseenv doifelsefastoptionalcheck doifelsefastoptionalcheckcs doifelsefieldbody \
-doifelsefieldcategory doifelsefigure doifelsefile doifelsefiledefined doifelsefileexists \
-doifelsefirstchar doifelseflagged doifelsefontchar doifelsefontpresent doifelsefontsynonym \
-doifelsehasspace doifelsehelp doifelseincsname doifelseinelement doifelseinputfile \
-doifelseinsertion doifelseinset doifelseinstring doifelseinsymbolset doifelseintoks \
-doifelseintwopassdata doifelseitalic doifelselanguage doifelselayerdata doifelselayoutdefined \
-doifelselayoutsomeline doifelselayouttextline doifelseleapyear doifelselist doifelselocation \
-doifelselocfile doifelsemainfloatbody doifelsemarkedpage doifelsemarking doifelsemeaning \
-doifelsemessage doifelsemode doifelsenextbgroup doifelsenextbgroupcs doifelsenextchar \
-doifelsenextoptional doifelsenextoptionalcs doifelsenextparenthesis doifelsenonzeropositive doifelsenoteonsamepage \
-doifelsenothing doifelsenumber doifelseobjectfound doifelseobjectreferencefound doifelseoddpage \
-doifelseoddpagefloat doifelseoldercontext doifelseolderversion doifelseoverlapping doifelseoverlay \
-doifelseparallel doifelseparentfile doifelsepath doifelsepathexists doifelsepatterns \
-doifelseposition doifelsepositionaction doifelsepositiononpage doifelsepositionsonsamepage doifelsepositionsonthispage \
-doifelsepositionsused doifelsereferencefound doifelserightpagefloat doifelserighttoleftinbox doifelsesamelinereference \
-doifelsesamestring doifelsesetups doifelsesomebackground doifelsesomespace doifelsesomething \
-doifelsesometoks doifelsestringinstring doifelsestructurelisthasnumber doifelsestructurelisthaspage doifelsesymboldefined \
-doifelsesymbolset doifelsetext doifelsetextflow doifelsetextflowcollector doifelsetopofpage \
-doifelsetypingfile doifelseundefined doifelseurldefined doifelsevalue doifelsevaluenothing \
-doifelsevariable doifempty doifemptyelse doifemptytoks doifemptyvalue \
-doifemptyvalueelse doifemptyvariable doifemptyvariableelse doifenv doifenvelse \
-doiffastoptionalcheckcselse doiffastoptionalcheckelse doiffieldbodyelse doiffieldcategoryelse doiffigureelse \
-doiffile doiffiledefinedelse doiffileelse doiffileexistselse doiffirstcharelse \
-doifflaggedelse doiffontcharelse doiffontpresentelse doiffontsynonymelse doifhasspaceelse \
-doifhelpelse doifincsnameelse doifinelementelse doifinputfileelse doifinsertionelse \
-doifinset doifinsetelse doifinstring doifinstringelse doifinsymbolset \
-doifinsymbolsetelse doifintokselse doifintwopassdataelse doifitalicelse doiflanguageelse \
-doiflayerdataelse doiflayoutdefinedelse doiflayoutsomelineelse doiflayouttextlineelse doifleapyearelse \
-doiflistelse doiflocationelse doiflocfileelse doifmainfloatbodyelse doifmarkingelse \
-doifmeaningelse doifmessageelse doifmode doifmodeelse doifnextbgroupcselse \
-doifnextbgroupelse doifnextcharelse doifnextoptionalcselse doifnextoptionalelse doifnextparenthesiselse \
-doifnonzeropositiveelse doifnot doifnotallcommon doifnotallmodes doifnotcommandhandler \
-doifnotcommon doifnotcounter doifnotdocumentargument doifnotdocumentfilename doifnotempty \
-doifnotemptyvalue doifnotemptyvariable doifnotenv doifnoteonsamepageelse doifnotescollected \
-doifnotfile doifnotflagged doifnothing doifnothingelse doifnotinset \
-doifnotinsidesplitfloat doifnotinstring doifnotmode doifnotnumber doifnotsamestring \
-doifnotsetups doifnotvalue doifnotvariable doifnumber doifnumberelse \
-doifobjectfoundelse doifobjectreferencefoundelse doifoddpageelse doifoddpagefloatelse doifoldercontextelse \
-doifolderversionelse doifoverlappingelse doifoverlayelse doifparallelelse doifparentfileelse \
-doifpathelse doifpathexistselse doifpatternselse doifposition doifpositionaction \
-doifpositionactionelse doifpositionelse doifpositiononpageelse doifpositionsonsamepageelse doifpositionsonthispageelse \
-doifpositionsusedelse doifreferencefoundelse doifrightpagefloatelse doifrighttoleftinboxelse doifsamelinereferenceelse \
-doifsamestring doifsamestringelse doifsetups doifsetupselse doifsomebackground \
-doifsomebackgroundelse doifsomespaceelse doifsomething doifsomethingelse doifsometoks \
-doifsometokselse doifstringinstringelse doifstructurelisthasnumberelse doifstructurelisthaspageelse doifsymboldefinedelse \
-doifsymbolsetelse doiftext doiftextelse doiftextflowcollectorelse doiftextflowelse \
-doiftopofpageelse doiftypingfileelse doifundefined doifundefinedcounter doifundefinedelse \
+doifdocumentvariable doifdocumentvariableelse doifdrawingblackelse doifelse doifelseMPgraphic \
+doifelseallcommon doifelsealldefined doifelseallmodes doifelseassignment doifelseassignmentcs \
+doifelseblack doifelsebox doifelseboxincache doifelsebuffer doifelsecolor \
+doifelsecommandhandler doifelsecommon doifelseconversiondefined doifelseconversionnumber doifelsecounter \
+doifelsecurrentfonthasfeature doifelsecurrentsortingused doifelsecurrentsynonymshown doifelsecurrentsynonymused doifelsedefined \
+doifelsedefinedcounter doifelsedimension doifelsedimenstring doifelsedocumentargument doifelsedocumentfilename \
+doifelsedocumentvariable doifelsedrawingblack doifelseempty doifelseemptyvalue doifelseemptyvariable \
+doifelseenv doifelsefastoptionalcheck doifelsefastoptionalcheckcs doifelsefieldbody doifelsefieldcategory \
+doifelsefigure doifelsefile doifelsefiledefined doifelsefileexists doifelsefirstchar \
+doifelseflagged doifelsefontchar doifelsefontfeature doifelsefontpresent doifelsefontsynonym \
+doifelseframed doifelsehasspace doifelsehelp doifelseincsname doifelseinelement \
+doifelseinputfile doifelseinsertion doifelseinset doifelseinstring doifelseinsymbolset \
+doifelseintoks doifelseintwopassdata doifelseitalic doifelselanguage doifelselayerdata \
+doifelselayoutdefined doifelselayoutsomeline doifelselayouttextline doifelseleapyear doifelselist \
+doifelselocation doifelselocfile doifelsemainfloatbody doifelsemarkedpage doifelsemarking \
+doifelsemeaning doifelsemessage doifelsemode doifelsenextbgroup doifelsenextbgroupcs \
+doifelsenextchar doifelsenextoptional doifelsenextoptionalcs doifelsenextparenthesis doifelsenonzeropositive \
+doifelsenoteonsamepage doifelsenothing doifelsenumber doifelseobjectfound doifelseobjectreferencefound \
+doifelseoddpage doifelseoddpagefloat doifelseoldercontext doifelseolderversion doifelseoverlapping \
+doifelseoverlay doifelseparallel doifelseparentfile doifelsepath doifelsepathexists \
+doifelsepatterns doifelseposition doifelsepositionaction doifelsepositiononpage doifelsepositionsonsamepage \
+doifelsepositionsonthispage doifelsepositionsused doifelsereferencefound doifelserightpage doifelserightpagefloat \
+doifelserighttoleftinbox doifelsesamelinereference doifelsesamestring doifelsesetups doifelsesomebackground \
+doifelsesomespace doifelsesomething doifelsesometoks doifelsestringinstring doifelsestructurelisthasnumber \
+doifelsestructurelisthaspage doifelsesymboldefined doifelsesymbolset doifelsetext doifelsetextflow \
+doifelsetextflowcollector doifelsetopofpage doifelsetypingfile doifelseundefined doifelseurldefined \
+doifelsevalue doifelsevaluenothing doifelsevariable doifempty doifemptyelse \
+doifemptytoks doifemptyvalue doifemptyvalueelse doifemptyvariable doifemptyvariableelse \
+doifenv doifenvelse doiffastoptionalcheckcselse doiffastoptionalcheckelse doiffieldbodyelse \
+doiffieldcategoryelse doiffigureelse doiffile doiffiledefinedelse doiffileelse \
+doiffileexistselse doiffirstcharelse doifflaggedelse doiffontcharelse doiffontfeatureelse \
+doiffontpresentelse doiffontsynonymelse doifhasspaceelse doifhelpelse doifincsnameelse \
+doifinelementelse doifinputfileelse doifinsertionelse doifinset doifinsetelse \
+doifinstring doifinstringelse doifinsymbolset doifinsymbolsetelse doifintokselse \
+doifintwopassdataelse doifitalicelse doiflanguageelse doiflayerdataelse doiflayoutdefinedelse \
+doiflayoutsomelineelse doiflayouttextlineelse doifleapyearelse doiflistelse doiflocationelse \
+doiflocfileelse doifmainfloatbodyelse doifmarkingelse doifmeaningelse doifmessageelse \
+doifmode doifmodeelse doifnextbgroupcselse doifnextbgroupelse doifnextcharelse \
+doifnextoptionalcselse doifnextoptionalelse doifnextparenthesiselse doifnonzeropositiveelse doifnot \
+doifnotallcommon doifnotallmodes doifnotcommandhandler doifnotcommon doifnotcounter \
+doifnotdocumentargument doifnotdocumentfilename doifnotdocumentvariable doifnotempty doifnotemptyvalue \
+doifnotemptyvariable doifnotenv doifnoteonsamepageelse doifnotescollected doifnotfile \
+doifnotflagged doifnothing doifnothingelse doifnotinset doifnotinsidesplitfloat \
+doifnotinstring doifnotmode doifnotnumber doifnotsamestring doifnotsetups \
+doifnotvalue doifnotvariable doifnumber doifnumberelse doifobjectfoundelse \
+doifobjectreferencefoundelse doifoddpageelse doifoddpagefloatelse doifoldercontextelse doifolderversionelse \
+doifoverlappingelse doifoverlayelse doifparallelelse doifparentfileelse doifpathelse \
+doifpathexistselse doifpatternselse doifposition doifpositionaction doifpositionactionelse \
+doifpositionelse doifpositiononpageelse doifpositionsonsamepageelse doifpositionsonthispageelse doifpositionsusedelse \
+doifreferencefoundelse doifrightpagefloatelse doifrighttoleftinboxelse doifsamelinereferenceelse doifsamestring \
+doifsamestringelse doifsetups doifsetupselse doifsomebackground doifsomebackgroundelse \
+doifsomespaceelse doifsomething doifsomethingelse doifsometoks doifsometokselse \
+doifstringinstringelse doifstructurelisthasnumberelse doifstructurelisthaspageelse doifsymboldefinedelse doifsymbolsetelse \
+doiftext doiftextelse doiftextflowcollectorelse doiftextflowelse doiftopofpageelse \
+doiftypingfileelse doifundefined doifundefinedcounter doifundefinedelse doifunknownfontfeature \
doifurldefinedelse doifvalue doifvalueelse doifvaluenothing doifvaluenothingelse \
doifvaluesomething doifvariable doifvariableelse doindentation dollar \
doloop doloopoverlist donothing dontconvertfont dontleavehmode \
@@ -417,23 +422,24 @@ equiv erightarrowfill erightharpoondownfill erightharpoonupfill eta \
eth ethiopic etilde etwoheadrightarrowfill eunderbarfill \
eunderbracefill eunderbracketfill eunderparentfill exclamdown executeifdefined \
exists exitloop exitloopnow expandcheckedcsname expanded \
-expandfontsynonym expdoif expdoifcommonelse expdoifelse expdoifelsecommon \
-expdoifelseinset expdoifinsetelse expdoifnot exponentiale externalfigure \
-externalfigurecollectionmaxheight externalfigurecollectionmaxwidth externalfigurecollectionminheight externalfigurecollectionminwidth externalfigurecollectionparameter \
-fakebox fallingdotseq fastdecrement fastincrement fastlocalframed \
-fastloopfinal fastloopindex fastscale fastsetup fastsetupwithargument \
-fastsetupwithargumentswapped fastswitchtobodyfont fastsxsy feature fence \
-fenced fetchallmarkings fetchallmarks fetchmark fetchmarking \
-fetchonemark fetchonemarking fetchruntinecommand fetchtwomarkings fetchtwomarks \
-ffiligature ffligature fflligature fhook field \
-fieldbody fieldstack fifthoffivearguments fifthofsixarguments figurefilename \
-figurefilepath figurefiletype figurefullname figureheight figurenaturalheight \
-figurenaturalwidth figurespace figuresymbol figurewidth filename \
-filigature filledhboxb filledhboxc filledhboxg filledhboxk \
-filledhboxm filledhboxr filledhboxy filler fillinline \
-fillinrules fillintext filterfromnext filterfromvalue filterpages \
-filterreference findtwopassdata finishregisterentry firstcharacter firstcounter \
-firstcountervalue firstoffivearguments firstoffourarguments firstofoneargument firstofoneunexpanded \
+expandeddoif expandeddoifelse expandeddoifnot expandfontsynonym expdoif \
+expdoifcommonelse expdoifelse expdoifelsecommon expdoifelseinset expdoifinsetelse \
+expdoifnot exponentiale externalfigure externalfigurecollectionmaxheight externalfigurecollectionmaxwidth \
+externalfigurecollectionminheight externalfigurecollectionminwidth externalfigurecollectionparameter fakebox fallingdotseq \
+fastdecrement fastincrement fastlocalframed fastloopfinal fastloopindex \
+fastscale fastsetup fastsetupwithargument fastsetupwithargumentswapped fastswitchtobodyfont \
+fastsxsy feature fence fenced fetchallmarkings \
+fetchallmarks fetchmark fetchmarking fetchonemark fetchonemarking \
+fetchruntinecommand fetchtwomarkings fetchtwomarks ffiligature ffligature \
+fflligature fhook field fieldbody fieldstack \
+fifthoffivearguments fifthofsixarguments figurefilename figurefilepath figurefiletype \
+figurefullname figureheight figurenaturalheight figurenaturalwidth figurespace \
+figuresymbol figurewidth filename filigature filledhboxb \
+filledhboxc filledhboxg filledhboxk filledhboxm filledhboxr \
+filledhboxy filler fillinline fillinrules fillintext \
+fillupto filterfromnext filterfromvalue filterpages filterreference \
+findtwopassdata finishregisterentry firstcharacter firstcounter firstcountervalue \
+firstinlist firstoffivearguments firstoffourarguments firstofoneargument firstofoneunexpanded \
firstofsixarguments firstofthreearguments firstofthreeunexpanded firstoftwoarguments firstoftwounexpanded \
firstrealpage firstrealpagenumber firstsubcountervalue firstsubpage firstsubpagenumber \
firstuserpage firstuserpagenumber fitfield fitfieldframed fittopbaselinegrid \
@@ -444,68 +450,69 @@ flushnotes flushoutputstream flushshapebox flushtextflow flushtokens \
flushtoks fontalternative fontbody fontchar fontcharbyindex \
fontclass fontclassname fontface fontfeaturelist fontsize \
fontstyle footnote footnotetext forall forcecharacterstripping \
-forcelocalfloats forgeteverypar forgetparameters forgetragged formula \
-formulanumber foundbox fourfifths fourperemspace fourthoffivearguments \
-fourthoffourarguments fourthofsixarguments frac framed frameddimension \
-framedparameter framedtext freezedimenmacro freezemeasure frenchspacing \
-from fromlinenote frown frozenhbox frule \
-gacute gamma gbreve gcaron gcircumflex \
-gcommaaccent gdefconvertedargument gdefconvertedcommand gdotaccent ge \
-geq geqq geqslant getMPdrawing getMPlayer \
-getboxfromcache getboxllx getboxlly getbuffer getbufferdata \
-getcommacommandsize getcommalistsize getdayoftheweek getdayspermonth getdefinedbuffer \
-getdocumentargument getdocumentargumentdefault getdocumentfilename getdummyparameters getemptyparameters \
-geteparameters getexpandedparameters getfiguredimensions getfirstcharacter getfirsttwopassdata \
-getfromcommacommand getfromcommalist getfromtwopassdata getglyphdirect getglyphstyled \
-getgparameters getlasttwopassdata getlocalfloat getlocalfloats getmarking \
-getmessage getnamedglyphdirect getnamedglyphstyled getnamedtwopassdatalist getnaturaldimensions \
-getnoflines getobject getobjectdimensions getpaletsize getparameters \
-getprivatechar getprivateslot getrandomcount getrandomdimen getrandomfloat \
-getrandomnumber getrandomseed getraweparameters getrawgparameters getrawnoflines \
-getrawparameters getrawxparameters getreference getreferenceentry getroundednoflines \
-gets getsubstring gettwopassdata gettwopassdatalist getuvalue \
-getvalue getvariable getvariabledefault getxparameters gg \
-ggg gggtr gimel globaldisablemode globalenablemode \
-globalletempty globalpopbox globalpopmacro globalpreventmode globalprocesscommalist \
-globalpushbox globalpushmacro globalswapcounts globalswapdimens globalswapmacros \
-globalundefine glyphfontfile gnapprox gneqq gnsim \
-gobbledoubleempty gobbleeightarguments gobblefivearguments gobblefiveoptionals gobblefourarguments \
-gobblefouroptionals gobbleninearguments gobbleoneargument gobbleoneoptional gobblesevenarguments \
-gobblesingleempty gobblesixarguments gobblespacetokens gobbletenarguments gobblethreearguments \
-gobblethreeoptionals gobbletwoarguments gobbletwooptionals gobbleuntil gobbleuntilrelax \
-godown goto gotobox gotopage grabbufferdata \
-grabbufferdatadirect grabuntil grave graycolor grayvalue \
-greedysplitstring greekAlpha greekAlphadasia greekAlphadasiaperispomeni greekAlphadasiatonos \
-greekAlphadasiavaria greekAlphaiotasub greekAlphaiotasubdasia greekAlphaiotasubdasiaperispomeni greekAlphaiotasubdasiatonos \
-greekAlphaiotasubdasiavaria greekAlphaiotasubpsili greekAlphaiotasubpsiliperispomeni greekAlphaiotasubpsilitonos greekAlphaiotasubpsilivaria \
-greekAlphamacron greekAlphapsili greekAlphapsiliperispomeni greekAlphapsilitonos greekAlphapsilivaria \
-greekAlphatonos greekAlphavaria greekAlphavrachy greekBeta greekChi \
-greekCoronis greekDelta greekEpsilon greekEpsilondasia greekEpsilondasiatonos \
-greekEpsilondasiavaria greekEpsilonpsili greekEpsilonpsilitonos greekEpsilonpsilivaria greekEpsilontonos \
-greekEpsilonvaria greekEta greekEtadasia greekEtadasiaperispomeni greekEtadasiatonos \
-greekEtadasiavaria greekEtaiotasub greekEtaiotasubdasia greekEtaiotasubdasiaperispomeni greekEtaiotasubdasiatonos \
-greekEtaiotasubdasiavaria greekEtaiotasubpsili greekEtaiotasubpsiliperispomeni greekEtaiotasubpsilitonos greekEtaiotasubpsilivaria \
-greekEtapsili greekEtapsiliperispomeni greekEtapsilitonos greekEtapsilivaria greekEtatonos \
-greekEtavaria greekGamma greekIota greekIotadasia greekIotadasiaperispomeni \
-greekIotadasiatonos greekIotadasiavaria greekIotadialytika greekIotamacron greekIotapsili \
-greekIotapsiliperispomeni greekIotapsilitonos greekIotapsilivaria greekIotatonos greekIotavaria \
-greekIotavrachy greekKappa greekLambda greekMu greekNu \
-greekOmega greekOmegadasia greekOmegadasiaperispomeni greekOmegadasiatonos greekOmegadasiavaria \
-greekOmegaiotasub greekOmegaiotasubdasia greekOmegaiotasubdasiaperispomeni greekOmegaiotasubdasiatonos greekOmegaiotasubdasiavaria \
-greekOmegaiotasubpsili greekOmegaiotasubpsiliperispomeni greekOmegaiotasubpsilitonos greekOmegaiotasubpsilivaria greekOmegapsili \
-greekOmegapsiliperispomeni greekOmegapsilitonos greekOmegapsilivaria greekOmegatonos greekOmegavaria \
-greekOmicron greekOmicrondasia greekOmicrondasiatonos greekOmicrondasiavaria greekOmicronpsili \
-greekOmicronpsilitonos greekOmicronpsilivaria greekOmicrontonos greekOmicronvaria greekPhi \
-greekPi greekPsi greekRho greekRhodasia greekSigma \
-greekSigmalunate greekTau greekTheta greekUpsilon greekUpsilondasia \
-greekUpsilondasiaperispomeni greekUpsilondasiatonos greekUpsilondasiavaria greekUpsilondialytika greekUpsilonmacron \
-greekUpsilontonos greekUpsilonvaria greekUpsilonvrachy greekXi greekZeta \
-greekalpha greekalphadasia greekalphadasiaperispomeni greekalphadasiatonos greekalphadasiavaria \
-greekalphaiotasub greekalphaiotasubdasia greekalphaiotasubdasiaperispomeni greekalphaiotasubdasiatonos greekalphaiotasubdasiavaria \
-greekalphaiotasubperispomeni greekalphaiotasubpsili greekalphaiotasubpsiliperispomeni greekalphaiotasubpsilitonos greekalphaiotasubpsilivaria \
-greekalphaiotasubtonos greekalphaiotasubvaria greekalphamacron greekalphaoxia greekalphaperispomeni \
-greekalphapsili greekalphapsiliperispomeni greekalphapsilitonos greekalphapsilivaria greekalphatonos \
-greekalphavaria greekalphavrachy greekbeta greekchi greekdasia \
+forcelocalfloats forgeteverypar forgetparameters forgetparskip forgetragged \
+formula formulanumber foundbox fourfifths fourperemspace \
+fourthoffivearguments fourthoffourarguments fourthofsixarguments frac framed \
+frameddimension framedparameter framedtext freezedimenmacro freezemeasure \
+frenchspacing from fromlinenote frown frozenhbox \
+frule gacute gamma gbreve gcaron \
+gcircumflex gcommaaccent gdefconvertedargument gdefconvertedcommand gdotaccent \
+ge geq geqq geqslant getMPdrawing \
+getMPlayer getboxfromcache getboxllx getboxlly getbuffer \
+getbufferdata getcommacommandsize getcommalistsize getdayoftheweek getdayspermonth \
+getdefinedbuffer getdocumentargument getdocumentargumentdefault getdocumentfilename getdummyparameters \
+getemptyparameters geteparameters getexpandedparameters getfiguredimensions getfirstcharacter \
+getfirsttwopassdata getfromcommacommand getfromcommalist getfromtwopassdata getglyphdirect \
+getglyphstyled getgparameters getinlineuserdata getlasttwopassdata getlocalfloat \
+getlocalfloats getmarking getmessage getnamedglyphdirect getnamedglyphstyled \
+getnamedtwopassdatalist getnaturaldimensions getnoflines getobject getobjectdimensions \
+getpaletsize getparameters getprivatechar getprivateslot getrandomcount \
+getrandomdimen getrandomfloat getrandomnumber getrandomseed getraweparameters \
+getrawgparameters getrawnoflines getrawparameters getrawxparameters getreference \
+getreferenceentry getroundednoflines gets getsubstring gettokenlist \
+gettwopassdata gettwopassdatalist getuserdata getuvalue getvalue \
+getvariable getvariabledefault getxparameters gg ggg \
+gggtr gimel globaldisablemode globalenablemode globalletempty \
+globalpopbox globalpopmacro globalpreventmode globalprocesscommalist globalpushbox \
+globalpushmacro globalswapcounts globalswapdimens globalswapmacros globalundefine \
+glyphfontfile gnapprox gneqq gnsim gobbledoubleempty \
+gobbleeightarguments gobblefivearguments gobblefiveoptionals gobblefourarguments gobblefouroptionals \
+gobbleninearguments gobbleoneargument gobbleoneoptional gobblesevenarguments gobblesingleempty \
+gobblesixarguments gobblespacetokens gobbletenarguments gobblethreearguments gobblethreeoptionals \
+gobbletwoarguments gobbletwooptionals gobbleuntil gobbleuntilrelax godown \
+goto gotobox gotopage grabbufferdata grabbufferdatadirect \
+grabuntil grave graycolor grayvalue greedysplitstring \
+greekAlpha greekAlphadasia greekAlphadasiaperispomeni greekAlphadasiatonos greekAlphadasiavaria \
+greekAlphaiotasub greekAlphaiotasubdasia greekAlphaiotasubdasiaperispomeni greekAlphaiotasubdasiatonos greekAlphaiotasubdasiavaria \
+greekAlphaiotasubpsili greekAlphaiotasubpsiliperispomeni greekAlphaiotasubpsilitonos greekAlphaiotasubpsilivaria greekAlphamacron \
+greekAlphapsili greekAlphapsiliperispomeni greekAlphapsilitonos greekAlphapsilivaria greekAlphatonos \
+greekAlphavaria greekAlphavrachy greekBeta greekChi greekCoronis \
+greekDelta greekEpsilon greekEpsilondasia greekEpsilondasiatonos greekEpsilondasiavaria \
+greekEpsilonpsili greekEpsilonpsilitonos greekEpsilonpsilivaria greekEpsilontonos greekEpsilonvaria \
+greekEta greekEtadasia greekEtadasiaperispomeni greekEtadasiatonos greekEtadasiavaria \
+greekEtaiotasub greekEtaiotasubdasia greekEtaiotasubdasiaperispomeni greekEtaiotasubdasiatonos greekEtaiotasubdasiavaria \
+greekEtaiotasubpsili greekEtaiotasubpsiliperispomeni greekEtaiotasubpsilitonos greekEtaiotasubpsilivaria greekEtapsili \
+greekEtapsiliperispomeni greekEtapsilitonos greekEtapsilivaria greekEtatonos greekEtavaria \
+greekGamma greekIota greekIotadasia greekIotadasiaperispomeni greekIotadasiatonos \
+greekIotadasiavaria greekIotadialytika greekIotamacron greekIotapsili greekIotapsiliperispomeni \
+greekIotapsilitonos greekIotapsilivaria greekIotatonos greekIotavaria greekIotavrachy \
+greekKappa greekLambda greekMu greekNu greekOmega \
+greekOmegadasia greekOmegadasiaperispomeni greekOmegadasiatonos greekOmegadasiavaria greekOmegaiotasub \
+greekOmegaiotasubdasia greekOmegaiotasubdasiaperispomeni greekOmegaiotasubdasiatonos greekOmegaiotasubdasiavaria greekOmegaiotasubpsili \
+greekOmegaiotasubpsiliperispomeni greekOmegaiotasubpsilitonos greekOmegaiotasubpsilivaria greekOmegapsili greekOmegapsiliperispomeni \
+greekOmegapsilitonos greekOmegapsilivaria greekOmegatonos greekOmegavaria greekOmicron \
+greekOmicrondasia greekOmicrondasiatonos greekOmicrondasiavaria greekOmicronpsili greekOmicronpsilitonos \
+greekOmicronpsilivaria greekOmicrontonos greekOmicronvaria greekPhi greekPi \
+greekPsi greekRho greekRhodasia greekSigma greekSigmalunate \
+greekTau greekTheta greekUpsilon greekUpsilondasia greekUpsilondasiaperispomeni \
+greekUpsilondasiatonos greekUpsilondasiavaria greekUpsilondialytika greekUpsilonmacron greekUpsilontonos \
+greekUpsilonvaria greekUpsilonvrachy greekXi greekZeta greekalpha \
+greekalphadasia greekalphadasiaperispomeni greekalphadasiatonos greekalphadasiavaria greekalphaiotasub \
+greekalphaiotasubdasia greekalphaiotasubdasiaperispomeni greekalphaiotasubdasiatonos greekalphaiotasubdasiavaria greekalphaiotasubperispomeni \
+greekalphaiotasubpsili greekalphaiotasubpsiliperispomeni greekalphaiotasubpsilitonos greekalphaiotasubpsilivaria greekalphaiotasubtonos \
+greekalphaiotasubvaria greekalphamacron greekalphaoxia greekalphaperispomeni greekalphapsili \
+greekalphapsiliperispomeni greekalphapsilitonos greekalphapsilivaria greekalphatonos greekalphavaria \
+greekalphavrachy greekbeta greekbetaalt greekchi greekdasia \
greekdasiaperispomeni greekdasiatonos greekdasiavaria greekdelta greekdialytikaperispomeni \
greekdialytikatonos greekdialytikavaria greekdigamma greekepsilon greekepsilonalt \
greekepsilondasia greekepsilondasiatonos greekepsilondasiavaria greekepsilonoxia greekepsilonpsili \
@@ -563,89 +570,90 @@ hyphenatedurl hyphenatedword iacute ibox ibreve \
icaron icircumflex ideographichalffillspace ideographicspace idiaeresis \
idotaccent idotbelow idoublegrave ifassignment iff \
ifinobject ifinoutputstream ifparameters iftrialtypesetting ignoreimplicitspaces \
-ignorevalue igrave ihook iiiint iiiintop \
-iiint iiintop iint iintop iinvertedbreve \
-ijligature imacron imaginaryi imaginaryj imath \
-immediatesavetwopassdata impliedby implies imply in \
-includemenu includeversioninfo increment incrementcounter incrementedcounter \
-incrementpagenumber incrementsubpagenumber incrementvalue indentation index \
-infofont infofontbold inframed infty infull \
-inheritparameter inhibitblank ininner ininneredge ininnermargin \
-initializeboxstack inleft inleftedge inleftmargin inline \
-inlinebuffer inlinedbox inlinemath inlinemathematics inlinemessage \
-inlineordisplaymath inlineprettyprintbuffer inlinerange inmargin inmframed \
-innerflushshapebox inother inouter inouteredge inoutermargin \
-input inputfilebarename inputfilename inputfilerealsuffix inputfilesuffix \
-inputgivenfile inright inrightedge inrightmargin insertpages \
-installactionhandler installactivecharacter installanddefineactivecharacter installattributestack installautocommandhandler \
-installautosetuphandler installbasicautosetuphandler installbasicparameterhandler installbottomframerenderer installcommandhandler \
-installcorenamespace installdefinehandler installdefinitionset installdefinitionsetmember installdirectcommandhandler \
-installdirectparameterhandler installdirectparametersethandler installdirectsetuphandler installdirectstyleandcolorhandler installframedautocommandhandler \
-installframedcommandhandler installlanguage installleftframerenderer installnamespace installoutputroutine \
-installpagearrangement installparameterhandler installparameterhashhandler installparametersethandler installparentinjector \
-installrightframerenderer installrootparameterhandler installsetuphandler installsetuponlycommandhandler installshipoutmethod \
-installsimplecommandhandler installsimpleframedcommandhandler installstyleandcolorhandler installswitchcommandhandler installswitchsetuphandler \
-installtexdirective installtextracker installtopframerenderer installunitsseparator installunitsspace \
-installversioninfo int intclockwise integerrounding integers \
-interactionbar interactionbuttons interactionmenu intercal intertext \
-intop invisibletimes invokepageheandler iogonek iota \
-istltdir istrtdir italic italicbold italiccorrection \
-italicface item items itemtag itilde \
-jcaron jcircumflex jmath jobfilename jobfilesuffix \
-kap kappa kcaron kcommaaccent keepblocks \
-keeplinestogether keepunwantedspaces kerncharacters khook kkra \
-koreancirclenumerals koreannumerals koreannumeralsc koreannumeralsp koreanparentnumerals \
-lVert labellanguage labeltext labeltexts lacute \
-lambda lambdabar land langle language \
-languageCharacters languagecharacters languagecharwidth lastcounter lastcountervalue \
-lastdigit lastlinewidth lastnaturalboxdp lastnaturalboxht lastnaturalboxwd \
-lastpredefinedsymbol lastrealpage lastrealpagenumber lastsubcountervalue lastsubpage \
-lastsubpagenumber lasttwodigits lastuserpage lastuserpagenumber lateluacode \
-latin layeredtext layerheight layerwidth lazysavetaggedtwopassdata \
-lazysavetwopassdata lbar lbox lbrace lbracket \
-lcaron lceil lcommaaccent lcurl ldotmiddle \
-ldotp ldots le leadsto left \
-leftaligned leftarrow leftarrowtail leftarrowtriangle leftbottombox \
-leftbox leftdasharrow leftguillemot leftharpoondown leftharpoonup \
-lefthbox leftheadtext leftlabeltext leftleftarrows leftline \
-leftmathlabeltext leftorrighthbox leftorrightvbox leftorrightvtop leftrightarrow \
-leftrightarrows leftrightarrowtriangle leftrightharpoons leftrightsquigarrow leftskipadaption \
-leftsquigarrow leftsubguillemot leftthreetimes lefttopbox lefttoright \
-lefttorighthbox lefttorightvbox lefttorightvtop leftwavearrow leftwhitearrow \
-leq leqq leqslant lessapprox lessdot \
-lesseqgtr lesseqqgtr lessgtr lesssim letbeundefined \
-letcatcodecommand letcscsname letcsnamecs letcsnamecsname letdummyparameter \
-letempty letgvalue letgvalueempty letgvalurelax letterampersand \
-letterat letterbackslash letterbar letterbgroup letterclosebrace \
-lettercolon letterdollar letterdoublequote letteregroup letterescape \
-letterexclamationmark letterhash letterhat letterleftbrace letterleftbracket \
-letterleftparenthesis letterless lettermore letteropenbrace letterpercent \
-letterquestionmark letterrightbrace letterrightbracket letterrightparenthesis lettersinglequote \
-letterslash letterspacing lettertilde letterunderscore letvalue \
-letvalueempty letvaluerelax lfence lfloor lgroup \
-lhbox lhooknwarrow lhooksearrow limitatefirstline limitatelines \
-limitatetext line linefeed linenote linespanningtext \
-linethickness linterval listcitation listcite listlength \
-listnamespaces ljligature ll llangle llap \
-llbracket llcorner lll llless lmoustache \
-lnapprox lneq lneqq lnot lnsim \
-loadanyfile loadanyfileonce loadbtxdefinitionfile loadbtxreplacementfile loadcldfile \
-loadcldfileonce loadfontgoodies loadluafile loadluafileonce loadspellchecklist \
-loadtexfile loadtexfileonce loadtypescriptfile localframed localframedwithsettings \
-localhsize localpopbox localpopmacro localpushbox localpushmacro \
-localundefine locatedfilepath locatefilepath locfilename logo \
-lohi lointerval lomihi longleftarrow longleftrightarrow \
-longmapsfrom longmapsto longrightarrow longrightsquigarrow looparrowleft \
-looparrowright lor low lowerbox lowercased \
-lowercasestring lowerleftdoubleninequote lowerleftsingleninequote lowerrightdoubleninequote lowerrightsingleninequote \
-lozenge lparent lrcorner lrointerval lrtbbox \
-lstroke lt ltimes ltop luaTeX \
-luacode luaconditional luaenvironment luaexpanded luaexpr \
-luafunction luajitTeX luamajorversion luaminorversion luaparameterset \
-luasetup luaversion lvert m mLeftarrow \
-mLeftrightarrow mRightarrow mainlanguage makecharacteractive makerawcommalist \
-makestrutofbox maltese mapfontsize mapsdown mapsfrom \
-mapsto mapsup margindata margintext markcontent \
+ignoretagsinexport ignorevalue igrave ihook iiiint \
+iiiintop iiint iiintop iint iintop \
+iinvertedbreve ijligature imacron imaginaryi imaginaryj \
+imath immediatesavetwopassdata impliedby implies imply \
+in includemenu includeversioninfo increment incrementcounter \
+incrementedcounter incrementpagenumber incrementsubpagenumber incrementvalue indentation \
+index infofont infofontbold inframed infty \
+infull inheritparameter inhibitblank ininner ininneredge \
+ininnermargin initializeboxstack inleft inleftedge inleftmargin \
+inline inlinebuffer inlinedbox inlinemath inlinemathematics \
+inlinemessage inlineordisplaymath inlineprettyprintbuffer inlinerange inmargin \
+inmframed innerflushshapebox inother inouter inouteredge \
+inoutermargin input inputfilebarename inputfilename inputfilerealsuffix \
+inputfilesuffix inputgivenfile inright inrightedge inrightmargin \
+insertpages installactionhandler installactivecharacter installanddefineactivecharacter installattributestack \
+installautocommandhandler installautosetuphandler installbasicautosetuphandler installbasicparameterhandler installbottomframerenderer \
+installcommandhandler installcorenamespace installdefinehandler installdefinitionset installdefinitionsetmember \
+installdirectcommandhandler installdirectparameterhandler installdirectparametersethandler installdirectsetuphandler installdirectstyleandcolorhandler \
+installframedautocommandhandler installframedcommandhandler installglobalmacrostack installlanguage installleftframerenderer \
+installmacrostack installnamespace installoutputroutine installpagearrangement installparameterhandler \
+installparameterhashhandler installparametersethandler installparentinjector installrightframerenderer installrootparameterhandler \
+installsetuphandler installsetuponlycommandhandler installshipoutmethod installsimplecommandhandler installsimpleframedcommandhandler \
+installstyleandcolorhandler installswitchcommandhandler installswitchsetuphandler installtexdirective installtextracker \
+installtopframerenderer installunitsseparator installunitsspace installversioninfo int \
+intclockwise integerrounding integers interactionbar interactionbuttons \
+interactionmenu intercal intertext intop invisibletimes \
+invokepageheandler iogonek iota istltdir istrtdir \
+italic italicbold italiccorrection italicface item \
+items itemtag itilde jcaron jcircumflex \
+jmath jobfilename jobfilesuffix kap kappa \
+kcaron kcommaaccent keepblocks keeplinestogether keepunwantedspaces \
+kerncharacters khook kkra koreancirclenumerals koreannumerals \
+koreannumeralsc koreannumeralsp koreanparentnumerals lVert labellanguage \
+labeltext labeltexts lacute lambda lambdabar \
+land langle language languageCharacters languagecharacters \
+languagecharwidth lastcounter lastcountervalue lastdigit lastlinewidth \
+lastnaturalboxdp lastnaturalboxht lastnaturalboxwd lastpredefinedsymbol lastrealpage \
+lastrealpagenumber lastsubcountervalue lastsubpage lastsubpagenumber lasttwodigits \
+lastuserpage lastuserpagenumber lateluacode latin layeredtext \
+layerheight layerwidth lazysavetaggedtwopassdata lazysavetwopassdata lbar \
+lbox lbrace lbracket lcaron lceil \
+lcommaaccent lcurl ldotmiddle ldotp ldots \
+le leadsto left leftaligned leftarrow \
+leftarrowtail leftarrowtriangle leftbottombox leftbox leftdasharrow \
+leftguillemot leftharpoondown leftharpoonup lefthbox leftheadtext \
+leftlabeltext leftleftarrows leftline leftmathlabeltext leftorrighthbox \
+leftorrightvbox leftorrightvtop leftrightarrow leftrightarrows leftrightarrowtriangle \
+leftrightharpoons leftrightsquigarrow leftskipadaption leftsquigarrow leftsubguillemot \
+leftthreetimes lefttopbox lefttoright lefttorighthbox lefttorightvbox \
+lefttorightvtop leftwavearrow leftwhitearrow leq leqq \
+leqslant lessapprox lessdot lesseqgtr lesseqqgtr \
+lessgtr lesssim letbeundefined letcatcodecommand letcscsname \
+letcsnamecs letcsnamecsname letdummyparameter letempty letgvalue \
+letgvalueempty letgvalurelax letterampersand letterat letterbackslash \
+letterbar letterbgroup letterclosebrace lettercolon letterdollar \
+letterdoublequote letteregroup letterescape letterexclamationmark letterhash \
+letterhat letterleftbrace letterleftbracket letterleftparenthesis letterless \
+lettermore letteropenbrace letterpercent letterquestionmark letterrightbrace \
+letterrightbracket letterrightparenthesis lettersinglequote letterslash letterspacing \
+lettertilde letterunderscore letvalue letvalueempty letvaluerelax \
+lfence lfloor lgroup lhbox lhooknwarrow \
+lhooksearrow limitatefirstline limitatelines limitatetext line \
+linebox linefeed linenote linespanningtext linethickness \
+linterval listcitation listcite listlength listnamespaces \
+ljligature ll llangle llap llbracket \
+llcorner lll llless lmoustache lnapprox \
+lneq lneqq lnot lnsim loadanyfile \
+loadanyfileonce loadbtxdefinitionfile loadbtxreplacementfile loadcldfile loadcldfileonce \
+loadfontgoodies loadluafile loadluafileonce loadspellchecklist loadtexfile \
+loadtexfileonce loadtypescriptfile localframed localframedwithsettings localhsize \
+localpopbox localpopmacro localpushbox localpushmacro localundefine \
+locatedfilepath locatefilepath locfilename logo lohi \
+lointerval lomihi longleftarrow longleftrightarrow longmapsfrom \
+longmapsto longrightarrow longrightsquigarrow looparrowleft looparrowright \
+lor low lowerbox lowercased lowercasestring \
+lowerleftdoubleninequote lowerleftsingleninequote lowerrightdoubleninequote lowerrightsingleninequote lozenge \
+lparent lrcorner lrointerval lrtbbox lstroke \
+lt ltimes ltop luaTeX luacode \
+luaconditional luaenvironment luaexpanded luaexpr luafunction \
+luajitTeX luamajorversion luaminorversion luaparameterset luasetup \
+luaversion lvert m mLeftarrow mLeftrightarrow \
+mRightarrow mainlanguage makecharacteractive makerawcommalist makestrutofbox \
+maltese mapfontsize mapsdown mapsfrom mapsto \
+mapsup margindata margintext markcontent markedpages \
marking markinjector markpage mat math \
mathampersand mathbf mathbi mathblackboard mathbs \
mathdefault mathdollar mathdouble mathematics mathfraktur \
@@ -676,78 +684,79 @@ napprox napproxEq narrownobreakspace nasymp natural \
naturalhbox naturalhpack naturalnumbers naturalvbox naturalvcenter \
naturalvpack naturalvtop naturalwd ncaron ncommaaccent \
ncong ncurl ndivides ne nearrow \
-neg negatecolorbox negated negativesign negthinspace \
-neng neq nequiv neswarrow newattribute \
-newcatcodetable newcounter newevery newfrenchspacing newmode \
-newsignal newsystemmode nexists nextbox nextboxdp \
-nextboxht nextboxhtdp nextboxwd nextcounter nextcountervalue \
-nextdepth nextparagraphs nextrealpage nextrealpagenumber nextsubcountervalue \
-nextsubpage nextsubpagenumber nextuserpage nextuserpagenumber ngeq \
-ngrave ngtr ngtrless ngtrsim ni \
-nihongo nin njligature nleftarrow nleftrightarrow \
-nleq nless nlessgtr nlesssim nmid \
-nni nobar nobreakspace nocap nocitation \
-nocite nodetostring noffigurepages noflines noflocalfloats \
-noheaderandfooterlines noheightstrut noindentation noitem nonfrenchspacing \
-nonmathematics normal normalboldface normalframedwithsettings normalitalicface \
-normalizebodyfontsize normalizedfontsize normalizefontdepth normalizefontheight normalizefontline \
-normalizefontwidth normalizetextdepth normalizetextheight normalizetextline normalizetextwidth \
-normalslantedface normaltypeface nospace not note \
-notesymbol notin notopandbottomlines notragged nowns \
-nparallel nprec npreccurlyeq nrightarrow nsim \
-nsimeq nsqsubseteq nsqsupseteq nsubset nsubseteq \
-nsucc nsucccurlyeq nsupset nsupseteq ntilde \
-ntimes ntriangleleft ntrianglelefteq ntriangleright ntrianglerighteq \
-nu numberofpoints numbers nvDash nvdash \
-nvleftarrow nvleftrightarrow nvrightarrow nwarrow nwsearrow \
-oacute obeydepth objectdepth objectheight objectmargin \
-objectwidth obox obreve ocaron ocircumflex \
-ocircumflexacute ocircumflexdotbelow ocircumflexgrave ocircumflexhook ocircumflextilde \
-odiaeresis odiaeresismacron odot odotaccent odotaccentmacron \
-odotbelow odoublegrave oeligature offset offsetbox \
-ograve ohm ohook ohorn ohornacute \
-ohorndotbelow ohorngrave ohornhook ohorntilde ohungarumlaut \
-oiiint oiint oint ointclockwise ointctrclockwise \
-oinvertedbreve omacron omega omicron ominus \
-onedigitrounding oneeighth onefifth onehalf onequarter \
-onesixth onesuperior onethird oogonek oogonekmacron \
-operatorlanguage operatortext oplus ordfeminine ordinaldaynumber \
-ordinalstr ordmasculine ornamenttext oslash ostroke \
-ostrokeacute otilde otildemacron otimes outputfilename \
-outputstreambox outputstreamcopy outputstreamunvbox outputstreamunvcopy over \
-overbar overbars overbarunderbar overbrace overbraceunderbrace \
-overbracket overbracketunderbracket overlaybutton overlaycolor overlaydepth \
-overlayfigure overlayheight overlaylinecolor overlaylinewidth overlayoffset \
-overlayrollbutton overlaywidth overleftarrow overloaderror overparent \
-overparentunderparent overrightarrow overset overstrike overstrikes \
-owns page pagearea pagebreak pagefigure \
-pagegridspanwidth pageinjection pagenumber pagereference pagestaterealpage \
-paletsize paragraphmark parallel part partial \
-pdfTeX pdfactualtext pdfbackendactualtext pdfbackendcurrentresources pdfbackendsetcatalog \
-pdfbackendsetcolorspace pdfbackendsetextgstate pdfbackendsetinfo pdfbackendsetname pdfbackendsetpageattribute \
-pdfbackendsetpageresource pdfbackendsetpagesattribute pdfbackendsetpattern pdfbackendsetshade pdfcolor \
-pdfeTeX percent percentdimen periodcentered periods \
-permitcaretescape permitcircumflexescape permitspacesbetweengroups perp persiandecimals \
-persiandecimalseparator persiannumerals persianthousandsseparator perthousand phantom \
-phantombox phi phook pi pickupgroupedcommand \
-pitchfork placeattachments placebookmarks placebtxrendering placechemical \
-placecitation placecombinedlist placecomments placecontent placecurrentformulanumber \
-placedbox placefigure placefloat placefloatwithsetups placefootnotes \
-placeformula placeframed placegraphic placeheadnumber placeheadtext \
-placehelp placeindex placeinitial placeintermezzo placelayer \
-placelayeredtext placelegend placelist placelistofabbreviations placelistofchemicals \
-placelistoffigures placelistofgraphics placelistofintermezzi placelistoflogos placelistofpublications \
-placelistofsorts placelistofsynonyms placelistoftables placelocalfootnotes placelocalnotes \
-placement placenamedfloat placenamedformula placenotes placeongrid \
-placeontopofeachother placepagenumber placepairedbox placeparallel placerawlist \
-placeregister placerenderingwindow placesidebyside placesubformula placetable \
-pm popattribute popmacro popmode popsystemmode \
-position positionoverlay positionregionoverlay positivesign postponenotes \
-prec precapprox preccurlyeq preceq preceqq \
-precnapprox precneq precneqq precnsim precsim \
-predefinedfont predefinefont predefinesymbol prefixedpagenumber prefixlanguage \
-prefixtext prependetoks prependgvalue prependtocommalist prependtoks \
-prependtoksonce prependvalue presetbtxlabeltext presetdocument presetfieldsymbols \
+neg negatecolorbox negated negativesign negemspace \
+negenspace negthinspace neng neq nequiv \
+neswarrow newattribute newcatcodetable newcounter newevery \
+newfrenchspacing newmode newsignal newsystemmode nexists \
+nextbox nextboxdp nextboxht nextboxhtdp nextboxwd \
+nextcounter nextcountervalue nextdepth nextparagraphs nextrealpage \
+nextrealpagenumber nextsubcountervalue nextsubpage nextsubpagenumber nextuserpage \
+nextuserpagenumber ngeq ngrave ngtr ngtrless \
+ngtrsim ni nihongo nin njligature \
+nleftarrow nleftrightarrow nleq nless nlessgtr \
+nlesssim nmid nni nobar nobreakspace \
+nocap nocharacteralign nocitation nocite nodetostring \
+noffigurepages noflines noflocalfloats noheaderandfooterlines noheightstrut \
+noindentation noitem nonfrenchspacing nonmathematics normal \
+normalboldface normalframedwithsettings normalitalicface normalizebodyfontsize normalizedfontsize \
+normalizefontdepth normalizefontheight normalizefontline normalizefontwidth normalizetextdepth \
+normalizetextheight normalizetextline normalizetextwidth normalslantedface normaltypeface \
+nospace not note notesymbol notin \
+notopandbottomlines notragged nowns nparallel nprec \
+npreccurlyeq nrightarrow nsim nsimeq nsqsubseteq \
+nsqsupseteq nsubset nsubseteq nsucc nsucccurlyeq \
+nsupset nsupseteq ntilde ntimes ntriangleleft \
+ntrianglelefteq ntriangleright ntrianglerighteq nu numberofpoints \
+numbers nvDash nvdash nvleftarrow nvleftrightarrow \
+nvrightarrow nwarrow nwsearrow oacute obeydepth \
+objectdepth objectheight objectmargin objectwidth obox \
+obreve ocaron ocircumflex ocircumflexacute ocircumflexdotbelow \
+ocircumflexgrave ocircumflexhook ocircumflextilde odiaeresis odiaeresismacron \
+odot odotaccent odotaccentmacron odotbelow odoublegrave \
+oeligature offset offsetbox ograve ohm \
+ohook ohorn ohornacute ohorndotbelow ohorngrave \
+ohornhook ohorntilde ohungarumlaut oiiint oiint \
+oint ointclockwise ointctrclockwise oinvertedbreve omacron \
+omega omicron ominus onedigitrounding oneeighth \
+onefifth onehalf onequarter onesixth onesuperior \
+onethird oogonek oogonekmacron operatorlanguage operatortext \
+oplus ordfeminine ordinaldaynumber ordinalstr ordmasculine \
+ornamenttext oslash ostroke ostrokeacute otilde \
+otildemacron otimes outputfilename outputstreambox outputstreamcopy \
+outputstreamunvbox outputstreamunvcopy over overbar overbars \
+overbarunderbar overbrace overbraceunderbrace overbracket overbracketunderbracket \
+overlaybutton overlaycolor overlaydepth overlayfigure overlayheight \
+overlayimage overlaylinecolor overlaylinewidth overlayoffset overlayrollbutton \
+overlaywidth overleftarrow overloaderror overparent overparentunderparent \
+overrightarrow overset overstrike overstrikes owns \
+page pagearea pagebreak pagefigure pageinjection \
+pagenumber pagereference pagestaterealpage pagestaterealpageorder paletsize \
+paragraphmark parallel part partial pdfTeX \
+pdfactualtext pdfbackendactualtext pdfbackendcurrentresources pdfbackendsetcatalog pdfbackendsetcolorspace \
+pdfbackendsetextgstate pdfbackendsetinfo pdfbackendsetname pdfbackendsetpageattribute pdfbackendsetpageresource \
+pdfbackendsetpagesattribute pdfbackendsetpattern pdfbackendsetshade pdfcolor pdfeTeX \
+percent percentdimen periodcentered periods permitcaretescape \
+permitcircumflexescape permitspacesbetweengroups perp persiandecimals persiandecimalseparator \
+persiannumerals persianthousandsseparator perthousand phantom phantombox \
+phi phook pi pickupgroupedcommand pitchfork \
+placeattachments placebookmarks placebtxrendering placechemical placecitation \
+placecombinedlist placecomments placecontent placecurrentformulanumber placedbox \
+placefigure placefloat placefloatwithsetups placefootnotes placeformula \
+placeframed placegraphic placeheadnumber placeheadtext placehelp \
+placeindex placeinitial placeintermezzo placelayer placelayeredtext \
+placelegend placelist placelistofabbreviations placelistofchemicals placelistoffigures \
+placelistofgraphics placelistofintermezzi placelistoflogos placelistofpublications placelistofsorts \
+placelistofsynonyms placelistoftables placelocalfootnotes placelocalnotes placement \
+placenamedfloat placenamedformula placenotes placeongrid placeontopofeachother \
+placepagenumber placepairedbox placeparallel placerawlist placeregister \
+placerenderingwindow placesidebyside placesubformula placetable pm \
+popattribute popmacro popmode popsystemmode position \
+positionoverlay positionregionoverlay positivesign postponenotes prec \
+precapprox preccurlyeq preceq preceqq precnapprox \
+precneq precneqq precnsim precsim predefinedfont \
+predefinefont predefinesymbol prefixedpagenumber prefixlanguage prefixtext \
+prependetoks prependgvalue prependtocommalist prependtoks prependtoksonce \
+prependvalue prerollblank presetbtxlabeltext presetdocument presetfieldsymbols \
presetheadtext presetlabeltext presetmathlabeltext presetoperatortext presetprefixtext \
presetsuffixtext presettaglabeltext presetunittext pretocommalist prettyprintbuffer \
prevcounter prevcountervalue preventmode prevrealpage prevrealpagenumber \
@@ -791,85 +800,89 @@ resetcharacterstripping resetcollector resetcounter resetdigitsmanipulation rese
resetfeature resetflag resetfontcolorsheme resetfontfallback resetfontsolution \
resethyphenationfeatures resetinjector resetinteractionmenu resetitaliccorrection resetlayer \
resetlocalfloats resetmarker resetmarking resetmode resetpagenumber \
-resetparallel resetpath resetpenalties resetprofile resetrecurselevel \
-resetreference resetreplacement resetscript resetsetups resetshownsynonyms \
-resetsubpagenumber resetsymbolset resetsystemmode resettimer resettrackers \
-resettrialtypesetting resetusedsortings resetusedsynonyms resetuserpagenumber resetvalue \
-resetvisualizers reshapebox resolvedglyphdirect resolvedglyphstyled restartcounter \
-restorebox restorecatcodes restorecounter restorecurrentattributes restoreendofline \
-restoreglobalbodyfont restriction reusableMPgraphic reuseMPgraphic reuserandomseed \
-reverseddoubleprime reversedprime reversedtripleprime revivefeature rfence \
-rfloor rgroup rhbox rho rhooknearrow \
-rhookswarrow right rightaligned rightangle rightarrow \
-rightarrowbar rightarrowtail rightarrowtriangle rightbottombox rightbox \
-rightdasharrow rightguillemot rightharpoondown rightharpoonup righthbox \
-rightheadtext rightlabeltext rightleftarrows rightleftharpoons rightline \
-rightmathlabeltext rightorleftpageaction rightrightarrows rightskipadaption rightsquigarrow \
-rightsubguillemot rightthreearrows rightthreetimes righttoleft righttolefthbox \
-righttoleftvbox righttoleftvtop righttopbox rightwavearrow rightwhitearrow \
-ring rinterval rinvertedbreve risingdotseq rlap \
-rlointerval rmoustache rneq robustaddtocommalist robustdoifelseinset \
-robustdoifinsetelse robustpretocommalist rointerval rollbutton roman \
-romanC romanD romanI romanII romanIII \
-romanIV romanIX romanL romanM romanV \
-romanVI romanVII romanVIII romanX romanXI \
-romanXII romanc romand romani romanii \
-romaniii romaniv romanix romanl romanm \
-romannumerals romanv romanvi romanvii romanviii \
-romanx romanxi romanxii rootradical rotate \
-rparent rrangle rrbracket rrointerval rtimes \
-rtop ruledhbox ruledhpack ruledmbox ruledtopv \
-ruledtpack ruledvbox ruledvpack ruledvtop runMPbuffer \
-runninghbox rvert sacute safechar samplefile \
-sans sansbold sansnormal sansserif savebox \
-savebtxdataset savebuffer savecounter savecurrentattributes savenormalmeaning \
-savetaggedtwopassdata savetwopassdata sbox scale scaron \
-scedilla schwa schwahook scircumflex scommaaccent \
-screen searrow secondoffivearguments secondoffourarguments secondofsixarguments \
-secondofthreearguments secondofthreeunexpanded secondoftwoarguments secondoftwounexpanded section \
-sectionmark seeindex select selectblocks serializecommalist \
-serializedcommalist serif serifbold serifnormal setJSpreamble \
-setMPlayer setMPpositiongraphic setMPpositiongraphicrange setMPtext setMPvariable \
-setMPvariables setbar setbigbodyfont setboxllx setboxlly \
-setbreakpoints setcapstrut setcatcodetable setcharacteralign setcharactercasing \
-setcharactercleaning setcharacterkerning setcharacterspacing setcharacterstripping setcharstrut \
-setcollector setcolormodell setcounter setcounterown setcurrentfontclass \
-setdataset setdefaultpenalties setdigitsmanipulation setdirection setdocumentargument \
-setdocumentargumentdefault setdocumentfilename setdummyparameter setelementexporttag setemeasure \
-setevalue setevariable setevariables setfirstline setflag \
-setfont setfontcolorsheme setfontfeature setfontsolution setfontstrut \
-setgmeasure setgvalue setgvariable setgvariables sethboxregister \
-sethyphenatedurlafter sethyphenatedurlbefore sethyphenatedurlnormal sethyphenationfeatures setinitial \
-setinjector setinteraction setinterfacecommand setinterfaceconstant setinterfaceelement \
-setinterfacemessage setinterfacevariable setinternalrendering setitaliccorrection setlayer \
-setlayerframed setlayertext setlinefiller setlocalhsize setmainbodyfont \
-setmainparbuilder setmarker setmarking setmathstyle setmeasure \
-setmessagetext setminus setmode setnostrut setnote \
-setnotetext setobject setoldstyle setpagegrid setpagereference \
-setpagestate setpagestaterealpageno setpenalties setpercentdimen setposition \
-setpositionbox setpositiondata setpositiondataplus setpositiononly setpositionplus \
-setpositionstrut setprofile setrandomseed setreference setreferencedobject \
-setregisterentry setreplacement setrigidcolumnbalance setrigidcolumnhsize setscript \
+resetparallel resetpath resetpenalties resetperiodkerning resetprofile \
+resetrecurselevel resetreference resetreplacement resetscript resetsetups \
+resetshownsynonyms resetsubpagenumber resetsymbolset resetsystemmode resettimer \
+resettokenlist resettrackers resettrialtypesetting resetusedsortings resetusedsynonyms \
+resetuserpagenumber resetvalue resetvisualizers reshapebox resolvedglyphdirect \
+resolvedglyphstyled restartcounter restorebox restorecatcodes restorecounter \
+restorecurrentattributes restoreendofline restoreglobalbodyfont restriction reusableMPgraphic \
+reuseMPgraphic reuserandomseed reverseddoubleprime reversedprime reversedtripleprime \
+revivefeature rfence rfloor rgroup rhbox \
+rho rhooknearrow rhookswarrow right rightaligned \
+rightangle rightarrow rightarrowbar rightarrowtail rightarrowtriangle \
+rightbottombox rightbox rightdasharrow rightguillemot rightharpoondown \
+rightharpoonup righthbox rightheadtext rightlabeltext rightleftarrows \
+rightleftharpoons rightline rightmathlabeltext rightorleftpageaction rightpageorder \
+rightrightarrows rightskipadaption rightsquigarrow rightsubguillemot rightthreearrows \
+rightthreetimes righttoleft righttolefthbox righttoleftvbox righttoleftvtop \
+righttopbox rightwavearrow rightwhitearrow ring rinterval \
+rinvertedbreve risingdotseq rlap rlointerval rmoustache \
+rneq robustaddtocommalist robustdoifelseinset robustdoifinsetelse robustpretocommalist \
+rointerval rollbutton roman romanC romanD \
+romanI romanII romanIII romanIV romanIX \
+romanL romanM romanV romanVI romanVII \
+romanVIII romanX romanXI romanXII romanc \
+romand romani romanii romaniii romaniv \
+romanix romanl romanm romannumerals romanv \
+romanvi romanvii romanviii romanx romanxi \
+romanxii rootradical rotate rparent rrangle \
+rrbracket rrointerval rtimes rtop ruby \
+ruledhbox ruledhpack ruledmbox ruledtopv ruledtpack \
+ruledvbox ruledvpack ruledvtop runMPbuffer runninghbox \
+rvert sacute safechar samplefile sans \
+sansbold sansnormal sansserif savebox savebtxdataset \
+savebuffer savecounter savecurrentattributes savenormalmeaning savetaggedtwopassdata \
+savetwopassdata sbox scale scaron scedilla \
+schwa schwahook scircumflex scommaaccent screen \
+searrow secondoffivearguments secondoffourarguments secondofsixarguments secondofthreearguments \
+secondofthreeunexpanded secondoftwoarguments secondoftwounexpanded section sectionmark \
+seeindex select selectblocks serializecommalist serializedcommalist \
+serif serifbold serifnormal setJSpreamble setMPlayer \
+setMPpositiongraphic setMPpositiongraphicrange setMPtext setMPvariable setMPvariables \
+setautopagestaterealpageno setbar setbigbodyfont setboxllx setboxlly \
+setbreakpoints setcapstrut setcatcodetable setcharacteralign setcharacteraligndetail \
+setcharactercasing setcharactercleaning setcharacterkerning setcharacterspacing setcharacterstripping \
+setcharstrut setcollector setcolormodell setcounter setcounterown \
+setcurrentfontclass setdataset setdefaultpenalties setdigitsmanipulation setdirection \
+setdocumentargument setdocumentargumentdefault setdocumentfilename setdummyparameter setelementexporttag \
+setemeasure setevalue setevariable setevariables setfirstline \
+setfirstpasscharacteralign setflag setfont setfontcolorsheme setfontfeature \
+setfontsolution setfontstrut setglobalscript setgmeasure setgvalue \
+setgvariable setgvariables sethboxregister sethyphenatedurlafter sethyphenatedurlbefore \
+sethyphenatedurlnormal sethyphenationfeatures setinitial setinjector setinteraction \
+setinterfacecommand setinterfaceconstant setinterfaceelement setinterfacemessage setinterfacevariable \
+setinternalrendering setitaliccorrection setlayer setlayerframed setlayertext \
+setlinefiller setlocalhsize setlocalscript setmainbodyfont setmainparbuilder \
+setmarker setmarking setmathstyle setmeasure setmessagetext \
+setminus setmode setnostrut setnote setnotetext \
+setobject setoldstyle setpagereference setpagestate setpagestaterealpageno \
+setpenalties setpercentdimen setperiodkerning setposition setpositionbox \
+setpositiondata setpositiondataplus setpositiononly setpositionplus setpositionstrut \
+setprofile setrandomseed setreference setreferencedobject setregisterentry \
+setreplacement setrigidcolumnbalance setrigidcolumnhsize setscript setsecondpasscharacteralign \
setsectionblock setsimplecolumnhsize setsmallbodyfont setsmallcaps setstackbox \
setstructurepageregister setstrut setsuperiors setsystemmode settabular \
-settaggedmetadata settextcontent settightobject settightreferencedobject settightunreferencedobject \
-settrialtypesetting setuevalue setugvalue setunreferencedobject setup \
-setupMPgraphics setupMPinstance setupMPpage setupMPvariables setupTABLE \
-setupTEXpage setupalign setupalternativestyles setuparranging setupattachment \
-setupattachments setupbackend setupbackground setupbackgrounds setupbar \
-setupbars setupblackrules setupblank setupbleeding setupblock \
-setupbodyfont setupbookmark setupbottom setupbottomtexts setupbtx \
-setupbtxdataset setupbtxlabeltext setupbtxlist setupbtxregister setupbtxrendering \
-setupbuffer setupbutton setupcapitals setupcaption setupcaptions \
-setupcharacterkerning setupcharacterspacing setupchemical setupchemicalframed setupclipping \
-setupcollector setupcolor setupcolors setupcolumns setupcolumnspan \
-setupcombination setupcombinedlist setupcomment setupcontent setupcounter \
-setupdataset setupdelimitedtext setupdescription setupdirections setupdocument \
-setupeffect setupenumeration setupenumerations setupenv setupexport \
-setupexternalfigure setupexternalsoundtracks setupfield setupfieldbody setupfieldcategory \
+settaggedmetadata settextcontent settightobject settightreferencedobject settightstrut \
+settightunreferencedobject settokenlist settrialtypesetting setuevalue setugvalue \
+setunreferencedobject setup setupMPgraphics setupMPinstance setupMPpage \
+setupMPvariables setupTABLE setupTEXpage setupalign setupalternativestyles \
+setuparranging setupattachment setupattachments setupbackend setupbackground \
+setupbackgrounds setupbar setupbars setupblackrules setupblank \
+setupbleeding setupblock setupbodyfont setupbookmark setupbottom \
+setupbottomtexts setupbtx setupbtxdataset setupbtxlabeltext setupbtxlist \
+setupbtxregister setupbtxrendering setupbuffer setupbutton setupcapitals \
+setupcaption setupcaptions setupcharacteralign setupcharacterkerning setupcharacterspacing \
+setupchemical setupchemicalframed setupclipping setupcollector setupcolor \
+setupcolors setupcolumns setupcolumnset setupcolumnsetarea setupcolumnsetareatext \
+setupcolumnsetlines setupcolumnsetspan setupcolumnsetstart setupcolumnspan setupcombination \
+setupcombinedlist setupcomment setupcontent setupcounter setupdataset \
+setupdelimitedtext setupdescription setupdirections setupdocument setupeffect \
+setupenumeration setupenumerations setupenv setupexport setupexternalfigure \
+setupexternalsoundtracks setupfacingfloat setupfield setupfieldbody setupfieldcategory \
setupfieldcontentframed setupfieldlabelframed setupfields setupfieldtotalframed setupfiller \
setupfillinlines setupfillinrules setupfirstline setupfittingpage setupfloat \
-setupfloatcaption setupfloats setupfloatsplitting setupfontexpansion setupfontprotrusion \
+setupfloatframed setupfloats setupfloatsplitting setupfontexpansion setupfontprotrusion \
setupfonts setupfontsolution setupfooter setupfootertexts setupforms \
setupformula setupformulae setupformulaframed setupframed setupframedcontent \
setupframedtable setupframedtablecolumn setupframedtablerow setupframedtext setupframedtexts \
@@ -889,80 +902,82 @@ setupmathematics setupmathfence setupmathfraction setupmathfractions setupmathfr
setupmathlabeltext setupmathmatrix setupmathornament setupmathradical setupmathstackers \
setupmathstyle setupmixedcolumns setupmodule setupnarrower setupnotation \
setupnotations setupnote setupnotes setupoffset setupoffsetbox \
-setupoperatortext setupoppositeplacing setupoutputroutine setuppagechecker setuppagecomment \
-setuppagegrid setuppagegridarea setuppagegridareatext setuppagegridlines setuppagegridspan \
-setuppagegridstart setuppageinjection setuppageinjectionalternative setuppagenumber setuppagenumbering \
+setupoperatortext setupoppositeplacing setupoutputroutine setuppagechecker setuppagecolumns \
+setuppagecomment setuppageinjection setuppageinjectionalternative setuppagenumber setuppagenumbering \
setuppageshift setuppagestate setuppagetransitions setuppairedbox setuppalet \
setuppaper setuppapersize setupparagraph setupparagraphintro setupparagraphnumbering \
-setupparagraphs setupparallel setupperiods setupplacement setuppositionbar \
-setuppositioning setupprefixtext setupprocessor setupprofile setupprograms \
-setupquotation setupquote setuprealpagenumber setupreferenceformat setupreferenceprefix \
-setupreferencestructureprefix setupreferencing setupregister setupregisters setuprenderingwindow \
-setuprotate setups setupscale setupscript setupscripts \
-setupsectionblock setupselector setupshift setupsidebar setupsorting \
-setupspacing setupspellchecking setupstartstop setupstretched setupstruts \
-setupstyle setupsubformula setupsubformulas setupsubpagenumber setupsuffixtext \
-setupsymbolset setupsynctex setupsynonyms setuptables setuptabulate \
-setuptabulation setuptagging setuptaglabeltext setuptext setuptextbackground \
-setuptextflow setuptextrules setuptexttexts setupthinrules setuptolerance \
-setuptooltip setuptop setuptoptexts setuptype setuptyping \
-setupunit setupunittext setupurl setupuserpagenumber setupversion \
-setupviewerlayer setupvspacing setupwhitespace setupwithargument setupwithargumentswapped \
-setupxml setupxtable setuvalue setuxvalue setvalue \
-setvariable setvariables setvboxregister setvisualizerfont setvtopregister \
-setwidthof setxmeasure setxvalue setxvariable setxvariables \
-seveneighths sfrac shapedhbox sharp shiftdown \
+setupparagraphs setupparallel setupperiodkerning setupperiods setupplacement \
+setuppositionbar setuppositioning setupprefixtext setupprocessor setupprofile \
+setupprograms setupquotation setupquote setuprealpagenumber setupreferenceformat \
+setupreferenceprefix setupreferencestructureprefix setupreferencing setupregister setupregisters \
+setuprenderingwindow setuprotate setupruby setups setupscale \
+setupscript setupscripts setupsectionblock setupselector setupshift \
+setupsidebar setupsorting setupspacing setupspellchecking setupstartstop \
+setupstretched setupstruts setupstyle setupsubformula setupsubformulas \
+setupsubpagenumber setupsuffixtext setupsymbolset setupsynctex setupsynonyms \
+setuptables setuptabulate setuptabulation setuptagging setuptaglabeltext \
+setuptext setuptextbackground setuptextflow setuptextrules setuptexttexts \
+setupthinrules setuptolerance setuptooltip setuptop setuptoptexts \
+setuptype setuptyping setupunit setupunittext setupurl \
+setupuserdata setupuserdataalternative setupuserpagenumber setupversion setupviewerlayer \
+setupvspacing setupwhitespace setupwithargument setupwithargumentswapped setupxml \
+setupxtable setuvalue setuxvalue setvalue setvariable \
+setvariables setvboxregister setvisualizerfont setvtopregister setwidthof \
+setxmeasure setxvalue setxvariable setxvariables seveneighths \
+sfrac shapedhbox sharp shiftbox shiftdown \
shiftup showallmakeup showattributes showbodyfont showbodyfontenvironment \
showboxes showbtxdatasetauthors showbtxdatasetcompleteness showbtxdatasetfields showbtxfields \
showbtxhashedauthors showbtxtables showchardata showcharratio showcolor \
showcolorbar showcolorcomponents showcolorgroup showcolorset showcolorstruts \
showcounter showdirectives showdirsinmargin showedebuginfo showexperiments \
-showfont showfontdata showfontitalics showfontkerns showfontparameters \
-showfontstrip showfontstyle showframe showglyphs showgrid \
-showgridsnapping showhelp showhyphenationtrace showhyphens showinjector \
-showjustification showkerning showlayout showlayoutcomponents showligature \
-showligatures showlogcategories showmakeup showmargins showmessage \
-showminimalbaseline shownextbox showotfcomposition showpalet showparentchain \
-showprint showsetups showsetupsdefinition showstruts showsymbolset \
-showtimer showtokens showtrackers showvalue showvariable \
-showwarning sigma sim simeq simplealignedbox \
-simplealignedboxplus simplealignedspreadbox simplegroupedcommand simplereversealignedbox simplereversealignedboxplus \
-singalcharacteralign singlebond singleverticalbar sixperemspace sixthofsixarguments \
-slanted slantedbold slantedface slash slicepages \
-slong slovenianNumerals sloveniannumerals small smallbodyfont \
-smallbold smallbolditalic smallboldslanted smallcappedcharacters smallcappedromannumerals \
-smaller smallitalicbold smallnormal smallskip smallslanted \
-smallslantedbold smalltype smash smashbox smashboxed \
-smashedhbox smashedvbox smile snaptogrid softhyphen \
-solidus someheadnumber somekindoftab someline somelocalfloat \
-somenamedheadnumber someplace somewhere space spadesuit \
-spanishNumerals spanishnumerals speech sphericalangle splitatasterisk \
-splitatcolon splitatcolons splitatcomma splitatperiod splitdfrac \
-splitfilename splitfloat splitfrac splitoffbase splitofffull \
-splitoffkind splitoffname splitoffpath splitoffroot splitofftokens \
-splitofftype splitstring spreadhbox sqcap sqcup \
-sqrt sqsubset sqsubseteq sqsubsetneq sqsupset \
-sqsupseteq sqsupsetneq square squaredots ssharp \
-stackrel star stareq startJScode startJSpreamble \
-startLUA startMP startMPclip startMPcode startMPdefinitions \
-startMPdrawing startMPenvironment startMPextensions startMPinclusions startMPinitializations \
-startMPpage startMPpositiongraphic startMPpositionmethod startMPrun startPARSEDXML \
-startTABLE startTABLEbody startTABLEfoot startTABLEhead startTABLEnext \
-startTC startTD startTDs startTEX startTEXpage \
-startTH startTN startTR startTRs startTX \
-startTY startXML startalign startalignment startallmodes \
-startappendices startarrangedpages startaside startattachment startbackground \
-startbackmatter startbar startbbordermatrix startbitmapimage startblockquote \
-startbodymatter startbordermatrix startboxedcolumns startbtxlabeltext startbtxrenderingdefinitions \
-startbuffer startcases startcatcodetable startcenteraligned startchapter \
-startcharacteralign startcheckedfences startchemical startchemicaltext startcollect \
-startcollecting startcolor startcolorintent startcoloronly startcolorset \
-startcolumns startcolumnspan startcombination startcomment startcomponent \
-startcontextcode startcontextdefinitioncode startctxfunction startctxfunctiondefinition startcurrentcolor \
-startcurrentlistentrywrapper startdelimited startdelimitedtext startdisplaymath startdmath \
-startdocument starteffect startelement startembeddedxtable startendnote \
-startendofline startenvironment startexceptions startexpanded startexpandedcollect \
-startextendedcatcodetable startexternalfigurecollection startfact startfigure startfiguretext \
+showfont showfontdata showfontexpansion showfontitalics showfontkerns \
+showfontparameters showfontstrip showfontstyle showframe showglyphdata \
+showglyphs showgrid showgridsnapping showhelp showhyphenationtrace \
+showhyphens showinjector showjustification showkerning showlayout \
+showlayoutcomponents showligature showligatures showlogcategories showmakeup \
+showmargins showmessage showminimalbaseline shownextbox showotfcomposition \
+showpalet showparentchain showprint showsetups showsetupsdefinition \
+showstruts showsymbolset showtimer showtokens showtrackers \
+showvalue showvariable showwarning sigma signalrightpage \
+sim simeq simplealignedbox simplealignedboxplus simplealignedspreadbox \
+simplegroupedcommand simplereversealignedbox simplereversealignedboxplus singalcharacteralign singlebond \
+singleverticalbar sixperemspace sixthofsixarguments slanted slantedbold \
+slantedface slash slicepages slong slovenianNumerals \
+sloveniannumerals small smallbodyfont smallbold smallbolditalic \
+smallboldslanted smallcappedcharacters smallcappedromannumerals smaller smallitalicbold \
+smallnormal smallskip smallslanted smallslantedbold smalltype \
+smash smashbox smashboxed smashedhbox smashedvbox \
+smile snaptogrid softhyphen solidus someheadnumber \
+somekindoftab someline somelocalfloat somenamedheadnumber someplace \
+somewhere space spaceddigits spaceddigitsmethod spaceddigitsseparator \
+spaceddigitssymbol spadesuit spanishNumerals spanishnumerals speech \
+sphericalangle splitatasterisk splitatcolon splitatcolons splitatcomma \
+splitatperiod splitdfrac splitfilename splitfloat splitfrac \
+splitoffbase splitofffull splitoffkind splitoffname splitoffpath \
+splitoffroot splitofftokens splitofftype splitstring spreadhbox \
+sqcap sqcup sqrt sqsubset sqsubseteq \
+sqsubsetneq sqsupset sqsupseteq sqsupsetneq square \
+squaredots ssharp stackrel star stareq \
+startJScode startJSpreamble startLUA startMP startMPclip \
+startMPcode startMPdefinitions startMPdrawing startMPenvironment startMPextensions \
+startMPinclusions startMPinitializations startMPpage startMPpositiongraphic startMPpositionmethod \
+startMPrun startPARSEDXML startTABLE startTABLEbody startTABLEfoot \
+startTABLEhead startTABLEnext startTC startTD startTDs \
+startTEX startTEXpage startTH startTN startTR \
+startTRs startTX startTY startXML startalign \
+startalignment startallmodes startappendices startarrangedpages startaside \
+startattachment startbackground startbackmatter startbar startbbordermatrix \
+startbitmapimage startblockquote startbodymatter startbordermatrix startboxedcolumns \
+startbtxlabeltext startbtxrenderingdefinitions startbuffer startcases startcatcodetable \
+startcenteraligned startchapter startcharacteralign startcheckedfences startchemical \
+startchemicaltext startcollect startcollecting startcolor startcolorintent \
+startcoloronly startcolorset startcolumns startcolumnset startcolumnsetspan \
+startcolumnspan startcombination startcomment startcomponent startcontextcode \
+startcontextdefinitioncode startctxfunction startctxfunctiondefinition startcurrentcolor startcurrentlistentrywrapper \
+startdelimited startdelimitedtext startdisplaymath startdmath startdocument \
+starteffect startelement startembeddedxtable startendnote startendofline \
+startenvironment startexceptions startexpanded startexpandedcollect startextendedcatcodetable \
+startexternalfigurecollection startfacingfloat startfact startfigure startfiguretext \
startfittingpage startfixed startfloatcombination startfont startfontclass \
startfontsolution startfootnote startformula startformulas startframed \
startframedcell startframedcontent startframedrow startframedtable startframedtext \
@@ -971,114 +986,117 @@ starthbox starthboxestohbox starthboxregister starthead startheadtext \
starthelptext starthiding starthighlight starthyphenation startimath \
startindentation startindentedtext startinteraction startinteractionmenu startinterface \
startintermezzotext startintertext startitem startitemgroup startitemgroupcolumns \
-startitemize startknockout startlabeltext startlayout startleftaligned \
-startlegend startline startlinealignment startlinecorrection startlinefiller \
-startlinenote startlinenumbering startlines startlinetable startlinetablebody \
-startlinetablecell startlinetablehead startlocalfootnotes startlocalheadsetup startlocallinecorrection \
-startlocalnotes startlocalsetups startlua startluacode startluaparameterset \
-startluasetups startmakeup startmarginblock startmarginrule startmarkedcontent \
-startmathalignment startmathcases startmathlabeltext startmathmatrix startmathmode \
-startmathstyle startmatrices startmatrix startmaxaligned startmdformula \
-startmidaligned startmiddlealigned startmiddlemakeup startmixedcolumns startmode \
-startmodeset startmodule startmoduletestsection startmpformula startnamedsection \
-startnamedsubformulas startnarrow startnarrower startnegative startnicelyfilledbox \
-startnointerference startnotallmodes startnotext startnotmode startoperatortext \
-startopposite startoutputstream startoverlay startoverprint startpacked \
-startpagecomment startpagefigure startpagegrid startpagegridspan startpagelayout \
-startpagemakeup startpar startparagraph startparagraphs startparagraphscell \
-startparbuilder startpart startpath startplacechemical startplacefigure \
-startplacefloat startplaceformula startplacegraphic startplaceintermezzo startplacelegend \
-startplacepairedbox startplacetable startpositioning startpositionoverlay startpositive \
-startpostponing startprefixtext startprocessassignmentcommand startprocessassignmentlist startprocesscommacommand \
-startprocesscommalist startproduct startproject startprotect startprotectedcolors \
-startpublication startpunctuation startquotation startquote startrandomized \
-startrandomseed startrawsetups startreadingfile startreferenceprefix startregime \
-startregister startreusableMPgraphic startrightaligned startscript startsdformula \
-startsection startsectionblock startsectionblockenvironment startsectionlevel startsetups \
-startshapebox startshift startsidebar startsimplecolumns startspecialitem \
-startspeech startspformula startsplitformula startspread startstandardmakeup \
-startstartstop startstaticMPfigure startstaticMPgraphic startstrictinspectnextcharacter startstructurepageregister \
-startstrut startstyle startsubformulas startsubject startsubjectlevel \
-startsubsection startsubsentence startsubstack startsubsubject startsubsubsection \
-startsubsubsubject startsubsubsubsection startsubsubsubsubject startsubsubsubsubsection startsubsubsubsubsubject \
-startsuffixtext startsymbolset starttable starttablehead starttables \
-starttabletail starttabletext starttabulate starttabulatehead starttabulatetail \
-starttagged starttaglabeltext starttexcode starttexdefinition starttext \
-starttextbackground starttextbackgroundmanual starttextcolor starttextcolorintent starttextflow \
-starttextmakeup starttextrule starttitle starttokens starttransparent \
-starttypescript starttypescriptcollection starttyping startuniqueMPgraphic startuniqueMPpagegraphic \
-startunittext startunpacked startusableMPgraphic startuseMPgraphic startusemathstyleparameter \
+startitemize startknockout startlabeltext startlanguage startlayout \
+startleftaligned startlegend startline startlinealignment startlinecorrection \
+startlinefiller startlinenote startlinenumbering startlines startlinetable \
+startlinetablebody startlinetablecell startlinetablehead startlocalfootnotes startlocalheadsetup \
+startlocallinecorrection startlocalnotes startlocalsetups startlua startluacode \
+startluaparameterset startluasetups startmakeup startmarginblock startmarginrule \
+startmarkedcontent startmarkpages startmathalignment startmathcases startmathlabeltext \
+startmathmatrix startmathmode startmathstyle startmatrices startmatrix \
+startmaxaligned startmdformula startmidaligned startmiddlealigned startmiddlemakeup \
+startmixedcolumns startmode startmodeset startmodule startmoduletestsection \
+startmpformula startnamedsection startnamedsubformulas startnarrow startnarrower \
+startnegative startnicelyfilledbox startnointerference startnotallmodes startnotext \
+startnotmode startoperatortext startopposite startoutputstream startoverlay \
+startoverprint startpacked startpagecolumns startpagecomment startpagefigure \
+startpagelayout startpagemakeup startpar startparagraph startparagraphs \
+startparagraphscell startparbuilder startpart startpath startplacechemical \
+startplacefigure startplacefloat startplaceformula startplacegraphic startplaceintermezzo \
+startplacelegend startplacepairedbox startplacetable startpositioning startpositionoverlay \
+startpositive startpostponing startpostponingnotes startprefixtext startprocessassignmentcommand \
+startprocessassignmentlist startprocesscommacommand startprocesscommalist startproduct startproject \
+startprotect startprotectedcolors startpublication startpunctuation startquotation \
+startquote startrandomized startrandomseed startrawsetups startreadingfile \
+startreferenceprefix startregime startregister startreusableMPgraphic startrightaligned \
+startruby startscript startsdformula startsection startsectionblock \
+startsectionblockenvironment startsectionlevel startsetups startshapebox startshift \
+startsidebar startsimplecolumns startspecialitem startspeech startspformula \
+startsplitformula startsplittext startspread startstandardmakeup startstaticMPfigure \
+startstaticMPgraphic startstrictinspectnextcharacter startstructurepageregister startstrut startstyle \
+startsubformulas startsubject startsubjectlevel startsubsection startsubsentence \
+startsubstack startsubsubject startsubsubsection startsubsubsubject startsubsubsubsection \
+startsubsubsubsubject startsubsubsubsubsection startsubsubsubsubsubject startsuffixtext startsymbolset \
+starttable starttablehead starttables starttabletail starttabletext \
+starttabulate starttabulatehead starttabulatetail starttagged starttaglabeltext \
+starttexcode starttexdefinition starttext starttextbackground starttextbackgroundmanual \
+starttextcolor starttextcolorintent starttextflow starttextmakeup starttextrule \
+starttitle starttokenlist starttokens starttransparent starttypescript \
+starttypescriptcollection starttyping startuniqueMPgraphic startuniqueMPpagegraphic startunittext \
+startunpacked startusableMPgraphic startuseMPgraphic startusemathstyleparameter startuserdata \
startusingbtxspecification startvbox startvboxregister startvboxtohbox startvboxtohboxseparator \
startviewerlayer startvtop startvtopregister startxcell startxcellgroup \
-startxgroup startxmldisplayverbatim startxmlinlineverbatim startxmlraw startxmlsetups \
-startxrow startxrowgroup startxtable startxtablebody startxtablefoot \
-startxtablehead startxtablenext stligature stopJScode stopJSpreamble \
-stopLUA stopMP stopMPclip stopMPcode stopMPdefinitions \
-stopMPdrawing stopMPenvironment stopMPextensions stopMPinclusions stopMPinitializations \
-stopMPpage stopMPpositiongraphic stopMPpositionmethod stopMPrun stopPARSEDXML \
-stopTABLE stopTABLEbody stopTABLEfoot stopTABLEhead stopTABLEnext \
-stopTC stopTD stopTDs stopTEX stopTEXpage \
-stopTH stopTN stopTR stopTRs stopTX \
-stopTY stopXML stopalign stopalignment stopallmodes \
-stopappendices stoparrangedpages stopaside stopattachment stopbackground \
-stopbackmatter stopbar stopbbordermatrix stopbitmapimage stopblockquote \
-stopbodymatter stopbordermatrix stopboxedcolumns stopbtxlabeltext stopbtxrenderingdefinitions \
-stopbuffer stopcases stopcatcodetable stopcenteraligned stopchapter \
-stopcharacteralign stopcheckedfences stopchemical stopchemicaltext stopcollect \
-stopcollecting stopcolor stopcolorintent stopcoloronly stopcolorset \
-stopcolumns stopcolumnspan stopcombination stopcomment stopcomponent \
-stopcontextcode stopcontextdefinitioncode stopctxfunction stopctxfunctiondefinition stopcurrentcolor \
-stopcurrentlistentrywrapper stopdelimited stopdelimitedtext stopdisplaymath stopdmath \
-stopdocument stopeffect stopelement stopembeddedxtable stopendnote \
-stopendofline stopenvironment stopexceptions stopexpanded stopexpandedcollect \
-stopextendedcatcodetable stopexternalfigurecollection stopfact stopfigure stopfiguretext \
-stopfittingpage stopfixed stopfloatcombination stopfont stopfontclass \
-stopfontsolution stopfootnote stopformula stopformulas stopframed \
-stopframedcell stopframedcontent stopframedrow stopframedtable stopframedtext \
-stopfrontmatter stopgoto stopgraphictext stopgridsnapping stophanging \
-stophbox stophboxestohbox stophboxregister stophead stopheadtext \
-stophelptext stophiding stophighlight stophyphenation stopimath \
-stopindentation stopindentedtext stopinteraction stopinteractionmenu stopinterface \
-stopintermezzotext stopintertext stopitem stopitemgroup stopitemgroupcolumns \
-stopitemize stopknockout stoplabeltext stoplayout stopleftaligned \
+startxcolumn startxgroup startxmldisplayverbatim startxmlinlineverbatim startxmlraw \
+startxmlsetups startxrow startxrowgroup startxtable startxtablebody \
+startxtablefoot startxtablehead startxtablenext stligature stopJScode \
+stopJSpreamble stopLUA stopMP stopMPclip stopMPcode \
+stopMPdefinitions stopMPdrawing stopMPenvironment stopMPextensions stopMPinclusions \
+stopMPinitializations stopMPpage stopMPpositiongraphic stopMPpositionmethod stopMPrun \
+stopPARSEDXML stopTABLE stopTABLEbody stopTABLEfoot stopTABLEhead \
+stopTABLEnext stopTC stopTD stopTDs stopTEX \
+stopTEXpage stopTH stopTN stopTR stopTRs \
+stopTX stopTY stopXML stopalign stopalignment \
+stopallmodes stopappendices stoparrangedpages stopaside stopattachment \
+stopbackground stopbackmatter stopbar stopbbordermatrix stopbitmapimage \
+stopblockquote stopbodymatter stopbordermatrix stopboxedcolumns stopbtxlabeltext \
+stopbtxrenderingdefinitions stopbuffer stopcases stopcatcodetable stopcenteraligned \
+stopchapter stopcharacteralign stopcheckedfences stopchemical stopchemicaltext \
+stopcollect stopcollecting stopcolor stopcolorintent stopcoloronly \
+stopcolorset stopcolumns stopcolumnset stopcolumnsetspan stopcolumnspan \
+stopcombination stopcomment stopcomponent stopcontextcode stopcontextdefinitioncode \
+stopctxfunction stopctxfunctiondefinition stopcurrentcolor stopcurrentlistentrywrapper stopdelimited \
+stopdelimitedtext stopdisplaymath stopdmath stopdocument stopeffect \
+stopelement stopembeddedxtable stopendnote stopendofline stopenvironment \
+stopexceptions stopexpanded stopexpandedcollect stopextendedcatcodetable stopexternalfigurecollection \
+stopfacingfloat stopfact stopfigure stopfiguretext stopfittingpage \
+stopfixed stopfloatcombination stopfont stopfontclass stopfontsolution \
+stopfootnote stopformula stopformulas stopframed stopframedcell \
+stopframedcontent stopframedrow stopframedtable stopframedtext stopfrontmatter \
+stopgoto stopgraphictext stopgridsnapping stophanging stophbox \
+stophboxestohbox stophboxregister stophead stopheadtext stophelptext \
+stophiding stophighlight stophyphenation stopimath stopindentation \
+stopindentedtext stopinteraction stopinteractionmenu stopinterface stopintermezzotext \
+stopintertext stopitem stopitemgroup stopitemgroupcolumns stopitemize \
+stopknockout stoplabeltext stoplanguage stoplayout stopleftaligned \
stoplegend stopline stoplinealignment stoplinecorrection stoplinefiller \
stoplinenote stoplinenumbering stoplines stoplinetable stoplinetablebody \
stoplinetablecell stoplinetablehead stoplocalfootnotes stoplocalheadsetup stoplocallinecorrection \
stoplocalnotes stoplocalsetups stoplua stopluacode stopluaparameterset \
stopluasetups stopmakeup stopmarginblock stopmarginrule stopmarkedcontent \
-stopmathalignment stopmathcases stopmathlabeltext stopmathmatrix stopmathmode \
-stopmathstyle stopmatrices stopmatrix stopmaxaligned stopmdformula \
-stopmidaligned stopmiddlealigned stopmiddlemakeup stopmixedcolumns stopmode \
-stopmodeset stopmodule stopmoduletestsection stopmpformula stopnamedsection \
-stopnamedsubformulas stopnarrow stopnarrower stopnegative stopnicelyfilledbox \
-stopnointerference stopnotallmodes stopnotext stopnotmode stopoperatortext \
-stopopposite stopoutputstream stopoverlay stopoverprint stoppacked \
-stoppagecomment stoppagefigure stoppagegrid stoppagegridspan stoppagelayout \
+stopmarkpages stopmathalignment stopmathcases stopmathlabeltext stopmathmatrix \
+stopmathmode stopmathstyle stopmatrices stopmatrix stopmaxaligned \
+stopmdformula stopmidaligned stopmiddlealigned stopmiddlemakeup stopmixedcolumns \
+stopmode stopmodeset stopmodule stopmoduletestsection stopmpformula \
+stopnamedsection stopnamedsubformulas stopnarrow stopnarrower stopnegative \
+stopnicelyfilledbox stopnointerference stopnotallmodes stopnotext stopnotmode \
+stopoperatortext stopopposite stopoutputstream stopoverlay stopoverprint \
+stoppacked stoppagecolumns stoppagecomment stoppagefigure stoppagelayout \
stoppagemakeup stoppar stopparagraph stopparagraphs stopparagraphscell \
stopparbuilder stoppart stoppath stopplacechemical stopplacefigure \
stopplacefloat stopplaceformula stopplacegraphic stopplaceintermezzo stopplacelegend \
stopplacepairedbox stopplacetable stoppositioning stoppositionoverlay stoppositive \
-stoppostponing stopprefixtext stopprocessassignmentcommand stopprocessassignmentlist stopprocesscommacommand \
-stopprocesscommalist stopproduct stopproject stopprotect stopprotectedcolors \
-stoppublication stoppunctuation stopquotation stopquote stoprandomized \
-stoprandomseed stoprawsetups stopreadingfile stopreferenceprefix stopregime \
-stopregister stopreusableMPgraphic stoprightaligned stopscript stopsdformula \
-stopsection stopsectionblock stopsectionblockenvironment stopsectionlevel stopsetups \
-stopshapebox stopshift stopsidebar stopsimplecolumns stopspecialitem \
-stopspeech stopspformula stopsplitformula stopspread stopstandardmakeup \
-stopstartstop stopstaticMPfigure stopstaticMPgraphic stopstrictinspectnextcharacter stopstructurepageregister \
-stopstrut stopstyle stopsubformulas stopsubject stopsubjectlevel \
-stopsubsection stopsubsentence stopsubstack stopsubsubject stopsubsubsection \
-stopsubsubsubject stopsubsubsubsection stopsubsubsubsubject stopsubsubsubsubsection stopsubsubsubsubsubject \
-stopsuffixtext stopsymbolset stoptable stoptablehead stoptables \
-stoptabletail stoptabletext stoptabulate stoptabulatehead stoptabulatetail \
-stoptagged stoptaglabeltext stoptexcode stoptexdefinition stoptext \
-stoptextbackground stoptextbackgroundmanual stoptextcolor stoptextcolorintent stoptextflow \
-stoptextmakeup stoptextrule stoptitle stoptokens stoptransparent \
-stoptypescript stoptypescriptcollection stoptyping stopuniqueMPgraphic stopuniqueMPpagegraphic \
-stopunittext stopunpacked stopusableMPgraphic stopuseMPgraphic stopusemathstyleparameter \
-stopusingbtxspecification stopvbox stopvboxregister stopvboxtohbox stopvboxtohboxseparator \
-stopviewerlayer stopvtop stopvtopregister stopxcell stopxcellgroup \
+stoppostponing stoppostponingnotes stopprefixtext stopprocessassignmentcommand stopprocessassignmentlist \
+stopprocesscommacommand stopprocesscommalist stopproduct stopproject stopprotect \
+stopprotectedcolors stoppublication stoppunctuation stopquotation stopquote \
+stoprandomized stoprandomseed stoprawsetups stopreadingfile stopreferenceprefix \
+stopregime stopregister stopreusableMPgraphic stoprightaligned stopruby \
+stopscript stopsdformula stopsection stopsectionblock stopsectionblockenvironment \
+stopsectionlevel stopsetups stopshapebox stopshift stopsidebar \
+stopsimplecolumns stopspecialitem stopspeech stopspformula stopsplitformula \
+stopsplittext stopspread stopstandardmakeup stopstaticMPfigure stopstaticMPgraphic \
+stopstrictinspectnextcharacter stopstructurepageregister stopstrut stopstyle stopsubformulas \
+stopsubject stopsubjectlevel stopsubsection stopsubsentence stopsubstack \
+stopsubsubject stopsubsubsection stopsubsubsubject stopsubsubsubsection stopsubsubsubsubject \
+stopsubsubsubsubsection stopsubsubsubsubsubject stopsuffixtext stopsymbolset stoptable \
+stoptablehead stoptables stoptabletail stoptabletext stoptabulate \
+stoptabulatehead stoptabulatetail stoptagged stoptaglabeltext stoptexcode \
+stoptexdefinition stoptext stoptextbackground stoptextbackgroundmanual stoptextcolor \
+stoptextcolorintent stoptextflow stoptextmakeup stoptextrule stoptitle \
+stoptokenlist stoptokens stoptransparent stoptypescript stoptypescriptcollection \
+stoptyping stopuniqueMPgraphic stopuniqueMPpagegraphic stopunittext stopunpacked \
+stopusableMPgraphic stopuseMPgraphic stopusemathstyleparameter stopuserdata stopusingbtxspecification \
+stopvbox stopvboxregister stopvboxtohbox stopvboxtohboxseparator stopviewerlayer \
+stopvtop stopvtopregister stopxcell stopxcellgroup stopxcolumn \
stopxgroup stopxmldisplayverbatim stopxmlinlineverbatim stopxmlraw stopxmlsetups \
stopxrow stopxrowgroup stopxtable stopxtablebody stopxtablefoot \
stopxtablehead stopxtablenext stretched strictdoifelsenextoptional strictdoifnextoptionalelse \
@@ -1115,104 +1133,105 @@ textellipsis texteuro textflowcollector textfraction textgrave \
texthash texthorizontalbar texthungarumlaut texthyphen textkelvin \
textlognot textmacron textmath textmho textminus \
textmu textmultiply textnumero textogonek textohm \
-textormathchar textounce textpercent textperiod textplus \
-textpm textreference textring textrule textslash \
-textsterling texttilde textunderscore textvisiblespace textyen \
-thai thainumerals thefirstcharacter thenormalizedbodyfontsize therefore \
-theremainingcharacters theta thickspace thinrule thinrules \
-thinspace thirdoffivearguments thirdoffourarguments thirdofsixarguments thirdofthreearguments \
-thirdofthreeunexpanded thook thookleftarrow thookrightarrow thorn \
-threedigitrounding threeeighths threefifths threeperemspace threequarter \
-threesuperior tibetannumerals tightlayer tilde times \
-tinyfont title tlap tleftarrow tleftharpoondown \
-tleftharpoonup tleftrightarrow tleftrightharpoons tmapsto to \
-tochar tolinenote tooltip top topbox \
-topleftbox toplinebox toprightbox topskippedbox tracecatcodetables \
-tracedfontname traceoutputroutines tracepositions trademark translate \
-transparencycomponents transparent trel triangle triangledown \
-triangleleft triangleq triangleright trightarrow trightharpoondown \
-trightharpoonup trightleftharpoons trightoverleftarrow triplebond tripleprime \
-tripleverticalbar truefilename truefontname tstroke ttraggedright \
-ttriplerel ttwoheadleftarrow ttwoheadrightarrow turnediota twodigitrounding \
-twofifths twoheaddownarrow twoheadleftarrow twoheadrightarrow twoheadrightarrowtail \
-twoheaduparrow twosuperior twothirds tx txx \
-typ type typebuffer typedefinedbuffer typeface \
-typefile typeinlinebuffer typescriptone typescriptprefix typescriptthree \
-typescripttwo typesetbuffer typesetfile uacute ubreve \
-ucaron ucircumflex uconvertnumber udiaeresis udiaeresisacute \
-udiaeresiscaron udiaeresisgrave udiaeresismacron udotbelow udots \
-udoublegrave uedcatcodecommand ugrave uhook uhorn \
-uhornacute uhorndotbelow uhorngrave uhornhook uhorntilde \
-uhungarumlaut uinvertedbreve ulcorner umacron undefinevalue \
-undepthed underbar underbars underbrace underbracket \
-underdash underdashes underdot underdots underleftarrow \
-underparent underrandom underrandoms underrightarrow underset \
-understrike understrikes undoassign unexpandeddocumentvariable unframed \
-unhhbox unihex uniqueMPgraphic uniqueMPpagegraphic unit \
-unitlanguage unitshigh unitslow unittext unknown \
-unprotected unregisterhyphenationpattern unspaceafter unspaceargument unspaced \
-unspacestring untexargument untexcommand uogonek upand \
-uparrow updasharrow updownarrow updownarrowbar updownarrows \
-upharpoonleft upharpoonright uplus uppercased uppercasestring \
-upperleftdoubleninequote upperleftdoublesixquote upperleftsingleninequote upperleftsinglesixquote upperrightdoubleninequote \
-upperrightdoublesixquote upperrightsingleninequote upperrightsinglesixquote upsilon upuparrows \
-upwhitearrow urcorner uring url useJSscripts \
-useMPenvironmentbuffer useMPgraphic useMPlibrary useMPrun useMPvariables \
-useURL usealignparameter useblankparameter useblocks usebodyfont \
-usebodyfontparameter usebtxdataset usebtxdefinitions usecitation usecolors \
-usecomponent usedirectory usedummycolorparameter usedummystyleandcolor usedummystyleparameter \
-useenvironment useexternaldocument useexternalfigure useexternalrendering useexternalsoundtrack \
-usefigurebase usefile usegridparameter useindentingparameter useindentnextparameter \
-useinterlinespaceparameter uselanguageparameter useluamodule usemathstyleparameter usemodule \
-useproduct useprofileparameter useproject usereferenceparameter userpagenumber \
-usesetupsparameter usestaticMPfigure usesubpath usesymbols usetexmodule \
-usetypescript usetypescriptfile useurl usezipfile utfchar \
-utflower utfupper utilde utilityregisterlength vDash \
-varTheta varepsilon varkappa varnothing varphi \
-varpi varrho varsigma vartheta vboxreference \
-vdash vdots vec vee veebar \
-veeeq verbatim verbatimstring verbosenumber version \
-vert verticalgrowingbar verticalpositionbar veryraggedcenter veryraggedleft \
-veryraggedright vglue viewerlayer vl vphantom \
-vpos vsmash vsmashbox vsmashed vspace \
-vspacing wcircumflex wdofstring wedge wedgeeq \
-weekday whitearrowupfrombar widehat widetilde widthofstring \
-widthspanningtext withoutpt word wordright words \
-wordtonumber wp wr writebetweenlist writedatatolist \
-writestatus writetolist xLeftarrow xLeftrightarrow xRightarrow \
-xdefconvertedargument xequal xfrac xhookleftarrow xhookrightarrow \
-xi xleftarrow xleftharpoondown xleftharpoonup xleftrightarrow \
-xleftrightharpoons xmapsto xmladdindex xmlafterdocumentsetup xmlaftersetup \
-xmlall xmlappenddocumentsetup xmlappendsetup xmlapplyselectors xmlatt \
-xmlattdef xmlattribute xmlattributedef xmlbadinclusions xmlbeforedocumentsetup \
-xmlbeforesetup xmlchainatt xmlchainattdef xmlchecknamespace xmlcommand \
-xmlconcat xmlconcatrange xmlcontext xmlcount xmldefaulttotext \
-xmldirectives xmldirectivesafter xmldirectivesbefore xmldisplayverbatim xmldoif \
-xmldoifelse xmldoifelseempty xmldoifelseselfempty xmldoifelsetext xmldoifelsevalue \
-xmldoifnot xmldoifnotselfempty xmldoifnottext xmldoifselfempty xmldoiftext \
-xmlelement xmlfilter xmlfirst xmlflush xmlflushcontext \
-xmlflushdocumentsetups xmlflushlinewise xmlflushpure xmlflushspacewise xmlflushtext \
-xmlinclude xmlinclusion xmlinclusions xmlinfo xmlinjector \
-xmlinlineprettyprint xmlinlineprettyprinttext xmlinlineverbatim xmlinstalldirective xmllast \
-xmllastatt xmllastmatch xmllastpar xmlloadbuffer xmlloaddata \
-xmlloaddirectives xmlloadfile xmlloadonly xmlmain xmlmapvalue \
-xmlname xmlnamespace xmlnonspace xmlpar xmlparam \
-xmlpath xmlpos xmlposition xmlprependdocumentsetup xmlprependsetup \
-xmlprettyprint xmlprettyprinttext xmlprocessbuffer xmlprocessdata xmlprocessfile \
-xmlpure xmlraw xmlrefatt xmlregistereddocumentsetups xmlregisteredsetups \
-xmlregisterns xmlremapname xmlremapnamespace xmlremovedocumentsetup xmlremovesetup \
-xmlresetdocumentsetups xmlresetinjectors xmlresetsetups xmlsave xmlsetatt \
-xmlsetattribute xmlsetentity xmlsetfunction xmlsetinjectors xmlsetpar \
-xmlsetparam xmlsetsetup xmlsetup xmlshow xmlsnippet \
-xmlstrip xmlstripnolines xmlstripped xmlstrippednolines xmltag \
-xmltexentity xmltext xmltobuffer xmltobufferverbose xmltofile \
-xmlvalue xmlverbatim xrel xrightarrow xrightharpoondown \
-xrightharpoonup xrightleftharpoons xrightoverleftarrow xsplitstring xtriplerel \
-xtwoheadleftarrow xtwoheadrightarrow xxfrac xypos yacute \
-ycircumflex ydiaeresis ydotbelow yen ygrave \
-yhook ymacron ytilde zacute zcaron \
-zdotaccent zerowidthnobreakspace zerowidthspace zeta zhook \
-zstroke zwj zwnj
+textormathchar textormathchars textounce textpercent textperiod \
+textplus textpm textreference textring textrule \
+textslash textsterling texttilde textunderscore textvisiblespace \
+textyen thai thainumerals thefirstcharacter thenormalizedbodyfontsize \
+therefore theremainingcharacters theta thickspace thinrule \
+thinrules thinspace thirdoffivearguments thirdoffourarguments thirdofsixarguments \
+thirdofthreearguments thirdofthreeunexpanded thook thookleftarrow thookrightarrow \
+thorn threedigitrounding threeeighths threefifths threeperemspace \
+threequarter threesuperior tibetannumerals tightlayer tilde \
+times tinyfont title tlap tleftarrow \
+tleftharpoondown tleftharpoonup tleftrightarrow tleftrightharpoons tmapsto \
+to tochar tolinenote tooltip top \
+topbox topleftbox toplinebox toprightbox topskippedbox \
+tracecatcodetables tracedfontname traceoutputroutines tracepositions trademark \
+translate transparencycomponents transparent trel triangle \
+triangledown triangleleft triangleq triangleright trightarrow \
+trightharpoondown trightharpoonup trightleftharpoons trightoverleftarrow triplebond \
+tripleprime tripleverticalbar truefilename truefontname tstroke \
+ttraggedright ttriplerel ttwoheadleftarrow ttwoheadrightarrow turnediota \
+twodigitrounding twofifths twoheaddownarrow twoheadleftarrow twoheadrightarrow \
+twoheadrightarrowtail twoheaduparrow twosuperior twothirds tx \
+txx typ type typebuffer typedefinedbuffer \
+typeface typefile typeinlinebuffer typescriptone typescriptprefix \
+typescriptthree typescripttwo typesetbuffer typesetfile uacute \
+ubreve ucaron ucircumflex uconvertnumber udiaeresis \
+udiaeresisacute udiaeresiscaron udiaeresisgrave udiaeresismacron udotbelow \
+udots udoublegrave uedcatcodecommand ugrave uhook \
+uhorn uhornacute uhorndotbelow uhorngrave uhornhook \
+uhorntilde uhungarumlaut uinvertedbreve ulcorner umacron \
+undefinevalue undepthed underbar underbars underbrace \
+underbracket underdash underdashes underdot underdots \
+underleftarrow underparent underrandom underrandoms underrightarrow \
+underset understrike understrikes undoassign unexpandeddocumentvariable \
+unframed unhhbox unihex uniqueMPgraphic uniqueMPpagegraphic \
+unit unitlanguage unitshigh unitslow unittext \
+unknown unprotected unregisterhyphenationpattern unspaceafter unspaceargument \
+unspaced unspacestring untexargument untexcommand uogonek \
+upand uparrow updasharrow updownarrow updownarrowbar \
+updownarrows upharpoonleft upharpoonright uplus uppercased \
+uppercasestring upperleftdoubleninequote upperleftdoublesixquote upperleftsingleninequote upperleftsinglesixquote \
+upperrightdoubleninequote upperrightdoublesixquote upperrightsingleninequote upperrightsinglesixquote upsilon \
+upuparrows upwhitearrow urcorner uring url \
+useJSscripts useMPenvironmentbuffer useMPgraphic useMPlibrary useMPrun \
+useMPvariables useURL usealignparameter useblankparameter useblocks \
+usebodyfont usebodyfontparameter usebtxdataset usebtxdefinitions usecitation \
+usecolors usecomponent usedirectory usedummycolorparameter usedummystyleandcolor \
+usedummystyleparameter useenvironment useexternaldocument useexternalfigure useexternalrendering \
+useexternalsoundtrack usefigurebase usefile usegridparameter useindentingparameter \
+useindentnextparameter useinterlinespaceparameter uselanguageparameter useluamodule usemathstyleparameter \
+usemodule useproduct useprofileparameter useproject usereferenceparameter \
+userpagenumber usesetupsparameter usestaticMPfigure usesubpath usesymbols \
+usetexmodule usetypescript usetypescriptfile useurl usezipfile \
+utfchar utflower utfupper utilde utilityregisterlength \
+vDash varTheta varepsilon varkappa varnothing \
+varphi varpi varrho varsigma vartheta \
+vboxreference vdash vdots vec vee \
+veebar veeeq verbatim verbatimstring verbosenumber \
+version vert verticalgrowingbar verticalpositionbar veryraggedcenter \
+veryraggedleft veryraggedright vglue viewerlayer vl \
+vphantom vpos vsmash vsmashbox vsmashed \
+vspace vspacing wcircumflex wdofstring wedge \
+wedgeeq weekday whitearrowupfrombar widehat widetilde \
+widthofstring widthspanningtext withoutpt word wordright \
+words wordtonumber wp wr writebetweenlist \
+writedatatolist writestatus writetolist xLeftarrow xLeftrightarrow \
+xRightarrow xdefconvertedargument xequal xfrac xhookleftarrow \
+xhookrightarrow xi xleftarrow xleftharpoondown xleftharpoonup \
+xleftrightarrow xleftrightharpoons xmapsto xmladdindex xmlafterdocumentsetup \
+xmlaftersetup xmlall xmlappenddocumentsetup xmlappendsetup xmlapplyselectors \
+xmlatt xmlattdef xmlattribute xmlattributedef xmlbadinclusions \
+xmlbeforedocumentsetup xmlbeforesetup xmlchainatt xmlchainattdef xmlchecknamespace \
+xmlcommand xmlconcat xmlconcatrange xmlcontext xmlcount \
+xmldefaulttotext xmldirectives xmldirectivesafter xmldirectivesbefore xmldisplayverbatim \
+xmldoif xmldoifatt xmldoifelse xmldoifelseatt xmldoifelseempty \
+xmldoifelseselfempty xmldoifelsetext xmldoifelsevalue xmldoifnot xmldoifnotatt \
+xmldoifnotselfempty xmldoifnottext xmldoifselfempty xmldoiftext xmlelement \
+xmlfilter xmlfirst xmlflush xmlflushcontext xmlflushdocumentsetups \
+xmlflushlinewise xmlflushpure xmlflushspacewise xmlflushtext xmlinclude \
+xmlinclusion xmlinclusions xmlinfo xmlinjector xmlinlineprettyprint \
+xmlinlineprettyprinttext xmlinlineverbatim xmlinstalldirective xmllast xmllastatt \
+xmllastmatch xmllastpar xmlloadbuffer xmlloaddata xmlloaddirectives \
+xmlloadfile xmlloadonly xmlmain xmlmapvalue xmlname \
+xmlnamespace xmlnonspace xmlpar xmlparam xmlpath \
+xmlpos xmlposition xmlprependdocumentsetup xmlprependsetup xmlprettyprint \
+xmlprettyprinttext xmlprocessbuffer xmlprocessdata xmlprocessfile xmlpure \
+xmlraw xmlrefatt xmlregistereddocumentsetups xmlregisteredsetups xmlregisterns \
+xmlremapname xmlremapnamespace xmlremovedocumentsetup xmlremovesetup xmlresetdocumentsetups \
+xmlresetinjectors xmlresetsetups xmlsave xmlsetatt xmlsetattribute \
+xmlsetentity xmlsetfunction xmlsetinjectors xmlsetpar xmlsetparam \
+xmlsetsetup xmlsetup xmlshow xmlsnippet xmlstrip \
+xmlstripnolines xmlstripped xmlstrippednolines xmltag xmltexentity \
+xmltext xmltobuffer xmltobufferverbose xmltofile xmlvalue \
+xmlverbatim xrel xrightarrow xrightharpoondown xrightharpoonup \
+xrightleftharpoons xrightoverleftarrow xsplitstring xtriplerel xtwoheadleftarrow \
+xtwoheadrightarrow xxfrac xypos yacute ycircumflex \
+ydiaeresis ydotbelow yen ygrave yhook \
+ymacron ytilde zacute zcaron zdotaccent \
+zerowidthnobreakspace zerowidthspace zeta zhook zstroke \
+zwj zwnj
keywordclass.context.cs=\
Cisla Kap MESIC Rimskecislice \
@@ -1262,29 +1281,30 @@ pref prelozit prepninazakladnifont preskoc prizpusobivepole \
prizpusobvzhled produkt projekt prostredi resetznaceni \
rimskecislice rozdelplvouciobjekt roztazene schovejbloky sedabarva \
sloupec slovovpravo stanovcharakteristickuseznamu stanovcislonadpisu startbarva \
-startinteraktivnimenu startjdina startkomponenta startmarginalnilinka startnadpis \
-startoramovani startpolozka startpozadi startprodukt startprojekt \
-startprostredi startpublikace startradek starttextovalinka startumistirovnici \
-startzarovnanonastred startzarovnanovlevo startzarovnanovpravo startzhustene stopbarva \
-stopinteraktivnimenu stopjdina stopkomponenta stopmarginalnilinka stopnadpis \
-stoporamovani stoppolozka stoppozadi stopprodukt stopprojekt \
-stopprostredi stoppublikace stopradek stoptextovalinka stopumistirovnici \
-stopzarovnanonastred stopzarovnanovlevo stopzarovnanovpravo stopzhustene strana \
-tecky tenkalinka tenkelinky textovalinka tlacitko \
-tlacitkomenu tloustkacary tref tvrdamezera tvrdemezery \
-ukazbarvu ukazmrizku ukaznastaveni ukazpaletu ukazpodpery \
-ukazpostredizakladnihofontu ukazramecek ukazsadusymbolu ukazskupinubarev ukazupravu \
-ukazvytisk ukazvzhled ukazzakladnifont umistikombinovanyseznam umistilokalnipoznamkypodcarou \
-umistinadsebe umistinamrizku umistipodrovnici umistipoznamkypodcarou umistirejstrik \
-umistirovnici umistiseznam umistivedlesebe umistizalozky urcicharakteristikurejstriku \
-uzijJSscripts uzijURL uzijadresar uzijbloky uzijexternidokument \
-uzijexterniobraz uzijexternizvuk uzijmodul uzijsymbol uzijurl \
-verze vlasovalinka vradku vsedniden vyberbloky \
-vyplnenytext vyplnovelinky vyplnovyradek vysoky zachovejbloky \
-zadnamezera zadnehorniadolniradky zadnezahlaviaupati zalozka zapisdoseznamu \
-zapismeziseznam zaramovani zarovnanonastred zarovnanovlevo zarovnanovpravo \
-zasobnikpoli ziskejbuffer ziskejznaceni znaceni znak \
-znaky zpracujbloky zrcadlit zref
+startinteraktivnimenu startjazyk startjdina startkomponenta startmarginalnilinka \
+startnadpis startoramovani startpolozka startpozadi startprodukt \
+startprojekt startprostredi startpublikace startradek starttextovalinka \
+startumistirovnici startzarovnanonastred startzarovnanovlevo startzarovnanovpravo startzhustene \
+stopbarva stopinteraktivnimenu stopjazyk stopjdina stopkomponenta \
+stopmarginalnilinka stopnadpis stoporamovani stoppolozka stoppozadi \
+stopprodukt stopprojekt stopprostredi stoppublikace stopradek \
+stoptextovalinka stopumistirovnici stopzarovnanonastred stopzarovnanovlevo stopzarovnanovpravo \
+stopzhustene strana tecky tenkalinka tenkelinky \
+textovalinka tlacitko tlacitkomenu tloustkacary tref \
+tvrdamezera tvrdemezery ukazbarvu ukazmrizku ukaznastaveni \
+ukazpaletu ukazpodpery ukazpostredizakladnihofontu ukazramecek ukazsadusymbolu \
+ukazskupinubarev ukazupravu ukazvytisk ukazvzhled ukazzakladnifont \
+umistikombinovanyseznam umistilokalnipoznamkypodcarou umistinadsebe umistinamrizku umistipodrovnici \
+umistipoznamkypodcarou umistirejstrik umistirovnici umistiseznam umistivedlesebe \
+umistizalozky urcicharakteristikurejstriku uzijJSscripts uzijURL uzijadresar \
+uzijbloky uzijexternidokument uzijexterniobraz uzijexternizvuk uzijmodul \
+uzijsymbol uzijurl verze vlasovalinka vradku \
+vsedniden vyberbloky vyplnenytext vyplnovelinky vyplnovyradek \
+vysoky zachovejbloky zadnamezera zadnehorniadolniradky zadnezahlaviaupati \
+zalozka zapisdoseznamu zapismeziseznam zaramovani zarovnanonastred \
+zarovnanovlevo zarovnanovpravo zasobnikpoli ziskejbuffer ziskejznaceni \
+znaceni znak znaky zpracujbloky zrcadlit \
+zref
keywordclass.context.de=\
Buchstabe Buchstaben Kap MONAT \
@@ -1323,40 +1343,40 @@ seite seitenreferenz seitenummer settext spalte \
spatium spiegeln sprache startfarbe starthintergrund \
startinteraktionsmenue startkleinerdurchschuss startkomponente startkopf startlinksbuendig \
startmarginallinie startplatziereformel startpos startprodukt startprojekt \
-startpublikation startrechtsbuendig starttextlinie startumgebung startumrahmt \
-startzeile startzentriert startzu stelleabsaetzeein stelleabsatznummerierungein \
-stelleabschnittsblockein stelleanordnenein stelleaufzaehlungenein stelleausrichtungein stelleausschnittein \
-stellebeschreibungein stellebeschriftungein stellebilderunterschriftein stellebildunterschriftein stellebindestrichein \
-stelleblankoein stelleblockein stelledrehenein stelleduennerumrissein stelleeinziehenein \
-stelleengerein stellefarbeein stellefarbenein stellefeldein stellefelderin \
-stellefliesstextein stelleformelnein stellefusszeileein stellefusszeilentextein stellegefuelltesrechteckein \
-stellegefuelltezeileein stellegegenueberplatzierenein stellegleitobjekteein stellegleitobjektein stellehintergruendeein \
-stellehintergrundein stelleinteraktionein stelleinteraktionsbalkenein stelleinteraktionsbildschirmein stelleinteraktionsmenueein \
-stellekommentarein stellekopfzahlein stellekopfzeileein stellekopfzeilentextein stellelayoutein \
-stellelinienbreiteein stellelisteein stellemarginallinieein stellenobenein stellepaletteein \
-stellepapierformatein stelleplatziegeteiltegleitobjekt stellepositionierenein stellepostenein stelleprogrammein \
-stellepufferein stellerechteckein stellereferenzierenein stelleregisterein stelleseitenkommentarein \
-stelleseitennummerein stelleseitennummeriernungein stelleseitenuebergangein stellesortierenein stellespaltenein \
-stellespatiumein stellespracheein stellesymbolsetein stellesynonymein stelletabellenein \
-stelletabulatorein stelletextein stelletextobenein stelletexttexteein stelletextumrissein \
-stelletextuntenein stelletipein stelletippenein stelletoleranzein stelleueberschriftein \
-stelleueberschriftenein stelleumbruchein stelleumrahmtein stelleumrahmtetexteein stelleuntenein \
-stelleunterseitennummerein stelleurlein stelleversalienein stellezeilenabstandein stellezeilenein \
-stellezeilennumerierungein stellezitierenein stellezusammengestelltelisteein stellezwischenraumein stopfarbe \
-stophintergrund stopinteraktionsmenue stopkleinerdurchschuss stopkomponente stopkopf \
-stoplinksbuendig stopmarginallinie stopplatziereformel stoppos stopprodukt \
-stopprojekt stoppublikation stoprechtsbuendig stoptextlinie stopumgebung \
-stopumrahmt stopzeile stopzentriert stopzu teilegleitobjekt \
-textlinie textreferenz tief tiho tip \
-tippedatei tippen tippepuffer ueber uebersetzten \
-umgebung umrahmt unbekant verbergebloecke vergleichefarbengruppe \
-vergleichepalette verwendeJSscript verwendeURL verwendebloecke verwendeexteresdokument \
-verwendeexterneabbildung verwendeexternestonstueck verwendemodul verwendesymbole verwendeurl \
-volleswort von waehlebloeckeaus wechselezumfliesstext wochentag \
-wortrechts zeigedruck zeigeeinstellungen zeigefarbe zeigefarbengruppe \
-zeigefliesstext zeigefliesstextumgebung zeigegitter zeigelayout zeigepalette \
-zeigerahmen zeigestruts zeigeumbruch zentriert ziffern \
-zu zurbox zurseite
+startpublikation startrechtsbuendig startsprache starttextlinie startumgebung \
+startumrahmt startzeile startzentriert startzu stelleabsaetzeein \
+stelleabsatznummerierungein stelleabschnittsblockein stelleanordnenein stelleaufzaehlungenein stelleausrichtungein \
+stelleausschnittein stellebeschreibungein stellebeschriftungein stellebilderunterschriftein stellebildunterschriftein \
+stellebindestrichein stelleblankoein stelleblockein stelledrehenein stelleduennerumrissein \
+stelleeinziehenein stelleengerein stellefarbeein stellefarbenein stellefeldein \
+stellefelderin stellefliesstextein stelleformelnein stellefusszeileein stellefusszeilentextein \
+stellegefuelltesrechteckein stellegefuelltezeileein stellegegenueberplatzierenein stellegleitobjekteein stellegleitobjektein \
+stellehintergruendeein stellehintergrundein stelleinteraktionein stelleinteraktionsbalkenein stelleinteraktionsbildschirmein \
+stelleinteraktionsmenueein stellekommentarein stellekopfzahlein stellekopfzeileein stellekopfzeilentextein \
+stellelayoutein stellelinienbreiteein stellelisteein stellemarginallinieein stellenobenein \
+stellepaletteein stellepapierformatein stelleplatziegeteiltegleitobjekt stellepositionierenein stellepostenein \
+stelleprogrammein stellepufferein stellerechteckein stellereferenzierenein stelleregisterein \
+stelleseitenkommentarein stelleseitennummerein stelleseitennummeriernungein stelleseitenuebergangein stellesortierenein \
+stellespaltenein stellespatiumein stellespracheein stellesymbolsetein stellesynonymein \
+stelletabellenein stelletabulatorein stelletextein stelletextobenein stelletexttexteein \
+stelletextumrissein stelletextuntenein stelletipein stelletippenein stelletoleranzein \
+stelleueberschriftein stelleueberschriftenein stelleumbruchein stelleumrahmtein stelleumrahmtetexteein \
+stelleuntenein stelleunterseitennummerein stelleurlein stelleversalienein stellezeilenabstandein \
+stellezeilenein stellezeilennumerierungein stellezitierenein stellezusammengestelltelisteein stellezwischenraumein \
+stopfarbe stophintergrund stopinteraktionsmenue stopkleinerdurchschuss stopkomponente \
+stopkopf stoplinksbuendig stopmarginallinie stopplatziereformel stoppos \
+stopprodukt stopprojekt stoppublikation stoprechtsbuendig stopsprache \
+stoptextlinie stopumgebung stopumrahmt stopzeile stopzentriert \
+stopzu teilegleitobjekt textlinie textreferenz tief \
+tiho tip tippedatei tippen tippepuffer \
+ueber uebersetzten umgebung umrahmt unbekant \
+verbergebloecke vergleichefarbengruppe vergleichepalette verwendeJSscript verwendeURL \
+verwendebloecke verwendeexteresdokument verwendeexterneabbildung verwendeexternestonstueck verwendemodul \
+verwendesymbole verwendeurl volleswort von waehlebloeckeaus \
+wechselezumfliesstext wochentag wortrechts zeigedruck zeigeeinstellungen \
+zeigefarbe zeigefarbengruppe zeigefliesstext zeigefliesstextumgebung zeigegitter \
+zeigelayout zeigepalette zeigerahmen zeigestruts zeigeumbruch \
+zentriert ziffern zu zurbox zurseite
keywordclass.context.en=\
@@ -1376,79 +1396,81 @@ de definicaractere definit definitaccent definitbloc \
definitblocsection definitbuffer definitcalque definitchamp definitcommande \
definitconversion definitcouleur definitdactylo definitdemarrestoppe definitdescription \
definitdisposition definitenumeration definitenvironnementpolicecorps definitetiquette definitflottant \
-definitformatreference definitgroupecouleur definithbox definitliste definitlisteimbriquee \
-definitmakeup definitmarquage definitmenuinteraction definitpalette definitparagraphes \
-definitpilechamp definitpolice definitpolicecorps definitprofil definitprogramme \
-definitreference definitregistre definitrevetement definitsautdecolonne definitsautdepage \
-definitsection definitsouschamp definitstyle definitstylepolice definitsymbole \
-definitsymbolefigure definitsynonymepolice definitsynonymes definittabulation definittaillepapier \
-definittete definittexte definittrametableau definittri definittype \
-definitvide demarreJScode demarreJSpreamble demarreLUA demarreMP \
-demarreMPclip demarreMPcode demarreMPdefinitions demarreMPdrawing demarreMPenvironment \
-demarreMPextensions demarreMPinclusions demarreMPinitializations demarreMPpage demarreMPpositiongraphic \
-demarreMPpositionmethod demarreMPrun demarrePARSEDXML demarreTABLE demarreTABLEbody \
-demarreTABLEfoot demarreTABLEhead demarreTABLEnext demarreTC demarreTD \
-demarreTDs demarreTEX demarreTEXpage demarreTH demarreTN \
-demarreTR demarreTRs demarreTX demarreTY demarreXML \
-demarrealign demarrealigneadroite demarrealigneagauche demarrealigneaumilieu demarrealignment \
-demarreallmodes demarreappendices demarrearrangedpages demarrearriereplan demarreaside \
-demarreattachment demarrebackmatter demarrebar demarrebbordermatrix demarrebitmapimage \
-demarreblockquote demarrebodymatter demarrebordermatrix demarreboxedcolumns demarrebtxlabeltext \
-demarrebtxrenderingdefinitions demarrebuffer demarrecases demarrecatcodetable demarrecenteraligned \
-demarrechapter demarrecharacteralign demarrecheckedfences demarrechemical demarrechemicaltext \
-demarreciter demarrecollect demarrecollecting demarrecolorintent demarrecoloronly \
-demarrecolorset demarrecolumns demarrecolumnspan demarrecombination demarrecomment \
-demarrecomposant demarrecontextcode demarrecontextdefinitioncode demarrecouleur demarrectxfunction \
-demarrectxfunctiondefinition demarrecurrentcolor demarrecurrentlistentrywrapper demarredelimited demarredelimitedtext \
-demarredisplaymath demarredmath demarredocument demarreeffect demarreelement \
-demarreembeddedxtable demarreendnote demarreendofline demarreenvironement demarreexceptions \
-demarreexpanded demarreexpandedcollect demarreextendedcatcodetable demarreexternalfigurecollection demarrefact \
-demarrefigure demarrefiguretext demarrefittingpage demarrefixed demarrefloatcombination \
-demarrefont demarrefontclass demarrefontsolution demarrefootnote demarreformula \
-demarreformulas demarreframed demarreframedcell demarreframedcontent demarreframedrow \
-demarreframedtable demarreframedtext demarrefrontmatter demarregraphictext demarregridsnapping \
-demarregroupe demarrehanging demarrehbox demarrehboxestohbox demarrehboxregister \
-demarreheadtext demarrehelptext demarrehiding demarrehighlight demarrehyphenation \
-demarreimath demarreindentation demarreindentedtext demarreinteraction demarreinterface \
-demarreintermezzotext demarreintertext demarreitemgroup demarreitemgroupcolumns demarreitemize \
-demarreknockout demarrelabeltext demarrelayout demarrelegend demarreligne \
+definitformatreference definitgroupecouleur definithbox definitjeucolonne definitliste \
+definitlisteimbriquee definitmakeup definitmarquage definitmenuinteraction definitpalette \
+definitparagraphes definitpilechamp definitpolice definitpolicecorps definitprofil \
+definitprogramme definitreference definitregistre definitrevetement definitsautdecolonne \
+definitsautdepage definitsection definitsouschamp definitstyle definitstylepolice \
+definitsymbole definitsymbolefigure definitsynonymepolice definitsynonymes definittabulation \
+definittaillepapier definittete definittexte definittrametableau definittri \
+definittype definitvide demarreJScode demarreJSpreamble demarreLUA \
+demarreMP demarreMPclip demarreMPcode demarreMPdefinitions demarreMPdrawing \
+demarreMPenvironment demarreMPextensions demarreMPinclusions demarreMPinitializations demarreMPpage \
+demarreMPpositiongraphic demarreMPpositionmethod demarreMPrun demarrePARSEDXML demarreTABLE \
+demarreTABLEbody demarreTABLEfoot demarreTABLEhead demarreTABLEnext demarreTC \
+demarreTD demarreTDs demarreTEX demarreTEXpage demarreTH \
+demarreTN demarreTR demarreTRs demarreTX demarreTY \
+demarreXML demarrealign demarrealigneadroite demarrealigneagauche demarrealigneaumilieu \
+demarrealignment demarreallmodes demarreappendices demarrearrangedpages demarrearriereplan \
+demarreaside demarreattachment demarrebackmatter demarrebar demarrebbordermatrix \
+demarrebitmapimage demarreblockquote demarrebodymatter demarrebordermatrix demarreboxedcolumns \
+demarrebtxlabeltext demarrebtxrenderingdefinitions demarrebuffer demarrecases demarrecatcodetable \
+demarrecenteraligned demarrechapter demarrecharacteralign demarrecheckedfences demarrechemical \
+demarrechemicaltext demarreciter demarrecollect demarrecollecting demarrecolorintent \
+demarrecoloronly demarrecolorset demarrecolumns demarrecolumnset demarrecolumnsetspan \
+demarrecolumnspan demarrecombination demarrecomment demarrecomposant demarrecontextcode \
+demarrecontextdefinitioncode demarrecouleur demarrectxfunction demarrectxfunctiondefinition demarrecurrentcolor \
+demarrecurrentlistentrywrapper demarredelimited demarredelimitedtext demarredisplaymath demarredmath \
+demarredocument demarreeffect demarreelement demarreembeddedxtable demarreendnote \
+demarreendofline demarreenvironement demarreexceptions demarreexpanded demarreexpandedcollect \
+demarreextendedcatcodetable demarreexternalfigurecollection demarrefacingfloat demarrefact demarrefigure \
+demarrefiguretext demarrefittingpage demarrefixed demarrefloatcombination demarrefont \
+demarrefontclass demarrefontsolution demarrefootnote demarreformula demarreformulas \
+demarreframed demarreframedcell demarreframedcontent demarreframedrow demarreframedtable \
+demarreframedtext demarrefrontmatter demarregraphictext demarregridsnapping demarregroupe \
+demarrehanging demarrehbox demarrehboxestohbox demarrehboxregister demarreheadtext \
+demarrehelptext demarrehiding demarrehighlight demarrehyphenation demarreimath \
+demarreindentation demarreindentedtext demarreinteraction demarreinterface demarreintermezzotext \
+demarreintertext demarreitemgroup demarreitemgroupcolumns demarreitemize demarreknockout \
+demarrelabeltext demarrelangue demarrelayout demarrelegend demarreligne \
demarreligneregleetexte demarrelinealignment demarrelinecorrection demarrelinefiller demarrelinenumbering \
demarrelines demarrelinetable demarrelinetablebody demarrelinetablecell demarrelinetablehead \
demarrelocalfootnotes demarrelocalheadsetup demarrelocallinecorrection demarrelocalnotes demarrelocalsetups \
demarrelua demarreluacode demarreluaparameterset demarreluasetups demarremakeup \
-demarremargereglee demarremarginblock demarremarkedcontent demarremathalignment demarremathcases \
-demarremathlabeltext demarremathmatrix demarremathmode demarremathstyle demarrematrices \
-demarrematrix demarremaxaligned demarremdformula demarremenuinteraction demarremiddlealigned \
-demarremiddlemakeup demarremixedcolumns demarremode demarremodeset demarremodule \
-demarremoduletestsection demarrempformula demarrenamedsection demarrenamedsubformulas demarrenarrow \
-demarrenarrower demarrenegative demarrenicelyfilledbox demarrenointerference demarrenotallmodes \
-demarrenotext demarrenotmode demarreoperatortext demarreopposite demarreoutputstream \
-demarreoverlay demarreoverprint demarrepagecomment demarrepagefigure demarrepagegrid \
-demarrepagegridspan demarrepagelayout demarrepagemakeup demarrepar demarreparagraph \
+demarremargereglee demarremarginblock demarremarkedcontent demarremarkpages demarremathalignment \
+demarremathcases demarremathlabeltext demarremathmatrix demarremathmode demarremathstyle \
+demarrematrices demarrematrix demarremaxaligned demarremdformula demarremenuinteraction \
+demarremiddlealigned demarremiddlemakeup demarremixedcolumns demarremode demarremodeset \
+demarremodule demarremoduletestsection demarrempformula demarrenamedsection demarrenamedsubformulas \
+demarrenarrow demarrenarrower demarrenegative demarrenicelyfilledbox demarrenointerference \
+demarrenotallmodes demarrenotext demarrenotmode demarreoperatortext demarreopposite \
+demarreoutputstream demarreoverlay demarreoverprint demarrepagecolumns demarrepagecomment \
+demarrepagefigure demarrepagelayout demarrepagemakeup demarrepar demarreparagraph \
demarreparagraphs demarreparagraphscell demarreparbuilder demarrepart demarrepath \
demarreplacechemical demarreplacefigure demarreplaceflottant demarreplaceformule demarreplacegraphic \
demarreplaceintermezzo demarreplacelegend demarreplacepairedbox demarreplacetable demarrepositioning \
-demarrepositionoverlay demarrepositive demarrepostponing demarreprefixtext demarreprocessassignmentcommand \
-demarreprocessassignmentlist demarreprocesscommacommand demarreprocesscommalist demarreproduit demarreprojet \
-demarreprotect demarreprotectedcolors demarrepublication demarrepunctuation demarrequotation \
-demarrequote demarrerandomized demarrerandomseed demarrerawsetups demarrereadingfile \
-demarrereferenceprefix demarreregime demarrereusableMPgraphic demarrescript demarresdformula \
-demarresection demarresectionblock demarresectionblockenvironment demarresectionlevel demarresetups \
-demarreshapebox demarreshift demarresidebar demarresimplecolumns demarrespecialitem \
-demarrespeech demarrespformula demarresplitformula demarrespread demarrestandardmakeup \
-demarrestartstop demarrestaticMPfigure demarrestaticMPgraphic demarrestrictinspectnextcharacter demarrestrut \
-demarrestyle demarresubformulas demarresubject demarresubjectlevel demarresubsection \
-demarresubsentence demarresubstack demarresubsubject demarresubsubsection demarresubsubsubject \
-demarresubsubsubsection demarresubsubsubsubject demarresubsubsubsubsection demarresubsubsubsubsubject demarresuffixtext \
-demarresymbolset demarretable demarretablehead demarretables demarretabletail \
-demarretabletext demarretabulate demarretabulatehead demarretabulatetail demarretagged \
-demarretaglabeltext demarretete demarretexcode demarretexdefinition demarretext \
-demarretextbackground demarretextbackgroundmanual demarretextcolor demarretextcolorintent demarretextflow \
-demarretextmakeup demarretitle demarretokens demarretransparent demarretypescript \
-demarretypescriptcollection demarretyping demarreuniqueMPgraphic demarreuniqueMPpagegraphic demarreunittext \
-demarreunpacked demarreusableMPgraphic demarreuseMPgraphic demarreusemathstyleparameter demarreusingbtxspecification \
-demarreva demarrevbox demarrevboxregister demarrevboxtohbox demarrevboxtohboxseparator \
-demarreviewerlayer demarrevtop demarrevtopregister demarrexcell demarrexcellgroup \
+demarrepositionoverlay demarrepositive demarrepostponing demarrepostponingnotes demarreprefixtext \
+demarreprocessassignmentcommand demarreprocessassignmentlist demarreprocesscommacommand demarreprocesscommalist demarreproduit \
+demarreprojet demarreprotect demarreprotectedcolors demarrepublication demarrepunctuation \
+demarrequotation demarrequote demarrerandomized demarrerandomseed demarrerawsetups \
+demarrereadingfile demarrereferenceprefix demarreregime demarrereusableMPgraphic demarreruby \
+demarrescript demarresdformula demarresection demarresectionblock demarresectionblockenvironment \
+demarresectionlevel demarresetups demarreshapebox demarreshift demarresidebar \
+demarresimplecolumns demarrespecialitem demarrespeech demarrespformula demarresplitformula \
+demarresplittext demarrespread demarrestandardmakeup demarrestaticMPfigure demarrestaticMPgraphic \
+demarrestrictinspectnextcharacter demarrestrut demarrestyle demarresubformulas demarresubject \
+demarresubjectlevel demarresubsection demarresubsentence demarresubstack demarresubsubject \
+demarresubsubsection demarresubsubsubject demarresubsubsubsection demarresubsubsubsubject demarresubsubsubsubsection \
+demarresubsubsubsubsubject demarresuffixtext demarresymbolset demarretable demarretablehead \
+demarretables demarretabletail demarretabletext demarretabulate demarretabulatehead \
+demarretabulatetail demarretagged demarretaglabeltext demarretete demarretexcode \
+demarretexdefinition demarretext demarretextbackground demarretextbackgroundmanual demarretextcolor \
+demarretextcolorintent demarretextflow demarretextmakeup demarretitle demarretokenlist \
+demarretokens demarretransparent demarretypescript demarretypescriptcollection demarretyping \
+demarreuniqueMPgraphic demarreuniqueMPpagegraphic demarreunittext demarreunpacked demarreusableMPgraphic \
+demarreuseMPgraphic demarreusemathstyleparameter demarreuserdata demarreusingbtxspecification demarreva \
+demarrevbox demarrevboxregister demarrevboxtohbox demarrevboxtohboxseparator demarreviewerlayer \
+demarrevtop demarrevtopregister demarrexcell demarrexcellgroup demarrexcolumn \
demarrexgroup demarrexmldisplayverbatim demarrexmlinlineverbatim demarrexmlraw demarrexmlsetups \
demarrexrow demarrexrowgroup demarrextable demarrextablebody demarrextablefoot \
demarrextablehead demarrextablenext determinecaracteristiqueliste determinecaracteristiquesregistre determinenumerotete \
@@ -1476,84 +1498,86 @@ regledemarrestoppe regledisposition regleecraninteraction regleelements regleenc
regleentete regleenumerations regleepaisseurligne regleespaceblanc regleespacement \
regleespacementinterligne regleflottant regleflottants regleformulaires regleformules \
reglegroupeselements regleinf regleinteraction regleintitule regleintitules \
-reglejeusymboles reglelangue reglelignes reglelignesnoires reglelignesreglestexte \
-regleliste reglelisteimbriquee reglemakeup reglemargereglee reglemarquage \
-reglemarquagehyphenation reglemenuinteraction reglenumeropage reglenumerotationligne reglenumerotationpage \
-reglenumerotationparagraphe reglenumerotete regleoriente reglepalette reglepapier \
-regleparagraphes reglepdp regleplacementopposition reglepolicecorps reglepositionnement \
-regleprogrammes reglereferencage regleregistre regleremplitligne regleremplitlignesreglees \
-regleseparationflottant reglesousnumeropage reglesup reglesynonymes regletableaux \
-regletabulation regletaillepapier regletete regletetes regletexte \
-regletextesentete regletextesinf regletextespdp regletextessup regletextestexte \
-regletolerance regletraitsfins regletransitionspage regletri regletype \
-regleurl remplitligne remplitlignesreglees remplittexte sansespace \
-sanslignesenteteetpdp sanslignessupetinf selectionneblocs separeflottant settext \
-sousnumeropage stoppeJScode stoppeJSpreamble stoppeLUA stoppeMP \
-stoppeMPclip stoppeMPcode stoppeMPdefinitions stoppeMPdrawing stoppeMPenvironment \
-stoppeMPextensions stoppeMPinclusions stoppeMPinitializations stoppeMPpage stoppeMPpositiongraphic \
-stoppeMPpositionmethod stoppeMPrun stoppePARSEDXML stoppeTABLE stoppeTABLEbody \
-stoppeTABLEfoot stoppeTABLEhead stoppeTABLEnext stoppeTC stoppeTD \
-stoppeTDs stoppeTEX stoppeTEXpage stoppeTH stoppeTN \
-stoppeTR stoppeTRs stoppeTX stoppeTY stoppeXML \
-stoppealign stoppealigneadroite stoppealigneagauche stoppealigneaumilieu stoppealignment \
-stoppeallmodes stoppeappendices stoppearrangedpages stoppearriereplan stoppeaside \
-stoppeattachment stoppebackmatter stoppebar stoppebbordermatrix stoppebitmapimage \
-stoppeblockquote stoppebodymatter stoppebordermatrix stoppeboxedcolumns stoppebtxlabeltext \
-stoppebtxrenderingdefinitions stoppebuffer stoppecases stoppecatcodetable stoppecenteraligned \
-stoppechapter stoppecharacteralign stoppecheckedfences stoppechemical stoppechemicaltext \
-stoppecollect stoppecollecting stoppecolorintent stoppecoloronly stoppecolorset \
-stoppecolumns stoppecolumnspan stoppecombination stoppecomment stoppecomposant \
-stoppecontextcode stoppecontextdefinitioncode stoppecouleur stoppectxfunction stoppectxfunctiondefinition \
-stoppecurrentcolor stoppecurrentlistentrywrapper stoppedelimited stoppedelimitedtext stoppedisplaymath \
-stoppedmath stoppedocument stoppeeffect stoppeelement stoppeembeddedxtable \
-stoppeendnote stoppeendofline stoppeenvironement stoppeexceptions stoppeexpanded \
-stoppeexpandedcollect stoppeextendedcatcodetable stoppeexternalfigurecollection stoppefact stoppefigure \
-stoppefiguretext stoppefittingpage stoppefixed stoppefloatcombination stoppefont \
-stoppefontclass stoppefontsolution stoppefootnote stoppeformula stoppeformulas \
-stoppeframed stoppeframedcell stoppeframedcontent stoppeframedrow stoppeframedtable \
-stoppeframedtext stoppefrontmatter stoppegraphictext stoppegridsnapping stoppegroupe \
-stoppehanging stoppehbox stoppehboxestohbox stoppehboxregister stoppeheadtext \
-stoppehelptext stoppehiding stoppehighlight stoppehyphenation stoppeimath \
-stoppeindentation stoppeindentedtext stoppeinteraction stoppeinterface stoppeintermezzotext \
-stoppeintertext stoppeitemgroup stoppeitemgroupcolumns stoppeitemize stoppeknockout \
-stoppelabeltext stoppelayout stoppelegend stoppeligne stoppeligneregleetexte \
+reglejeucolonne reglejeusymboles reglelangue reglelignes reglelignesnoires \
+reglelignesreglestexte regleliste reglelisteimbriquee reglemakeup reglemargereglee \
+reglemarquage reglemarquagehyphenation reglemenuinteraction reglenumeropage reglenumerotationligne \
+reglenumerotationpage reglenumerotationparagraphe reglenumerotete regleoriente reglepalette \
+reglepapier regleparagraphes reglepdp regleplacementopposition reglepolicecorps \
+reglepositionnement regleprogrammes reglereferencage regleregistre regleremplitligne \
+regleremplitlignesreglees regleseparationflottant reglesousnumeropage reglesup reglesynonymes \
+regletableaux regletabulation regletaillepapier regletete regletetes \
+regletexte regletextesentete regletextesinf regletextespdp regletextessup \
+regletextestexte regletolerance regletraitsfins regletransitionspage regletri \
+regletype regleurl remplitligne remplitlignesreglees remplittexte \
+sansespace sanslignesenteteetpdp sanslignessupetinf selectionneblocs separeflottant \
+settext sousnumeropage stoppeJScode stoppeJSpreamble stoppeLUA \
+stoppeMP stoppeMPclip stoppeMPcode stoppeMPdefinitions stoppeMPdrawing \
+stoppeMPenvironment stoppeMPextensions stoppeMPinclusions stoppeMPinitializations stoppeMPpage \
+stoppeMPpositiongraphic stoppeMPpositionmethod stoppeMPrun stoppePARSEDXML stoppeTABLE \
+stoppeTABLEbody stoppeTABLEfoot stoppeTABLEhead stoppeTABLEnext stoppeTC \
+stoppeTD stoppeTDs stoppeTEX stoppeTEXpage stoppeTH \
+stoppeTN stoppeTR stoppeTRs stoppeTX stoppeTY \
+stoppeXML stoppealign stoppealigneadroite stoppealigneagauche stoppealigneaumilieu \
+stoppealignment stoppeallmodes stoppeappendices stoppearrangedpages stoppearriereplan \
+stoppeaside stoppeattachment stoppebackmatter stoppebar stoppebbordermatrix \
+stoppebitmapimage stoppeblockquote stoppebodymatter stoppebordermatrix stoppeboxedcolumns \
+stoppebtxlabeltext stoppebtxrenderingdefinitions stoppebuffer stoppecases stoppecatcodetable \
+stoppecenteraligned stoppechapter stoppecharacteralign stoppecheckedfences stoppechemical \
+stoppechemicaltext stoppecollect stoppecollecting stoppecolorintent stoppecoloronly \
+stoppecolorset stoppecolumns stoppecolumnset stoppecolumnsetspan stoppecolumnspan \
+stoppecombination stoppecomment stoppecomposant stoppecontextcode stoppecontextdefinitioncode \
+stoppecouleur stoppectxfunction stoppectxfunctiondefinition stoppecurrentcolor stoppecurrentlistentrywrapper \
+stoppedelimited stoppedelimitedtext stoppedisplaymath stoppedmath stoppedocument \
+stoppeeffect stoppeelement stoppeembeddedxtable stoppeendnote stoppeendofline \
+stoppeenvironement stoppeexceptions stoppeexpanded stoppeexpandedcollect stoppeextendedcatcodetable \
+stoppeexternalfigurecollection stoppefacingfloat stoppefact stoppefigure stoppefiguretext \
+stoppefittingpage stoppefixed stoppefloatcombination stoppefont stoppefontclass \
+stoppefontsolution stoppefootnote stoppeformula stoppeformulas stoppeframed \
+stoppeframedcell stoppeframedcontent stoppeframedrow stoppeframedtable stoppeframedtext \
+stoppefrontmatter stoppegraphictext stoppegridsnapping stoppegroupe stoppehanging \
+stoppehbox stoppehboxestohbox stoppehboxregister stoppeheadtext stoppehelptext \
+stoppehiding stoppehighlight stoppehyphenation stoppeimath stoppeindentation \
+stoppeindentedtext stoppeinteraction stoppeinterface stoppeintermezzotext stoppeintertext \
+stoppeitemgroup stoppeitemgroupcolumns stoppeitemize stoppeknockout stoppelabeltext \
+stoppelangue stoppelayout stoppelegend stoppeligne stoppeligneregleetexte \
stoppelinealignment stoppelinecorrection stoppelinefiller stoppelinenumbering stoppelines \
stoppelinetable stoppelinetablebody stoppelinetablecell stoppelinetablehead stoppelocalfootnotes \
stoppelocalheadsetup stoppelocallinecorrection stoppelocalnotes stoppelocalsetups stoppelua \
stoppeluacode stoppeluaparameterset stoppeluasetups stoppemakeup stoppemargereglee \
-stoppemarginblock stoppemarkedcontent stoppemathalignment stoppemathcases stoppemathlabeltext \
-stoppemathmatrix stoppemathmode stoppemathstyle stoppematrices stoppematrix \
-stoppemaxaligned stoppemdformula stoppemenuinteraction stoppemiddlealigned stoppemiddlemakeup \
-stoppemixedcolumns stoppemode stoppemodeset stoppemodule stoppemoduletestsection \
-stoppempformula stoppenamedsection stoppenamedsubformulas stoppenarrow stoppenarrower \
-stoppenegative stoppenicelyfilledbox stoppenointerference stoppenotallmodes stoppenotext \
-stoppenotmode stoppeoperatortext stoppeopposite stoppeoutputstream stoppeoverlay \
-stoppeoverprint stoppepagecomment stoppepagefigure stoppepagegrid stoppepagegridspan \
+stoppemarginblock stoppemarkedcontent stoppemarkpages stoppemathalignment stoppemathcases \
+stoppemathlabeltext stoppemathmatrix stoppemathmode stoppemathstyle stoppematrices \
+stoppematrix stoppemaxaligned stoppemdformula stoppemenuinteraction stoppemiddlealigned \
+stoppemiddlemakeup stoppemixedcolumns stoppemode stoppemodeset stoppemodule \
+stoppemoduletestsection stoppempformula stoppenamedsection stoppenamedsubformulas stoppenarrow \
+stoppenarrower stoppenegative stoppenicelyfilledbox stoppenointerference stoppenotallmodes \
+stoppenotext stoppenotmode stoppeoperatortext stoppeopposite stoppeoutputstream \
+stoppeoverlay stoppeoverprint stoppepagecolumns stoppepagecomment stoppepagefigure \
stoppepagelayout stoppepagemakeup stoppepar stoppeparagraph stoppeparagraphs \
stoppeparagraphscell stoppeparbuilder stoppepart stoppepath stoppeplacechemical \
stoppeplacefigure stoppeplaceflottant stoppeplaceformule stoppeplacegraphic stoppeplaceintermezzo \
stoppeplacelegend stoppeplacepairedbox stoppeplacetable stoppepositioning stoppepositionoverlay \
-stoppepositive stoppepostponing stoppeprefixtext stoppeprocessassignmentcommand stoppeprocessassignmentlist \
-stoppeprocesscommacommand stoppeprocesscommalist stoppeproduit stoppeprojet stoppeprotect \
-stoppeprotectedcolors stoppepublication stoppepunctuation stoppequotation stoppequote \
-stopperandomized stopperandomseed stopperawsetups stoppereadingfile stoppereferenceprefix \
-stopperegime stoppereusableMPgraphic stoppescript stoppesdformula stoppesection \
-stoppesectionblock stoppesectionblockenvironment stoppesectionlevel stoppesetups stoppeshapebox \
-stoppeshift stoppesidebar stoppesimplecolumns stoppespecialitem stoppespeech \
-stoppespformula stoppesplitformula stoppespread stoppestandardmakeup stoppestartstop \
-stoppestaticMPfigure stoppestaticMPgraphic stoppestrictinspectnextcharacter stoppestrut stoppestyle \
-stoppesubformulas stoppesubject stoppesubjectlevel stoppesubsection stoppesubsentence \
-stoppesubstack stoppesubsubject stoppesubsubsection stoppesubsubsubject stoppesubsubsubsection \
-stoppesubsubsubsubject stoppesubsubsubsubsection stoppesubsubsubsubsubject stoppesuffixtext stoppesymbolset \
-stoppetable stoppetablehead stoppetables stoppetabletail stoppetabletext \
-stoppetabulate stoppetabulatehead stoppetabulatetail stoppetagged stoppetaglabeltext \
-stoppetete stoppetexcode stoppetexdefinition stoppetext stoppetextbackground \
-stoppetextbackgroundmanual stoppetextcolor stoppetextcolorintent stoppetextflow stoppetextmakeup \
-stoppetitle stoppetokens stoppetransparent stoppetypescript stoppetypescriptcollection \
-stoppetyping stoppeuniqueMPgraphic stoppeuniqueMPpagegraphic stoppeunittext stoppeunpacked \
-stoppeusableMPgraphic stoppeuseMPgraphic stoppeusemathstyleparameter stoppeusingbtxspecification stoppeva \
-stoppevbox stoppevboxregister stoppevboxtohbox stoppevboxtohboxseparator stoppeviewerlayer \
-stoppevtop stoppevtopregister stoppexcell stoppexcellgroup stoppexgroup \
+stoppepositive stoppepostponing stoppepostponingnotes stoppeprefixtext stoppeprocessassignmentcommand \
+stoppeprocessassignmentlist stoppeprocesscommacommand stoppeprocesscommalist stoppeproduit stoppeprojet \
+stoppeprotect stoppeprotectedcolors stoppepublication stoppepunctuation stoppequotation \
+stoppequote stopperandomized stopperandomseed stopperawsetups stoppereadingfile \
+stoppereferenceprefix stopperegime stoppereusableMPgraphic stopperuby stoppescript \
+stoppesdformula stoppesection stoppesectionblock stoppesectionblockenvironment stoppesectionlevel \
+stoppesetups stoppeshapebox stoppeshift stoppesidebar stoppesimplecolumns \
+stoppespecialitem stoppespeech stoppespformula stoppesplitformula stoppesplittext \
+stoppespread stoppestandardmakeup stoppestaticMPfigure stoppestaticMPgraphic stoppestrictinspectnextcharacter \
+stoppestrut stoppestyle stoppesubformulas stoppesubject stoppesubjectlevel \
+stoppesubsection stoppesubsentence stoppesubstack stoppesubsubject stoppesubsubsection \
+stoppesubsubsubject stoppesubsubsubsection stoppesubsubsubsubject stoppesubsubsubsubsection stoppesubsubsubsubsubject \
+stoppesuffixtext stoppesymbolset stoppetable stoppetablehead stoppetables \
+stoppetabletail stoppetabletext stoppetabulate stoppetabulatehead stoppetabulatetail \
+stoppetagged stoppetaglabeltext stoppetete stoppetexcode stoppetexdefinition \
+stoppetext stoppetextbackground stoppetextbackgroundmanual stoppetextcolor stoppetextcolorintent \
+stoppetextflow stoppetextmakeup stoppetitle stoppetokenlist stoppetokens \
+stoppetransparent stoppetypescript stoppetypescriptcollection stoppetyping stoppeuniqueMPgraphic \
+stoppeuniqueMPpagegraphic stoppeunittext stoppeunpacked stoppeusableMPgraphic stoppeuseMPgraphic \
+stoppeusemathstyleparameter stoppeuserdata stoppeusingbtxspecification stoppeva stoppevbox \
+stoppevboxregister stoppevboxtohbox stoppevboxtohboxseparator stoppeviewerlayer stoppevtop \
+stoppevtopregister stoppexcell stoppexcellgroup stoppexcolumn stoppexgroup \
stoppexmldisplayverbatim stoppexmlinlineverbatim stoppexmlraw stoppexmlsetups stoppexrow \
stoppexrowgroup stoppextable stoppextablebody stoppextablefoot stoppextablehead \
stoppextablenext symbole tapebuffer textenotepdp traduire \
@@ -1575,54 +1599,55 @@ data datadioggi definisci definisciaccento definisciambientefontdeltesto \
definisciblocco definiscibloccosezione definiscibuffer definiscicampo definiscicapoversi \
definiscicarattere definiscicolore definiscicomando definisciconversione definiscidescrizione \
definiscidimensionicarta definiscielenco definiscielencocombinato definiscienumerazione definiscietichetta \
-definiscifigurasimbolo definiscifont definiscifontdeltesto definisciformatoriferimento definiscigruppocolori \
-definiscihbox definisciincorniciato definisciiniziatermina definiscilayout definiscimakeup \
-definiscimarcatura definiscimenuinterazione definiscimodellotabella definiscioggettomobile definisciordinamento \
-definisciprofilo definisciprogramma definisciregistro definisciriferimento definiscisezione \
-definiscisimbolo definiscisinonimi definiscisinonimofont definiscisottocampo definiscisovrapposizione \
-definiscistackcampi definiscistile definiscistilefont definiscitabulato definiscitavolozza \
-definiscitesta definiscitesto definiscitestoincorniciato definiscitype definiscityping \
-determinacaratteristicheregistro determinacarattersticheelenco determinanumerotesta elaborablocchi elementi \
-elemento figuraesterna giornosettimana griglia ignoto \
-impostaallineamento impostaampiezzariga impostabarrainterazione impostablocco impostabloccosezione \
-impostabuffer impostacampi impostacampo impostacapoversi impostacaption \
-impostacaptions impostacima impostaclippling impostacolonne impostacolore \
-impostacolori impostacommento impostacommentopagina impostadimensionicarta impostaelementi \
-impostaelencazioni impostaelenco impostaelencocombinato impostaenumerazioni impostafondo \
-impostafontdeltesto impostaforms impostaformule impostaincorniciato impostainiziatermina \
-impostainstestazione impostainterazione impostainterlinea impostalayout impostalineemargine \
-impostalineenere impostalineeriempimento impostalineesottili impostalineetesto impostalingua \
-impostamaiuscole impostamakeup impostamarcatura impostamenuinterazione impostamenzione \
-impostanumerazionecapoversi impostanumerazionepagina impostanumerazionerighe impostanumeropagina impostanumerosottopagina \
-impostanumerotesta impostaoggettimobili impostaoggettomobile impostaordinamento impostaparranging \
-impostapdp impostapiustretto impostaposizionamento impostaposizionamentoopposti impostaprogrammi \
-impostaregistro impostarientro impostariferimento impostarighe impostarigheriempimento \
-impostarigovuoto impostarotazione impostaschermointerazione impostasegnosillabazione impostasetsimboli \
-impostasfondi impostasfondo impostasinonimi impostaspaziatura impostaspaziobianco \
-impostaspezzamentooggettomobile impostatabelle impostatabulato impostatavolozza impostatesta \
-impostateste impostatesticima impostatestifondo impostatestiincorniciati impostatestiintestazioni \
-impostatestipdp impostatesto impostatestotesti impostatolleranza impostatransizionepagina \
-impostatype impostatyping impostaurl incorniciato iniziaJScode \
-iniziaJSpreamble iniziaLUA iniziaMP iniziaMPclip iniziaMPcode \
-iniziaMPdefinitions iniziaMPdrawing iniziaMPenvironment iniziaMPextensions iniziaMPinclusions \
-iniziaMPinitializations iniziaMPpage iniziaMPpositiongraphic iniziaMPpositionmethod iniziaMPrun \
-iniziaPARSEDXML iniziaTABLE iniziaTABLEbody iniziaTABLEfoot iniziaTABLEhead \
-iniziaTABLEnext iniziaTC iniziaTD iniziaTDs iniziaTEX \
-iniziaTEXpage iniziaTH iniziaTN iniziaTR iniziaTRs \
-iniziaTX iniziaTY iniziaXML iniziaalign iniziaalignment \
-iniziaallineacentro iniziaallineadestra iniziaallineasinistra iniziaallmodes iniziaambiente \
-iniziaappendices iniziaarrangedpages iniziaaside iniziaattachment iniziabackmatter \
-iniziabar iniziabbordermatrix iniziabitmapimage iniziablockquote iniziabodymatter \
-iniziabordermatrix iniziaboxedcolumns iniziabtxlabeltext iniziabtxrenderingdefinitions iniziabuffer \
-iniziacases iniziacatcodetable iniziacenteraligned iniziachapter iniziacharacteralign \
-iniziacheckedfences iniziachemical iniziachemicaltext iniziacollect iniziacollecting \
-iniziacolore iniziacolorintent iniziacoloronly iniziacolorset iniziacolumns \
-iniziacolumnspan iniziacombination iniziacomment iniziacomponenet iniziacontextcode \
-iniziacontextdefinitioncode iniziactxfunction iniziactxfunctiondefinition iniziacurrentcolor iniziacurrentlistentrywrapper \
-iniziadelimited iniziadelimitedtext iniziadisplaymath iniziadmath iniziadocument \
-iniziaeffect iniziaelement iniziaelemento iniziaembeddedxtable iniziaendnote \
-iniziaendofline iniziaexceptions iniziaexpanded iniziaexpandedcollect iniziaextendedcatcodetable \
-iniziaexternalfigurecollection iniziafact iniziafigure iniziafiguretext iniziafittingpage \
+definiscifigurasimbolo definiscifont definiscifontdeltesto definisciformatoriferimento definiscigruppocolonne \
+definiscigruppocolori definiscihbox definisciincorniciato definisciiniziatermina definiscilayout \
+definiscimakeup definiscimarcatura definiscimenuinterazione definiscimodellotabella definiscioggettomobile \
+definisciordinamento definisciprofilo definisciprogramma definisciregistro definisciriferimento \
+definiscisezione definiscisimbolo definiscisinonimi definiscisinonimofont definiscisottocampo \
+definiscisovrapposizione definiscistackcampi definiscistile definiscistilefont definiscitabulato \
+definiscitavolozza definiscitesta definiscitesto definiscitestoincorniciato definiscitype \
+definiscityping determinacaratteristicheregistro determinacarattersticheelenco determinanumerotesta elaborablocchi \
+elementi elemento figuraesterna giornosettimana griglia \
+ignoto impostaallineamento impostaampiezzariga impostabarrainterazione impostablocco \
+impostabloccosezione impostabuffer impostacampi impostacampo impostacapoversi \
+impostacaption impostacaptions impostacima impostaclippling impostacolonne \
+impostacolore impostacolori impostacommento impostacommentopagina impostadimensionicarta \
+impostaelementi impostaelencazioni impostaelenco impostaelencocombinato impostaenumerazioni \
+impostafondo impostafontdeltesto impostaforms impostaformule impostagruppocolonne \
+impostaincorniciato impostainiziatermina impostainstestazione impostainterazione impostainterlinea \
+impostalayout impostalineemargine impostalineenere impostalineeriempimento impostalineesottili \
+impostalineetesto impostalingua impostamaiuscole impostamakeup impostamarcatura \
+impostamenuinterazione impostamenzione impostanumerazionecapoversi impostanumerazionepagina impostanumerazionerighe \
+impostanumeropagina impostanumerosottopagina impostanumerotesta impostaoggettimobili impostaoggettomobile \
+impostaordinamento impostaparranging impostapdp impostapiustretto impostaposizionamento \
+impostaposizionamentoopposti impostaprogrammi impostaregistro impostarientro impostariferimento \
+impostarighe impostarigheriempimento impostarigovuoto impostarotazione impostaschermointerazione \
+impostasegnosillabazione impostasetsimboli impostasfondi impostasfondo impostasinonimi \
+impostaspaziatura impostaspaziobianco impostaspezzamentooggettomobile impostatabelle impostatabulato \
+impostatavolozza impostatesta impostateste impostatesticima impostatestifondo \
+impostatestiincorniciati impostatestiintestazioni impostatestipdp impostatesto impostatestotesti \
+impostatolleranza impostatransizionepagina impostatype impostatyping impostaurl \
+incorniciato iniziaJScode iniziaJSpreamble iniziaLUA iniziaMP \
+iniziaMPclip iniziaMPcode iniziaMPdefinitions iniziaMPdrawing iniziaMPenvironment \
+iniziaMPextensions iniziaMPinclusions iniziaMPinitializations iniziaMPpage iniziaMPpositiongraphic \
+iniziaMPpositionmethod iniziaMPrun iniziaPARSEDXML iniziaTABLE iniziaTABLEbody \
+iniziaTABLEfoot iniziaTABLEhead iniziaTABLEnext iniziaTC iniziaTD \
+iniziaTDs iniziaTEX iniziaTEXpage iniziaTH iniziaTN \
+iniziaTR iniziaTRs iniziaTX iniziaTY iniziaXML \
+iniziaalign iniziaalignment iniziaallineacentro iniziaallineadestra iniziaallineasinistra \
+iniziaallmodes iniziaambiente iniziaappendices iniziaarrangedpages iniziaaside \
+iniziaattachment iniziabackmatter iniziabar iniziabbordermatrix iniziabitmapimage \
+iniziablockquote iniziabodymatter iniziabordermatrix iniziaboxedcolumns iniziabtxlabeltext \
+iniziabtxrenderingdefinitions iniziabuffer iniziacases iniziacatcodetable iniziacenteraligned \
+iniziachapter iniziacharacteralign iniziacheckedfences iniziachemical iniziachemicaltext \
+iniziacollect iniziacollecting iniziacolore iniziacolorintent iniziacoloronly \
+iniziacolorset iniziacolumns iniziacolumnset iniziacolumnsetspan iniziacolumnspan \
+iniziacombination iniziacomment iniziacomponenet iniziacontextcode iniziacontextdefinitioncode \
+iniziactxfunction iniziactxfunctiondefinition iniziacurrentcolor iniziacurrentlistentrywrapper iniziadelimited \
+iniziadelimitedtext iniziadisplaymath iniziadmath iniziadocument iniziaeffect \
+iniziaelement iniziaelemento iniziaembeddedxtable iniziaendnote iniziaendofline \
+iniziaexceptions iniziaexpanded iniziaexpandedcollect iniziaextendedcatcodetable iniziaexternalfigurecollection \
+iniziafacingfloat iniziafact iniziafigure iniziafiguretext iniziafittingpage \
iniziafixed iniziafloatcombination iniziafont iniziafontclass iniziafontsolution \
iniziafootnote iniziaformula iniziaformulas iniziaframedcell iniziaframedcontent \
iniziaframedrow iniziaframedtable iniziaframedtext iniziafrontmatter iniziagraphictext \
@@ -1633,130 +1658,133 @@ iniziainteraction iniziainterface iniziaintermezzotext iniziaintertext iniziaite
iniziaitemgroupcolumns iniziaitemize iniziaknockout inizialabeltext inizialayout \
inizialegend inizialinealignment inizialineamargine inizialineatesto inizialinecorrection \
inizialinefiller inizialinenumbering inizialines inizialinetable inizialinetablebody \
-inizialinetablecell inizialinetablehead inizialocalfootnotes inizialocalheadsetup inizialocallinecorrection \
-inizialocalnotes inizialocalsetups inizialua inizialuacode inizialuaparameterset \
-inizialuasetups iniziamakeup iniziamarginblock iniziamarkedcontent iniziamathalignment \
-iniziamathcases iniziamathlabeltext iniziamathmatrix iniziamathmode iniziamathstyle \
-iniziamatrices iniziamatrix iniziamaxaligned iniziamdformula iniziamenuinterattivo \
-iniziamettiformula iniziamiddlealigned iniziamiddlemakeup iniziamixedcolumns iniziamode \
-iniziamodeset iniziamodule iniziamoduletestsection iniziampformula inizianamedsection \
-inizianamedsubformulas inizianarrow inizianarrower inizianegative inizianicelyfilledbox \
-inizianointerference inizianotallmodes inizianotext inizianotmode iniziaoperatortext \
-iniziaopposite iniziaoutputstream iniziaoverlay iniziaoverprint iniziapagecomment \
-iniziapagefigure iniziapagegrid iniziapagegridspan iniziapagelayout iniziapagemakeup \
-iniziapar iniziaparagraph iniziaparagraphs iniziaparagraphscell iniziaparbuilder \
-iniziapart iniziapath iniziaplacechemical iniziaplacefigure iniziaplacefloat \
-iniziaplacegraphic iniziaplaceintermezzo iniziaplacelegend iniziaplacepairedbox iniziaplacetable \
-iniziapositioning iniziapositionoverlay iniziapositive iniziapostponing iniziaprefixtext \
-iniziaprocessassignmentcommand iniziaprocessassignmentlist iniziaprocesscommacommand iniziaprocesscommalist iniziaprodotto \
-iniziaprogetto iniziaprotect iniziaprotectedcolors iniziapubblicazione iniziapunctuation \
-iniziaquotation iniziaquote iniziarandomized iniziarandomseed iniziarawsetups \
-iniziareadingfile iniziareferenceprefix iniziaregime iniziareusableMPgraphic iniziariga \
-iniziascript iniziasdformula iniziasection iniziasectionblock iniziasectionblockenvironment \
-iniziasectionlevel iniziasetups iniziasfondo iniziashapebox iniziashift \
-iniziasidebar iniziasimplecolumns iniziaspecialitem iniziaspeech iniziaspformula \
-iniziasplitformula iniziaspread iniziastandardmakeup iniziastartstop iniziastaticMPfigure \
-iniziastaticMPgraphic iniziastrictinspectnextcharacter iniziastrut iniziastyle iniziasubformulas \
-iniziasubject iniziasubjectlevel iniziasubsection iniziasubsentence iniziasubstack \
-iniziasubsubject iniziasubsubsection iniziasubsubsubject iniziasubsubsubsection iniziasubsubsubsubject \
-iniziasubsubsubsubsection iniziasubsubsubsubsubject iniziasuffixtext iniziasymbolset iniziatable \
-iniziatablehead iniziatables iniziatabletail iniziatabletext iniziatabulate \
-iniziatabulatehead iniziatabulatetail iniziatagged iniziataglabeltext iniziatesta \
-iniziatexcode iniziatexdefinition iniziatext iniziatextbackground iniziatextbackgroundmanual \
-iniziatextcolor iniziatextcolorintent iniziatextflow iniziatextmakeup iniziatitle \
-iniziatokens iniziatransparent iniziatypescript iniziatypescriptcollection iniziatyping \
-iniziauniqueMPgraphic iniziauniqueMPpagegraphic iniziaunittext iniziaunpacked iniziausableMPgraphic \
-iniziauseMPgraphic iniziausemathstyleparameter iniziausingbtxspecification iniziavaia iniziavbox \
+inizialinetablecell inizialinetablehead inizialingua inizialocalfootnotes inizialocalheadsetup \
+inizialocallinecorrection inizialocalnotes inizialocalsetups inizialua inizialuacode \
+inizialuaparameterset inizialuasetups iniziamakeup iniziamarginblock iniziamarkedcontent \
+iniziamarkpages iniziamathalignment iniziamathcases iniziamathlabeltext iniziamathmatrix \
+iniziamathmode iniziamathstyle iniziamatrices iniziamatrix iniziamaxaligned \
+iniziamdformula iniziamenuinterattivo iniziamettiformula iniziamiddlealigned iniziamiddlemakeup \
+iniziamixedcolumns iniziamode iniziamodeset iniziamodule iniziamoduletestsection \
+iniziampformula inizianamedsection inizianamedsubformulas inizianarrow inizianarrower \
+inizianegative inizianicelyfilledbox inizianointerference inizianotallmodes inizianotext \
+inizianotmode iniziaoperatortext iniziaopposite iniziaoutputstream iniziaoverlay \
+iniziaoverprint iniziapagecolumns iniziapagecomment iniziapagefigure iniziapagelayout \
+iniziapagemakeup iniziapar iniziaparagraph iniziaparagraphs iniziaparagraphscell \
+iniziaparbuilder iniziapart iniziapath iniziaplacechemical iniziaplacefigure \
+iniziaplacefloat iniziaplacegraphic iniziaplaceintermezzo iniziaplacelegend iniziaplacepairedbox \
+iniziaplacetable iniziapositioning iniziapositionoverlay iniziapositive iniziapostponing \
+iniziapostponingnotes iniziaprefixtext iniziaprocessassignmentcommand iniziaprocessassignmentlist iniziaprocesscommacommand \
+iniziaprocesscommalist iniziaprodotto iniziaprogetto iniziaprotect iniziaprotectedcolors \
+iniziapubblicazione iniziapunctuation iniziaquotation iniziaquote iniziarandomized \
+iniziarandomseed iniziarawsetups iniziareadingfile iniziareferenceprefix iniziaregime \
+iniziareusableMPgraphic iniziariga iniziaruby iniziascript iniziasdformula \
+iniziasection iniziasectionblock iniziasectionblockenvironment iniziasectionlevel iniziasetups \
+iniziasfondo iniziashapebox iniziashift iniziasidebar iniziasimplecolumns \
+iniziaspecialitem iniziaspeech iniziaspformula iniziasplitformula iniziasplittext \
+iniziaspread iniziastandardmakeup iniziastaticMPfigure iniziastaticMPgraphic iniziastrictinspectnextcharacter \
+iniziastrut iniziastyle iniziasubformulas iniziasubject iniziasubjectlevel \
+iniziasubsection iniziasubsentence iniziasubstack iniziasubsubject iniziasubsubsection \
+iniziasubsubsubject iniziasubsubsubsection iniziasubsubsubsubject iniziasubsubsubsubsection iniziasubsubsubsubsubject \
+iniziasuffixtext iniziasymbolset iniziatable iniziatablehead iniziatables \
+iniziatabletail iniziatabletext iniziatabulate iniziatabulatehead iniziatabulatetail \
+iniziatagged iniziataglabeltext iniziatesta iniziatexcode iniziatexdefinition \
+iniziatext iniziatextbackground iniziatextbackgroundmanual iniziatextcolor iniziatextcolorintent \
+iniziatextflow iniziatextmakeup iniziatitle iniziatokenlist iniziatokens \
+iniziatransparent iniziatypescript iniziatypescriptcollection iniziatyping iniziauniqueMPgraphic \
+iniziauniqueMPpagegraphic iniziaunittext iniziaunpacked iniziausableMPgraphic iniziauseMPgraphic \
+iniziausemathstyleparameter iniziauserdata iniziausingbtxspecification iniziavaia iniziavbox \
iniziavboxregister iniziavboxtohbox iniziavboxtohboxseparator iniziaviewerlayer iniziavtop \
-iniziavtopregister iniziaxcell iniziaxcellgroup iniziaxgroup iniziaxmldisplayverbatim \
-iniziaxmlinlineverbatim iniziaxmlraw iniziaxmlsetups iniziaxrow iniziaxrowgroup \
-iniziaxtable iniziaxtablebody iniziaxtablefoot iniziaxtablehead iniziaxtablenext \
-inriga installalingua intorno lettera lettere \
-lineanera lineasottile lineatesto lineenere lineeriempimento \
-lineesottili lingua linguaprincipale lunghezzaelenco marcatura \
-matematica menuinterattivo mese mettielenco mettielencocombinato \
-mettifiancoafianco mettiformula mettiingriglia mettinotepdp mettinotepdplocali \
-mettinumeropagina mettiregistro mettisegnalibro mettisottoformula mettiunosullaltro \
-mostraambientefontdeltesto mostracolore mostracornice mostrafontdeltesto mostragriglia \
-mostragruppocolori mostraimpostazioni mostralyout mostramakeup mostrasetsimboli \
-mostrastampa mostrastruts mostratavolozza nascondiblocchi nientelineecimafondo \
-nientelineintestazionepdp nientespazio nota numeri numeriromani \
-numeroformula numeropagina numeropaginacompleto numerotesta numerotestacorrente \
-pagina paroladestra ped pedap perlungo \
-posizionanumerotesta posizionatestotesta posizione prendibuffer prendimarcatura \
-prodotto progetto programma pulsante pulsantemenu \
-pulsantinterazione punti qualcheriga reimpostamarcatura rif \
-riferimento riferimentopagina riferimentotesto riflessione rigariempimento \
-rigovuoto ruota scala schermo scrividentroelenco \
-scriviinelenco segnalibro selezionablocchi settext sfondo \
-simbolo spazifissi spazio spaziofisso spessoreriga \
-spezzaoggettomobile stackcampi stirato terminaJScode terminaJSpreamble \
-terminaLUA terminaMP terminaMPclip terminaMPcode terminaMPdefinitions \
-terminaMPdrawing terminaMPenvironment terminaMPextensions terminaMPinclusions terminaMPinitializations \
-terminaMPpage terminaMPpositiongraphic terminaMPpositionmethod terminaMPrun terminaPARSEDXML \
-terminaTABLE terminaTABLEbody terminaTABLEfoot terminaTABLEhead terminaTABLEnext \
-terminaTC terminaTD terminaTDs terminaTEX terminaTEXpage \
-terminaTH terminaTN terminaTR terminaTRs terminaTX \
-terminaTY terminaXML terminaalign terminaalignment terminaallineacentro \
-terminaallineadestra terminaallineasinistra terminaallmodes terminaambiente terminaappendices \
-terminaarrangedpages terminaaside terminaattachment terminabackmatter terminabar \
-terminabbordermatrix terminabitmapimage terminablockquote terminabodymatter terminabordermatrix \
-terminaboxedcolumns terminabtxlabeltext terminabtxrenderingdefinitions terminabuffer terminacases \
-terminacatcodetable terminacenteraligned terminachapter terminacharacteralign terminacheckedfences \
-terminachemical terminachemicaltext terminacollect terminacollecting terminacolore \
-terminacolorintent terminacoloronly terminacolorset terminacolumns terminacolumnspan \
-terminacombination terminacomment terminacomponenet terminacontextcode terminacontextdefinitioncode \
-terminactxfunction terminactxfunctiondefinition terminacurrentcolor terminacurrentlistentrywrapper terminadelimited \
-terminadelimitedtext terminadisplaymath terminadmath terminadocument terminaeffect \
-terminaelement terminaelemento terminaembeddedxtable terminaendnote terminaendofline \
-terminaexceptions terminaexpanded terminaexpandedcollect terminaextendedcatcodetable terminaexternalfigurecollection \
-terminafact terminafigure terminafiguretext terminafittingpage terminafixed \
-terminafloatcombination terminafont terminafontclass terminafontsolution terminafootnote \
-terminaformula terminaformulas terminaframedcell terminaframedcontent terminaframedrow \
-terminaframedtable terminaframedtext terminafrontmatter terminagraphictext terminagridsnapping \
-terminahanging terminahbox terminahboxestohbox terminahboxregister terminaheadtext \
-terminahelptext terminahiding terminahighlight terminahyphenation terminaimath \
-terminaimpaccato terminaincorniciato terminaindentation terminaindentedtext terminainteraction \
-terminainterface terminaintermezzotext terminaintertext terminaitemgroup terminaitemgroupcolumns \
-terminaitemize terminaknockout terminalabeltext terminalayout terminalegend \
-terminalinealignment terminalineamargine terminalineatesto terminalinecorrection terminalinefiller \
-terminalinenumbering terminalines terminalinetable terminalinetablebody terminalinetablecell \
-terminalinetablehead terminalocalfootnotes terminalocalheadsetup terminalocallinecorrection terminalocalnotes \
+iniziavtopregister iniziaxcell iniziaxcellgroup iniziaxcolumn iniziaxgroup \
+iniziaxmldisplayverbatim iniziaxmlinlineverbatim iniziaxmlraw iniziaxmlsetups iniziaxrow \
+iniziaxrowgroup iniziaxtable iniziaxtablebody iniziaxtablefoot iniziaxtablehead \
+iniziaxtablenext inriga installalingua intorno lettera \
+lettere lineanera lineasottile lineatesto lineenere \
+lineeriempimento lineesottili lingua linguaprincipale lunghezzaelenco \
+marcatura matematica menuinterattivo mese mettielenco \
+mettielencocombinato mettifiancoafianco mettiformula mettiingriglia mettinotepdp \
+mettinotepdplocali mettinumeropagina mettiregistro mettisegnalibro mettisottoformula \
+mettiunosullaltro mostraambientefontdeltesto mostracolore mostracornice mostrafontdeltesto \
+mostragriglia mostragruppocolori mostraimpostazioni mostralyout mostramakeup \
+mostrasetsimboli mostrastampa mostrastruts mostratavolozza nascondiblocchi \
+nientelineecimafondo nientelineintestazionepdp nientespazio nota numeri \
+numeriromani numeroformula numeropagina numeropaginacompleto numerotesta \
+numerotestacorrente pagina paroladestra ped pedap \
+perlungo posizionanumerotesta posizionatestotesta posizione prendibuffer \
+prendimarcatura prodotto progetto programma pulsante \
+pulsantemenu pulsantinterazione punti qualcheriga reimpostamarcatura \
+rif riferimento riferimentopagina riferimentotesto riflessione \
+rigariempimento rigovuoto ruota scala schermo \
+scrividentroelenco scriviinelenco segnalibro selezionablocchi settext \
+sfondo simbolo spazifissi spazio spaziofisso \
+spessoreriga spezzaoggettomobile stackcampi stirato terminaJScode \
+terminaJSpreamble terminaLUA terminaMP terminaMPclip terminaMPcode \
+terminaMPdefinitions terminaMPdrawing terminaMPenvironment terminaMPextensions terminaMPinclusions \
+terminaMPinitializations terminaMPpage terminaMPpositiongraphic terminaMPpositionmethod terminaMPrun \
+terminaPARSEDXML terminaTABLE terminaTABLEbody terminaTABLEfoot terminaTABLEhead \
+terminaTABLEnext terminaTC terminaTD terminaTDs terminaTEX \
+terminaTEXpage terminaTH terminaTN terminaTR terminaTRs \
+terminaTX terminaTY terminaXML terminaalign terminaalignment \
+terminaallineacentro terminaallineadestra terminaallineasinistra terminaallmodes terminaambiente \
+terminaappendices terminaarrangedpages terminaaside terminaattachment terminabackmatter \
+terminabar terminabbordermatrix terminabitmapimage terminablockquote terminabodymatter \
+terminabordermatrix terminaboxedcolumns terminabtxlabeltext terminabtxrenderingdefinitions terminabuffer \
+terminacases terminacatcodetable terminacenteraligned terminachapter terminacharacteralign \
+terminacheckedfences terminachemical terminachemicaltext terminacollect terminacollecting \
+terminacolore terminacolorintent terminacoloronly terminacolorset terminacolumns \
+terminacolumnset terminacolumnsetspan terminacolumnspan terminacombination terminacomment \
+terminacomponenet terminacontextcode terminacontextdefinitioncode terminactxfunction terminactxfunctiondefinition \
+terminacurrentcolor terminacurrentlistentrywrapper terminadelimited terminadelimitedtext terminadisplaymath \
+terminadmath terminadocument terminaeffect terminaelement terminaelemento \
+terminaembeddedxtable terminaendnote terminaendofline terminaexceptions terminaexpanded \
+terminaexpandedcollect terminaextendedcatcodetable terminaexternalfigurecollection terminafacingfloat terminafact \
+terminafigure terminafiguretext terminafittingpage terminafixed terminafloatcombination \
+terminafont terminafontclass terminafontsolution terminafootnote terminaformula \
+terminaformulas terminaframedcell terminaframedcontent terminaframedrow terminaframedtable \
+terminaframedtext terminafrontmatter terminagraphictext terminagridsnapping terminahanging \
+terminahbox terminahboxestohbox terminahboxregister terminaheadtext terminahelptext \
+terminahiding terminahighlight terminahyphenation terminaimath terminaimpaccato \
+terminaincorniciato terminaindentation terminaindentedtext terminainteraction terminainterface \
+terminaintermezzotext terminaintertext terminaitemgroup terminaitemgroupcolumns terminaitemize \
+terminaknockout terminalabeltext terminalayout terminalegend terminalinealignment \
+terminalineamargine terminalineatesto terminalinecorrection terminalinefiller terminalinenumbering \
+terminalines terminalinetable terminalinetablebody terminalinetablecell terminalinetablehead \
+terminalingua terminalocalfootnotes terminalocalheadsetup terminalocallinecorrection terminalocalnotes \
terminalocalsetups terminalua terminaluacode terminaluaparameterset terminaluasetups \
-terminamakeup terminamarginblock terminamarkedcontent terminamathalignment terminamathcases \
-terminamathlabeltext terminamathmatrix terminamathmode terminamathstyle terminamatrices \
-terminamatrix terminamaxaligned terminamdformula terminamenuinterattivo terminamettiformula \
-terminamiddlealigned terminamiddlemakeup terminamixedcolumns terminamode terminamodeset \
-terminamodule terminamoduletestsection terminampformula terminanamedsection terminanamedsubformulas \
-terminanarrow terminanarrower terminanegative terminanicelyfilledbox terminanointerference \
-terminanotallmodes terminanotext terminanotmode terminaoperatortext terminaopposite \
-terminaoutputstream terminaoverlay terminaoverprint terminapagecomment terminapagefigure \
-terminapagegrid terminapagegridspan terminapagelayout terminapagemakeup terminapar \
+terminamakeup terminamarginblock terminamarkedcontent terminamarkpages terminamathalignment \
+terminamathcases terminamathlabeltext terminamathmatrix terminamathmode terminamathstyle \
+terminamatrices terminamatrix terminamaxaligned terminamdformula terminamenuinterattivo \
+terminamettiformula terminamiddlealigned terminamiddlemakeup terminamixedcolumns terminamode \
+terminamodeset terminamodule terminamoduletestsection terminampformula terminanamedsection \
+terminanamedsubformulas terminanarrow terminanarrower terminanegative terminanicelyfilledbox \
+terminanointerference terminanotallmodes terminanotext terminanotmode terminaoperatortext \
+terminaopposite terminaoutputstream terminaoverlay terminaoverprint terminapagecolumns \
+terminapagecomment terminapagefigure terminapagelayout terminapagemakeup terminapar \
terminaparagraph terminaparagraphs terminaparagraphscell terminaparbuilder terminapart \
terminapath terminaplacechemical terminaplacefigure terminaplacefloat terminaplacegraphic \
terminaplaceintermezzo terminaplacelegend terminaplacepairedbox terminaplacetable terminapositioning \
-terminapositionoverlay terminapositive terminapostponing terminaprefixtext terminaprocessassignmentcommand \
-terminaprocessassignmentlist terminaprocesscommacommand terminaprocesscommalist terminaprodotto terminaprogetto \
-terminaprotect terminaprotectedcolors terminapubblicazione terminapunctuation terminaquotation \
-terminaquote terminarandomized terminarandomseed terminarawsetups terminareadingfile \
-terminareferenceprefix terminaregime terminareusableMPgraphic terminariga terminascript \
-terminasdformula terminasection terminasectionblock terminasectionblockenvironment terminasectionlevel \
-terminasetups terminasfondo terminashapebox terminashift terminasidebar \
-terminasimplecolumns terminaspecialitem terminaspeech terminaspformula terminasplitformula \
-terminaspread terminastandardmakeup terminastartstop terminastaticMPfigure terminastaticMPgraphic \
-terminastrictinspectnextcharacter terminastrut terminastyle terminasubformulas terminasubject \
-terminasubjectlevel terminasubsection terminasubsentence terminasubstack terminasubsubject \
-terminasubsubsection terminasubsubsubject terminasubsubsubsection terminasubsubsubsubject terminasubsubsubsubsection \
-terminasubsubsubsubsubject terminasuffixtext terminasymbolset terminatable terminatablehead \
-terminatables terminatabletail terminatabletext terminatabulate terminatabulatehead \
-terminatabulatetail terminatagged terminataglabeltext terminatesta terminatexcode \
-terminatexdefinition terminatext terminatextbackground terminatextbackgroundmanual terminatextcolor \
-terminatextcolorintent terminatextflow terminatextmakeup terminatitle terminatokens \
-terminatransparent terminatypescript terminatypescriptcollection terminatyping terminauniqueMPgraphic \
-terminauniqueMPpagegraphic terminaunittext terminaunpacked terminausableMPgraphic terminauseMPgraphic \
-terminausemathstyleparameter terminausingbtxspecification terminavaia terminavbox terminavboxregister \
-terminavboxtohbox terminavboxtohboxseparator terminaviewerlayer terminavtop terminavtopregister \
-terminaxcell terminaxcellgroup terminaxgroup terminaxmldisplayverbatim terminaxmlinlineverbatim \
+terminapositionoverlay terminapositive terminapostponing terminapostponingnotes terminaprefixtext \
+terminaprocessassignmentcommand terminaprocessassignmentlist terminaprocesscommacommand terminaprocesscommalist terminaprodotto \
+terminaprogetto terminaprotect terminaprotectedcolors terminapubblicazione terminapunctuation \
+terminaquotation terminaquote terminarandomized terminarandomseed terminarawsetups \
+terminareadingfile terminareferenceprefix terminaregime terminareusableMPgraphic terminariga \
+terminaruby terminascript terminasdformula terminasection terminasectionblock \
+terminasectionblockenvironment terminasectionlevel terminasetups terminasfondo terminashapebox \
+terminashift terminasidebar terminasimplecolumns terminaspecialitem terminaspeech \
+terminaspformula terminasplitformula terminasplittext terminaspread terminastandardmakeup \
+terminastaticMPfigure terminastaticMPgraphic terminastrictinspectnextcharacter terminastrut terminastyle \
+terminasubformulas terminasubject terminasubjectlevel terminasubsection terminasubsentence \
+terminasubstack terminasubsubject terminasubsubsection terminasubsubsubject terminasubsubsubsection \
+terminasubsubsubsubject terminasubsubsubsubsection terminasubsubsubsubsubject terminasuffixtext terminasymbolset \
+terminatable terminatablehead terminatables terminatabletail terminatabletext \
+terminatabulate terminatabulatehead terminatabulatetail terminatagged terminataglabeltext \
+terminatesta terminatexcode terminatexdefinition terminatext terminatextbackground \
+terminatextbackgroundmanual terminatextcolor terminatextcolorintent terminatextflow terminatextmakeup \
+terminatitle terminatokenlist terminatokens terminatransparent terminatypescript \
+terminatypescriptcollection terminatyping terminauniqueMPgraphic terminauniqueMPpagegraphic terminaunittext \
+terminaunpacked terminausableMPgraphic terminauseMPgraphic terminausemathstyleparameter terminauserdata \
+terminausingbtxspecification terminavaia terminavbox terminavboxregister terminavboxtohbox \
+terminavboxtohboxseparator terminaviewerlayer terminavtop terminavtopregister terminaxcell \
+terminaxcellgroup terminaxcolumn terminaxgroup terminaxmldisplayverbatim terminaxmlinlineverbatim \
terminaxmlraw terminaxmlsetups terminaxrow terminaxrowgroup terminaxtable \
terminaxtablebody terminaxtablefoot terminaxtablehead terminaxtablenext testonotapdp \
testoriempimento tieniblocchi traduci usaJSscripts usaURL \
@@ -1774,50 +1802,51 @@ definieer definieeraccent definieeralineas definieerblok definieerbuffer \
definieercombinatie definieercommando definieerconversie definieerfiguursymbool definieerfont \
definieerfontstijl definieerfontsynoniem definieerhbox definieeringesprongentext definieerinteractiemenu \
definieeritemgroep definieerkadertekst definieerkarakter definieerkleur definieerkleurgroep \
-definieerkolomovergang definieerkop definieerkorps definieerkorpsomgeving definieerlayer \
-definieerlayout definieerletter definieerlijst definieermarkering definieeromlijnd \
-definieeropmaak definieeroverlay definieerpaginaovergang definieerpalet definieerpapierformaat \
-definieerplaats definieerplaatsblok definieerprofiel definieerprogramma definieerreferentie \
-definieerreferentieformaat definieerregister definieersamengesteldelijst definieersectie definieersectieblok \
-definieersorteren definieerstartstop definieersubveld definieersymbool definieersynoniemen \
-definieertabelvorm definieertabulatie definieertekst definieertekstachtergrond definieertype \
-definieertypen definieerveld definieerveldstapel definieerwiskundeuitlijnen doordefinieren \
-doorlabelen doornummeren dunnelijn dunnelijnen eenregel \
-ergens externfiguur formulenummer gebruikJSscripts gebruikURL \
-gebruikblokken gebruikexterndocument gebruikexternfiguur gebruikexterngeluidsfragment gebruikmodule \
-gebruikpad gebruiksymbolen gebruiktypescript gebruiktypescriptfile gebruikurl \
-geenbovenenonderregels geenhoofdenvoetregels geenspatie grijskleur haalbuffer \
-haalmarkering haarlijn handhaafblokken hoofdtaal hoog \
-huidigedatum huidigekopnummer inlijnd inregel installeertaal \
-interactiebalk interactiebuttons interactiemenu invullijnen invulregel \
-invultekst kleur kleurenbalk kleurwaarde kloonveld \
-kolom kopnummer laag laho legeregels \
-letter letters lijndikte lijstlengte maand \
-markeer naar naarbox naarpagina nokap \
-noot omgeving omlaag omlijnd onbekend \
-onderdeel op oppagina pagina paginanummer \
-paginareferentie paslayoutaan passendveld plaatsbookmarks plaatsformule \
-plaatskopnummer plaatskoptekst plaatslijst plaatslijstmetsynoniemen plaatslokalevoetnoten \
-plaatsnaastelkaar plaatsonderelkaar plaatsopgrid plaatspaginanummer plaatsplaatsblok \
-plaatsregister plaatsruwelijst plaatssamengesteldelijst plaatssubformule plaatsvoetnoten \
-positioneer produkt programma projekt punten \
-refereer referentie regellinks regelmidden regelrechts \
-resetmarkering romeins rooster roteer schaal \
-scherm schrijfnaarlijst schrijftussenlijst selecteerblokken som \
-spatie spiegel splitsplaatsblok startachtergrond startinteractiemenu \
-startkantlijn startkleur startkop startlokalevoetnoten startmargeblok \
-startnaar startomgeving startomlijnd startonderdeel startopelkaar \
-startplaatsformule startplaatsplaatsblok startprodukt startprojekt startpublicatie \
-startregel startregelcorrectie startregellinks startregelmidden startregelrechts \
-startsom starttekstachtergrond starttekstlijn startuitlijnen stelachtergrondenin \
-stelachtergrondin stelalineasin stelarrangerenin stelblankoin stelblokin \
-stelblokjesin stelblokkopjein stelblokkopjesin stelbovenin stelboventekstenin \
-stelbufferin stelciterenin stelclipin stelcommentaarin steldoordefinierenin \
-steldoornummerenin steldunnelijnenin stelformulein stelformulesin stelformulierenin \
-stelhoofdin stelhoofdtekstenin stelingesprongentextin stelinmargein stelinspringenin \
-stelinteractiebalkin stelinteractiein stelinteractiemenuin stelinteractieschermin stelinterliniein \
-stelinvullijnenin stelinvulregelsin stelitemgroepin stelitemsin stelkadertekstenin \
-stelkadertekstin stelkantlijnin stelkapitalenin stelkleurenin stelkleurin \
+definieerkolomgroep definieerkolomovergang definieerkop definieerkorps definieerkorpsomgeving \
+definieerlayer definieerlayout definieerletter definieerlijst definieermarkering \
+definieeromlijnd definieeropmaak definieeroverlay definieerpaginaovergang definieerpalet \
+definieerpapierformaat definieerplaats definieerplaatsblok definieerprofiel definieerprogramma \
+definieerreferentie definieerreferentieformaat definieerregister definieersamengesteldelijst definieersectie \
+definieersectieblok definieersorteren definieerstartstop definieersubveld definieersymbool \
+definieersynoniemen definieertabelvorm definieertabulatie definieertekst definieertekstachtergrond \
+definieertype definieertypen definieerveld definieerveldstapel definieerwiskundeuitlijnen \
+doordefinieren doorlabelen doornummeren dunnelijn dunnelijnen \
+eenregel ergens externfiguur formulenummer gebruikJSscripts \
+gebruikURL gebruikblokken gebruikexterndocument gebruikexternfiguur gebruikexterngeluidsfragment \
+gebruikmodule gebruikpad gebruiksymbolen gebruiktypescript gebruiktypescriptfile \
+gebruikurl geenbovenenonderregels geenhoofdenvoetregels geenspatie grijskleur \
+haalbuffer haalmarkering haarlijn handhaafblokken hoofdtaal \
+hoog huidigedatum huidigekopnummer inlijnd inregel \
+installeertaal interactiebalk interactiebuttons interactiemenu invullijnen \
+invulregel invultekst kleur kleurenbalk kleurwaarde \
+kloonveld kolom kopnummer laag laho \
+legeregels letter letters lijndikte lijstlengte \
+maand markeer naar naarbox naarpagina \
+nokap noot omgeving omlaag omlijnd \
+onbekend onderdeel op oppagina pagina \
+paginanummer paginareferentie paslayoutaan passendveld plaatsbookmarks \
+plaatsformule plaatskopnummer plaatskoptekst plaatslijst plaatslijstmetsynoniemen \
+plaatslokalevoetnoten plaatsnaastelkaar plaatsonderelkaar plaatsopgrid plaatspaginanummer \
+plaatsplaatsblok plaatsregister plaatsruwelijst plaatssamengesteldelijst plaatssubformule \
+plaatsvoetnoten positioneer produkt programma projekt \
+punten refereer referentie regellinks regelmidden \
+regelrechts resetmarkering romeins rooster roteer \
+schaal scherm schrijfnaarlijst schrijftussenlijst selecteerblokken \
+som spatie spiegel splitsplaatsblok startachtergrond \
+startinteractiemenu startkantlijn startkleur startkop startlokalevoetnoten \
+startmargeblok startnaar startomgeving startomlijnd startonderdeel \
+startopelkaar startplaatsformule startplaatsplaatsblok startprodukt startprojekt \
+startpublicatie startregel startregelcorrectie startregellinks startregelmidden \
+startregelrechts startsom starttaal starttekstachtergrond starttekstlijn \
+startuitlijnen stelachtergrondenin stelachtergrondin stelalineasin stelarrangerenin \
+stelblankoin stelblokin stelblokjesin stelblokkopjein stelblokkopjesin \
+stelbovenin stelboventekstenin stelbufferin stelciterenin stelclipin \
+stelcommentaarin steldoordefinierenin steldoornummerenin steldunnelijnenin stelformulein \
+stelformulesin stelformulierenin stelhoofdin stelhoofdtekstenin stelingesprongentextin \
+stelinmargein stelinspringenin stelinteractiebalkin stelinteractiein stelinteractiemenuin \
+stelinteractieschermin stelinterliniein stelinvullijnenin stelinvulregelsin stelitemgroepin \
+stelitemsin stelkadertekstenin stelkadertekstin stelkantlijnin stelkapitalenin \
+stelkleurenin stelkleurin stelkolomgroepin stelkolomgroepregelsin stelkolomgroepstartin \
stelkolommenin stelkopin stelkopnummerin stelkoppeltekenin stelkoppenin \
stelkorpsin stellayoutin stellijndiktein stellijstin stelmargeblokkenin \
stelmarkeringin stelnaastplaatsenin stelomlijndin stelonderin stelondertekstenin \
@@ -1835,16 +1864,16 @@ stopinteractiemenu stopkantlijn stopkleur stopkop stoplokalevoetnoten \
stopmargeblok stopnaar stopomgeving stopomlijnd stoponderdeel \
stopopelkaar stopplaatsformule stopplaatsplaatsblok stopprodukt stopprojekt \
stoppublicatie stopregel stopregelcorrectie stopregellinks stopregelmidden \
-stopregelrechts stopsom stoptekstachtergrond stoptekstlijn stopuitlijnen \
-subpaginanummer switchnaarkorps symbool taal tekstlijn \
-tekstreferentie testkolom testpagina toelichting toongrid \
-tooninstellingen toonkader toonkleur toonkleurgroep toonkorps \
-toonkorpsomgeving toonlayout toonopmaak toonpalet toonprint \
-toonstruts toonsymboolset uit uitgerekt vastespatie \
-vastespaties veld veldstapel verbergblokken vergelijkkleurgroep \
-vergelijkpalet versie vertaal verwerkblokken voetnoottekst \
-volledigepaginanummer volledigregister voluit weekdag wiskunde \
-woordrechts
+stopregelrechts stopsom stoptaal stoptekstachtergrond stoptekstlijn \
+stopuitlijnen subpaginanummer switchnaarkorps symbool taal \
+tekstlijn tekstreferentie testkolom testpagina toelichting \
+toongrid tooninstellingen toonkader toonkleur toonkleurgroep \
+toonkorps toonkorpsomgeving toonlayout toonopmaak toonpalet \
+toonprint toonstruts toonsymboolset uit uitgerekt \
+vastespatie vastespaties veld veldstapel verbergblokken \
+vergelijkkleurgroep vergelijkpalet versie vertaal verwerkblokken \
+voetnoottekst volledigepaginanummer volledigregister voluit weekdag \
+wiskunde woordrechts
keywordclass.context.pe=\
آیتم آیتمها آینه از \
@@ -1856,200 +1885,204 @@ keywordclass.context.pe=\
بارگذاری‌تایپ‌کردن بارگذاری‌ترتیب بارگذاری‌تنظیم بارگذاری‌تنظیم‌ریاضی بارگذاری‌ته‌برگ \
بارگذاری‌تورفتگی بارگذاری‌توضیح بارگذاری‌توضیح‌صفحه بارگذاری‌ثبت بارگذاری‌جانشانی \
بارگذاری‌جدولها بارگذاری‌جدول‌بندی بارگذاری‌خالی بارگذاری‌خطها بارگذاری‌خطهای‌حاشیه \
-بارگذاری‌خطهای‌سیاه بارگذاری‌خطهای‌متن بارگذاری‌خطها‌ی‌نازک بارگذاری‌درج‌درخطها بارگذاری‌درج‌مخالف \
-بارگذاری‌دوران بارگذاری‌رنگ بارگذاری‌رنگها بارگذاری‌زبان بارگذاری‌ستونها \
-بارگذاری‌سر بارگذاری‌سربرگ بارگذاری‌سرها بارگذاری‌شرح بارگذاری‌شرحها \
-بارگذاری‌شروع‌پایان بارگذاری‌شماره‌زیرصفحه بارگذاری‌شماره‌سر بارگذاری‌شماره‌صفحه بارگذاری‌شماره‌گذاریها \
-بارگذاری‌شماره‌گذاری‌صفحه بارگذاری‌شماره‌گذاری‌پاراگراف بارگذاری‌شماره‌‌گذاری‌خط بارگذاری‌شناور بارگذاری‌شناورها \
-بارگذاری‌شکافتن‌شناورها بارگذاری‌طرح بارگذاری‌طرح‌بندی بارگذاری‌عرض‌خط بارگذاری‌فاصله‌بین‌خط \
-بارگذاری‌فرمولها بارگذاری‌فضای‌سفید بارگذاری‌فضا‌گذاری بارگذاری‌قالبی بارگذاری‌قلم‌متن \
-بارگذاری‌لوح بارگذاری‌لیست بارگذاری‌لیست‌ترکیبی بارگذاری‌مترادفها بارگذاری‌متن \
-بارگذاری‌متنهای‌بالا بارگذاری‌متن‌سربرگ بارگذاری‌متن‌قالبی بارگذاری‌متن‌متنها بارگذاری‌متن‌پانوشت \
-بارگذاری‌متن‌پایین بارگذاری‌مجموعه‌نماد بارگذاری‌منوی‌پانل بارگذاری‌مکان‌گذاری بارگذاری‌میدان \
-بارگذاری‌میدانها بارگذاری‌میله‌پانل بارگذاری‌نشانه‌شکستن بارگذاری‌نشانه‌گذاری بارگذاری‌نقل \
-بارگذاری‌پاراگرافها بارگذاری‌پانل بارگذاری‌پایین بارگذاری‌پرده‌پانل بارگذاری‌پرکردن‌خطها \
-بارگذاری‌پس‌زمینه بارگذاری‌پس‌زمینه‌ها بارگذاری‌چیدن بارگذاری‌گذارصفحه بارگذاری‌گروههای‌آیتم \
-بارگذاری‌گروه‌آیتم بازنشانی‌نشانه‌گذاری بدون‌خط‌بالاوپایین بدون‌خط‌سروته‌برگ بدون‌فضا \
-برنامه بروبه بروبه‌جعبه بروبه‌صفحه بروپایین \
-بلند بلوکهای‌پردازش بلوکها‌پنهان بنویس‌بین‌لیست بنویس‌در‌لیست \
-تاریخ تاریخ‌جاری تایپ تایپ‌بافر تایپ‌پرونده \
-ترجمه تعریف تعریف‌آرایش تعریف‌الگوی‌جدول تعریف‌اندازه‌برگ \
-تعریف‌بافر تعریف‌بخش تعریف‌برنامه تعریف‌برچسب تعریف‌بلوک \
-تعریف‌بلوک‌بخش تعریف‌تایپ تعریف‌تایپ‌کردن تعریف‌تبدیل تعریف‌ترتیب \
-تعریف‌ترکیب تعریف‌تنظیم‌ریاضی تعریف‌توده‌میدان تعریف‌ثبت تعریف‌جانشانی \
-تعریف‌جدول‌بندی تعریف‌جعبه‌‌افقی تعریف‌حرف تعریف‌رنگ تعریف‌زیرمیدان \
-تعریف‌سبک تعریف‌سبک‌قلم تعریف‌سر تعریف‌شرح تعریف‌شروع‌پایان \
-تعریف‌شماره‌بندی تعریف‌شمایل‌مرجع تعریف‌شناور تعریف‌شکستن‌ستون تعریف‌شکست‌صفحه \
-تعریف‌طرح‌بندی تعریف‌فرمان تعریف‌قالبی تعریف‌قلم تعریف‌قلم‌متن \
-تعریف‌لایه تعریف‌لهجه تعریف‌لوح تعریف‌لیست تعریف‌لیست‌ترکیبی \
-تعریف‌مترادفها تعریف‌مترادف‌قلم تعریف‌متن تعریف‌متن‌قالبی تعریف‌محیط‌قلم‌بدنه \
-تعریف‌مرجع تعریف‌منوی‌پانل تعریف‌میدان تعریف‌نشانه‌گذاری تعریف‌نماد \
-تعریف‌نمادشکل تعریف‌پاراگرافها تعریف‌پروفایل تعریف‌پوشش تعریف‌گروه‌آیتم \
-تعریف‌گروه‌رنگ تعیین‌شماره‌سر تعیین‌محتوای‌متن تعیین‌مشخصات‌ثبت تعیین‌مشخصات‌لیست \
-تغییربه‌قلم‌بدنه تنظیم‌راست تنظیم‌طرح‌بندی تنظیم‌وسط توجه \
-توری تولید تک ثبت‌کامل حرف \
-حرفها حفظ‌بلوکها خالی خطهای‌سیاه خطهای‌نازک \
-خطها‌خالی خط‌سیاه خط‌متن خط‌مو خط‌نازک \
-خ‌ا خ‌ع در درج‌ثبت درج‌درخط \
-درج‌درخطها درج‌درمتن درج‌در‌بالای‌یکدیگر درج‌در‌توری درج‌زیرفرمول \
-درج‌شماره‌سر درج‌شماره‌صفحه درج‌شناور درج‌فرمول درج‌لیست \
-درج‌لیست‌خام درج‌لیست‌مختلط درج‌متن‌سر درج‌پانوشتها درج‌پانوشتهای‌موضعی \
-درج‌چوب‌خط درج‌کنار‌به‌کنار درخط درصفحه درقالبی \
-درمورد درون درپر دریافت‌بافر دریافت‌نشانه \
-دوران دکمه دکمه‌منو دکمه‌پانل رج \
-رنگ رنگ‌خاکستری روزهفته ریاضی زبان \
-زبان‌اصلی ستون ستون‌امتحان سرپوش‌کوچک‌نه شروعJScode \
-شروعJSpreamble شروعLUA شروعMP شروعMPclip شروعMPcode \
-شروعMPdefinitions شروعMPdrawing شروعMPenvironment شروعMPextensions شروعMPinclusions \
-شروعMPinitializations شروعMPpage شروعMPpositiongraphic شروعMPpositionmethod شروعMPrun \
-شروعPARSEDXML شروعTABLE شروعTABLEbody شروعTABLEfoot شروعTABLEhead \
-شروعTABLEnext شروعTC شروعTD شروعTDs شروعTEX \
-شروعTEXpage شروعTH شروعTN شروعTR شروعTRs \
-شروعTX شروعTY شروعXML شروعalign شروعalignment \
-شروعallmodes شروعappendices شروعarrangedpages شروعaside شروعattachment \
-شروعbackmatter شروعbar شروعbbordermatrix شروعbitmapimage شروعblockquote \
-شروعbodymatter شروعbordermatrix شروعboxedcolumns شروعbtxlabeltext شروعbtxrenderingdefinitions \
-شروعbuffer شروعcases شروعcatcodetable شروعcenteraligned شروعchapter \
-شروعcharacteralign شروعcheckedfences شروعchemical شروعchemicaltext شروعcollect \
-شروعcollecting شروعcolorintent شروعcoloronly شروعcolorset شروعcolumns \
-شروعcolumnspan شروعcombination شروعcomment شروعcontextcode شروعcontextdefinitioncode \
-شروعctxfunction شروعctxfunctiondefinition شروعcurrentcolor شروعcurrentlistentrywrapper شروعdelimited \
-شروعdelimitedtext شروعdisplaymath شروعdmath شروعdocument شروعeffect \
-شروعelement شروعembeddedxtable شروعendnote شروعendofline شروعexceptions \
-شروعexpanded شروعexpandedcollect شروعextendedcatcodetable شروعexternalfigurecollection شروعfact \
-شروعfigure شروعfiguretext شروعfittingpage شروعfixed شروعfloatcombination \
-شروعfont شروعfontclass شروعfontsolution شروعfootnote شروعformula \
-شروعformulas شروعframedcell شروعframedcontent شروعframedrow شروعframedtable \
-شروعframedtext شروعfrontmatter شروعgraphictext شروعgridsnapping شروعhanging \
-شروعhbox شروعhboxestohbox شروعhboxregister شروعheadtext شروعhelptext \
-شروعhiding شروعhighlight شروعhyphenation شروعimath شروعindentation \
-شروعindentedtext شروعinteraction شروعinterface شروعintermezzotext شروعintertext \
-شروعitemgroup شروعitemgroupcolumns شروعitemize شروعknockout شروعlabeltext \
-شروعlayout شروعlegend شروعlinealignment شروعlinecorrection شروعlinefiller \
-شروعlinenumbering شروعlines شروعlinetable شروعlinetablebody شروعlinetablecell \
-شروعlinetablehead شروعlocalfootnotes شروعlocalheadsetup شروعlocallinecorrection شروعlocalnotes \
-شروعlocalsetups شروعlua شروعluacode شروعluaparameterset شروعluasetups \
-شروعmakeup شروعmarginblock شروعmarkedcontent شروعmathalignment شروعmathcases \
-شروعmathlabeltext شروعmathmatrix شروعmathmode شروعmathstyle شروعmatrices \
-شروعmatrix شروعmaxaligned شروعmdformula شروعmiddlealigned شروعmiddlemakeup \
-شروعmixedcolumns شروعmode شروعmodeset شروعmodule شروعmoduletestsection \
-شروعmpformula شروعnamedsection شروعnamedsubformulas شروعnarrow شروعnarrower \
-شروعnegative شروعnicelyfilledbox شروعnointerference شروعnotallmodes شروعnotext \
-شروعnotmode شروعoperatortext شروعopposite شروعoutputstream شروعoverlay \
-شروعoverprint شروعpagecomment شروعpagefigure شروعpagegrid شروعpagegridspan \
-شروعpagelayout شروعpagemakeup شروعpar شروعparagraph شروعparagraphs \
-شروعparagraphscell شروعparbuilder شروعpart شروعpath شروعplacechemical \
-شروعplacefigure شروعplacegraphic شروعplaceintermezzo شروعplacelegend شروعplacepairedbox \
-شروعplacetable شروعpositioning شروعpositionoverlay شروعpositive شروعpostponing \
-شروعprefixtext شروعprocessassignmentcommand شروعprocessassignmentlist شروعprocesscommacommand شروعprocesscommalist \
-شروعprotect شروعprotectedcolors شروعpunctuation شروعquotation شروعquote \
-شروعrandomized شروعrandomseed شروعrawsetups شروعreadingfile شروعreferenceprefix \
-شروعregime شروعreusableMPgraphic شروعscript شروعsdformula شروعsection \
-شروعsectionblock شروعsectionblockenvironment شروعsectionlevel شروعsetups شروعshapebox \
-شروعshift شروعsidebar شروعsimplecolumns شروعspecialitem شروعspeech \
-شروعspformula شروعsplitformula شروعspread شروعstandardmakeup شروعstartstop \
-شروعstaticMPfigure شروعstaticMPgraphic شروعstrictinspectnextcharacter شروعstrut شروعstyle \
-شروعsubformulas شروعsubject شروعsubjectlevel شروعsubsection شروعsubsentence \
-شروعsubstack شروعsubsubject شروعsubsubsection شروعsubsubsubject شروعsubsubsubsection \
-شروعsubsubsubsubject شروعsubsubsubsubsection شروعsubsubsubsubsubject شروعsuffixtext شروعsymbolset \
-شروعtable شروعtablehead شروعtables شروعtabletail شروعtabletext \
-شروعtabulate شروعtabulatehead شروعtabulatetail شروعtagged شروعtaglabeltext \
-شروعtexcode شروعtexdefinition شروعtext شروعtextbackground شروعtextbackgroundmanual \
-شروعtextcolor شروعtextcolorintent شروعtextflow شروعtextmakeup شروعtitle \
+بارگذاری‌خطهای‌سیاه بارگذاری‌خطهای‌متن بارگذاری‌خطهای‌مجموعه‌ستون بارگذاری‌خطها‌ی‌نازک بارگذاری‌درج‌درخطها \
+بارگذاری‌درج‌مخالف بارگذاری‌دوران بارگذاری‌رنگ بارگذاری‌رنگها بارگذاری‌زبان \
+بارگذاری‌ستونها بارگذاری‌سر بارگذاری‌سربرگ بارگذاری‌سرها بارگذاری‌شرح \
+بارگذاری‌شرحها بارگذاری‌شروع‌مجموعه‌ستون بارگذاری‌شروع‌پایان بارگذاری‌شماره‌زیرصفحه بارگذاری‌شماره‌سر \
+بارگذاری‌شماره‌صفحه بارگذاری‌شماره‌گذاریها بارگذاری‌شماره‌گذاری‌صفحه بارگذاری‌شماره‌گذاری‌پاراگراف بارگذاری‌شماره‌‌گذاری‌خط \
+بارگذاری‌شناور بارگذاری‌شناورها بارگذاری‌شکافتن‌شناورها بارگذاری‌طرح بارگذاری‌طرح‌بندی \
+بارگذاری‌عرض‌خط بارگذاری‌فاصله‌بین‌خط بارگذاری‌فرمولها بارگذاری‌فضای‌سفید بارگذاری‌فضا‌گذاری \
+بارگذاری‌قالبی بارگذاری‌قلم‌متن بارگذاری‌لوح بارگذاری‌لیست بارگذاری‌لیست‌ترکیبی \
+بارگذاری‌مترادفها بارگذاری‌متن بارگذاری‌متنهای‌بالا بارگذاری‌متن‌سربرگ بارگذاری‌متن‌قالبی \
+بارگذاری‌متن‌متنها بارگذاری‌متن‌پانوشت بارگذاری‌متن‌پایین بارگذاری‌مجموعه‌ستون بارگذاری‌مجموعه‌نماد \
+بارگذاری‌منوی‌پانل بارگذاری‌مکان‌گذاری بارگذاری‌میدان بارگذاری‌میدانها بارگذاری‌میله‌پانل \
+بارگذاری‌نشانه‌شکستن بارگذاری‌نشانه‌گذاری بارگذاری‌نقل بارگذاری‌پاراگرافها بارگذاری‌پانل \
+بارگذاری‌پایین بارگذاری‌پرده‌پانل بارگذاری‌پرکردن‌خطها بارگذاری‌پس‌زمینه بارگذاری‌پس‌زمینه‌ها \
+بارگذاری‌چیدن بارگذاری‌گذارصفحه بارگذاری‌گروههای‌آیتم بارگذاری‌گروه‌آیتم بازنشانی‌نشانه‌گذاری \
+بدون‌خط‌بالاوپایین بدون‌خط‌سروته‌برگ بدون‌فضا برنامه بروبه \
+بروبه‌جعبه بروبه‌صفحه بروپایین بلند بلوکهای‌پردازش \
+بلوکها‌پنهان بنویس‌بین‌لیست بنویس‌در‌لیست تاریخ تاریخ‌جاری \
+تایپ تایپ‌بافر تایپ‌پرونده ترجمه تعریف \
+تعریف‌آرایش تعریف‌الگوی‌جدول تعریف‌اندازه‌برگ تعریف‌بافر تعریف‌بخش \
+تعریف‌برنامه تعریف‌برچسب تعریف‌بلوک تعریف‌بلوک‌بخش تعریف‌تایپ \
+تعریف‌تایپ‌کردن تعریف‌تبدیل تعریف‌ترتیب تعریف‌ترکیب تعریف‌تنظیم‌ریاضی \
+تعریف‌توده‌میدان تعریف‌ثبت تعریف‌جانشانی تعریف‌جدول‌بندی تعریف‌جعبه‌‌افقی \
+تعریف‌حرف تعریف‌رنگ تعریف‌زیرمیدان تعریف‌سبک تعریف‌سبک‌قلم \
+تعریف‌سر تعریف‌شرح تعریف‌شروع‌پایان تعریف‌شماره‌بندی تعریف‌شمایل‌مرجع \
+تعریف‌شناور تعریف‌شکستن‌ستون تعریف‌شکست‌صفحه تعریف‌طرح‌بندی تعریف‌فرمان \
+تعریف‌قالبی تعریف‌قلم تعریف‌قلم‌متن تعریف‌لایه تعریف‌لهجه \
+تعریف‌لوح تعریف‌لیست تعریف‌لیست‌ترکیبی تعریف‌مترادفها تعریف‌مترادف‌قلم \
+تعریف‌متن تعریف‌متن‌قالبی تعریف‌مجموعه‌ستون تعریف‌محیط‌قلم‌بدنه تعریف‌مرجع \
+تعریف‌منوی‌پانل تعریف‌میدان تعریف‌نشانه‌گذاری تعریف‌نماد تعریف‌نمادشکل \
+تعریف‌پاراگرافها تعریف‌پروفایل تعریف‌پوشش تعریف‌گروه‌آیتم تعریف‌گروه‌رنگ \
+تعیین‌شماره‌سر تعیین‌محتوای‌متن تعیین‌مشخصات‌ثبت تعیین‌مشخصات‌لیست تغییربه‌قلم‌بدنه \
+تنظیم‌راست تنظیم‌طرح‌بندی تنظیم‌وسط توجه توری \
+تولید تک ثبت‌کامل حرف حرفها \
+حفظ‌بلوکها خالی خطهای‌سیاه خطهای‌نازک خطها‌خالی \
+خط‌سیاه خط‌متن خط‌مو خط‌نازک خ‌ا \
+خ‌ع در درج‌ثبت درج‌درخط درج‌درخطها \
+درج‌درمتن درج‌در‌بالای‌یکدیگر درج‌در‌توری درج‌زیرفرمول درج‌شماره‌سر \
+درج‌شماره‌صفحه درج‌شناور درج‌فرمول درج‌لیست درج‌لیست‌خام \
+درج‌لیست‌مختلط درج‌متن‌سر درج‌پانوشتها درج‌پانوشتهای‌موضعی درج‌چوب‌خط \
+درج‌کنار‌به‌کنار درخط درصفحه درقالبی درمورد \
+درون درپر دریافت‌بافر دریافت‌نشانه دوران \
+دکمه دکمه‌منو دکمه‌پانل رج رنگ \
+رنگ‌خاکستری روزهفته ریاضی زبان زبان‌اصلی \
+ستون ستون‌امتحان سرپوش‌کوچک‌نه شروعJScode شروعJSpreamble \
+شروعLUA شروعMP شروعMPclip شروعMPcode شروعMPdefinitions \
+شروعMPdrawing شروعMPenvironment شروعMPextensions شروعMPinclusions شروعMPinitializations \
+شروعMPpage شروعMPpositiongraphic شروعMPpositionmethod شروعMPrun شروعPARSEDXML \
+شروعTABLE شروعTABLEbody شروعTABLEfoot شروعTABLEhead شروعTABLEnext \
+شروعTC شروعTD شروعTDs شروعTEX شروعTEXpage \
+شروعTH شروعTN شروعTR شروعTRs شروعTX \
+شروعTY شروعXML شروعalign شروعalignment شروعallmodes \
+شروعappendices شروعarrangedpages شروعaside شروعattachment شروعbackmatter \
+شروعbar شروعbbordermatrix شروعbitmapimage شروعblockquote شروعbodymatter \
+شروعbordermatrix شروعboxedcolumns شروعbtxlabeltext شروعbtxrenderingdefinitions شروعbuffer \
+شروعcases شروعcatcodetable شروعcenteraligned شروعchapter شروعcharacteralign \
+شروعcheckedfences شروعchemical شروعchemicaltext شروعcollect شروعcollecting \
+شروعcolorintent شروعcoloronly شروعcolorset شروعcolumns شروعcolumnset \
+شروعcolumnsetspan شروعcolumnspan شروعcombination شروعcomment شروعcontextcode \
+شروعcontextdefinitioncode شروعctxfunction شروعctxfunctiondefinition شروعcurrentcolor شروعcurrentlistentrywrapper \
+شروعdelimited شروعdelimitedtext شروعdisplaymath شروعdmath شروعdocument \
+شروعeffect شروعelement شروعembeddedxtable شروعendnote شروعendofline \
+شروعexceptions شروعexpanded شروعexpandedcollect شروعextendedcatcodetable شروعexternalfigurecollection \
+شروعfacingfloat شروعfact شروعfigure شروعfiguretext شروعfittingpage \
+شروعfixed شروعfloatcombination شروعfont شروعfontclass شروعfontsolution \
+شروعfootnote شروعformula شروعformulas شروعframedcell شروعframedcontent \
+شروعframedrow شروعframedtable شروعframedtext شروعfrontmatter شروعgraphictext \
+شروعgridsnapping شروعhanging شروعhbox شروعhboxestohbox شروعhboxregister \
+شروعheadtext شروعhelptext شروعhiding شروعhighlight شروعhyphenation \
+شروعimath شروعindentation شروعindentedtext شروعinteraction شروعinterface \
+شروعintermezzotext شروعintertext شروعitemgroup شروعitemgroupcolumns شروعitemize \
+شروعknockout شروعlabeltext شروعlayout شروعlegend شروعlinealignment \
+شروعlinecorrection شروعlinefiller شروعlinenumbering شروعlines شروعlinetable \
+شروعlinetablebody شروعlinetablecell شروعlinetablehead شروعlocalfootnotes شروعlocalheadsetup \
+شروعlocallinecorrection شروعlocalnotes شروعlocalsetups شروعlua شروعluacode \
+شروعluaparameterset شروعluasetups شروعmakeup شروعmarginblock شروعmarkedcontent \
+شروعmarkpages شروعmathalignment شروعmathcases شروعmathlabeltext شروعmathmatrix \
+شروعmathmode شروعmathstyle شروعmatrices شروعmatrix شروعmaxaligned \
+شروعmdformula شروعmiddlealigned شروعmiddlemakeup شروعmixedcolumns شروعmode \
+شروعmodeset شروعmodule شروعmoduletestsection شروعmpformula شروعnamedsection \
+شروعnamedsubformulas شروعnarrow شروعnarrower شروعnegative شروعnicelyfilledbox \
+شروعnointerference شروعnotallmodes شروعnotext شروعnotmode شروعoperatortext \
+شروعopposite شروعoutputstream شروعoverlay شروعoverprint شروعpagecolumns \
+شروعpagecomment شروعpagefigure شروعpagelayout شروعpagemakeup شروعpar \
+شروعparagraph شروعparagraphs شروعparagraphscell شروعparbuilder شروعpart \
+شروعpath شروعplacechemical شروعplacefigure شروعplacegraphic شروعplaceintermezzo \
+شروعplacelegend شروعplacepairedbox شروعplacetable شروعpositioning شروعpositionoverlay \
+شروعpositive شروعpostponing شروعpostponingnotes شروعprefixtext شروعprocessassignmentcommand \
+شروعprocessassignmentlist شروعprocesscommacommand شروعprocesscommalist شروعprotect شروعprotectedcolors \
+شروعpunctuation شروعquotation شروعquote شروعrandomized شروعrandomseed \
+شروعrawsetups شروعreadingfile شروعreferenceprefix شروعregime شروعreusableMPgraphic \
+شروعruby شروعscript شروعsdformula شروعsection شروعsectionblock \
+شروعsectionblockenvironment شروعsectionlevel شروعsetups شروعshapebox شروعshift \
+شروعsidebar شروعsimplecolumns شروعspecialitem شروعspeech شروعspformula \
+شروعsplitformula شروعsplittext شروعspread شروعstandardmakeup شروعstaticMPfigure \
+شروعstaticMPgraphic شروعstrictinspectnextcharacter شروعstrut شروعstyle شروعsubformulas \
+شروعsubject شروعsubjectlevel شروعsubsection شروعsubsentence شروعsubstack \
+شروعsubsubject شروعsubsubsection شروعsubsubsubject شروعsubsubsubsection شروعsubsubsubsubject \
+شروعsubsubsubsubsection شروعsubsubsubsubsubject شروعsuffixtext شروعsymbolset شروعtable \
+شروعtablehead شروعtables شروعtabletail شروعtabletext شروعtabulate \
+شروعtabulatehead شروعtabulatetail شروعtagged شروعtaglabeltext شروعtexcode \
+شروعtexdefinition شروعtext شروعtextbackground شروعtextbackgroundmanual شروعtextcolor \
+شروعtextcolorintent شروعtextflow شروعtextmakeup شروعtitle شروعtokenlist \
شروعtokens شروعtransparent شروعtypescript شروعtypescriptcollection شروعtyping \
شروعuniqueMPgraphic شروعuniqueMPpagegraphic شروعunittext شروعunpacked شروعusableMPgraphic \
-شروعuseMPgraphic شروعusemathstyleparameter شروعusingbtxspecification شروعvbox شروعvboxregister \
-شروعvboxtohbox شروعvboxtohboxseparator شروعviewerlayer شروعvtop شروعvtopregister \
-شروعxcell شروعxcellgroup شروعxgroup شروعxmldisplayverbatim شروعxmlinlineverbatim \
-شروعxmlraw شروعxmlsetups شروعxrow شروعxrowgroup شروعxtable \
-شروعxtablebody شروعxtablefoot شروعxtablehead شروعxtablenext شروعآیتم \
-شروعبروبه شروعتنظیم‌راست شروعتنظیم‌وسط شروعتولید شروعخط‌حاشیه \
-شروعخط‌متن شروعدرج‌شناور شروعدرج‌فرمول شروعرنگ شروعسر \
-شروعفشرده شروعقالبی شروعمحیط شروعمنوی‌پانل شروعمولفه \
-شروعنشر شروعپروژه شروعپس‌زمینه شروعچپ‌چین شروع‌خط \
-شماره‌زیرصفحه شماره‌سر شماره‌سرجاری شماره‌صفحه شماره‌صفحه‌کامل \
-شماره‌فرمول شماره‌مبدل شماره‌ها شکافتن‌شناور شکل‌خارجی \
-صفحه صفحه‌تست طول‌لیست عرض‌خط فضا \
-فضاهای‌ثابت فضای‌ثابت فضای‌سفیدصحیح قالبی لوح‌مقایسه \
-ماه متن‌پانوشت محیط مراجعه مرجع \
-مرجع‌صفحه مرجع‌متن مقایسه‌گروه‌رنگ مقداررنگ مقیاس \
-منوی‌پانل مولفه مکان میدان میدان‌شبیه‌سازی \
-میدان‌پشته میدان‌کپی میله‌رنگ میله‌پانل ناشناس \
-نسخه نشانه‌گذاری نصب‌زبان نقطه‌ها نماد \
-نمایش‌آرایش نمایش‌بارگذاریها نمایش‌بستها نمایش‌توری نمایش‌رنگ \
-نمایش‌طرح‌بندی نمایش‌قالب نمایش‌قلم‌بدنه نمایش‌لوح نمایش‌مجموعه‌علامت \
-نمایش‌محیط‌قلم‌بدنه نمایش‌چاپ نمایش‌گروه‌رنگ پابا پایانJScode \
-پایانJSpreamble پایانLUA پایانMP پایانMPclip پایانMPcode \
-پایانMPdefinitions پایانMPdrawing پایانMPenvironment پایانMPextensions پایانMPinclusions \
-پایانMPinitializations پایانMPpage پایانMPpositiongraphic پایانMPpositionmethod پایانMPrun \
-پایانPARSEDXML پایانTABLE پایانTABLEbody پایانTABLEfoot پایانTABLEhead \
-پایانTABLEnext پایانTC پایانTD پایانTDs پایانTEX \
-پایانTEXpage پایانTH پایانTN پایانTR پایانTRs \
-پایانTX پایانTY پایانXML پایانalign پایانalignment \
-پایانallmodes پایانappendices پایانarrangedpages پایانaside پایانattachment \
-پایانbackmatter پایانbar پایانbbordermatrix پایانbitmapimage پایانblockquote \
-پایانbodymatter پایانbordermatrix پایانboxedcolumns پایانbtxlabeltext پایانbtxrenderingdefinitions \
-پایانbuffer پایانcases پایانcatcodetable پایانcenteraligned پایانchapter \
-پایانcharacteralign پایانcheckedfences پایانchemical پایانchemicaltext پایانcollect \
-پایانcollecting پایانcolorintent پایانcoloronly پایانcolorset پایانcolumns \
+شروعuseMPgraphic شروعusemathstyleparameter شروعuserdata شروعusingbtxspecification شروعvbox \
+شروعvboxregister شروعvboxtohbox شروعvboxtohboxseparator شروعviewerlayer شروعvtop \
+شروعvtopregister شروعxcell شروعxcellgroup شروعxcolumn شروعxgroup \
+شروعxmldisplayverbatim شروعxmlinlineverbatim شروعxmlraw شروعxmlsetups شروعxrow \
+شروعxrowgroup شروعxtable شروعxtablebody شروعxtablefoot شروعxtablehead \
+شروعxtablenext شروعآیتم شروعبروبه شروعتنظیم‌راست شروعتنظیم‌وسط \
+شروعتولید شروعخط‌حاشیه شروعخط‌متن شروعدرج‌شناور شروعدرج‌فرمول \
+شروعرنگ شروعزبان شروعسر شروعفشرده شروعقالبی \
+شروعمحیط شروعمنوی‌پانل شروعمولفه شروعنشر شروعپروژه \
+شروعپس‌زمینه شروعچپ‌چین شروع‌خط شماره‌زیرصفحه شماره‌سر \
+شماره‌سرجاری شماره‌صفحه شماره‌صفحه‌کامل شماره‌فرمول شماره‌مبدل \
+شماره‌ها شکافتن‌شناور شکل‌خارجی صفحه صفحه‌تست \
+طول‌لیست عرض‌خط فضا فضاهای‌ثابت فضای‌ثابت \
+فضای‌سفیدصحیح قالبی لوح‌مقایسه ماه متن‌پانوشت \
+محیط مراجعه مرجع مرجع‌صفحه مرجع‌متن \
+مقایسه‌گروه‌رنگ مقداررنگ مقیاس منوی‌پانل مولفه \
+مکان میدان میدان‌شبیه‌سازی میدان‌پشته میدان‌کپی \
+میله‌رنگ میله‌پانل ناشناس نسخه نشانه‌گذاری \
+نصب‌زبان نقطه‌ها نماد نمایش‌آرایش نمایش‌بارگذاریها \
+نمایش‌بستها نمایش‌توری نمایش‌رنگ نمایش‌طرح‌بندی نمایش‌قالب \
+نمایش‌قلم‌بدنه نمایش‌لوح نمایش‌مجموعه‌علامت نمایش‌محیط‌قلم‌بدنه نمایش‌چاپ \
+نمایش‌گروه‌رنگ پابا پایانJScode پایانJSpreamble پایانLUA \
+پایانMP پایانMPclip پایانMPcode پایانMPdefinitions پایانMPdrawing \
+پایانMPenvironment پایانMPextensions پایانMPinclusions پایانMPinitializations پایانMPpage \
+پایانMPpositiongraphic پایانMPpositionmethod پایانMPrun پایانPARSEDXML پایانTABLE \
+پایانTABLEbody پایانTABLEfoot پایانTABLEhead پایانTABLEnext پایانTC \
+پایانTD پایانTDs پایانTEX پایانTEXpage پایانTH \
+پایانTN پایانTR پایانTRs پایانTX پایانTY \
+پایانXML پایانalign پایانalignment پایانallmodes پایانappendices \
+پایانarrangedpages پایانaside پایانattachment پایانbackmatter پایانbar \
+پایانbbordermatrix پایانbitmapimage پایانblockquote پایانbodymatter پایانbordermatrix \
+پایانboxedcolumns پایانbtxlabeltext پایانbtxrenderingdefinitions پایانbuffer پایانcases \
+پایانcatcodetable پایانcenteraligned پایانchapter پایانcharacteralign پایانcheckedfences \
+پایانchemical پایانchemicaltext پایانcollect پایانcollecting پایانcolorintent \
+پایانcoloronly پایانcolorset پایانcolumns پایانcolumnset پایانcolumnsetspan \
پایانcolumnspan پایانcombination پایانcomment پایانcontextcode پایانcontextdefinitioncode \
پایانctxfunction پایانctxfunctiondefinition پایانcurrentcolor پایانcurrentlistentrywrapper پایانdelimited \
پایانdelimitedtext پایانdisplaymath پایانdmath پایانdocument پایانeffect \
پایانelement پایانembeddedxtable پایانendnote پایانendofline پایانexceptions \
-پایانexpanded پایانexpandedcollect پایانextendedcatcodetable پایانexternalfigurecollection پایانfact \
-پایانfigure پایانfiguretext پایانfittingpage پایانfixed پایانfloatcombination \
-پایانfont پایانfontclass پایانfontsolution پایانfootnote پایانformula \
-پایانformulas پایانframedcell پایانframedcontent پایانframedrow پایانframedtable \
-پایانframedtext پایانfrontmatter پایانgraphictext پایانgridsnapping پایانhanging \
-پایانhbox پایانhboxestohbox پایانhboxregister پایانheadtext پایانhelptext \
-پایانhiding پایانhighlight پایانhyphenation پایانimath پایانindentation \
-پایانindentedtext پایانinteraction پایانinterface پایانintermezzotext پایانintertext \
-پایانitemgroup پایانitemgroupcolumns پایانitemize پایانknockout پایانlabeltext \
-پایانlayout پایانlegend پایانlinealignment پایانlinecorrection پایانlinefiller \
-پایانlinenumbering پایانlines پایانlinetable پایانlinetablebody پایانlinetablecell \
-پایانlinetablehead پایانlocalfootnotes پایانlocalheadsetup پایانlocallinecorrection پایانlocalnotes \
-پایانlocalsetups پایانlua پایانluacode پایانluaparameterset پایانluasetups \
-پایانmakeup پایانmarginblock پایانmarkedcontent پایانmathalignment پایانmathcases \
-پایانmathlabeltext پایانmathmatrix پایانmathmode پایانmathstyle پایانmatrices \
-پایانmatrix پایانmaxaligned پایانmdformula پایانmiddlealigned پایانmiddlemakeup \
-پایانmixedcolumns پایانmode پایانmodeset پایانmodule پایانmoduletestsection \
-پایانmpformula پایانnamedsection پایانnamedsubformulas پایانnarrow پایانnarrower \
-پایانnegative پایانnicelyfilledbox پایانnointerference پایانnotallmodes پایانnotext \
-پایانnotmode پایانoperatortext پایانopposite پایانoutputstream پایانoverlay \
-پایانoverprint پایانpagecomment پایانpagefigure پایانpagegrid پایانpagegridspan \
-پایانpagelayout پایانpagemakeup پایانpar پایانparagraph پایانparagraphs \
-پایانparagraphscell پایانparbuilder پایانpart پایانpath پایانplacechemical \
-پایانplacefigure پایانplacegraphic پایانplaceintermezzo پایانplacelegend پایانplacepairedbox \
-پایانplacetable پایانpositioning پایانpositionoverlay پایانpositive پایانpostponing \
-پایانprefixtext پایانprocessassignmentcommand پایانprocessassignmentlist پایانprocesscommacommand پایانprocesscommalist \
-پایانprotect پایانprotectedcolors پایانpunctuation پایانquotation پایانquote \
-پایانrandomized پایانrandomseed پایانrawsetups پایانreadingfile پایانreferenceprefix \
-پایانregime پایانreusableMPgraphic پایانscript پایانsdformula پایانsection \
-پایانsectionblock پایانsectionblockenvironment پایانsectionlevel پایانsetups پایانshapebox \
-پایانshift پایانsidebar پایانsimplecolumns پایانspecialitem پایانspeech \
-پایانspformula پایانsplitformula پایانspread پایانstandardmakeup پایانstartstop \
-پایانstaticMPfigure پایانstaticMPgraphic پایانstrictinspectnextcharacter پایانstrut پایانstyle \
-پایانsubformulas پایانsubject پایانsubjectlevel پایانsubsection پایانsubsentence \
-پایانsubstack پایانsubsubject پایانsubsubsection پایانsubsubsubject پایانsubsubsubsection \
-پایانsubsubsubsubject پایانsubsubsubsubsection پایانsubsubsubsubsubject پایانsuffixtext پایانsymbolset \
-پایانtable پایانtablehead پایانtables پایانtabletail پایانtabletext \
-پایانtabulate پایانtabulatehead پایانtabulatetail پایانtagged پایانtaglabeltext \
-پایانtexcode پایانtexdefinition پایانtext پایانtextbackground پایانtextbackgroundmanual \
-پایانtextcolor پایانtextcolorintent پایانtextflow پایانtextmakeup پایانtitle \
-پایانtokens پایانtransparent پایانtypescript پایانtypescriptcollection پایانtyping \
-پایانuniqueMPgraphic پایانuniqueMPpagegraphic پایانunittext پایانunpacked پایانusableMPgraphic \
-پایانuseMPgraphic پایانusemathstyleparameter پایانusingbtxspecification پایانvbox پایانvboxregister \
+پایانexpanded پایانexpandedcollect پایانextendedcatcodetable پایانexternalfigurecollection پایانfacingfloat \
+پایانfact پایانfigure پایانfiguretext پایانfittingpage پایانfixed \
+پایانfloatcombination پایانfont پایانfontclass پایانfontsolution پایانfootnote \
+پایانformula پایانformulas پایانframedcell پایانframedcontent پایانframedrow \
+پایانframedtable پایانframedtext پایانfrontmatter پایانgraphictext پایانgridsnapping \
+پایانhanging پایانhbox پایانhboxestohbox پایانhboxregister پایانheadtext \
+پایانhelptext پایانhiding پایانhighlight پایانhyphenation پایانimath \
+پایانindentation پایانindentedtext پایانinteraction پایانinterface پایانintermezzotext \
+پایانintertext پایانitemgroup پایانitemgroupcolumns پایانitemize پایانknockout \
+پایانlabeltext پایانlayout پایانlegend پایانlinealignment پایانlinecorrection \
+پایانlinefiller پایانlinenumbering پایانlines پایانlinetable پایانlinetablebody \
+پایانlinetablecell پایانlinetablehead پایانlocalfootnotes پایانlocalheadsetup پایانlocallinecorrection \
+پایانlocalnotes پایانlocalsetups پایانlua پایانluacode پایانluaparameterset \
+پایانluasetups پایانmakeup پایانmarginblock پایانmarkedcontent پایانmarkpages \
+پایانmathalignment پایانmathcases پایانmathlabeltext پایانmathmatrix پایانmathmode \
+پایانmathstyle پایانmatrices پایانmatrix پایانmaxaligned پایانmdformula \
+پایانmiddlealigned پایانmiddlemakeup پایانmixedcolumns پایانmode پایانmodeset \
+پایانmodule پایانmoduletestsection پایانmpformula پایانnamedsection پایانnamedsubformulas \
+پایانnarrow پایانnarrower پایانnegative پایانnicelyfilledbox پایانnointerference \
+پایانnotallmodes پایانnotext پایانnotmode پایانoperatortext پایانopposite \
+پایانoutputstream پایانoverlay پایانoverprint پایانpagecolumns پایانpagecomment \
+پایانpagefigure پایانpagelayout پایانpagemakeup پایانpar پایانparagraph \
+پایانparagraphs پایانparagraphscell پایانparbuilder پایانpart پایانpath \
+پایانplacechemical پایانplacefigure پایانplacegraphic پایانplaceintermezzo پایانplacelegend \
+پایانplacepairedbox پایانplacetable پایانpositioning پایانpositionoverlay پایانpositive \
+پایانpostponing پایانpostponingnotes پایانprefixtext پایانprocessassignmentcommand پایانprocessassignmentlist \
+پایانprocesscommacommand پایانprocesscommalist پایانprotect پایانprotectedcolors پایانpunctuation \
+پایانquotation پایانquote پایانrandomized پایانrandomseed پایانrawsetups \
+پایانreadingfile پایانreferenceprefix پایانregime پایانreusableMPgraphic پایانruby \
+پایانscript پایانsdformula پایانsection پایانsectionblock پایانsectionblockenvironment \
+پایانsectionlevel پایانsetups پایانshapebox پایانshift پایانsidebar \
+پایانsimplecolumns پایانspecialitem پایانspeech پایانspformula پایانsplitformula \
+پایانsplittext پایانspread پایانstandardmakeup پایانstaticMPfigure پایانstaticMPgraphic \
+پایانstrictinspectnextcharacter پایانstrut پایانstyle پایانsubformulas پایانsubject \
+پایانsubjectlevel پایانsubsection پایانsubsentence پایانsubstack پایانsubsubject \
+پایانsubsubsection پایانsubsubsubject پایانsubsubsubsection پایانsubsubsubsubject پایانsubsubsubsubsection \
+پایانsubsubsubsubsubject پایانsuffixtext پایانsymbolset پایانtable پایانtablehead \
+پایانtables پایانtabletail پایانtabletext پایانtabulate پایانtabulatehead \
+پایانtabulatetail پایانtagged پایانtaglabeltext پایانtexcode پایانtexdefinition \
+پایانtext پایانtextbackground پایانtextbackgroundmanual پایانtextcolor پایانtextcolorintent \
+پایانtextflow پایانtextmakeup پایانtitle پایانtokenlist پایانtokens \
+پایانtransparent پایانtypescript پایانtypescriptcollection پایانtyping پایانuniqueMPgraphic \
+پایانuniqueMPpagegraphic پایانunittext پایانunpacked پایانusableMPgraphic پایانuseMPgraphic \
+پایانusemathstyleparameter پایانuserdata پایانusingbtxspecification پایانvbox پایانvboxregister \
پایانvboxtohbox پایانvboxtohboxseparator پایانviewerlayer پایانvtop پایانvtopregister \
-پایانxcell پایانxcellgroup پایانxgroup پایانxmldisplayverbatim پایانxmlinlineverbatim \
-پایانxmlraw پایانxmlsetups پایانxrow پایانxrowgroup پایانxtable \
-پایانxtablebody پایانxtablefoot پایانxtablehead پایانxtablenext پایانآیتم \
-پایانبروبه پایانتنظیم‌راست پایانتنظیم‌وسط پایانتولید پایانخط‌حاشیه \
-پایانخط‌متن پایاندرج‌شناور پایاندرج‌فرمول پایانرنگ پایانسر \
-پایانفشرده پایانقالبی پایانمحیط پایانمنوی‌پانل پایانمولفه \
-پایاننشر پایانپروژه پایانپس‌زمینه پایانچپ‌چین پایان‌خط \
-پایین پرده پروژه پرکردن‌میدان پس‌زمینه \
-چوبخط چپ‌چین کشیده کلمه‌راست گیره \
-یادداشت یک‌جا یک‌خط
+پایانxcell پایانxcellgroup پایانxcolumn پایانxgroup پایانxmldisplayverbatim \
+پایانxmlinlineverbatim پایانxmlraw پایانxmlsetups پایانxrow پایانxrowgroup \
+پایانxtable پایانxtablebody پایانxtablefoot پایانxtablehead پایانxtablenext \
+پایانآیتم پایانبروبه پایانتنظیم‌راست پایانتنظیم‌وسط پایانتولید \
+پایانخط‌حاشیه پایانخط‌متن پایاندرج‌شناور پایاندرج‌فرمول پایانرنگ \
+پایانزبان پایانسر پایانفشرده پایانقالبی پایانمحیط \
+پایانمنوی‌پانل پایانمولفه پایاننشر پایانپروژه پایانپس‌زمینه \
+پایانچپ‌چین پایان‌خط پایین پرده پروژه \
+پرکردن‌میدان پس‌زمینه چوبخط چپ‌چین کشیده \
+کلمه‌راست گیره یادداشت یک‌جا یک‌خط
keywordclass.context.ro=\
CUVANT CUVINTE Cuvant Cuvinte \
@@ -2113,12 +2146,12 @@ seteazatextesus seteazatextetext seteazatitlu seteazatitluri seteazatoleranta \
seteazatranzitiepagina seteazatype seteazatyping seteazaurl simbol \
spatiifixate spatiu spatiufixat startaliniatcentru startaliniatdreapta \
startaliniatstanga startcomponenta startculoare startdute startfundal \
-startimpachetat startlinie startliniemargine startmediu startmeniuinteractiune \
-startprodus startproiect startpublicatie startpuneformula startriglatext \
-starttitlu stivacampuri stopaliniatcentru stopaliniatdreapta stopaliniatstanga \
-stopcomponenta stopculoare stopdute stopfundal stopimpachetat \
-stoplinie stopliniemargine stopmediu stopmeniuinteractiune stopprodus \
-stopproiect stoppublicatie stoppuneformula stopriglatext stoptitlu \
-textumplere traduce trecilafonttext undeva valoareculoare \
-versiune zidinsaptamana
+startimpachetat startlimba startlinie startliniemargine startmediu \
+startmeniuinteractiune startprodus startproiect startpublicatie startpuneformula \
+startriglatext starttitlu stivacampuri stopaliniatcentru stopaliniatdreapta \
+stopaliniatstanga stopcomponenta stopculoare stopdute stopfundal \
+stopimpachetat stoplimba stoplinie stopliniemargine stopmediu \
+stopmeniuinteractiune stopprodus stopproiect stoppublicatie stoppuneformula \
+stopriglatext stoptitlu textumplere traduce trecilafonttext \
+undeva valoareculoare versiune zidinsaptamana
diff --git a/context/data/scite/context/scite-context-data-metafun.properties b/context/data/scite/context/scite-context-data-metafun.properties
index e83313132..8830da05c 100644
--- a/context/data/scite/context/scite-context-data-metafun.properties
+++ b/context/data/scite/context/scite-context-data-metafun.properties
@@ -27,47 +27,60 @@ intersection_point intersection_found penpoint bbwidth bbheight \
withshade withcircularshade withlinearshade defineshade shaded \
shadedinto withshadecolors withshadedomain withshademethod withshadefactor \
withshadevector withshadecenter withshadedirection withshaderadius withshadetransform \
-withshadestep withshadefraction cmyk spotcolor multitonecolor \
-namedcolor drawfill undrawfill inverted uncolored \
-softened grayed greyed onlayer along \
-graphictext loadfigure externalfigure figure register \
-outlinetext checkedbounds checkbounds strut rule \
-withmask bitmapimage colordecimals ddecimal dddecimal \
-ddddecimal colordecimalslist textext thetextext rawtextext \
-textextoffset texbox thetexbox rawtexbox istextext \
-verbatim thelabel label autoalign transparent \
-withtransparency property properties withproperties asgroup \
-infont space crlf dquote percent \
-SPACE CRLF DQUOTE PERCENT grayscale \
-greyscale withgray withgrey colorpart colorlike \
-readfile clearxy unitvector center epsed \
-anchored originpath infinite break xstretched \
-ystretched snapped pathconnectors function constructedfunction \
-constructedpath constructedpairs straightfunction straightpath straightpairs \
-curvedfunction curvedpath curvedpairs evenly oddly \
-condition pushcurrentpicture popcurrentpicture arrowpath resetarrows \
-tensecircle roundedsquare colortype whitecolor blackcolor \
-basiccolors complementary complemented resolvedcolor normalfill \
-normaldraw visualizepaths detailpaths naturalizepaths drawboundary \
-drawwholepath drawpathonly visualizeddraw visualizedfill detaileddraw \
-draworigin drawboundingbox drawpath drawpoint drawpoints \
-drawcontrolpoints drawcontrollines drawpointlabels drawlineoptions drawpointoptions \
-drawcontroloptions drawlabeloptions draworiginoptions drawboundoptions drawpathoptions \
-resetdrawoptions undashed pencilled decorated redecorated \
-undecorated passvariable passarrayvariable tostring topair \
-format formatted quotation quote startpassingvariable \
-stoppassingvariable eofill eoclip nofill fillup \
-eofillup area addbackground shadedup shadeddown \
-shadedleft shadedright sortlist copylist shapedlist \
-listtocurves listtolines listsize listlast uniquelist \
-circularpath squarepath linearpath
+withshadestep withshadefraction withshadeorigin shownshadevector shownshadeorigin \
+cmyk spotcolor multitonecolor namedcolor drawfill \
+undrawfill inverted uncolored softened grayed \
+greyed onlayer along 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 transparent withtransparency property properties \
+withproperties asgroup infont space crlf \
+dquote percent SPACE CRLF DQUOTE \
+PERCENT grayscale greyscale withgray withgrey \
+colorpart colorlike readfile clearxy unitvector \
+center epsed anchored originpath infinite \
+break xstretched ystretched snapped pathconnectors \
+function constructedfunction constructedpath constructedpairs straightfunction \
+straightpath straightpairs curvedfunction curvedpath curvedpairs \
+evenly oddly condition pushcurrentpicture popcurrentpicture \
+arrowpath resetarrows tensecircle roundedsquare colortype \
+whitecolor blackcolor basiccolors complementary complemented \
+resolvedcolor normalfill normaldraw visualizepaths detailpaths \
+naturalizepaths drawboundary drawwholepath drawpathonly visualizeddraw \
+visualizedfill detaileddraw draworigin drawboundingbox drawpath \
+drawpoint drawpoints drawcontrolpoints drawcontrollines drawpointlabels \
+drawlineoptions drawpointoptions drawcontroloptions drawlabeloptions draworiginoptions \
+drawboundoptions drawpathoptions resetdrawoptions undashed pencilled \
+decorated redecorated undecorated passvariable passarrayvariable \
+tostring topair format formatted quotation \
+quote startpassingvariable stoppassingvariable eofill eoclip \
+nofill fillup eofillup area addbackground \
+shadedup shadeddown shadedleft shadedright 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
keywordclass.metafun.internals=\
nocolormodel greycolormodel graycolormodel rgbcolormodel \
-cmykcolormodel shadefactor textextoffset normaltransparent multiplytransparent \
-screentransparent overlaytransparent softlighttransparent hardlighttransparent colordodgetransparent \
-colorburntransparent darkentransparent lightentransparent differencetransparent exclusiontransparent \
-huetransparent saturationtransparent colortransparent luminositytransparent ahvariant \
-ahdimple ahfactor ahscale metapostversion maxdimensions \
-drawoptionsfactor dq sq crossingscale crossingoption
+cmykcolormodel shadefactor textextoffset textextanchor normaltransparent \
+multiplytransparent screentransparent overlaytransparent softlighttransparent hardlighttransparent \
+colordodgetransparent colorburntransparent darkentransparent lightentransparent differencetransparent \
+exclusiontransparent huetransparent saturationtransparent colortransparent luminositytransparent \
+ahvariant ahdimple ahfactor ahscale metapostversion \
+maxdimensions drawoptionsfactor dq sq crossingscale \
+crossingoption
diff --git a/context/data/scite/context/scite-context-data-tex.properties b/context/data/scite/context/scite-context-data-tex.properties
index 05ddc71fd..b980decbd 100644
--- a/context/data/scite/context/scite-context-data-tex.properties
+++ b/context/data/scite/context/scite-context-data-tex.properties
@@ -49,33 +49,37 @@ Ustartmath Ustopdisplaymath Ustopmath Usubscript Usuperscript \
Uunderdelimiter Uvextensible adjustspacing alignmark aligntab \
attribute attributedef automaticdiscretionary automatichyphenmode automatichyphenpenalty \
begincsname bodydir bodydirection boxdir boxdirection \
-breakafterdirmode catcodetable clearmarks copyfont compoundhyphenmode \
-crampeddisplaystyle crampedscriptscriptstyle crampedscriptstyle crampedtextstyle draftmode \
-dviextension dvifeedback dvivariable efcode etoksapp \
-etokspre expanded expandglyphsinfont explicitdiscretionary explicithyphenpenalty \
-fontid formatname gleaders hjcode hyphenationbounds \
-hyphenationmin hyphenpenaltymode ifabsdim ifabsnum ifincsname \
-ifprimitive ignoreligaturesinfont initcatcodetable insertht lastnamedcs \
-lastsavedboxresourceindex lastsavedimageresourceindex lastsavedimageresourcepages lastxpos lastypos \
-latelua leftghost leftmarginkern letcharcode letterspacefont \
+breakafterdirmode catcodetable clearmarks 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 lastsavedboxresourceindex \
+lastsavedimageresourceindex lastsavedimageresourcepages lastxpos lastypos latelua \
+lateluafunction leftghost leftmarginkern letcharcode letterspacefont \
linedir linedirection localbrokenpenalty localinterlinepenalty localleftbox \
-localrightbox lpcode luaescapestring luafunction luafunctioncall \
-luatexbanner luatexrevision luatexversion mathdelimitersmode mathdir \
-mathdirection mathdisplayskipmode matheqnogapstep mathitalicsmode mathnolimitsmode \
-mathoption mathpenaltiesmode mathrulesfam mathrulesmode mathscriptsmode \
-mathscriptboxmode mathstyle mathsurroundmode mathsurroundskip nohrule \
-nokerns noligs normaldeviate nospaces novrule \
-outputbox outputmode pagebottomoffset pagedir pagedirection \
-pageheight pageleftoffset pagerightoffset pagetopoffset pagewidth \
-pardir pardirection pdfextension pdffeedback pdfvariable \
-postexhyphenchar posthyphenchar prebinoppenalty predisplaygapfactor preexhyphenchar \
-prehyphenchar prerelpenalty primitive protrudechars pxdimen \
-quitvmode randomseed rightghost rightmarginkern rpcode \
-saveboxresource savecatcodetable saveimageresource savepos scantextokens \
-setfontid setrandomseed shapemode suppressfontnotfounderror suppressifcsnameerror \
-suppresslongerror suppressmathparerror suppressoutererror suppressprimitiveerror synctex \
-tagcode textdir textdirection toksapp tokspre \
-tracingfonts uniformdeviate useboxresource useimageresource
+localrightbox lpcode luabytecode luabytecodecall luacopyinputnodes \
+luadef luaescapestring luafunction luafunctioncall luatexbanner \
+luatexrevision luatexversion mathdelimitersmode mathdir mathdirection \
+mathdisplayskipmode matheqnogapstep mathflattenmode mathitalicsmode mathnolimitsmode \
+mathoption mathpenaltiesmode mathrulesfam mathrulesmode mathrulethicknessmode \
+mathscriptboxmode mathscriptcharmode mathscriptsmode mathstyle mathsurroundmode \
+mathsurroundskip nohrule nokerns noligs normaldeviate \
+nospaces novrule outputbox outputmode pagebottomoffset \
+pagedir pagedirection pageheight pageleftoffset pagerightoffset \
+pagetopoffset pagewidth pardir pardirection pdfextension \
+pdffeedback pdfvariable postexhyphenchar posthyphenchar prebinoppenalty \
+predisplaygapfactor preexhyphenchar prehyphenchar prerelpenalty primitive \
+protrudechars pxdimen quitvmode randomseed rightghost \
+rightmarginkern rpcode saveboxresource savecatcodetable saveimageresource \
+savepos scantextokens setfontid setrandomseed shapemode \
+suppressfontnotfounderror suppressifcsnameerror suppresslongerror suppressmathparerror suppressoutererror \
+suppressprimitiveerror synctex tagcode textdir textdirection \
+toksapp tokspre tracingfonts uniformdeviate useboxresource \
+useimageresource xtoksapp xtokspre
keywordclass.tex.omega=\
Omegaminorversion Omegarevision Omegaversion
@@ -91,18 +95,19 @@ pdfignoreddimen pdfignoreunknownimages pdfimageaddfilename pdfimageapplygamma pd
pdfimagehicolor pdfimageresolution pdfincludechars pdfinclusioncopyfonts pdfinclusionerrorlevel \
pdfinfo pdfinfoomitdate pdfinsertht pdflastannot pdflastlinedepth \
pdflastlink pdflastobj pdflastxform pdflastximage pdflastximagepages \
-pdflastxpos pdflastypos pdflinkmargin pdfliteral pdfmapfile \
-pdfmapline pdfmajorversion pdfminorversion pdfnames pdfnoligatures \
-pdfnormaldeviate pdfobj pdfobjcompresslevel pdfoutline pdfoutput \
-pdfpageattr pdfpagebox pdfpageheight pdfpageref pdfpageresources \
-pdfpagesattr pdfpagewidth pdfpkfixeddpi pdfpkmode pdfpkresolution \
-pdfprimitive pdfprotrudechars pdfpxdimen pdfrandomseed pdfrefobj \
-pdfrefxform pdfrefximage pdfreplacefont pdfrestore pdfretval \
-pdfsave pdfsavepos pdfsetmatrix pdfsetrandomseed pdfstartlink \
-pdfstartthread pdfsuppressoptionalinfo pdfsuppressptexinfo pdftexbanner pdftexrevision \
-pdftexversion pdfthread pdfthreadmargin pdftracingfonts pdftrailer \
-pdftrailerid pdfuniformdeviate pdfuniqueresname pdfvorigin pdfxform \
-pdfxformattr pdfxformmargin pdfxformname pdfxformresources pdfximage
+pdflastxpos pdflastypos pdflinkmargin pdfliteral pdfmajorversion \
+pdfmapfile pdfmapline pdfminorversion pdfnames pdfnoligatures \
+pdfnormaldeviate pdfobj pdfobjcompresslevel pdfomitcharset pdfomitcidset \
+pdfoutline pdfoutput pdfpageattr pdfpagebox pdfpageheight \
+pdfpageref pdfpageresources pdfpagesattr pdfpagewidth pdfpkfixeddpi \
+pdfpkmode pdfpkresolution pdfprimitive pdfprotrudechars pdfpxdimen \
+pdfrandomseed pdfrecompress pdfrefobj pdfrefxform pdfrefximage \
+pdfreplacefont pdfrestore pdfretval pdfsave pdfsavepos \
+pdfsetmatrix pdfsetrandomseed pdfstartlink pdfstartthread pdfsuppressoptionalinfo \
+pdfsuppressptexinfo pdftexbanner pdftexrevision pdftexversion pdfthread \
+pdfthreadmargin pdftracingfonts pdftrailer pdftrailerid pdfuniformdeviate \
+pdfuniqueresname pdfvorigin pdfxform pdfxformattr pdfxformmargin \
+pdfxformname pdfxformresources pdfximage
keywordclass.tex.tex=\
- / Uleft \
@@ -113,19 +118,19 @@ batchmode begingroup belowdisplayshortskip belowdisplayskip binoppenalty \
botmark boundary box boxmaxdepth brokenpenalty \
catcode char chardef cleaders closein \
closeout clubpenalty copy count countdef \
-cr crcr csname csstring day \
-deadcycles def defaulthyphenchar defaultskewchar delcode \
-delimiter delimiterfactor delimitershortfall dimen dimendef \
-directlua discretionary displayindent displaylimits displaystyle \
-displaywidowpenalty displaywidth divide doublehyphendemerits dp \
-dump edef else emergencystretch end \
-endcsname endgroup endinput endlinechar eqno \
-errhelp errmessage errorcontextlines errorstopmode escapechar \
-everycr everydisplay everyhbox everyjob everymath \
-everypar everyvbox exhyphenchar exhyphenpenalty expandafter \
-fam fi finalhyphendemerits firstmark firstvalidlanguage \
-floatingpenalty font fontdimen fontname futurelet \
-gdef global globaldefs halign hangafter \
+cr crcr csname day deadcycles \
+def defaulthyphenchar defaultskewchar delcode delimiter \
+delimiterfactor delimitershortfall dimen dimendef directlua \
+discretionary displayindent displaylimits displaystyle displaywidowpenalty \
+displaywidth divide doublehyphendemerits dp dump \
+edef else emergencystretch end endcsname \
+endgroup endinput endlinechar eqno errhelp \
+errmessage errorcontextlines errorstopmode escapechar everycr \
+everydisplay everyhbox everyjob everymath everypar \
+everyvbox exhyphenchar exhyphenpenalty expandafter fam \
+fi finalhyphendemerits firstmark firstvalidlanguage floatingpenalty \
+font fontdimen fontname futurelet gdef \
+glet global globaldefs halign hangafter \
hangindent hbadness hbox hfil hfill \
hfilneg hfuzz hoffset holdinginserts hpack \
hrule hsize hskip hss ht \
diff --git a/context/data/scite/context/scite-context-external.properties b/context/data/scite/context/scite-context-external.properties
index 5df60b99b..e9d5f58ba 100644
--- a/context/data/scite/context/scite-context-external.properties
+++ b/context/data/scite/context/scite-context-external.properties
@@ -41,6 +41,7 @@ lexer.*.lpeg=lpeg
file.patterns.cweb=*.w;*.ww;
file.patterns.cpp=*.h;*.c;*.hh;*.cc;*.hpp;*.cpp;*.hxx;*.cxx;
file.patterns.bib=*.bib
+file.patterns.json=*.json
file.patterns.sql=*.sql
lexer.$(file.patterns.metapost)=lpeg_scite-context-lexer-mps
@@ -54,6 +55,7 @@ lexer.$(file.patterns.cweb)=lpeg_scite-context-lexer-web
lexer.$(file.patterns.cpp)=lpeg_scite-context-lexer-cpp
lexer.$(file.patterns.bib)=lpeg_scite-context-lexer-bibtex
lexer.$(file.patterns.sql)=lpeg_scite-context-lexer-sql
+lexer.$(file.patterns.json)=lpeg_scite-context-lexer-json
lexer.$(file.patterns.tex)=lpeg_scite-context-lexer-tex
lexer.$(file.patterns.xml)=lpeg_scite-context-lexer-xml
@@ -85,6 +87,9 @@ comment.block.at.line.start.lpeg_scite-context-lexer-cld=1
comment.block.lpeg_scite-context-lexer-bibtex=%
comment.block.at.line.start.lpeg_scite-context-lexer-bibtex=1
+comment.block.lpeg_scite-context-lexer-json=%
+comment.block.at.line.start.lpeg_scite-context-lexer-json=1
+
comment.block.lpeg_props=#
comment.block.at.line.start.lpeg_props=1
diff --git a/context/data/scite/context/scite-context.properties b/context/data/scite/context/scite-context.properties
index e6ee79050..f3555c1fb 100644
--- a/context/data/scite/context/scite-context.properties
+++ b/context/data/scite/context/scite-context.properties
@@ -165,7 +165,7 @@ command.help.$(file.patterns.context)=mtxrun --gethelp --url="http://localhost:8
command.help.$(file.patterns.example)=
command.help.$(file.patterns.metafun)=
-command.help.subsystem.$(file.patterns.context)=1
+#~ command.help.subsystem.$(file.patterns.context)=1
# Commands: tools menu extensions
@@ -195,10 +195,10 @@ command.compile.$(file.patterns.metafun)=$(name.context.run) $(name.flag.pdfopen
command.compile.$(file.patterns.example)=$(name.context.run) --forcexml $(FileNameExt)
command.compile.*.fo=$(name.context.run) $(name.flag.pdfopen) --forcexml --use=foxet $(FileNameExt)
-command.compile.subsystem.$(file.patterns.context)=1
-command.compile.subsystem.$(file.patterns.metafun)=1
-command.compile.subsystem.$(file.patterns.example)=1
-command.compile.subsystem.*.fo=1
+#~ command.compile.subsystem.$(file.patterns.context)=1
+#~ command.compile.subsystem.$(file.patterns.metafun)=1
+#~ command.compile.subsystem.$(file.patterns.example)=1
+#~ command.compile.subsystem.*.fo=1
if PLAT_WIN
command.go.$(file.patterns.context)=$(FileName).pdf
@@ -239,13 +239,13 @@ command.1.$(file.patterns.metafun)=$(name.context.run) $(FileNameExt) --metapost
command.1.$(file.patterns.example)=$(name.context.run) $(FileNameExt) --xml
command.1.$(file.patterns.lua)=$(name.context.mtxrunjit) --script "$(FileNameExt)"
-command.1.subsystem.$(file.patterns.context)=1
-command.1.subsystem.$(file.patterns.metafun)=1
-command.1.subsystem.$(file.patterns.example)=1
-command.1.subsystem.$(file.patterns.lua)=1
+#~ command.1.subsystem.$(file.patterns.context)=1
+#~ command.1.subsystem.$(file.patterns.metafun)=1
+#~ command.1.subsystem.$(file.patterns.example)=1
+#~ command.1.subsystem.$(file.patterns.lua)=1
command.name.29.*=Run with jit
-command.subsystem.29.*=1
+#~ command.subsystem.29.*=1
command.29.$(file.patterns.context)=$(name.context.runjit) $(FileNameExt)
command.29.$(file.patterns.metafun)=$(name.context.runjit) $(FileNameExt) --metapost
command.29.$(file.patterns.example)=$(name.context.runjit) $(FileNameExt) --xml
@@ -322,11 +322,11 @@ command.7.$(file.patterns.metafun)=$(name.context.run) --extra=listing --pretty
command.7.$(file.patterns.example)=$(name.context.run) --extra=listing --pretty --result=$(FileName) $(FileNameExt)
command.7.$(file.patterns.lua)=$(name.context.run) --extra=listing --pretty --result=$(FileName) $(FileNameExt)
-command.7.subsystem=1
-command.7.subsystem.$(file.patterns.context)=1
-command.7.subsystem.$(file.patterns.metafun)=1
-command.7.subsystem.$(file.patterns.example)=1
-command.7.subsystem.$(file.patterns.lua)=1
+#~ command.7.subsystem=1
+#~ command.7.subsystem.$(file.patterns.context)=1
+#~ command.7.subsystem.$(file.patterns.metafun)=1
+#~ command.7.subsystem.$(file.patterns.example)=1
+#~ command.7.subsystem.$(file.patterns.lua)=1
# 10: arranging
@@ -336,9 +336,9 @@ command.name.10.$(file.patterns.example)=Process and Arrange
command.10.$(file.patterns.context)=$(name.context.run) --arrange $(FileNameExt)
command.10.$(file.patterns.metafun)=$(name.context.run) --mptex $(FileNameExt)
command.10.$(file.patterns.example)=$(name.context.run) --arrange --xml $(FileNameExt)
-command.10.subsystem.$(file.patterns.context)=1
-command.10.subsystem.$(file.patterns.metafun)=1
-command.10.subsystem.$(file.patterns.example)=1
+#~ command.10.subsystem.$(file.patterns.context)=1
+#~ command.10.subsystem.$(file.patterns.metafun)=1
+#~ command.10.subsystem.$(file.patterns.example)=1
# 11: make
@@ -348,21 +348,21 @@ command.name.11.$(file.patterns.example)=Generate Formats
command.11.$(file.patterns.context)=$(name.context.run) --make --all --pdftex
command.11.$(file.patterns.metafun)=$(name.context.run) --make --all
command.11.$(file.patterns.example)=$(name.context.run) --make --all
-command.11.subsystem.$(file.patterns.context)=1
-command.11.subsystem.$(file.patterns.metafun)=1
-command.11.subsystem.$(file.patterns.example)=1
+#~ command.11.subsystem.$(file.patterns.context)=1
+#~ command.11.subsystem.$(file.patterns.metafun)=1
+#~ command.11.subsystem.$(file.patterns.example)=1
# 12: make
command.name.12.$(file.patterns.context)=Generate Formats (luaTeX)
command.12.$(file.patterns.context)=$(name.context.run) --make --all --luatex
-command.12.subsystem.$(file.patterns.context)=1
+#~ command.12.subsystem.$(file.patterns.context)=1
# 13: make
command.name.13.$(file.patterns.context)=Generate Formats (XeTeX)
command.13.$(file.patterns.context)=$(name.context.run) --make --all --xetex
-command.13.subsystem.$(file.patterns.context)=1
+#~ command.13.subsystem.$(file.patterns.context)=1
# 15: example
diff --git a/context/data/scite/context/scite-ctx-bidi.lua b/context/data/scite/context/scite-ctx-bidi.lua
index ab64da70d..5e75f7e4c 100644
--- a/context/data/scite/context/scite-ctx-bidi.lua
+++ b/context/data/scite/context/scite-ctx-bidi.lua
@@ -334,7 +334,7 @@ local function resolve_weak(list,size,start,limit,orderbefore,orderafter)
break
end
end
- local rundirection = runstart == start and sor or list[runstart-1].direction
+ local rundirection = runstart == start and sor or (runstart > 1 and list[runstart-1].direction)
if rundirection ~= "en" then
rundirection = runlimit == limit and orderafter or list[runlimit+1].direction
end
diff --git a/context/data/scite/context/scite-ctx-context.properties b/context/data/scite/context/scite-ctx-context.properties
index a1d5800e6..40ad49ded 100644
--- a/context/data/scite/context/scite-ctx-context.properties
+++ b/context/data/scite/context/scite-ctx-context.properties
@@ -1,49 +1 @@
-command.name.25.$(file.patterns.context)=Whatever
-command.25.$(file.patterns.context)=insert_template $(ctx.template.list.context)
-
-ctx.template.list.context=\
- itemize=structure.itemize.context|\
- tabulate=structure.tabulate.context|\
- natural TABLE=structure.TABLE.context|\
- use MP graphic=graphics.usemp.context|\
- reuse MP graphic=graphics.reusemp.context|\
- typeface definition=fonts.typeface.context
-
-ctx.template.structure.itemize.context=\
-\startitemize\n\
-\item ?\n\
-\item ?\n\
-\item ?\n\
-\stopitemize\n
-
-ctx.template.structure.tabulate.context=\
-\starttabulate[|l|p|]\n\
-\NC ? \NC \NC \NR\n\
-\NC ? \NC \NC \NR\n\
-\NC ? \NC \NC \NR\n\
-\stoptabulate\n
-
-ctx.template.structure.TABLE.context=\
-\bTABLE\n\
-\bTR \bTD ? \eTD \bTD \eTD \eTR\n\
-\bTR \bTD ? \eTD \bTD \eTD \eTR\n\
-\bTR \bTD ? \eTD \bTD \eTD \eTR\n\
-\eTABLE\n
-
-ctx.template.graphics.usemp.context=\
-\defineoverlay[?][\useMPgraphic{}]\n\n\
-\startuseMPgraphic{}\n\n\
-\stopuseMPgraphic\n
-
-ctx.template.graphics.reusemp.context=\
-\defineoverlay[?][\reuseMPgraphic{}]\n\n\
-\startreusableMPgraphic{}\n\n\
-\stopreusableMPgraphic\n
-
-ctx.template.fonts.typeface.context=\
-\definetypeface[mainface][rm][serif][?][default][encoding=\defaultencoding]\n\
-\definetypeface[mainface][ss][sans] [?][default][encoding=\defaultencoding]\n\
-\definetypeface[mainface][tt][mono] [?][default][encoding=\defaultencoding]\n\
-\definetypeface[mainface][mm][math] [?][default][encoding=\defaultencoding]\n\
-\n\
-\setupbodyfont[mainface,10pt]\n
+command.25.$(file.patterns.context)=insert_template
diff --git a/context/data/scite/context/scite-ctx-example.properties b/context/data/scite/context/scite-ctx-example.properties
index 78b2f2859..58c0acc34 100644
--- a/context/data/scite/context/scite-ctx-example.properties
+++ b/context/data/scite/context/scite-ctx-example.properties
@@ -1,23 +1 @@
-command.25.$(file.patterns.example)=insert_template $(ctx.template.list.example)
-
-ctx.template.list.example=\
- bold=font.bold.example|\
- emphasized=font.emphasized.example|\
- |\
- inline math=math.inline.example|\
- display math=math.display.example|\
- |\
- itemize=structure.itemize.example
-
-ctx.template.font.bold.example=<b>?</b>
-ctx.template.font.emphasized.example=<em>?</em>
-
-ctx.template.math.inline.example=<m>?</m>
-ctx.template.math.display.example=<math>?</math>
-
-ctx.template.structure.itemize.example=\
-<itemize>\n\
-<item>?</item>\n\
-<item>?</item>\n\
-<item>?</item>\n\
-</itemize>\n
+command.25.$(file.patterns.example)=insert_template
diff --git a/context/data/scite/context/scite-ctx-templates.lua b/context/data/scite/context/scite-ctx-templates.lua
new file mode 100644
index 000000000..72b981c81
--- /dev/null
+++ b/context/data/scite/context/scite-ctx-templates.lua
@@ -0,0 +1,31 @@
+-- this is just an example
+
+return {
+ xml = {
+ {
+ name = "bold",
+ nature = "inline",
+ template = "<b>?</b>",
+ },
+ {
+ name = "emphasized",
+ nature = "inline",
+ template = "<em>?</em>",
+ },
+ {
+ name = "inline",
+ nature = "inline",
+ template = "<m>?</m>",
+ },
+ {
+ name = "display",
+ nature = "display",
+ template = "<math>?</math>",
+ },
+ {
+ name = "itemize",
+ nature = "display",
+ template = "<itemize>\n <item>?</item>\n <item>?</item>\n <item>?</item>\n</itemize>",
+ },
+ },
+}
diff --git a/context/data/scite/context/scite-ctx.lua b/context/data/scite/context/scite-ctx.lua
index f2f33ecbb..126f6b8f3 100644
--- a/context/data/scite/context/scite-ctx.lua
+++ b/context/data/scite/context/scite-ctx.lua
@@ -72,7 +72,9 @@
props = props or { } -- setmetatable(props,{ __index = function(k,v) props[k] = "unknown" return "unknown" end } )
-local byte, lower, upper, gsub, sub, find, rep, match, gmatch, format, char = string.byte, string.lower, string.upper, string.gsub, string.sub, string.find, string.rep, string.match, string.gmatch, string.format, string.char
+local byte, char = string.byte, string.char
+local lower, upper, format = string.lower, string.upper, string.format
+local gsub, sub, find, rep, match, gmatch = string.gsub, string.sub, string.find, string.rep, string.match, string.gmatch
local sort, concat = table.sort, table.concat
-- helpers : utf
@@ -115,6 +117,17 @@ function io.exists(filename)
end
end
+local function resultof(command)
+ local handle = io.popen(command,"r") -- already has flush
+ if handle then
+ local result = handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
+end
+
function os.envvar(str)
local s = os.getenv(str)
if s ~= '' then
@@ -974,22 +987,28 @@ end
local menuactions = { }
local menufunctions = { }
+local menuentries = { }
function UserListShow(menutrigger, menulist)
- local menuentries = { }
- local list = grab(menulist,"[^%|]+")
- menuactions = { }
- for i=1, #list do
- if list[i] ~= '' then
- for key, val in gmatch(list[i],"%s*(.+)=(.+)%s*") do
- menuentries[#menuentries+1] = key
- menuactions[key] = val
+ if type(menulist) == "string" then
+ menuentries = { }
+ menuactions = { }
+ for item in gmatch(menulist,"[^%|]+") do
+ if item ~= "" then
+ -- why not just a split
+ for key, value in gmatch(item,"%s*(.+)=(.+)%s*") do
+ menuentries[#menuentries+1] = key
+ menuactions[key] = value
+ end
end
end
+ else
+ menuentries = menulist
+ menuactions = false
end
local menustring = concat(menuentries,'|')
if menustring == "" then
- report("there are no templates defined for this file type")
+ report("there are no (further) options defined for this file type")
else
editor.AutoCSeparator = byte('|')
editor:UserListShow(menutrigger,menustring)
@@ -998,8 +1017,8 @@ function UserListShow(menutrigger, menulist)
end
function OnUserListSelection(trigger,choice)
- if menufunctions[trigger] and menuactions[choice] then
- return menufunctions[trigger](menuactions[choice])
+ if menufunctions[trigger] then
+ return menufunctions[trigger](menuactions and menuactions[choice] or choice)
else
return false
end
@@ -1025,131 +1044,135 @@ menufunctions[12] = process_menu
-- templates
-local templatetrigger = 13
+-- <?context-directive job ctxtemplate demotemplate.lua ?>
-local ctx_template_paths = { "./ctx-templates", "../ctx-templates", "../../ctx-templates" }
-local ctx_auto_templates = false
-local ctx_template_list = ""
+local templatetrigger = 13
-local ctx_path_list = { }
-local ctx_path_done = { }
-local ctx_path_name = { }
+local ctx_template_file = "scite-ctx-templates.lua"
+local ctx_template_list = { }
+local ctx_template_menu = { }
function ctx_list_loaded(path)
return ctx_path_list[path] and #ctx_path_list[path] > 0
end
+local function loadtable(name)
+ local f = io.open(name,"rb")
+ if f then
+ f:close()
+ return dofile(name)
+ end
+end
+
+local patterns = {
+ xml = "<%?context%-directive job ctxtemplate (.-) %?>"
+}
+
+local function loadtemplate(name)
+ local temp = gsub(name,"\\","/")
+ local okay = loadtable(temp)
+ if okay then
+ print("template loaded: " .. name)
+ end
+ return okay
+end
+
+local function loadtemplatefrompaths(path,name)
+ return loadtemplate(path .. "/" .. name) or
+ loadtemplate(path .. "/../" .. name) or
+ loadtemplate(path .. "/../../" .. name)
+end
+
function insert_template(templatelist)
- if props["ctx.template.scan"] == "yes" then
- local path = props["FileDir"]
- local rescan = props["ctx.template.rescan"] == "yes"
- local suffix = props["ctx.template.suffix." .. props["FileExt"]] -- alas, no suffix expansion here
- local current = path .. "+" .. props["FileExt"]
- if rescan then
- print("re-scanning enabled")
- end
- ctx_template_list = ""
- if not ctx_path_done[path] or rescan then
- local pattern = "*.*"
- for i, pathname in ipairs(ctx_template_paths) do
- print("scanning " .. gsub(path,"\\","/") .. "/" .. pathname)
- ctx_path_name[path] = pathname
- ctx_path_list[path] = get_dir_list(pathname .. "/" .. pattern)
- if ctx_list_loaded(path) then
- print("finished locating template files")
+ local path = props["FileDir"]
+ local suffix = props["FileExt"]
+ local list = ctx_template_list[path]
+ if list == nil then
+ local pattern = patterns[suffix]
+ local okay = false
+ if pattern then
+ for i=0,9 do
+ local line = editor:GetLine(i) or ""
+ local name = match(line,pattern)
+ if name then
+ okay = loadtemplatefrompaths(path,name)
+ if not okay then
+ name = resultof("mtxrun --find-file " .. name)
+ if name then
+ name = gsub(name,"\n","")
+ okay = loadtemplate(name)
+ end
+ end
break
end
end
- if ctx_list_loaded(path) then
- print(#ctx_path_list[path] .. " template files found")
- else
- print("no template files found")
- end
end
- if ctx_list_loaded(path) then
- ctx_template_list = ""
- local pattern = "%." .. suffix .. "$"
- local n = 0
- for j, filename in ipairs(ctx_path_list[path]) do
- if find(filename,pattern) then
- n = n + 1
- local menuname = gsub(filename,"%..-$","")
- if ctx_template_list ~= "" then
- ctx_template_list = ctx_template_list .. "|"
- end
- ctx_template_list = ctx_template_list .. menuname .. "=" .. ctx_path_name[path] .. "/" .. filename
- end
- end
- if not ctx_path_done[path] then
- print(n .. " suitable template files found")
- end
+ if not okay then
+ okay = loadtemplatefrompaths(path,ctx_template_file)
end
- ctx_path_done[path] = true
- if ctx_template_list == "" then
- ctx_auto_templates = false
- else
- ctx_auto_templates = true
- templatelist = ctx_template_list
+ if not okay then
+ okay = loadtemplate(props["SciteDefaultHome"] .. "/context/" .. ctx_template_file)
end
- else
- ctx_auto_templates = false
- end
- if templatelist ~= "" then
- UserListShow(templatetrigger, templatelist)
- end
-end
-
--- ctx.template.[whatever].[filetype]
--- ctx.template.[whatever].data.[filetype]
--- ctx.template.[whatever].file.[filetype]
--- ctx.template.[whatever].list.[filetype]
-
-function process_template_one(action)
- local text = nil
- if ctx_auto_templates then
- local f = io.open(action,"r")
- if f then
- text = gsub(f:read("*all"),"\n$","")
- f:close()
+ if okay then
+ list = okay
else
- print("unable to auto load template file " .. text)
- text = nil
+ list = false
+ print("no template file found")
end
+ ctx_template_list[path] = list
end
- if not text or text == "" then
- text = props["ctx.template." .. action .. ".file"]
- if not text or text == "" then
- text = props["ctx.template." .. action .. ".data"]
- if not text or text == "" then
- text = props["ctx.template." .. action]
- end
- else
- local f = io.open(text,"r")
- if f then
- text = gsub(f:read("*all"),"\n$","")
- f:close()
- else
- print("unable to load template file " .. text)
- text = nil
+ ctx_template_menu = { }
+ if list then
+ local okay = list[suffix]
+ if okay then
+ local menu = { }
+ for i=1,#okay do
+ local o = okay[i]
+ local n = o.name
+ menu[#menu+1] = n
+ ctx_template_menu[n] = o
end
+ UserListShow(templatetrigger, menu, true)
end
end
- if text then
- text = gsub(text,"\\n","\n")
- local pos = find(text,"%?")
- text = gsub(text,"%?","")
- editor:insert(editor.CurrentPos,text)
- if pos then
- editor.CurrentPos = editor.CurrentPos + pos - 1
- editor.SelectionStart = editor.CurrentPos
- editor.SelectionEnd = editor.CurrentPos
- editor:GotoPos(editor.CurrentPos)
+end
+
+function inject_template(action)
+ if ctx_template_menu then
+ local a = ctx_template_menu[action]
+ if a then
+ local template = a.template
+ local nature = a.nature
+ if template then
+ local margin = props['SelectionStartColumn'] - 1
+ -- template = gsub(template,"\\n","\n")
+ template = gsub(template,"%?%?","_____")
+ local pos = find(template,"%?")
+ template = gsub(template,"%?","")
+ template = gsub(template,"_____","?")
+ if nature == "display" then
+ local spaces = rep(" ",margin)
+ if not find(template,"\n$") then
+ template = template .. "\n"
+ end
+ template = gsub(template,"\n",function(s)
+ return "\n" .. spaces
+ end)
+ pos = pos + margin -- todo: check for first line
+ end
+ editor:insert(editor.CurrentPos,template)
+ if pos then
+ editor.CurrentPos = editor.CurrentPos + pos - 1
+ editor.SelectionStart = editor.CurrentPos
+ editor.SelectionEnd = editor.CurrentPos
+ editor:GotoPos(editor.CurrentPos)
+ end
+ end
end
end
end
-menufunctions[13] = process_template_one
-menufunctions[14] = process_template_two
+menufunctions[13] = inject_template
-- command.name.26.*=Open Logfile
-- command.subsystem.26.*=3
diff --git a/context/data/scite/context/scite-ctx.properties b/context/data/scite/context/scite-ctx.properties
index bcd939594..1a040c2dc 100644
--- a/context/data/scite/context/scite-ctx.properties
+++ b/context/data/scite/context/scite-ctx.properties
@@ -66,6 +66,14 @@ ctx.menulist.lua=\
wrap=wrap_text|\
sort=sort_text
+ctx.menulist.bibtex=\
+ wrap=wrap_text|\
+ sort=sort_text
+
+ctx.menulist.json=\
+ wrap=wrap_text|\
+ sort=sort_text
+
ctx.wraptext.length=80
ctx.spellcheck.language=auto
@@ -129,6 +137,20 @@ command.groupundo.21.$(file.patterns.lua)=yes
command.save.before.21.$(file.patterns.lua)=2
command.shortcut.21.$(file.patterns.lua)=Shift+F11
+command.name.21.$(file.patterns.bibtex)=BibTeX Action List
+command.subsystem.21.$(file.patterns.bibtex)=3
+command.21.$(file.patterns.bibtex)=show_menu $(ctx.menulist.bibtex)
+command.groupundo.21.$(file.patterns.bibtex)=yes
+command.save.before.21.$(file.patterns.bibtex)=2
+command.shortcut.21.$(file.patterns.bibtex)=Shift+F11
+
+command.name.21.$(file.patterns.json)=JSON Action List
+command.subsystem.21.$(file.patterns.json)=3
+command.21.$(file.patterns.json)=show_menu $(ctx.menulist.json)
+command.groupundo.21.$(file.patterns.json)=yes
+command.save.before.21.$(file.patterns.json)=2
+command.shortcut.21.$(file.patterns.json)=Shift+F11
+
#~ command.name.21.*=CTX Action List
#~ command.subsystem.21.*=3
#~ command.21.*=show_menu $(ctx.menulist.default)
diff --git a/context/data/scite/context/scite-pragma.properties b/context/data/scite/context/scite-pragma.properties
index 2dea18bad..109b02230 100644
--- a/context/data/scite/context/scite-pragma.properties
+++ b/context/data/scite/context/scite-pragma.properties
@@ -27,6 +27,8 @@ $(filter.lua)\
$(filter.text)\
$(filter.pdf)\
$(filter.cweb)\
+$(filter.bibtex)\
+$(filter.json)\
$(filter.txt)
# Editor: menus
@@ -38,4 +40,6 @@ XML|xml||\
Lua|lua||\
Text|txt||\
PDF|pdf||\
-CWeb|cweb||
+CWeb|cweb||\
+BibTeX|bibtex||\
+JSON|json||
diff --git a/context/data/textadept/context/data/scite-context-data-bidi.lua b/context/data/textadept/context/data/scite-context-data-bidi.lua
new file mode 100644
index 000000000..4221dee89
--- /dev/null
+++ b/context/data/textadept/context/data/scite-context-data-bidi.lua
@@ -0,0 +1,10357 @@
+return {
+ ["comment"]="generated by: mtxrun -- script interface.lua --bidi",
+ ["directions"]={
+ [0]="bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "s",
+ "b",
+ "s",
+ "ws",
+ "b",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "bn",
+ "b",
+ "b",
+ "b",
+ "s",
+ "ws",
+ "on",
+ "on",
+ "et",
+ "et",
+ "et",
+ "on",
+ "on",
+ "on",
+ "on",
+ "on",
+ "es",
+ "cs",
+ "es",
+ "cs",
+ "cs",
+ "en",
+ "en",
+ "en",
+ "en",
+ "en",
+ "en",
+ "en",
+ "en",
+ "en",
+ "en",
+ "cs",
+ "on",
+ "on",
+ "on",
+ "on",
+ "on",
+ "on",
+ [91]="on",
+ [92]="on",
+ [93]="on",
+ [94]="on",
+ [95]="on",
+ [96]="on",
+ [123]="on",
+ [124]="on",
+ [125]="on",
+ [126]="on",
+ [127]="bn",
+ [128]="bn",
+ [129]="bn",
+ [130]="bn",
+ [131]="bn",
+ [132]="bn",
+ [133]="b",
+ [134]="bn",
+ [135]="bn",
+ [136]="bn",
+ [137]="bn",
+ [138]="bn",
+ [139]="bn",
+ [140]="bn",
+ [141]="bn",
+ [142]="bn",
+ [143]="bn",
+ [144]="bn",
+ [145]="bn",
+ [146]="bn",
+ [147]="bn",
+ [148]="bn",
+ [149]="bn",
+ [150]="bn",
+ [151]="bn",
+ [152]="bn",
+ [153]="bn",
+ [154]="bn",
+ [155]="bn",
+ [156]="bn",
+ [157]="bn",
+ [158]="bn",
+ [159]="bn",
+ [160]="cs",
+ [161]="on",
+ [162]="et",
+ [163]="et",
+ [164]="et",
+ [165]="et",
+ [166]="on",
+ [167]="on",
+ [168]="on",
+ [169]="on",
+ [171]="on",
+ [172]="on",
+ [173]="bn",
+ [174]="on",
+ [175]="on",
+ [176]="et",
+ [177]="et",
+ [178]="en",
+ [179]="en",
+ [180]="on",
+ [182]="on",
+ [183]="on",
+ [184]="on",
+ [185]="en",
+ [187]="on",
+ [188]="on",
+ [189]="on",
+ [190]="on",
+ [191]="on",
+ [215]="on",
+ [247]="on",
+ [697]="on",
+ [698]="on",
+ [706]="on",
+ [707]="on",
+ [708]="on",
+ [709]="on",
+ [710]="on",
+ [711]="on",
+ [712]="on",
+ [713]="on",
+ [714]="on",
+ [715]="on",
+ [716]="on",
+ [717]="on",
+ [718]="on",
+ [719]="on",
+ [722]="on",
+ [723]="on",
+ [724]="on",
+ [725]="on",
+ [726]="on",
+ [727]="on",
+ [728]="on",
+ [729]="on",
+ [730]="on",
+ [731]="on",
+ [732]="on",
+ [733]="on",
+ [734]="on",
+ [735]="on",
+ [741]="on",
+ [742]="on",
+ [743]="on",
+ [744]="on",
+ [745]="on",
+ [746]="on",
+ [747]="on",
+ [748]="on",
+ [749]="on",
+ [751]="on",
+ [752]="on",
+ [753]="on",
+ [754]="on",
+ [755]="on",
+ [756]="on",
+ [757]="on",
+ [758]="on",
+ [759]="on",
+ [760]="on",
+ [761]="on",
+ [762]="on",
+ [763]="on",
+ [764]="on",
+ [765]="on",
+ [766]="on",
+ [767]="on",
+ [768]="nsm",
+ [769]="nsm",
+ [770]="nsm",
+ [771]="nsm",
+ [772]="nsm",
+ [773]="nsm",
+ [774]="nsm",
+ [775]="nsm",
+ [776]="nsm",
+ [777]="nsm",
+ [778]="nsm",
+ [779]="nsm",
+ [780]="nsm",
+ [781]="nsm",
+ [782]="nsm",
+ [783]="nsm",
+ [784]="nsm",
+ [785]="nsm",
+ [786]="nsm",
+ [787]="nsm",
+ [788]="nsm",
+ [789]="nsm",
+ [790]="nsm",
+ [791]="nsm",
+ [792]="nsm",
+ [793]="nsm",
+ [794]="nsm",
+ [795]="nsm",
+ [796]="nsm",
+ [797]="nsm",
+ [798]="nsm",
+ [799]="nsm",
+ [800]="nsm",
+ [801]="nsm",
+ [802]="nsm",
+ [803]="nsm",
+ [804]="nsm",
+ [805]="nsm",
+ [806]="nsm",
+ [807]="nsm",
+ [808]="nsm",
+ [809]="nsm",
+ [810]="nsm",
+ [811]="nsm",
+ [812]="nsm",
+ [813]="nsm",
+ [814]="nsm",
+ [815]="nsm",
+ [816]="nsm",
+ [817]="nsm",
+ [818]="nsm",
+ [819]="nsm",
+ [820]="nsm",
+ [821]="nsm",
+ [822]="nsm",
+ [823]="nsm",
+ [824]="nsm",
+ [825]="nsm",
+ [826]="nsm",
+ [827]="nsm",
+ [828]="nsm",
+ [829]="nsm",
+ [830]="nsm",
+ [831]="nsm",
+ [832]="nsm",
+ [833]="nsm",
+ [834]="nsm",
+ [835]="nsm",
+ [836]="nsm",
+ [837]="nsm",
+ [838]="nsm",
+ [839]="nsm",
+ [840]="nsm",
+ [841]="nsm",
+ [842]="nsm",
+ [843]="nsm",
+ [844]="nsm",
+ [845]="nsm",
+ [846]="nsm",
+ [847]="nsm",
+ [848]="nsm",
+ [849]="nsm",
+ [850]="nsm",
+ [851]="nsm",
+ [852]="nsm",
+ [853]="nsm",
+ [854]="nsm",
+ [855]="nsm",
+ [856]="nsm",
+ [857]="nsm",
+ [858]="nsm",
+ [859]="nsm",
+ [860]="nsm",
+ [861]="nsm",
+ [862]="nsm",
+ [863]="nsm",
+ [864]="nsm",
+ [865]="nsm",
+ [866]="nsm",
+ [867]="nsm",
+ [868]="nsm",
+ [869]="nsm",
+ [870]="nsm",
+ [871]="nsm",
+ [872]="nsm",
+ [873]="nsm",
+ [874]="nsm",
+ [875]="nsm",
+ [876]="nsm",
+ [877]="nsm",
+ [878]="nsm",
+ [879]="nsm",
+ [884]="on",
+ [885]="on",
+ [894]="on",
+ [900]="on",
+ [901]="on",
+ [903]="on",
+ [1014]="on",
+ [1155]="nsm",
+ [1156]="nsm",
+ [1157]="nsm",
+ [1158]="nsm",
+ [1159]="nsm",
+ [1160]="nsm",
+ [1161]="nsm",
+ [1418]="on",
+ [1421]="on",
+ [1422]="on",
+ [1423]="et",
+ [1425]="nsm",
+ [1426]="nsm",
+ [1427]="nsm",
+ [1428]="nsm",
+ [1429]="nsm",
+ [1430]="nsm",
+ [1431]="nsm",
+ [1432]="nsm",
+ [1433]="nsm",
+ [1434]="nsm",
+ [1435]="nsm",
+ [1436]="nsm",
+ [1437]="nsm",
+ [1438]="nsm",
+ [1439]="nsm",
+ [1440]="nsm",
+ [1441]="nsm",
+ [1442]="nsm",
+ [1443]="nsm",
+ [1444]="nsm",
+ [1445]="nsm",
+ [1446]="nsm",
+ [1447]="nsm",
+ [1448]="nsm",
+ [1449]="nsm",
+ [1450]="nsm",
+ [1451]="nsm",
+ [1452]="nsm",
+ [1453]="nsm",
+ [1454]="nsm",
+ [1455]="nsm",
+ [1456]="nsm",
+ [1457]="nsm",
+ [1458]="nsm",
+ [1459]="nsm",
+ [1460]="nsm",
+ [1461]="nsm",
+ [1462]="nsm",
+ [1463]="nsm",
+ [1464]="nsm",
+ [1465]="nsm",
+ [1466]="nsm",
+ [1467]="nsm",
+ [1468]="nsm",
+ [1469]="nsm",
+ [1470]="r",
+ [1471]="nsm",
+ [1472]="r",
+ [1473]="nsm",
+ [1474]="nsm",
+ [1475]="r",
+ [1476]="nsm",
+ [1477]="nsm",
+ [1478]="r",
+ [1479]="nsm",
+ [1488]="r",
+ [1489]="r",
+ [1490]="r",
+ [1491]="r",
+ [1492]="r",
+ [1493]="r",
+ [1494]="r",
+ [1495]="r",
+ [1496]="r",
+ [1497]="r",
+ [1498]="r",
+ [1499]="r",
+ [1500]="r",
+ [1501]="r",
+ [1502]="r",
+ [1503]="r",
+ [1504]="r",
+ [1505]="r",
+ [1506]="r",
+ [1507]="r",
+ [1508]="r",
+ [1509]="r",
+ [1510]="r",
+ [1511]="r",
+ [1512]="r",
+ [1513]="r",
+ [1514]="r",
+ [1520]="r",
+ [1521]="r",
+ [1522]="r",
+ [1523]="r",
+ [1524]="r",
+ [1536]="an",
+ [1537]="an",
+ [1538]="an",
+ [1539]="an",
+ [1540]="an",
+ [1541]="an",
+ [1542]="on",
+ [1543]="on",
+ [1544]="al",
+ [1545]="et",
+ [1546]="et",
+ [1547]="al",
+ [1548]="cs",
+ [1549]="al",
+ [1550]="on",
+ [1551]="on",
+ [1552]="nsm",
+ [1553]="nsm",
+ [1554]="nsm",
+ [1555]="nsm",
+ [1556]="nsm",
+ [1557]="nsm",
+ [1558]="nsm",
+ [1559]="nsm",
+ [1560]="nsm",
+ [1561]="nsm",
+ [1562]="nsm",
+ [1563]="al",
+ [1564]="al",
+ [1566]="al",
+ [1567]="al",
+ [1568]="al",
+ [1569]="al",
+ [1570]="al",
+ [1571]="al",
+ [1572]="al",
+ [1573]="al",
+ [1574]="al",
+ [1575]="al",
+ [1576]="al",
+ [1577]="al",
+ [1578]="al",
+ [1579]="al",
+ [1580]="al",
+ [1581]="al",
+ [1582]="al",
+ [1583]="al",
+ [1584]="al",
+ [1585]="al",
+ [1586]="al",
+ [1587]="al",
+ [1588]="al",
+ [1589]="al",
+ [1590]="al",
+ [1591]="al",
+ [1592]="al",
+ [1593]="al",
+ [1594]="al",
+ [1595]="al",
+ [1596]="al",
+ [1597]="al",
+ [1598]="al",
+ [1599]="al",
+ [1600]="al",
+ [1601]="al",
+ [1602]="al",
+ [1603]="al",
+ [1604]="al",
+ [1605]="al",
+ [1606]="al",
+ [1607]="al",
+ [1608]="al",
+ [1609]="al",
+ [1610]="al",
+ [1611]="nsm",
+ [1612]="nsm",
+ [1613]="nsm",
+ [1614]="nsm",
+ [1615]="nsm",
+ [1616]="nsm",
+ [1617]="nsm",
+ [1618]="nsm",
+ [1619]="nsm",
+ [1620]="nsm",
+ [1621]="nsm",
+ [1622]="nsm",
+ [1623]="nsm",
+ [1624]="nsm",
+ [1625]="nsm",
+ [1626]="nsm",
+ [1627]="nsm",
+ [1628]="nsm",
+ [1629]="nsm",
+ [1630]="nsm",
+ [1631]="nsm",
+ [1632]="an",
+ [1633]="an",
+ [1634]="an",
+ [1635]="an",
+ [1636]="an",
+ [1637]="an",
+ [1638]="an",
+ [1639]="an",
+ [1640]="an",
+ [1641]="an",
+ [1642]="et",
+ [1643]="an",
+ [1644]="an",
+ [1645]="al",
+ [1646]="al",
+ [1647]="al",
+ [1648]="nsm",
+ [1649]="al",
+ [1650]="al",
+ [1651]="al",
+ [1652]="al",
+ [1653]="al",
+ [1654]="al",
+ [1655]="al",
+ [1656]="al",
+ [1657]="al",
+ [1658]="al",
+ [1659]="al",
+ [1660]="al",
+ [1661]="al",
+ [1662]="al",
+ [1663]="al",
+ [1664]="al",
+ [1665]="al",
+ [1666]="al",
+ [1667]="al",
+ [1668]="al",
+ [1669]="al",
+ [1670]="al",
+ [1671]="al",
+ [1672]="al",
+ [1673]="al",
+ [1674]="al",
+ [1675]="al",
+ [1676]="al",
+ [1677]="al",
+ [1678]="al",
+ [1679]="al",
+ [1680]="al",
+ [1681]="al",
+ [1682]="al",
+ [1683]="al",
+ [1684]="al",
+ [1685]="al",
+ [1686]="al",
+ [1687]="al",
+ [1688]="al",
+ [1689]="al",
+ [1690]="al",
+ [1691]="al",
+ [1692]="al",
+ [1693]="al",
+ [1694]="al",
+ [1695]="al",
+ [1696]="al",
+ [1697]="al",
+ [1698]="al",
+ [1699]="al",
+ [1700]="al",
+ [1701]="al",
+ [1702]="al",
+ [1703]="al",
+ [1704]="al",
+ [1705]="al",
+ [1706]="al",
+ [1707]="al",
+ [1708]="al",
+ [1709]="al",
+ [1710]="al",
+ [1711]="al",
+ [1712]="al",
+ [1713]="al",
+ [1714]="al",
+ [1715]="al",
+ [1716]="al",
+ [1717]="al",
+ [1718]="al",
+ [1719]="al",
+ [1720]="al",
+ [1721]="al",
+ [1722]="al",
+ [1723]="al",
+ [1724]="al",
+ [1725]="al",
+ [1726]="al",
+ [1727]="al",
+ [1728]="al",
+ [1729]="al",
+ [1730]="al",
+ [1731]="al",
+ [1732]="al",
+ [1733]="al",
+ [1734]="al",
+ [1735]="al",
+ [1736]="al",
+ [1737]="al",
+ [1738]="al",
+ [1739]="al",
+ [1740]="al",
+ [1741]="al",
+ [1742]="al",
+ [1743]="al",
+ [1744]="al",
+ [1745]="al",
+ [1746]="al",
+ [1747]="al",
+ [1748]="al",
+ [1749]="al",
+ [1750]="nsm",
+ [1751]="nsm",
+ [1752]="nsm",
+ [1753]="nsm",
+ [1754]="nsm",
+ [1755]="nsm",
+ [1756]="nsm",
+ [1757]="an",
+ [1758]="on",
+ [1759]="nsm",
+ [1760]="nsm",
+ [1761]="nsm",
+ [1762]="nsm",
+ [1763]="nsm",
+ [1764]="nsm",
+ [1765]="al",
+ [1766]="al",
+ [1767]="nsm",
+ [1768]="nsm",
+ [1769]="on",
+ [1770]="nsm",
+ [1771]="nsm",
+ [1772]="nsm",
+ [1773]="nsm",
+ [1774]="al",
+ [1775]="al",
+ [1776]="en",
+ [1777]="en",
+ [1778]="en",
+ [1779]="en",
+ [1780]="en",
+ [1781]="en",
+ [1782]="en",
+ [1783]="en",
+ [1784]="en",
+ [1785]="en",
+ [1786]="al",
+ [1787]="al",
+ [1788]="al",
+ [1789]="al",
+ [1790]="al",
+ [1791]="al",
+ [1792]="al",
+ [1793]="al",
+ [1794]="al",
+ [1795]="al",
+ [1796]="al",
+ [1797]="al",
+ [1798]="al",
+ [1799]="al",
+ [1800]="al",
+ [1801]="al",
+ [1802]="al",
+ [1803]="al",
+ [1804]="al",
+ [1805]="al",
+ [1807]="al",
+ [1808]="al",
+ [1809]="nsm",
+ [1810]="al",
+ [1811]="al",
+ [1812]="al",
+ [1813]="al",
+ [1814]="al",
+ [1815]="al",
+ [1816]="al",
+ [1817]="al",
+ [1818]="al",
+ [1819]="al",
+ [1820]="al",
+ [1821]="al",
+ [1822]="al",
+ [1823]="al",
+ [1824]="al",
+ [1825]="al",
+ [1826]="al",
+ [1827]="al",
+ [1828]="al",
+ [1829]="al",
+ [1830]="al",
+ [1831]="al",
+ [1832]="al",
+ [1833]="al",
+ [1834]="al",
+ [1835]="al",
+ [1836]="al",
+ [1837]="al",
+ [1838]="al",
+ [1839]="al",
+ [1840]="nsm",
+ [1841]="nsm",
+ [1842]="nsm",
+ [1843]="nsm",
+ [1844]="nsm",
+ [1845]="nsm",
+ [1846]="nsm",
+ [1847]="nsm",
+ [1848]="nsm",
+ [1849]="nsm",
+ [1850]="nsm",
+ [1851]="nsm",
+ [1852]="nsm",
+ [1853]="nsm",
+ [1854]="nsm",
+ [1855]="nsm",
+ [1856]="nsm",
+ [1857]="nsm",
+ [1858]="nsm",
+ [1859]="nsm",
+ [1860]="nsm",
+ [1861]="nsm",
+ [1862]="nsm",
+ [1863]="nsm",
+ [1864]="nsm",
+ [1865]="nsm",
+ [1866]="nsm",
+ [1869]="al",
+ [1870]="al",
+ [1871]="al",
+ [1872]="al",
+ [1873]="al",
+ [1874]="al",
+ [1875]="al",
+ [1876]="al",
+ [1877]="al",
+ [1878]="al",
+ [1879]="al",
+ [1880]="al",
+ [1881]="al",
+ [1882]="al",
+ [1883]="al",
+ [1884]="al",
+ [1885]="al",
+ [1886]="al",
+ [1887]="al",
+ [1888]="al",
+ [1889]="al",
+ [1890]="al",
+ [1891]="al",
+ [1892]="al",
+ [1893]="al",
+ [1894]="al",
+ [1895]="al",
+ [1896]="al",
+ [1897]="al",
+ [1898]="al",
+ [1899]="al",
+ [1900]="al",
+ [1901]="al",
+ [1902]="al",
+ [1903]="al",
+ [1904]="al",
+ [1905]="al",
+ [1906]="al",
+ [1907]="al",
+ [1908]="al",
+ [1909]="al",
+ [1910]="al",
+ [1911]="al",
+ [1912]="al",
+ [1913]="al",
+ [1914]="al",
+ [1915]="al",
+ [1916]="al",
+ [1917]="al",
+ [1918]="al",
+ [1919]="al",
+ [1920]="al",
+ [1921]="al",
+ [1922]="al",
+ [1923]="al",
+ [1924]="al",
+ [1925]="al",
+ [1926]="al",
+ [1927]="al",
+ [1928]="al",
+ [1929]="al",
+ [1930]="al",
+ [1931]="al",
+ [1932]="al",
+ [1933]="al",
+ [1934]="al",
+ [1935]="al",
+ [1936]="al",
+ [1937]="al",
+ [1938]="al",
+ [1939]="al",
+ [1940]="al",
+ [1941]="al",
+ [1942]="al",
+ [1943]="al",
+ [1944]="al",
+ [1945]="al",
+ [1946]="al",
+ [1947]="al",
+ [1948]="al",
+ [1949]="al",
+ [1950]="al",
+ [1951]="al",
+ [1952]="al",
+ [1953]="al",
+ [1954]="al",
+ [1955]="al",
+ [1956]="al",
+ [1957]="al",
+ [1958]="nsm",
+ [1959]="nsm",
+ [1960]="nsm",
+ [1961]="nsm",
+ [1962]="nsm",
+ [1963]="nsm",
+ [1964]="nsm",
+ [1965]="nsm",
+ [1966]="nsm",
+ [1967]="nsm",
+ [1968]="nsm",
+ [1969]="al",
+ [1984]="r",
+ [1985]="r",
+ [1986]="r",
+ [1987]="r",
+ [1988]="r",
+ [1989]="r",
+ [1990]="r",
+ [1991]="r",
+ [1992]="r",
+ [1993]="r",
+ [1994]="r",
+ [1995]="r",
+ [1996]="r",
+ [1997]="r",
+ [1998]="r",
+ [1999]="r",
+ [2000]="r",
+ [2001]="r",
+ [2002]="r",
+ [2003]="r",
+ [2004]="r",
+ [2005]="r",
+ [2006]="r",
+ [2007]="r",
+ [2008]="r",
+ [2009]="r",
+ [2010]="r",
+ [2011]="r",
+ [2012]="r",
+ [2013]="r",
+ [2014]="r",
+ [2015]="r",
+ [2016]="r",
+ [2017]="r",
+ [2018]="r",
+ [2019]="r",
+ [2020]="r",
+ [2021]="r",
+ [2022]="r",
+ [2023]="r",
+ [2024]="r",
+ [2025]="r",
+ [2026]="r",
+ [2027]="nsm",
+ [2028]="nsm",
+ [2029]="nsm",
+ [2030]="nsm",
+ [2031]="nsm",
+ [2032]="nsm",
+ [2033]="nsm",
+ [2034]="nsm",
+ [2035]="nsm",
+ [2036]="r",
+ [2037]="r",
+ [2038]="on",
+ [2039]="on",
+ [2040]="on",
+ [2041]="on",
+ [2042]="r",
+ [2048]="r",
+ [2049]="r",
+ [2050]="r",
+ [2051]="r",
+ [2052]="r",
+ [2053]="r",
+ [2054]="r",
+ [2055]="r",
+ [2056]="r",
+ [2057]="r",
+ [2058]="r",
+ [2059]="r",
+ [2060]="r",
+ [2061]="r",
+ [2062]="r",
+ [2063]="r",
+ [2064]="r",
+ [2065]="r",
+ [2066]="r",
+ [2067]="r",
+ [2068]="r",
+ [2069]="r",
+ [2070]="nsm",
+ [2071]="nsm",
+ [2072]="nsm",
+ [2073]="nsm",
+ [2074]="r",
+ [2075]="nsm",
+ [2076]="nsm",
+ [2077]="nsm",
+ [2078]="nsm",
+ [2079]="nsm",
+ [2080]="nsm",
+ [2081]="nsm",
+ [2082]="nsm",
+ [2083]="nsm",
+ [2084]="r",
+ [2085]="nsm",
+ [2086]="nsm",
+ [2087]="nsm",
+ [2088]="r",
+ [2089]="nsm",
+ [2090]="nsm",
+ [2091]="nsm",
+ [2092]="nsm",
+ [2093]="nsm",
+ [2096]="r",
+ [2097]="r",
+ [2098]="r",
+ [2099]="r",
+ [2100]="r",
+ [2101]="r",
+ [2102]="r",
+ [2103]="r",
+ [2104]="r",
+ [2105]="r",
+ [2106]="r",
+ [2107]="r",
+ [2108]="r",
+ [2109]="r",
+ [2110]="r",
+ [2112]="r",
+ [2113]="r",
+ [2114]="r",
+ [2115]="r",
+ [2116]="r",
+ [2117]="r",
+ [2118]="r",
+ [2119]="r",
+ [2120]="r",
+ [2121]="r",
+ [2122]="r",
+ [2123]="r",
+ [2124]="r",
+ [2125]="r",
+ [2126]="r",
+ [2127]="r",
+ [2128]="r",
+ [2129]="r",
+ [2130]="r",
+ [2131]="r",
+ [2132]="r",
+ [2133]="r",
+ [2134]="r",
+ [2135]="r",
+ [2136]="r",
+ [2137]="nsm",
+ [2138]="nsm",
+ [2139]="nsm",
+ [2142]="r",
+ [2144]="al",
+ [2145]="al",
+ [2146]="al",
+ [2147]="al",
+ [2148]="al",
+ [2149]="al",
+ [2150]="al",
+ [2151]="al",
+ [2152]="al",
+ [2153]="al",
+ [2154]="al",
+ [2208]="al",
+ [2209]="al",
+ [2210]="al",
+ [2211]="al",
+ [2212]="al",
+ [2213]="al",
+ [2214]="al",
+ [2215]="al",
+ [2216]="al",
+ [2217]="al",
+ [2218]="al",
+ [2219]="al",
+ [2220]="al",
+ [2221]="al",
+ [2222]="al",
+ [2223]="al",
+ [2224]="al",
+ [2225]="al",
+ [2226]="al",
+ [2227]="al",
+ [2228]="al",
+ [2230]="al",
+ [2231]="al",
+ [2232]="al",
+ [2233]="al",
+ [2234]="al",
+ [2235]="al",
+ [2236]="al",
+ [2237]="al",
+ [2260]="nsm",
+ [2261]="nsm",
+ [2262]="nsm",
+ [2263]="nsm",
+ [2264]="nsm",
+ [2265]="nsm",
+ [2266]="nsm",
+ [2267]="nsm",
+ [2268]="nsm",
+ [2269]="nsm",
+ [2270]="nsm",
+ [2271]="nsm",
+ [2272]="nsm",
+ [2273]="nsm",
+ [2274]="an",
+ [2275]="nsm",
+ [2276]="nsm",
+ [2277]="nsm",
+ [2278]="nsm",
+ [2279]="nsm",
+ [2280]="nsm",
+ [2281]="nsm",
+ [2282]="nsm",
+ [2283]="nsm",
+ [2284]="nsm",
+ [2285]="nsm",
+ [2286]="nsm",
+ [2287]="nsm",
+ [2288]="nsm",
+ [2289]="nsm",
+ [2290]="nsm",
+ [2291]="nsm",
+ [2292]="nsm",
+ [2293]="nsm",
+ [2294]="nsm",
+ [2295]="nsm",
+ [2296]="nsm",
+ [2297]="nsm",
+ [2298]="nsm",
+ [2299]="nsm",
+ [2300]="nsm",
+ [2301]="nsm",
+ [2302]="nsm",
+ [2303]="nsm",
+ [2304]="nsm",
+ [2305]="nsm",
+ [2306]="nsm",
+ [2362]="nsm",
+ [2364]="nsm",
+ [2369]="nsm",
+ [2370]="nsm",
+ [2371]="nsm",
+ [2372]="nsm",
+ [2373]="nsm",
+ [2374]="nsm",
+ [2375]="nsm",
+ [2376]="nsm",
+ [2381]="nsm",
+ [2385]="nsm",
+ [2386]="nsm",
+ [2387]="nsm",
+ [2388]="nsm",
+ [2389]="nsm",
+ [2390]="nsm",
+ [2391]="nsm",
+ [2402]="nsm",
+ [2403]="nsm",
+ [2433]="nsm",
+ [2492]="nsm",
+ [2497]="nsm",
+ [2498]="nsm",
+ [2499]="nsm",
+ [2500]="nsm",
+ [2509]="nsm",
+ [2530]="nsm",
+ [2531]="nsm",
+ [2546]="et",
+ [2547]="et",
+ [2555]="et",
+ [2561]="nsm",
+ [2562]="nsm",
+ [2620]="nsm",
+ [2625]="nsm",
+ [2626]="nsm",
+ [2631]="nsm",
+ [2632]="nsm",
+ [2635]="nsm",
+ [2636]="nsm",
+ [2637]="nsm",
+ [2641]="nsm",
+ [2672]="nsm",
+ [2673]="nsm",
+ [2677]="nsm",
+ [2689]="nsm",
+ [2690]="nsm",
+ [2748]="nsm",
+ [2753]="nsm",
+ [2754]="nsm",
+ [2755]="nsm",
+ [2756]="nsm",
+ [2757]="nsm",
+ [2759]="nsm",
+ [2760]="nsm",
+ [2765]="nsm",
+ [2786]="nsm",
+ [2787]="nsm",
+ [2801]="et",
+ [2810]="nsm",
+ [2811]="nsm",
+ [2812]="nsm",
+ [2813]="nsm",
+ [2814]="nsm",
+ [2815]="nsm",
+ [2817]="nsm",
+ [2876]="nsm",
+ [2879]="nsm",
+ [2881]="nsm",
+ [2882]="nsm",
+ [2883]="nsm",
+ [2884]="nsm",
+ [2893]="nsm",
+ [2902]="nsm",
+ [2914]="nsm",
+ [2915]="nsm",
+ [2946]="nsm",
+ [3008]="nsm",
+ [3021]="nsm",
+ [3059]="on",
+ [3060]="on",
+ [3061]="on",
+ [3062]="on",
+ [3063]="on",
+ [3064]="on",
+ [3065]="et",
+ [3066]="on",
+ [3072]="nsm",
+ [3134]="nsm",
+ [3135]="nsm",
+ [3136]="nsm",
+ [3142]="nsm",
+ [3143]="nsm",
+ [3144]="nsm",
+ [3146]="nsm",
+ [3147]="nsm",
+ [3148]="nsm",
+ [3149]="nsm",
+ [3157]="nsm",
+ [3158]="nsm",
+ [3170]="nsm",
+ [3171]="nsm",
+ [3192]="on",
+ [3193]="on",
+ [3194]="on",
+ [3195]="on",
+ [3196]="on",
+ [3197]="on",
+ [3198]="on",
+ [3201]="nsm",
+ [3260]="nsm",
+ [3276]="nsm",
+ [3277]="nsm",
+ [3298]="nsm",
+ [3299]="nsm",
+ [3328]="nsm",
+ [3329]="nsm",
+ [3387]="nsm",
+ [3388]="nsm",
+ [3393]="nsm",
+ [3394]="nsm",
+ [3395]="nsm",
+ [3396]="nsm",
+ [3405]="nsm",
+ [3426]="nsm",
+ [3427]="nsm",
+ [3530]="nsm",
+ [3538]="nsm",
+ [3539]="nsm",
+ [3540]="nsm",
+ [3542]="nsm",
+ [3633]="nsm",
+ [3636]="nsm",
+ [3637]="nsm",
+ [3638]="nsm",
+ [3639]="nsm",
+ [3640]="nsm",
+ [3641]="nsm",
+ [3642]="nsm",
+ [3647]="et",
+ [3655]="nsm",
+ [3656]="nsm",
+ [3657]="nsm",
+ [3658]="nsm",
+ [3659]="nsm",
+ [3660]="nsm",
+ [3661]="nsm",
+ [3662]="nsm",
+ [3761]="nsm",
+ [3764]="nsm",
+ [3765]="nsm",
+ [3766]="nsm",
+ [3767]="nsm",
+ [3768]="nsm",
+ [3769]="nsm",
+ [3771]="nsm",
+ [3772]="nsm",
+ [3784]="nsm",
+ [3785]="nsm",
+ [3786]="nsm",
+ [3787]="nsm",
+ [3788]="nsm",
+ [3789]="nsm",
+ [3864]="nsm",
+ [3865]="nsm",
+ [3893]="nsm",
+ [3895]="nsm",
+ [3897]="nsm",
+ [3898]="on",
+ [3899]="on",
+ [3900]="on",
+ [3901]="on",
+ [3953]="nsm",
+ [3954]="nsm",
+ [3955]="nsm",
+ [3956]="nsm",
+ [3957]="nsm",
+ [3958]="nsm",
+ [3959]="nsm",
+ [3960]="nsm",
+ [3961]="nsm",
+ [3962]="nsm",
+ [3963]="nsm",
+ [3964]="nsm",
+ [3965]="nsm",
+ [3966]="nsm",
+ [3968]="nsm",
+ [3969]="nsm",
+ [3970]="nsm",
+ [3971]="nsm",
+ [3972]="nsm",
+ [3974]="nsm",
+ [3975]="nsm",
+ [3981]="nsm",
+ [3982]="nsm",
+ [3983]="nsm",
+ [3984]="nsm",
+ [3985]="nsm",
+ [3986]="nsm",
+ [3987]="nsm",
+ [3988]="nsm",
+ [3989]="nsm",
+ [3990]="nsm",
+ [3991]="nsm",
+ [3993]="nsm",
+ [3994]="nsm",
+ [3995]="nsm",
+ [3996]="nsm",
+ [3997]="nsm",
+ [3998]="nsm",
+ [3999]="nsm",
+ [4000]="nsm",
+ [4001]="nsm",
+ [4002]="nsm",
+ [4003]="nsm",
+ [4004]="nsm",
+ [4005]="nsm",
+ [4006]="nsm",
+ [4007]="nsm",
+ [4008]="nsm",
+ [4009]="nsm",
+ [4010]="nsm",
+ [4011]="nsm",
+ [4012]="nsm",
+ [4013]="nsm",
+ [4014]="nsm",
+ [4015]="nsm",
+ [4016]="nsm",
+ [4017]="nsm",
+ [4018]="nsm",
+ [4019]="nsm",
+ [4020]="nsm",
+ [4021]="nsm",
+ [4022]="nsm",
+ [4023]="nsm",
+ [4024]="nsm",
+ [4025]="nsm",
+ [4026]="nsm",
+ [4027]="nsm",
+ [4028]="nsm",
+ [4038]="nsm",
+ [4141]="nsm",
+ [4142]="nsm",
+ [4143]="nsm",
+ [4144]="nsm",
+ [4146]="nsm",
+ [4147]="nsm",
+ [4148]="nsm",
+ [4149]="nsm",
+ [4150]="nsm",
+ [4151]="nsm",
+ [4153]="nsm",
+ [4154]="nsm",
+ [4157]="nsm",
+ [4158]="nsm",
+ [4184]="nsm",
+ [4185]="nsm",
+ [4190]="nsm",
+ [4191]="nsm",
+ [4192]="nsm",
+ [4209]="nsm",
+ [4210]="nsm",
+ [4211]="nsm",
+ [4212]="nsm",
+ [4226]="nsm",
+ [4229]="nsm",
+ [4230]="nsm",
+ [4237]="nsm",
+ [4253]="nsm",
+ [4957]="nsm",
+ [4958]="nsm",
+ [4959]="nsm",
+ [5008]="on",
+ [5009]="on",
+ [5010]="on",
+ [5011]="on",
+ [5012]="on",
+ [5013]="on",
+ [5014]="on",
+ [5015]="on",
+ [5016]="on",
+ [5017]="on",
+ [5120]="on",
+ [5760]="ws",
+ [5787]="on",
+ [5788]="on",
+ [5906]="nsm",
+ [5907]="nsm",
+ [5908]="nsm",
+ [5938]="nsm",
+ [5939]="nsm",
+ [5940]="nsm",
+ [5970]="nsm",
+ [5971]="nsm",
+ [6002]="nsm",
+ [6003]="nsm",
+ [6068]="nsm",
+ [6069]="nsm",
+ [6071]="nsm",
+ [6072]="nsm",
+ [6073]="nsm",
+ [6074]="nsm",
+ [6075]="nsm",
+ [6076]="nsm",
+ [6077]="nsm",
+ [6086]="nsm",
+ [6089]="nsm",
+ [6090]="nsm",
+ [6091]="nsm",
+ [6092]="nsm",
+ [6093]="nsm",
+ [6094]="nsm",
+ [6095]="nsm",
+ [6096]="nsm",
+ [6097]="nsm",
+ [6098]="nsm",
+ [6099]="nsm",
+ [6107]="et",
+ [6109]="nsm",
+ [6128]="on",
+ [6129]="on",
+ [6130]="on",
+ [6131]="on",
+ [6132]="on",
+ [6133]="on",
+ [6134]="on",
+ [6135]="on",
+ [6136]="on",
+ [6137]="on",
+ [6144]="on",
+ [6145]="on",
+ [6146]="on",
+ [6147]="on",
+ [6148]="on",
+ [6149]="on",
+ [6150]="on",
+ [6151]="on",
+ [6152]="on",
+ [6153]="on",
+ [6154]="on",
+ [6155]="nsm",
+ [6156]="nsm",
+ [6157]="nsm",
+ [6158]="bn",
+ [6277]="nsm",
+ [6278]="nsm",
+ [6313]="nsm",
+ [6432]="nsm",
+ [6433]="nsm",
+ [6434]="nsm",
+ [6439]="nsm",
+ [6440]="nsm",
+ [6450]="nsm",
+ [6457]="nsm",
+ [6458]="nsm",
+ [6459]="nsm",
+ [6464]="on",
+ [6468]="on",
+ [6469]="on",
+ [6622]="on",
+ [6623]="on",
+ [6624]="on",
+ [6625]="on",
+ [6626]="on",
+ [6627]="on",
+ [6628]="on",
+ [6629]="on",
+ [6630]="on",
+ [6631]="on",
+ [6632]="on",
+ [6633]="on",
+ [6634]="on",
+ [6635]="on",
+ [6636]="on",
+ [6637]="on",
+ [6638]="on",
+ [6639]="on",
+ [6640]="on",
+ [6641]="on",
+ [6642]="on",
+ [6643]="on",
+ [6644]="on",
+ [6645]="on",
+ [6646]="on",
+ [6647]="on",
+ [6648]="on",
+ [6649]="on",
+ [6650]="on",
+ [6651]="on",
+ [6652]="on",
+ [6653]="on",
+ [6654]="on",
+ [6655]="on",
+ [6679]="nsm",
+ [6680]="nsm",
+ [6683]="nsm",
+ [6742]="nsm",
+ [6744]="nsm",
+ [6745]="nsm",
+ [6746]="nsm",
+ [6747]="nsm",
+ [6748]="nsm",
+ [6749]="nsm",
+ [6750]="nsm",
+ [6752]="nsm",
+ [6754]="nsm",
+ [6757]="nsm",
+ [6758]="nsm",
+ [6759]="nsm",
+ [6760]="nsm",
+ [6761]="nsm",
+ [6762]="nsm",
+ [6763]="nsm",
+ [6764]="nsm",
+ [6771]="nsm",
+ [6772]="nsm",
+ [6773]="nsm",
+ [6774]="nsm",
+ [6775]="nsm",
+ [6776]="nsm",
+ [6777]="nsm",
+ [6778]="nsm",
+ [6779]="nsm",
+ [6780]="nsm",
+ [6783]="nsm",
+ [6832]="nsm",
+ [6833]="nsm",
+ [6834]="nsm",
+ [6835]="nsm",
+ [6836]="nsm",
+ [6837]="nsm",
+ [6838]="nsm",
+ [6839]="nsm",
+ [6840]="nsm",
+ [6841]="nsm",
+ [6842]="nsm",
+ [6843]="nsm",
+ [6844]="nsm",
+ [6845]="nsm",
+ [6846]="nsm",
+ [6912]="nsm",
+ [6913]="nsm",
+ [6914]="nsm",
+ [6915]="nsm",
+ [6964]="nsm",
+ [6966]="nsm",
+ [6967]="nsm",
+ [6968]="nsm",
+ [6969]="nsm",
+ [6970]="nsm",
+ [6972]="nsm",
+ [6978]="nsm",
+ [7019]="nsm",
+ [7020]="nsm",
+ [7021]="nsm",
+ [7022]="nsm",
+ [7023]="nsm",
+ [7024]="nsm",
+ [7025]="nsm",
+ [7026]="nsm",
+ [7027]="nsm",
+ [7040]="nsm",
+ [7041]="nsm",
+ [7074]="nsm",
+ [7075]="nsm",
+ [7076]="nsm",
+ [7077]="nsm",
+ [7080]="nsm",
+ [7081]="nsm",
+ [7083]="nsm",
+ [7084]="nsm",
+ [7085]="nsm",
+ [7142]="nsm",
+ [7144]="nsm",
+ [7145]="nsm",
+ [7149]="nsm",
+ [7151]="nsm",
+ [7152]="nsm",
+ [7153]="nsm",
+ [7212]="nsm",
+ [7213]="nsm",
+ [7214]="nsm",
+ [7215]="nsm",
+ [7216]="nsm",
+ [7217]="nsm",
+ [7218]="nsm",
+ [7219]="nsm",
+ [7222]="nsm",
+ [7223]="nsm",
+ [7376]="nsm",
+ [7377]="nsm",
+ [7378]="nsm",
+ [7380]="nsm",
+ [7381]="nsm",
+ [7382]="nsm",
+ [7383]="nsm",
+ [7384]="nsm",
+ [7385]="nsm",
+ [7386]="nsm",
+ [7387]="nsm",
+ [7388]="nsm",
+ [7389]="nsm",
+ [7390]="nsm",
+ [7391]="nsm",
+ [7392]="nsm",
+ [7394]="nsm",
+ [7395]="nsm",
+ [7396]="nsm",
+ [7397]="nsm",
+ [7398]="nsm",
+ [7399]="nsm",
+ [7400]="nsm",
+ [7405]="nsm",
+ [7412]="nsm",
+ [7416]="nsm",
+ [7417]="nsm",
+ [7616]="nsm",
+ [7617]="nsm",
+ [7618]="nsm",
+ [7619]="nsm",
+ [7620]="nsm",
+ [7621]="nsm",
+ [7622]="nsm",
+ [7623]="nsm",
+ [7624]="nsm",
+ [7625]="nsm",
+ [7626]="nsm",
+ [7627]="nsm",
+ [7628]="nsm",
+ [7629]="nsm",
+ [7630]="nsm",
+ [7631]="nsm",
+ [7632]="nsm",
+ [7633]="nsm",
+ [7634]="nsm",
+ [7635]="nsm",
+ [7636]="nsm",
+ [7637]="nsm",
+ [7638]="nsm",
+ [7639]="nsm",
+ [7640]="nsm",
+ [7641]="nsm",
+ [7642]="nsm",
+ [7643]="nsm",
+ [7644]="nsm",
+ [7645]="nsm",
+ [7646]="nsm",
+ [7647]="nsm",
+ [7648]="nsm",
+ [7649]="nsm",
+ [7650]="nsm",
+ [7651]="nsm",
+ [7652]="nsm",
+ [7653]="nsm",
+ [7654]="nsm",
+ [7655]="nsm",
+ [7656]="nsm",
+ [7657]="nsm",
+ [7658]="nsm",
+ [7659]="nsm",
+ [7660]="nsm",
+ [7661]="nsm",
+ [7662]="nsm",
+ [7663]="nsm",
+ [7664]="nsm",
+ [7665]="nsm",
+ [7666]="nsm",
+ [7667]="nsm",
+ [7668]="nsm",
+ [7669]="nsm",
+ [7670]="nsm",
+ [7671]="nsm",
+ [7672]="nsm",
+ [7673]="nsm",
+ [7675]="nsm",
+ [7676]="nsm",
+ [7677]="nsm",
+ [7678]="nsm",
+ [7679]="nsm",
+ [8125]="on",
+ [8127]="on",
+ [8128]="on",
+ [8129]="on",
+ [8141]="on",
+ [8142]="on",
+ [8143]="on",
+ [8157]="on",
+ [8158]="on",
+ [8159]="on",
+ [8173]="on",
+ [8174]="on",
+ [8175]="on",
+ [8189]="on",
+ [8190]="on",
+ [8192]="ws",
+ [8193]="ws",
+ [8194]="ws",
+ [8195]="ws",
+ [8196]="ws",
+ [8197]="ws",
+ [8198]="ws",
+ [8199]="ws",
+ [8200]="ws",
+ [8201]="ws",
+ [8202]="ws",
+ [8203]="bn",
+ [8204]="bn",
+ [8205]="bn",
+ [8207]="r",
+ [8208]="on",
+ [8209]="on",
+ [8210]="on",
+ [8211]="on",
+ [8212]="on",
+ [8213]="on",
+ [8214]="on",
+ [8215]="on",
+ [8216]="on",
+ [8217]="on",
+ [8218]="on",
+ [8219]="on",
+ [8220]="on",
+ [8221]="on",
+ [8222]="on",
+ [8223]="on",
+ [8224]="on",
+ [8225]="on",
+ [8226]="on",
+ [8227]="on",
+ [8228]="on",
+ [8229]="on",
+ [8230]="on",
+ [8231]="on",
+ [8232]="ws",
+ [8233]="b",
+ [8234]="lre",
+ [8235]="rle",
+ [8236]="pdf",
+ [8237]="lro",
+ [8238]="rlo",
+ [8239]="cs",
+ [8240]="et",
+ [8241]="et",
+ [8242]="et",
+ [8243]="et",
+ [8244]="et",
+ [8245]="on",
+ [8246]="on",
+ [8247]="on",
+ [8248]="on",
+ [8249]="on",
+ [8250]="on",
+ [8251]="on",
+ [8252]="on",
+ [8253]="on",
+ [8254]="on",
+ [8255]="on",
+ [8256]="on",
+ [8257]="on",
+ [8258]="on",
+ [8259]="on",
+ [8260]="cs",
+ [8261]="on",
+ [8262]="on",
+ [8263]="on",
+ [8264]="on",
+ [8265]="on",
+ [8266]="on",
+ [8267]="on",
+ [8268]="on",
+ [8269]="on",
+ [8270]="on",
+ [8271]="on",
+ [8272]="on",
+ [8273]="on",
+ [8274]="on",
+ [8275]="on",
+ [8276]="on",
+ [8277]="on",
+ [8278]="on",
+ [8279]="on",
+ [8280]="on",
+ [8281]="on",
+ [8282]="on",
+ [8283]="on",
+ [8284]="on",
+ [8285]="on",
+ [8286]="on",
+ [8287]="ws",
+ [8288]="bn",
+ [8289]="bn",
+ [8290]="bn",
+ [8291]="bn",
+ [8292]="bn",
+ [8294]="lri",
+ [8295]="rli",
+ [8296]="fsi",
+ [8297]="pdi",
+ [8298]="bn",
+ [8299]="bn",
+ [8300]="bn",
+ [8301]="bn",
+ [8302]="bn",
+ [8303]="bn",
+ [8304]="en",
+ [8308]="en",
+ [8309]="en",
+ [8310]="en",
+ [8311]="en",
+ [8312]="en",
+ [8313]="en",
+ [8314]="es",
+ [8315]="es",
+ [8316]="on",
+ [8317]="on",
+ [8318]="on",
+ [8320]="en",
+ [8321]="en",
+ [8322]="en",
+ [8323]="en",
+ [8324]="en",
+ [8325]="en",
+ [8326]="en",
+ [8327]="en",
+ [8328]="en",
+ [8329]="en",
+ [8330]="es",
+ [8331]="es",
+ [8332]="on",
+ [8333]="on",
+ [8334]="on",
+ [8352]="et",
+ [8353]="et",
+ [8354]="et",
+ [8355]="et",
+ [8356]="et",
+ [8357]="et",
+ [8358]="et",
+ [8359]="et",
+ [8360]="et",
+ [8361]="et",
+ [8362]="et",
+ [8363]="et",
+ [8364]="et",
+ [8365]="et",
+ [8366]="et",
+ [8367]="et",
+ [8368]="et",
+ [8369]="et",
+ [8370]="et",
+ [8371]="et",
+ [8372]="et",
+ [8373]="et",
+ [8374]="et",
+ [8375]="et",
+ [8376]="et",
+ [8377]="et",
+ [8378]="et",
+ [8379]="et",
+ [8380]="et",
+ [8381]="et",
+ [8382]="et",
+ [8383]="et",
+ [8400]="nsm",
+ [8401]="nsm",
+ [8402]="nsm",
+ [8403]="nsm",
+ [8404]="nsm",
+ [8405]="nsm",
+ [8406]="nsm",
+ [8407]="nsm",
+ [8408]="nsm",
+ [8409]="nsm",
+ [8410]="nsm",
+ [8411]="nsm",
+ [8412]="nsm",
+ [8413]="nsm",
+ [8414]="nsm",
+ [8415]="nsm",
+ [8416]="nsm",
+ [8417]="nsm",
+ [8418]="nsm",
+ [8419]="nsm",
+ [8420]="nsm",
+ [8421]="nsm",
+ [8422]="nsm",
+ [8423]="nsm",
+ [8424]="nsm",
+ [8425]="nsm",
+ [8426]="nsm",
+ [8427]="nsm",
+ [8428]="nsm",
+ [8429]="nsm",
+ [8430]="nsm",
+ [8431]="nsm",
+ [8432]="nsm",
+ [8448]="on",
+ [8449]="on",
+ [8451]="on",
+ [8452]="on",
+ [8453]="on",
+ [8454]="on",
+ [8456]="on",
+ [8457]="on",
+ [8468]="on",
+ [8470]="on",
+ [8471]="on",
+ [8472]="on",
+ [8478]="on",
+ [8479]="on",
+ [8480]="on",
+ [8481]="on",
+ [8482]="on",
+ [8483]="on",
+ [8485]="on",
+ [8487]="on",
+ [8489]="on",
+ [8494]="et",
+ [8506]="on",
+ [8507]="on",
+ [8512]="on",
+ [8513]="on",
+ [8514]="on",
+ [8515]="on",
+ [8516]="on",
+ [8522]="on",
+ [8523]="on",
+ [8524]="on",
+ [8525]="on",
+ [8528]="on",
+ [8529]="on",
+ [8530]="on",
+ [8531]="on",
+ [8532]="on",
+ [8533]="on",
+ [8534]="on",
+ [8535]="on",
+ [8536]="on",
+ [8537]="on",
+ [8538]="on",
+ [8539]="on",
+ [8540]="on",
+ [8541]="on",
+ [8542]="on",
+ [8543]="on",
+ [8585]="on",
+ [8586]="on",
+ [8587]="on",
+ [8592]="on",
+ [8593]="on",
+ [8594]="on",
+ [8595]="on",
+ [8596]="on",
+ [8597]="on",
+ [8598]="on",
+ [8599]="on",
+ [8600]="on",
+ [8601]="on",
+ [8602]="on",
+ [8603]="on",
+ [8604]="on",
+ [8605]="on",
+ [8606]="on",
+ [8607]="on",
+ [8608]="on",
+ [8609]="on",
+ [8610]="on",
+ [8611]="on",
+ [8612]="on",
+ [8613]="on",
+ [8614]="on",
+ [8615]="on",
+ [8616]="on",
+ [8617]="on",
+ [8618]="on",
+ [8619]="on",
+ [8620]="on",
+ [8621]="on",
+ [8622]="on",
+ [8623]="on",
+ [8624]="on",
+ [8625]="on",
+ [8626]="on",
+ [8627]="on",
+ [8628]="on",
+ [8629]="on",
+ [8630]="on",
+ [8631]="on",
+ [8632]="on",
+ [8633]="on",
+ [8634]="on",
+ [8635]="on",
+ [8636]="on",
+ [8637]="on",
+ [8638]="on",
+ [8639]="on",
+ [8640]="on",
+ [8641]="on",
+ [8642]="on",
+ [8643]="on",
+ [8644]="on",
+ [8645]="on",
+ [8646]="on",
+ [8647]="on",
+ [8648]="on",
+ [8649]="on",
+ [8650]="on",
+ [8651]="on",
+ [8652]="on",
+ [8653]="on",
+ [8654]="on",
+ [8655]="on",
+ [8656]="on",
+ [8657]="on",
+ [8658]="on",
+ [8659]="on",
+ [8660]="on",
+ [8661]="on",
+ [8662]="on",
+ [8663]="on",
+ [8664]="on",
+ [8665]="on",
+ [8666]="on",
+ [8667]="on",
+ [8668]="on",
+ [8669]="on",
+ [8670]="on",
+ [8671]="on",
+ [8672]="on",
+ [8673]="on",
+ [8674]="on",
+ [8675]="on",
+ [8676]="on",
+ [8677]="on",
+ [8678]="on",
+ [8679]="on",
+ [8680]="on",
+ [8681]="on",
+ [8682]="on",
+ [8683]="on",
+ [8684]="on",
+ [8685]="on",
+ [8686]="on",
+ [8687]="on",
+ [8688]="on",
+ [8689]="on",
+ [8690]="on",
+ [8691]="on",
+ [8692]="on",
+ [8693]="on",
+ [8694]="on",
+ [8695]="on",
+ [8696]="on",
+ [8697]="on",
+ [8698]="on",
+ [8699]="on",
+ [8700]="on",
+ [8701]="on",
+ [8702]="on",
+ [8703]="on",
+ [8704]="on",
+ [8705]="on",
+ [8706]="on",
+ [8707]="on",
+ [8708]="on",
+ [8709]="on",
+ [8710]="on",
+ [8711]="on",
+ [8712]="on",
+ [8713]="on",
+ [8714]="on",
+ [8715]="on",
+ [8716]="on",
+ [8717]="on",
+ [8718]="on",
+ [8719]="on",
+ [8720]="on",
+ [8721]="on",
+ [8722]="es",
+ [8723]="et",
+ [8724]="on",
+ [8725]="on",
+ [8726]="on",
+ [8727]="on",
+ [8728]="on",
+ [8729]="on",
+ [8730]="on",
+ [8731]="on",
+ [8732]="on",
+ [8733]="on",
+ [8734]="on",
+ [8735]="on",
+ [8736]="on",
+ [8737]="on",
+ [8738]="on",
+ [8739]="on",
+ [8740]="on",
+ [8741]="on",
+ [8742]="on",
+ [8743]="on",
+ [8744]="on",
+ [8745]="on",
+ [8746]="on",
+ [8747]="on",
+ [8748]="on",
+ [8749]="on",
+ [8750]="on",
+ [8751]="on",
+ [8752]="on",
+ [8753]="on",
+ [8754]="on",
+ [8755]="on",
+ [8756]="on",
+ [8757]="on",
+ [8758]="on",
+ [8759]="on",
+ [8760]="on",
+ [8761]="on",
+ [8762]="on",
+ [8763]="on",
+ [8764]="on",
+ [8765]="on",
+ [8766]="on",
+ [8767]="on",
+ [8768]="on",
+ [8769]="on",
+ [8770]="on",
+ [8771]="on",
+ [8772]="on",
+ [8773]="on",
+ [8774]="on",
+ [8775]="on",
+ [8776]="on",
+ [8777]="on",
+ [8778]="on",
+ [8779]="on",
+ [8780]="on",
+ [8781]="on",
+ [8782]="on",
+ [8783]="on",
+ [8784]="on",
+ [8785]="on",
+ [8786]="on",
+ [8787]="on",
+ [8788]="on",
+ [8789]="on",
+ [8790]="on",
+ [8791]="on",
+ [8792]="on",
+ [8793]="on",
+ [8794]="on",
+ [8795]="on",
+ [8796]="on",
+ [8797]="on",
+ [8798]="on",
+ [8799]="on",
+ [8800]="on",
+ [8801]="on",
+ [8802]="on",
+ [8803]="on",
+ [8804]="on",
+ [8805]="on",
+ [8806]="on",
+ [8807]="on",
+ [8808]="on",
+ [8809]="on",
+ [8810]="on",
+ [8811]="on",
+ [8812]="on",
+ [8813]="on",
+ [8814]="on",
+ [8815]="on",
+ [8816]="on",
+ [8817]="on",
+ [8818]="on",
+ [8819]="on",
+ [8820]="on",
+ [8821]="on",
+ [8822]="on",
+ [8823]="on",
+ [8824]="on",
+ [8825]="on",
+ [8826]="on",
+ [8827]="on",
+ [8828]="on",
+ [8829]="on",
+ [8830]="on",
+ [8831]="on",
+ [8832]="on",
+ [8833]="on",
+ [8834]="on",
+ [8835]="on",
+ [8836]="on",
+ [8837]="on",
+ [8838]="on",
+ [8839]="on",
+ [8840]="on",
+ [8841]="on",
+ [8842]="on",
+ [8843]="on",
+ [8844]="on",
+ [8845]="on",
+ [8846]="on",
+ [8847]="on",
+ [8848]="on",
+ [8849]="on",
+ [8850]="on",
+ [8851]="on",
+ [8852]="on",
+ [8853]="on",
+ [8854]="on",
+ [8855]="on",
+ [8856]="on",
+ [8857]="on",
+ [8858]="on",
+ [8859]="on",
+ [8860]="on",
+ [8861]="on",
+ [8862]="on",
+ [8863]="on",
+ [8864]="on",
+ [8865]="on",
+ [8866]="on",
+ [8867]="on",
+ [8868]="on",
+ [8869]="on",
+ [8870]="on",
+ [8871]="on",
+ [8872]="on",
+ [8873]="on",
+ [8874]="on",
+ [8875]="on",
+ [8876]="on",
+ [8877]="on",
+ [8878]="on",
+ [8879]="on",
+ [8880]="on",
+ [8881]="on",
+ [8882]="on",
+ [8883]="on",
+ [8884]="on",
+ [8885]="on",
+ [8886]="on",
+ [8887]="on",
+ [8888]="on",
+ [8889]="on",
+ [8890]="on",
+ [8891]="on",
+ [8892]="on",
+ [8893]="on",
+ [8894]="on",
+ [8895]="on",
+ [8896]="on",
+ [8897]="on",
+ [8898]="on",
+ [8899]="on",
+ [8900]="on",
+ [8901]="on",
+ [8902]="on",
+ [8903]="on",
+ [8904]="on",
+ [8905]="on",
+ [8906]="on",
+ [8907]="on",
+ [8908]="on",
+ [8909]="on",
+ [8910]="on",
+ [8911]="on",
+ [8912]="on",
+ [8913]="on",
+ [8914]="on",
+ [8915]="on",
+ [8916]="on",
+ [8917]="on",
+ [8918]="on",
+ [8919]="on",
+ [8920]="on",
+ [8921]="on",
+ [8922]="on",
+ [8923]="on",
+ [8924]="on",
+ [8925]="on",
+ [8926]="on",
+ [8927]="on",
+ [8928]="on",
+ [8929]="on",
+ [8930]="on",
+ [8931]="on",
+ [8932]="on",
+ [8933]="on",
+ [8934]="on",
+ [8935]="on",
+ [8936]="on",
+ [8937]="on",
+ [8938]="on",
+ [8939]="on",
+ [8940]="on",
+ [8941]="on",
+ [8942]="on",
+ [8943]="on",
+ [8944]="on",
+ [8945]="on",
+ [8946]="on",
+ [8947]="on",
+ [8948]="on",
+ [8949]="on",
+ [8950]="on",
+ [8951]="on",
+ [8952]="on",
+ [8953]="on",
+ [8954]="on",
+ [8955]="on",
+ [8956]="on",
+ [8957]="on",
+ [8958]="on",
+ [8959]="on",
+ [8960]="on",
+ [8961]="on",
+ [8962]="on",
+ [8963]="on",
+ [8964]="on",
+ [8965]="on",
+ [8966]="on",
+ [8967]="on",
+ [8968]="on",
+ [8969]="on",
+ [8970]="on",
+ [8971]="on",
+ [8972]="on",
+ [8973]="on",
+ [8974]="on",
+ [8975]="on",
+ [8976]="on",
+ [8977]="on",
+ [8978]="on",
+ [8979]="on",
+ [8980]="on",
+ [8981]="on",
+ [8982]="on",
+ [8983]="on",
+ [8984]="on",
+ [8985]="on",
+ [8986]="on",
+ [8987]="on",
+ [8988]="on",
+ [8989]="on",
+ [8990]="on",
+ [8991]="on",
+ [8992]="on",
+ [8993]="on",
+ [8994]="on",
+ [8995]="on",
+ [8996]="on",
+ [8997]="on",
+ [8998]="on",
+ [8999]="on",
+ [9000]="on",
+ [9001]="on",
+ [9002]="on",
+ [9003]="on",
+ [9004]="on",
+ [9005]="on",
+ [9006]="on",
+ [9007]="on",
+ [9008]="on",
+ [9009]="on",
+ [9010]="on",
+ [9011]="on",
+ [9012]="on",
+ [9013]="on",
+ [9083]="on",
+ [9084]="on",
+ [9085]="on",
+ [9086]="on",
+ [9087]="on",
+ [9088]="on",
+ [9089]="on",
+ [9090]="on",
+ [9091]="on",
+ [9092]="on",
+ [9093]="on",
+ [9094]="on",
+ [9095]="on",
+ [9096]="on",
+ [9097]="on",
+ [9098]="on",
+ [9099]="on",
+ [9100]="on",
+ [9101]="on",
+ [9102]="on",
+ [9103]="on",
+ [9104]="on",
+ [9105]="on",
+ [9106]="on",
+ [9107]="on",
+ [9108]="on",
+ [9110]="on",
+ [9111]="on",
+ [9112]="on",
+ [9113]="on",
+ [9114]="on",
+ [9115]="on",
+ [9116]="on",
+ [9117]="on",
+ [9118]="on",
+ [9119]="on",
+ [9120]="on",
+ [9121]="on",
+ [9122]="on",
+ [9123]="on",
+ [9124]="on",
+ [9125]="on",
+ [9126]="on",
+ [9127]="on",
+ [9128]="on",
+ [9129]="on",
+ [9130]="on",
+ [9131]="on",
+ [9132]="on",
+ [9133]="on",
+ [9134]="on",
+ [9135]="on",
+ [9136]="on",
+ [9137]="on",
+ [9138]="on",
+ [9139]="on",
+ [9140]="on",
+ [9141]="on",
+ [9142]="on",
+ [9143]="on",
+ [9144]="on",
+ [9145]="on",
+ [9146]="on",
+ [9147]="on",
+ [9148]="on",
+ [9149]="on",
+ [9150]="on",
+ [9151]="on",
+ [9152]="on",
+ [9153]="on",
+ [9154]="on",
+ [9155]="on",
+ [9156]="on",
+ [9157]="on",
+ [9158]="on",
+ [9159]="on",
+ [9160]="on",
+ [9161]="on",
+ [9162]="on",
+ [9163]="on",
+ [9164]="on",
+ [9165]="on",
+ [9166]="on",
+ [9167]="on",
+ [9168]="on",
+ [9169]="on",
+ [9170]="on",
+ [9171]="on",
+ [9172]="on",
+ [9173]="on",
+ [9174]="on",
+ [9175]="on",
+ [9176]="on",
+ [9177]="on",
+ [9178]="on",
+ [9179]="on",
+ [9180]="on",
+ [9181]="on",
+ [9182]="on",
+ [9183]="on",
+ [9184]="on",
+ [9185]="on",
+ [9186]="on",
+ [9187]="on",
+ [9188]="on",
+ [9189]="on",
+ [9190]="on",
+ [9191]="on",
+ [9192]="on",
+ [9193]="on",
+ [9194]="on",
+ [9195]="on",
+ [9196]="on",
+ [9197]="on",
+ [9198]="on",
+ [9199]="on",
+ [9200]="on",
+ [9201]="on",
+ [9202]="on",
+ [9203]="on",
+ [9204]="on",
+ [9205]="on",
+ [9206]="on",
+ [9207]="on",
+ [9208]="on",
+ [9209]="on",
+ [9210]="on",
+ [9211]="on",
+ [9212]="on",
+ [9213]="on",
+ [9214]="on",
+ [9215]="on",
+ [9216]="on",
+ [9217]="on",
+ [9218]="on",
+ [9219]="on",
+ [9220]="on",
+ [9221]="on",
+ [9222]="on",
+ [9223]="on",
+ [9224]="on",
+ [9225]="on",
+ [9226]="on",
+ [9227]="on",
+ [9228]="on",
+ [9229]="on",
+ [9230]="on",
+ [9231]="on",
+ [9232]="on",
+ [9233]="on",
+ [9234]="on",
+ [9235]="on",
+ [9236]="on",
+ [9237]="on",
+ [9238]="on",
+ [9239]="on",
+ [9240]="on",
+ [9241]="on",
+ [9242]="on",
+ [9243]="on",
+ [9244]="on",
+ [9245]="on",
+ [9246]="on",
+ [9247]="on",
+ [9248]="on",
+ [9249]="on",
+ [9250]="on",
+ [9251]="on",
+ [9252]="on",
+ [9253]="on",
+ [9254]="on",
+ [9280]="on",
+ [9281]="on",
+ [9282]="on",
+ [9283]="on",
+ [9284]="on",
+ [9285]="on",
+ [9286]="on",
+ [9287]="on",
+ [9288]="on",
+ [9289]="on",
+ [9290]="on",
+ [9312]="on",
+ [9313]="on",
+ [9314]="on",
+ [9315]="on",
+ [9316]="on",
+ [9317]="on",
+ [9318]="on",
+ [9319]="on",
+ [9320]="on",
+ [9321]="on",
+ [9322]="on",
+ [9323]="on",
+ [9324]="on",
+ [9325]="on",
+ [9326]="on",
+ [9327]="on",
+ [9328]="on",
+ [9329]="on",
+ [9330]="on",
+ [9331]="on",
+ [9332]="on",
+ [9333]="on",
+ [9334]="on",
+ [9335]="on",
+ [9336]="on",
+ [9337]="on",
+ [9338]="on",
+ [9339]="on",
+ [9340]="on",
+ [9341]="on",
+ [9342]="on",
+ [9343]="on",
+ [9344]="on",
+ [9345]="on",
+ [9346]="on",
+ [9347]="on",
+ [9348]="on",
+ [9349]="on",
+ [9350]="on",
+ [9351]="on",
+ [9352]="en",
+ [9353]="en",
+ [9354]="en",
+ [9355]="en",
+ [9356]="en",
+ [9357]="en",
+ [9358]="en",
+ [9359]="en",
+ [9360]="en",
+ [9361]="en",
+ [9362]="en",
+ [9363]="en",
+ [9364]="en",
+ [9365]="en",
+ [9366]="en",
+ [9367]="en",
+ [9368]="en",
+ [9369]="en",
+ [9370]="en",
+ [9371]="en",
+ [9450]="on",
+ [9451]="on",
+ [9452]="on",
+ [9453]="on",
+ [9454]="on",
+ [9455]="on",
+ [9456]="on",
+ [9457]="on",
+ [9458]="on",
+ [9459]="on",
+ [9460]="on",
+ [9461]="on",
+ [9462]="on",
+ [9463]="on",
+ [9464]="on",
+ [9465]="on",
+ [9466]="on",
+ [9467]="on",
+ [9468]="on",
+ [9469]="on",
+ [9470]="on",
+ [9471]="on",
+ [9472]="on",
+ [9473]="on",
+ [9474]="on",
+ [9475]="on",
+ [9476]="on",
+ [9477]="on",
+ [9478]="on",
+ [9479]="on",
+ [9480]="on",
+ [9481]="on",
+ [9482]="on",
+ [9483]="on",
+ [9484]="on",
+ [9485]="on",
+ [9486]="on",
+ [9487]="on",
+ [9488]="on",
+ [9489]="on",
+ [9490]="on",
+ [9491]="on",
+ [9492]="on",
+ [9493]="on",
+ [9494]="on",
+ [9495]="on",
+ [9496]="on",
+ [9497]="on",
+ [9498]="on",
+ [9499]="on",
+ [9500]="on",
+ [9501]="on",
+ [9502]="on",
+ [9503]="on",
+ [9504]="on",
+ [9505]="on",
+ [9506]="on",
+ [9507]="on",
+ [9508]="on",
+ [9509]="on",
+ [9510]="on",
+ [9511]="on",
+ [9512]="on",
+ [9513]="on",
+ [9514]="on",
+ [9515]="on",
+ [9516]="on",
+ [9517]="on",
+ [9518]="on",
+ [9519]="on",
+ [9520]="on",
+ [9521]="on",
+ [9522]="on",
+ [9523]="on",
+ [9524]="on",
+ [9525]="on",
+ [9526]="on",
+ [9527]="on",
+ [9528]="on",
+ [9529]="on",
+ [9530]="on",
+ [9531]="on",
+ [9532]="on",
+ [9533]="on",
+ [9534]="on",
+ [9535]="on",
+ [9536]="on",
+ [9537]="on",
+ [9538]="on",
+ [9539]="on",
+ [9540]="on",
+ [9541]="on",
+ [9542]="on",
+ [9543]="on",
+ [9544]="on",
+ [9545]="on",
+ [9546]="on",
+ [9547]="on",
+ [9548]="on",
+ [9549]="on",
+ [9550]="on",
+ [9551]="on",
+ [9552]="on",
+ [9553]="on",
+ [9554]="on",
+ [9555]="on",
+ [9556]="on",
+ [9557]="on",
+ [9558]="on",
+ [9559]="on",
+ [9560]="on",
+ [9561]="on",
+ [9562]="on",
+ [9563]="on",
+ [9564]="on",
+ [9565]="on",
+ [9566]="on",
+ [9567]="on",
+ [9568]="on",
+ [9569]="on",
+ [9570]="on",
+ [9571]="on",
+ [9572]="on",
+ [9573]="on",
+ [9574]="on",
+ [9575]="on",
+ [9576]="on",
+ [9577]="on",
+ [9578]="on",
+ [9579]="on",
+ [9580]="on",
+ [9581]="on",
+ [9582]="on",
+ [9583]="on",
+ [9584]="on",
+ [9585]="on",
+ [9586]="on",
+ [9587]="on",
+ [9588]="on",
+ [9589]="on",
+ [9590]="on",
+ [9591]="on",
+ [9592]="on",
+ [9593]="on",
+ [9594]="on",
+ [9595]="on",
+ [9596]="on",
+ [9597]="on",
+ [9598]="on",
+ [9599]="on",
+ [9600]="on",
+ [9601]="on",
+ [9602]="on",
+ [9603]="on",
+ [9604]="on",
+ [9605]="on",
+ [9606]="on",
+ [9607]="on",
+ [9608]="on",
+ [9609]="on",
+ [9610]="on",
+ [9611]="on",
+ [9612]="on",
+ [9613]="on",
+ [9614]="on",
+ [9615]="on",
+ [9616]="on",
+ [9617]="on",
+ [9618]="on",
+ [9619]="on",
+ [9620]="on",
+ [9621]="on",
+ [9622]="on",
+ [9623]="on",
+ [9624]="on",
+ [9625]="on",
+ [9626]="on",
+ [9627]="on",
+ [9628]="on",
+ [9629]="on",
+ [9630]="on",
+ [9631]="on",
+ [9632]="on",
+ [9633]="on",
+ [9634]="on",
+ [9635]="on",
+ [9636]="on",
+ [9637]="on",
+ [9638]="on",
+ [9639]="on",
+ [9640]="on",
+ [9641]="on",
+ [9642]="on",
+ [9643]="on",
+ [9644]="on",
+ [9645]="on",
+ [9646]="on",
+ [9647]="on",
+ [9648]="on",
+ [9649]="on",
+ [9650]="on",
+ [9651]="on",
+ [9652]="on",
+ [9653]="on",
+ [9654]="on",
+ [9655]="on",
+ [9656]="on",
+ [9657]="on",
+ [9658]="on",
+ [9659]="on",
+ [9660]="on",
+ [9661]="on",
+ [9662]="on",
+ [9663]="on",
+ [9664]="on",
+ [9665]="on",
+ [9666]="on",
+ [9667]="on",
+ [9668]="on",
+ [9669]="on",
+ [9670]="on",
+ [9671]="on",
+ [9672]="on",
+ [9673]="on",
+ [9674]="on",
+ [9675]="on",
+ [9676]="on",
+ [9677]="on",
+ [9678]="on",
+ [9679]="on",
+ [9680]="on",
+ [9681]="on",
+ [9682]="on",
+ [9683]="on",
+ [9684]="on",
+ [9685]="on",
+ [9686]="on",
+ [9687]="on",
+ [9688]="on",
+ [9689]="on",
+ [9690]="on",
+ [9691]="on",
+ [9692]="on",
+ [9693]="on",
+ [9694]="on",
+ [9695]="on",
+ [9696]="on",
+ [9697]="on",
+ [9698]="on",
+ [9699]="on",
+ [9700]="on",
+ [9701]="on",
+ [9702]="on",
+ [9703]="on",
+ [9704]="on",
+ [9705]="on",
+ [9706]="on",
+ [9707]="on",
+ [9708]="on",
+ [9709]="on",
+ [9710]="on",
+ [9711]="on",
+ [9712]="on",
+ [9713]="on",
+ [9714]="on",
+ [9715]="on",
+ [9716]="on",
+ [9717]="on",
+ [9718]="on",
+ [9719]="on",
+ [9720]="on",
+ [9721]="on",
+ [9722]="on",
+ [9723]="on",
+ [9724]="on",
+ [9725]="on",
+ [9726]="on",
+ [9727]="on",
+ [9728]="on",
+ [9729]="on",
+ [9730]="on",
+ [9731]="on",
+ [9732]="on",
+ [9733]="on",
+ [9734]="on",
+ [9735]="on",
+ [9736]="on",
+ [9737]="on",
+ [9738]="on",
+ [9739]="on",
+ [9740]="on",
+ [9741]="on",
+ [9742]="on",
+ [9743]="on",
+ [9744]="on",
+ [9745]="on",
+ [9746]="on",
+ [9747]="on",
+ [9748]="on",
+ [9749]="on",
+ [9750]="on",
+ [9751]="on",
+ [9752]="on",
+ [9753]="on",
+ [9754]="on",
+ [9755]="on",
+ [9756]="on",
+ [9757]="on",
+ [9758]="on",
+ [9759]="on",
+ [9760]="on",
+ [9761]="on",
+ [9762]="on",
+ [9763]="on",
+ [9764]="on",
+ [9765]="on",
+ [9766]="on",
+ [9767]="on",
+ [9768]="on",
+ [9769]="on",
+ [9770]="on",
+ [9771]="on",
+ [9772]="on",
+ [9773]="on",
+ [9774]="on",
+ [9775]="on",
+ [9776]="on",
+ [9777]="on",
+ [9778]="on",
+ [9779]="on",
+ [9780]="on",
+ [9781]="on",
+ [9782]="on",
+ [9783]="on",
+ [9784]="on",
+ [9785]="on",
+ [9786]="on",
+ [9787]="on",
+ [9788]="on",
+ [9789]="on",
+ [9790]="on",
+ [9791]="on",
+ [9792]="on",
+ [9793]="on",
+ [9794]="on",
+ [9795]="on",
+ [9796]="on",
+ [9797]="on",
+ [9798]="on",
+ [9799]="on",
+ [9800]="on",
+ [9801]="on",
+ [9802]="on",
+ [9803]="on",
+ [9804]="on",
+ [9805]="on",
+ [9806]="on",
+ [9807]="on",
+ [9808]="on",
+ [9809]="on",
+ [9810]="on",
+ [9811]="on",
+ [9812]="on",
+ [9813]="on",
+ [9814]="on",
+ [9815]="on",
+ [9816]="on",
+ [9817]="on",
+ [9818]="on",
+ [9819]="on",
+ [9820]="on",
+ [9821]="on",
+ [9822]="on",
+ [9823]="on",
+ [9824]="on",
+ [9825]="on",
+ [9826]="on",
+ [9827]="on",
+ [9828]="on",
+ [9829]="on",
+ [9830]="on",
+ [9831]="on",
+ [9832]="on",
+ [9833]="on",
+ [9834]="on",
+ [9835]="on",
+ [9836]="on",
+ [9837]="on",
+ [9838]="on",
+ [9839]="on",
+ [9840]="on",
+ [9841]="on",
+ [9842]="on",
+ [9843]="on",
+ [9844]="on",
+ [9845]="on",
+ [9846]="on",
+ [9847]="on",
+ [9848]="on",
+ [9849]="on",
+ [9850]="on",
+ [9851]="on",
+ [9852]="on",
+ [9853]="on",
+ [9854]="on",
+ [9855]="on",
+ [9856]="on",
+ [9857]="on",
+ [9858]="on",
+ [9859]="on",
+ [9860]="on",
+ [9861]="on",
+ [9862]="on",
+ [9863]="on",
+ [9864]="on",
+ [9865]="on",
+ [9866]="on",
+ [9867]="on",
+ [9868]="on",
+ [9869]="on",
+ [9870]="on",
+ [9871]="on",
+ [9872]="on",
+ [9873]="on",
+ [9874]="on",
+ [9875]="on",
+ [9876]="on",
+ [9877]="on",
+ [9878]="on",
+ [9879]="on",
+ [9880]="on",
+ [9881]="on",
+ [9882]="on",
+ [9883]="on",
+ [9884]="on",
+ [9885]="on",
+ [9886]="on",
+ [9887]="on",
+ [9888]="on",
+ [9889]="on",
+ [9890]="on",
+ [9891]="on",
+ [9892]="on",
+ [9893]="on",
+ [9894]="on",
+ [9895]="on",
+ [9896]="on",
+ [9897]="on",
+ [9898]="on",
+ [9899]="on",
+ [9901]="on",
+ [9902]="on",
+ [9903]="on",
+ [9904]="on",
+ [9905]="on",
+ [9906]="on",
+ [9907]="on",
+ [9908]="on",
+ [9909]="on",
+ [9910]="on",
+ [9911]="on",
+ [9912]="on",
+ [9913]="on",
+ [9914]="on",
+ [9915]="on",
+ [9916]="on",
+ [9917]="on",
+ [9918]="on",
+ [9919]="on",
+ [9920]="on",
+ [9921]="on",
+ [9922]="on",
+ [9923]="on",
+ [9924]="on",
+ [9925]="on",
+ [9926]="on",
+ [9927]="on",
+ [9928]="on",
+ [9929]="on",
+ [9930]="on",
+ [9931]="on",
+ [9932]="on",
+ [9933]="on",
+ [9934]="on",
+ [9935]="on",
+ [9936]="on",
+ [9937]="on",
+ [9938]="on",
+ [9939]="on",
+ [9940]="on",
+ [9941]="on",
+ [9942]="on",
+ [9943]="on",
+ [9944]="on",
+ [9945]="on",
+ [9946]="on",
+ [9947]="on",
+ [9948]="on",
+ [9949]="on",
+ [9950]="on",
+ [9951]="on",
+ [9952]="on",
+ [9953]="on",
+ [9954]="on",
+ [9955]="on",
+ [9956]="on",
+ [9957]="on",
+ [9958]="on",
+ [9959]="on",
+ [9960]="on",
+ [9961]="on",
+ [9962]="on",
+ [9963]="on",
+ [9964]="on",
+ [9965]="on",
+ [9966]="on",
+ [9967]="on",
+ [9968]="on",
+ [9969]="on",
+ [9970]="on",
+ [9971]="on",
+ [9972]="on",
+ [9973]="on",
+ [9974]="on",
+ [9975]="on",
+ [9976]="on",
+ [9977]="on",
+ [9978]="on",
+ [9979]="on",
+ [9980]="on",
+ [9981]="on",
+ [9982]="on",
+ [9983]="on",
+ [9984]="on",
+ [9985]="on",
+ [9986]="on",
+ [9987]="on",
+ [9988]="on",
+ [9989]="on",
+ [9990]="on",
+ [9991]="on",
+ [9992]="on",
+ [9993]="on",
+ [9994]="on",
+ [9995]="on",
+ [9996]="on",
+ [9997]="on",
+ [9998]="on",
+ [9999]="on",
+ [10000]="on",
+ [10001]="on",
+ [10002]="on",
+ [10003]="on",
+ [10004]="on",
+ [10005]="on",
+ [10006]="on",
+ [10007]="on",
+ [10008]="on",
+ [10009]="on",
+ [10010]="on",
+ [10011]="on",
+ [10012]="on",
+ [10013]="on",
+ [10014]="on",
+ [10015]="on",
+ [10016]="on",
+ [10017]="on",
+ [10018]="on",
+ [10019]="on",
+ [10020]="on",
+ [10021]="on",
+ [10022]="on",
+ [10023]="on",
+ [10024]="on",
+ [10025]="on",
+ [10026]="on",
+ [10027]="on",
+ [10028]="on",
+ [10029]="on",
+ [10030]="on",
+ [10031]="on",
+ [10032]="on",
+ [10033]="on",
+ [10034]="on",
+ [10035]="on",
+ [10036]="on",
+ [10037]="on",
+ [10038]="on",
+ [10039]="on",
+ [10040]="on",
+ [10041]="on",
+ [10042]="on",
+ [10043]="on",
+ [10044]="on",
+ [10045]="on",
+ [10046]="on",
+ [10047]="on",
+ [10048]="on",
+ [10049]="on",
+ [10050]="on",
+ [10051]="on",
+ [10052]="on",
+ [10053]="on",
+ [10054]="on",
+ [10055]="on",
+ [10056]="on",
+ [10057]="on",
+ [10058]="on",
+ [10059]="on",
+ [10060]="on",
+ [10061]="on",
+ [10062]="on",
+ [10063]="on",
+ [10064]="on",
+ [10065]="on",
+ [10066]="on",
+ [10067]="on",
+ [10068]="on",
+ [10069]="on",
+ [10070]="on",
+ [10071]="on",
+ [10072]="on",
+ [10073]="on",
+ [10074]="on",
+ [10075]="on",
+ [10076]="on",
+ [10077]="on",
+ [10078]="on",
+ [10079]="on",
+ [10080]="on",
+ [10081]="on",
+ [10082]="on",
+ [10083]="on",
+ [10084]="on",
+ [10085]="on",
+ [10086]="on",
+ [10087]="on",
+ [10088]="on",
+ [10089]="on",
+ [10090]="on",
+ [10091]="on",
+ [10092]="on",
+ [10093]="on",
+ [10094]="on",
+ [10095]="on",
+ [10096]="on",
+ [10097]="on",
+ [10098]="on",
+ [10099]="on",
+ [10100]="on",
+ [10101]="on",
+ [10102]="on",
+ [10103]="on",
+ [10104]="on",
+ [10105]="on",
+ [10106]="on",
+ [10107]="on",
+ [10108]="on",
+ [10109]="on",
+ [10110]="on",
+ [10111]="on",
+ [10112]="on",
+ [10113]="on",
+ [10114]="on",
+ [10115]="on",
+ [10116]="on",
+ [10117]="on",
+ [10118]="on",
+ [10119]="on",
+ [10120]="on",
+ [10121]="on",
+ [10122]="on",
+ [10123]="on",
+ [10124]="on",
+ [10125]="on",
+ [10126]="on",
+ [10127]="on",
+ [10128]="on",
+ [10129]="on",
+ [10130]="on",
+ [10131]="on",
+ [10132]="on",
+ [10133]="on",
+ [10134]="on",
+ [10135]="on",
+ [10136]="on",
+ [10137]="on",
+ [10138]="on",
+ [10139]="on",
+ [10140]="on",
+ [10141]="on",
+ [10142]="on",
+ [10143]="on",
+ [10144]="on",
+ [10145]="on",
+ [10146]="on",
+ [10147]="on",
+ [10148]="on",
+ [10149]="on",
+ [10150]="on",
+ [10151]="on",
+ [10152]="on",
+ [10153]="on",
+ [10154]="on",
+ [10155]="on",
+ [10156]="on",
+ [10157]="on",
+ [10158]="on",
+ [10159]="on",
+ [10160]="on",
+ [10161]="on",
+ [10162]="on",
+ [10163]="on",
+ [10164]="on",
+ [10165]="on",
+ [10166]="on",
+ [10167]="on",
+ [10168]="on",
+ [10169]="on",
+ [10170]="on",
+ [10171]="on",
+ [10172]="on",
+ [10173]="on",
+ [10174]="on",
+ [10175]="on",
+ [10176]="on",
+ [10177]="on",
+ [10178]="on",
+ [10179]="on",
+ [10180]="on",
+ [10181]="on",
+ [10182]="on",
+ [10183]="on",
+ [10184]="on",
+ [10185]="on",
+ [10186]="on",
+ [10187]="on",
+ [10188]="on",
+ [10189]="on",
+ [10190]="on",
+ [10191]="on",
+ [10192]="on",
+ [10193]="on",
+ [10194]="on",
+ [10195]="on",
+ [10196]="on",
+ [10197]="on",
+ [10198]="on",
+ [10199]="on",
+ [10200]="on",
+ [10201]="on",
+ [10202]="on",
+ [10203]="on",
+ [10204]="on",
+ [10205]="on",
+ [10206]="on",
+ [10207]="on",
+ [10208]="on",
+ [10209]="on",
+ [10210]="on",
+ [10211]="on",
+ [10212]="on",
+ [10213]="on",
+ [10214]="on",
+ [10215]="on",
+ [10216]="on",
+ [10217]="on",
+ [10218]="on",
+ [10219]="on",
+ [10220]="on",
+ [10221]="on",
+ [10222]="on",
+ [10223]="on",
+ [10224]="on",
+ [10225]="on",
+ [10226]="on",
+ [10227]="on",
+ [10228]="on",
+ [10229]="on",
+ [10230]="on",
+ [10231]="on",
+ [10232]="on",
+ [10233]="on",
+ [10234]="on",
+ [10235]="on",
+ [10236]="on",
+ [10237]="on",
+ [10238]="on",
+ [10239]="on",
+ [10496]="on",
+ [10497]="on",
+ [10498]="on",
+ [10499]="on",
+ [10500]="on",
+ [10501]="on",
+ [10502]="on",
+ [10503]="on",
+ [10504]="on",
+ [10505]="on",
+ [10506]="on",
+ [10507]="on",
+ [10508]="on",
+ [10509]="on",
+ [10510]="on",
+ [10511]="on",
+ [10512]="on",
+ [10513]="on",
+ [10514]="on",
+ [10515]="on",
+ [10516]="on",
+ [10517]="on",
+ [10518]="on",
+ [10519]="on",
+ [10520]="on",
+ [10521]="on",
+ [10522]="on",
+ [10523]="on",
+ [10524]="on",
+ [10525]="on",
+ [10526]="on",
+ [10527]="on",
+ [10528]="on",
+ [10529]="on",
+ [10530]="on",
+ [10531]="on",
+ [10532]="on",
+ [10533]="on",
+ [10534]="on",
+ [10535]="on",
+ [10536]="on",
+ [10537]="on",
+ [10538]="on",
+ [10539]="on",
+ [10540]="on",
+ [10541]="on",
+ [10542]="on",
+ [10543]="on",
+ [10544]="on",
+ [10545]="on",
+ [10546]="on",
+ [10547]="on",
+ [10548]="on",
+ [10549]="on",
+ [10550]="on",
+ [10551]="on",
+ [10552]="on",
+ [10553]="on",
+ [10554]="on",
+ [10555]="on",
+ [10556]="on",
+ [10557]="on",
+ [10558]="on",
+ [10559]="on",
+ [10560]="on",
+ [10561]="on",
+ [10562]="on",
+ [10563]="on",
+ [10564]="on",
+ [10565]="on",
+ [10566]="on",
+ [10567]="on",
+ [10568]="on",
+ [10569]="on",
+ [10570]="on",
+ [10571]="on",
+ [10572]="on",
+ [10573]="on",
+ [10574]="on",
+ [10575]="on",
+ [10576]="on",
+ [10577]="on",
+ [10578]="on",
+ [10579]="on",
+ [10580]="on",
+ [10581]="on",
+ [10582]="on",
+ [10583]="on",
+ [10584]="on",
+ [10585]="on",
+ [10586]="on",
+ [10587]="on",
+ [10588]="on",
+ [10589]="on",
+ [10590]="on",
+ [10591]="on",
+ [10592]="on",
+ [10593]="on",
+ [10594]="on",
+ [10595]="on",
+ [10596]="on",
+ [10597]="on",
+ [10598]="on",
+ [10599]="on",
+ [10600]="on",
+ [10601]="on",
+ [10602]="on",
+ [10603]="on",
+ [10604]="on",
+ [10605]="on",
+ [10606]="on",
+ [10607]="on",
+ [10608]="on",
+ [10609]="on",
+ [10610]="on",
+ [10611]="on",
+ [10612]="on",
+ [10613]="on",
+ [10614]="on",
+ [10615]="on",
+ [10616]="on",
+ [10617]="on",
+ [10618]="on",
+ [10619]="on",
+ [10620]="on",
+ [10621]="on",
+ [10622]="on",
+ [10623]="on",
+ [10624]="on",
+ [10625]="on",
+ [10626]="on",
+ [10627]="on",
+ [10628]="on",
+ [10629]="on",
+ [10630]="on",
+ [10631]="on",
+ [10632]="on",
+ [10633]="on",
+ [10634]="on",
+ [10635]="on",
+ [10636]="on",
+ [10637]="on",
+ [10638]="on",
+ [10639]="on",
+ [10640]="on",
+ [10641]="on",
+ [10642]="on",
+ [10643]="on",
+ [10644]="on",
+ [10645]="on",
+ [10646]="on",
+ [10647]="on",
+ [10648]="on",
+ [10649]="on",
+ [10650]="on",
+ [10651]="on",
+ [10652]="on",
+ [10653]="on",
+ [10654]="on",
+ [10655]="on",
+ [10656]="on",
+ [10657]="on",
+ [10658]="on",
+ [10659]="on",
+ [10660]="on",
+ [10661]="on",
+ [10662]="on",
+ [10663]="on",
+ [10664]="on",
+ [10665]="on",
+ [10666]="on",
+ [10667]="on",
+ [10668]="on",
+ [10669]="on",
+ [10670]="on",
+ [10671]="on",
+ [10672]="on",
+ [10673]="on",
+ [10674]="on",
+ [10675]="on",
+ [10676]="on",
+ [10677]="on",
+ [10678]="on",
+ [10679]="on",
+ [10680]="on",
+ [10681]="on",
+ [10682]="on",
+ [10683]="on",
+ [10684]="on",
+ [10685]="on",
+ [10686]="on",
+ [10687]="on",
+ [10688]="on",
+ [10689]="on",
+ [10690]="on",
+ [10691]="on",
+ [10692]="on",
+ [10693]="on",
+ [10694]="on",
+ [10695]="on",
+ [10696]="on",
+ [10697]="on",
+ [10698]="on",
+ [10699]="on",
+ [10700]="on",
+ [10701]="on",
+ [10702]="on",
+ [10703]="on",
+ [10704]="on",
+ [10705]="on",
+ [10706]="on",
+ [10707]="on",
+ [10708]="on",
+ [10709]="on",
+ [10710]="on",
+ [10711]="on",
+ [10712]="on",
+ [10713]="on",
+ [10714]="on",
+ [10715]="on",
+ [10716]="on",
+ [10717]="on",
+ [10718]="on",
+ [10719]="on",
+ [10720]="on",
+ [10721]="on",
+ [10722]="on",
+ [10723]="on",
+ [10724]="on",
+ [10725]="on",
+ [10726]="on",
+ [10727]="on",
+ [10728]="on",
+ [10729]="on",
+ [10730]="on",
+ [10731]="on",
+ [10732]="on",
+ [10733]="on",
+ [10734]="on",
+ [10735]="on",
+ [10736]="on",
+ [10737]="on",
+ [10738]="on",
+ [10739]="on",
+ [10740]="on",
+ [10741]="on",
+ [10742]="on",
+ [10743]="on",
+ [10744]="on",
+ [10745]="on",
+ [10746]="on",
+ [10747]="on",
+ [10748]="on",
+ [10749]="on",
+ [10750]="on",
+ [10751]="on",
+ [10752]="on",
+ [10753]="on",
+ [10754]="on",
+ [10755]="on",
+ [10756]="on",
+ [10757]="on",
+ [10758]="on",
+ [10759]="on",
+ [10760]="on",
+ [10761]="on",
+ [10762]="on",
+ [10763]="on",
+ [10764]="on",
+ [10765]="on",
+ [10766]="on",
+ [10767]="on",
+ [10768]="on",
+ [10769]="on",
+ [10770]="on",
+ [10771]="on",
+ [10772]="on",
+ [10773]="on",
+ [10774]="on",
+ [10775]="on",
+ [10776]="on",
+ [10777]="on",
+ [10778]="on",
+ [10779]="on",
+ [10780]="on",
+ [10781]="on",
+ [10782]="on",
+ [10783]="on",
+ [10784]="on",
+ [10785]="on",
+ [10786]="on",
+ [10787]="on",
+ [10788]="on",
+ [10789]="on",
+ [10790]="on",
+ [10791]="on",
+ [10792]="on",
+ [10793]="on",
+ [10794]="on",
+ [10795]="on",
+ [10796]="on",
+ [10797]="on",
+ [10798]="on",
+ [10799]="on",
+ [10800]="on",
+ [10801]="on",
+ [10802]="on",
+ [10803]="on",
+ [10804]="on",
+ [10805]="on",
+ [10806]="on",
+ [10807]="on",
+ [10808]="on",
+ [10809]="on",
+ [10810]="on",
+ [10811]="on",
+ [10812]="on",
+ [10813]="on",
+ [10814]="on",
+ [10815]="on",
+ [10816]="on",
+ [10817]="on",
+ [10818]="on",
+ [10819]="on",
+ [10820]="on",
+ [10821]="on",
+ [10822]="on",
+ [10823]="on",
+ [10824]="on",
+ [10825]="on",
+ [10826]="on",
+ [10827]="on",
+ [10828]="on",
+ [10829]="on",
+ [10830]="on",
+ [10831]="on",
+ [10832]="on",
+ [10833]="on",
+ [10834]="on",
+ [10835]="on",
+ [10836]="on",
+ [10837]="on",
+ [10838]="on",
+ [10839]="on",
+ [10840]="on",
+ [10841]="on",
+ [10842]="on",
+ [10843]="on",
+ [10844]="on",
+ [10845]="on",
+ [10846]="on",
+ [10847]="on",
+ [10848]="on",
+ [10849]="on",
+ [10850]="on",
+ [10851]="on",
+ [10852]="on",
+ [10853]="on",
+ [10854]="on",
+ [10855]="on",
+ [10856]="on",
+ [10857]="on",
+ [10858]="on",
+ [10859]="on",
+ [10860]="on",
+ [10861]="on",
+ [10862]="on",
+ [10863]="on",
+ [10864]="on",
+ [10865]="on",
+ [10866]="on",
+ [10867]="on",
+ [10868]="on",
+ [10869]="on",
+ [10870]="on",
+ [10871]="on",
+ [10872]="on",
+ [10873]="on",
+ [10874]="on",
+ [10875]="on",
+ [10876]="on",
+ [10877]="on",
+ [10878]="on",
+ [10879]="on",
+ [10880]="on",
+ [10881]="on",
+ [10882]="on",
+ [10883]="on",
+ [10884]="on",
+ [10885]="on",
+ [10886]="on",
+ [10887]="on",
+ [10888]="on",
+ [10889]="on",
+ [10890]="on",
+ [10891]="on",
+ [10892]="on",
+ [10893]="on",
+ [10894]="on",
+ [10895]="on",
+ [10896]="on",
+ [10897]="on",
+ [10898]="on",
+ [10899]="on",
+ [10900]="on",
+ [10901]="on",
+ [10902]="on",
+ [10903]="on",
+ [10904]="on",
+ [10905]="on",
+ [10906]="on",
+ [10907]="on",
+ [10908]="on",
+ [10909]="on",
+ [10910]="on",
+ [10911]="on",
+ [10912]="on",
+ [10913]="on",
+ [10914]="on",
+ [10915]="on",
+ [10916]="on",
+ [10917]="on",
+ [10918]="on",
+ [10919]="on",
+ [10920]="on",
+ [10921]="on",
+ [10922]="on",
+ [10923]="on",
+ [10924]="on",
+ [10925]="on",
+ [10926]="on",
+ [10927]="on",
+ [10928]="on",
+ [10929]="on",
+ [10930]="on",
+ [10931]="on",
+ [10932]="on",
+ [10933]="on",
+ [10934]="on",
+ [10935]="on",
+ [10936]="on",
+ [10937]="on",
+ [10938]="on",
+ [10939]="on",
+ [10940]="on",
+ [10941]="on",
+ [10942]="on",
+ [10943]="on",
+ [10944]="on",
+ [10945]="on",
+ [10946]="on",
+ [10947]="on",
+ [10948]="on",
+ [10949]="on",
+ [10950]="on",
+ [10951]="on",
+ [10952]="on",
+ [10953]="on",
+ [10954]="on",
+ [10955]="on",
+ [10956]="on",
+ [10957]="on",
+ [10958]="on",
+ [10959]="on",
+ [10960]="on",
+ [10961]="on",
+ [10962]="on",
+ [10963]="on",
+ [10964]="on",
+ [10965]="on",
+ [10966]="on",
+ [10967]="on",
+ [10968]="on",
+ [10969]="on",
+ [10970]="on",
+ [10971]="on",
+ [10972]="on",
+ [10973]="on",
+ [10974]="on",
+ [10975]="on",
+ [10976]="on",
+ [10977]="on",
+ [10978]="on",
+ [10979]="on",
+ [10980]="on",
+ [10981]="on",
+ [10982]="on",
+ [10983]="on",
+ [10984]="on",
+ [10985]="on",
+ [10986]="on",
+ [10987]="on",
+ [10988]="on",
+ [10989]="on",
+ [10990]="on",
+ [10991]="on",
+ [10992]="on",
+ [10993]="on",
+ [10994]="on",
+ [10995]="on",
+ [10996]="on",
+ [10997]="on",
+ [10998]="on",
+ [10999]="on",
+ [11000]="on",
+ [11001]="on",
+ [11002]="on",
+ [11003]="on",
+ [11004]="on",
+ [11005]="on",
+ [11006]="on",
+ [11007]="on",
+ [11008]="on",
+ [11009]="on",
+ [11010]="on",
+ [11011]="on",
+ [11012]="on",
+ [11013]="on",
+ [11014]="on",
+ [11015]="on",
+ [11016]="on",
+ [11017]="on",
+ [11018]="on",
+ [11019]="on",
+ [11020]="on",
+ [11021]="on",
+ [11022]="on",
+ [11023]="on",
+ [11024]="on",
+ [11025]="on",
+ [11026]="on",
+ [11027]="on",
+ [11028]="on",
+ [11029]="on",
+ [11030]="on",
+ [11031]="on",
+ [11032]="on",
+ [11033]="on",
+ [11034]="on",
+ [11035]="on",
+ [11036]="on",
+ [11037]="on",
+ [11038]="on",
+ [11039]="on",
+ [11040]="on",
+ [11041]="on",
+ [11042]="on",
+ [11043]="on",
+ [11044]="on",
+ [11045]="on",
+ [11046]="on",
+ [11047]="on",
+ [11048]="on",
+ [11049]="on",
+ [11050]="on",
+ [11051]="on",
+ [11052]="on",
+ [11053]="on",
+ [11054]="on",
+ [11055]="on",
+ [11056]="on",
+ [11057]="on",
+ [11058]="on",
+ [11059]="on",
+ [11060]="on",
+ [11061]="on",
+ [11062]="on",
+ [11063]="on",
+ [11064]="on",
+ [11065]="on",
+ [11066]="on",
+ [11067]="on",
+ [11068]="on",
+ [11069]="on",
+ [11070]="on",
+ [11071]="on",
+ [11072]="on",
+ [11073]="on",
+ [11074]="on",
+ [11075]="on",
+ [11076]="on",
+ [11077]="on",
+ [11078]="on",
+ [11079]="on",
+ [11080]="on",
+ [11081]="on",
+ [11082]="on",
+ [11083]="on",
+ [11084]="on",
+ [11085]="on",
+ [11086]="on",
+ [11087]="on",
+ [11088]="on",
+ [11089]="on",
+ [11090]="on",
+ [11091]="on",
+ [11092]="on",
+ [11093]="on",
+ [11094]="on",
+ [11095]="on",
+ [11096]="on",
+ [11097]="on",
+ [11098]="on",
+ [11099]="on",
+ [11100]="on",
+ [11101]="on",
+ [11102]="on",
+ [11103]="on",
+ [11104]="on",
+ [11105]="on",
+ [11106]="on",
+ [11107]="on",
+ [11108]="on",
+ [11109]="on",
+ [11110]="on",
+ [11111]="on",
+ [11112]="on",
+ [11113]="on",
+ [11114]="on",
+ [11115]="on",
+ [11116]="on",
+ [11117]="on",
+ [11118]="on",
+ [11119]="on",
+ [11120]="on",
+ [11121]="on",
+ [11122]="on",
+ [11123]="on",
+ [11126]="on",
+ [11127]="on",
+ [11128]="on",
+ [11129]="on",
+ [11130]="on",
+ [11131]="on",
+ [11132]="on",
+ [11133]="on",
+ [11134]="on",
+ [11135]="on",
+ [11136]="on",
+ [11137]="on",
+ [11138]="on",
+ [11139]="on",
+ [11140]="on",
+ [11141]="on",
+ [11142]="on",
+ [11143]="on",
+ [11144]="on",
+ [11145]="on",
+ [11146]="on",
+ [11147]="on",
+ [11148]="on",
+ [11149]="on",
+ [11150]="on",
+ [11151]="on",
+ [11152]="on",
+ [11153]="on",
+ [11154]="on",
+ [11155]="on",
+ [11156]="on",
+ [11157]="on",
+ [11160]="on",
+ [11161]="on",
+ [11162]="on",
+ [11163]="on",
+ [11164]="on",
+ [11165]="on",
+ [11166]="on",
+ [11167]="on",
+ [11168]="on",
+ [11169]="on",
+ [11170]="on",
+ [11171]="on",
+ [11172]="on",
+ [11173]="on",
+ [11174]="on",
+ [11175]="on",
+ [11176]="on",
+ [11177]="on",
+ [11178]="on",
+ [11179]="on",
+ [11180]="on",
+ [11181]="on",
+ [11182]="on",
+ [11183]="on",
+ [11184]="on",
+ [11185]="on",
+ [11186]="on",
+ [11187]="on",
+ [11188]="on",
+ [11189]="on",
+ [11190]="on",
+ [11191]="on",
+ [11192]="on",
+ [11193]="on",
+ [11197]="on",
+ [11198]="on",
+ [11199]="on",
+ [11200]="on",
+ [11201]="on",
+ [11202]="on",
+ [11203]="on",
+ [11204]="on",
+ [11205]="on",
+ [11206]="on",
+ [11207]="on",
+ [11208]="on",
+ [11210]="on",
+ [11211]="on",
+ [11212]="on",
+ [11213]="on",
+ [11214]="on",
+ [11215]="on",
+ [11216]="on",
+ [11217]="on",
+ [11218]="on",
+ [11244]="on",
+ [11245]="on",
+ [11246]="on",
+ [11247]="on",
+ [11493]="on",
+ [11494]="on",
+ [11495]="on",
+ [11496]="on",
+ [11497]="on",
+ [11498]="on",
+ [11503]="nsm",
+ [11504]="nsm",
+ [11505]="nsm",
+ [11513]="on",
+ [11514]="on",
+ [11515]="on",
+ [11516]="on",
+ [11517]="on",
+ [11518]="on",
+ [11519]="on",
+ [11647]="nsm",
+ [11744]="nsm",
+ [11745]="nsm",
+ [11746]="nsm",
+ [11747]="nsm",
+ [11748]="nsm",
+ [11749]="nsm",
+ [11750]="nsm",
+ [11751]="nsm",
+ [11752]="nsm",
+ [11753]="nsm",
+ [11754]="nsm",
+ [11755]="nsm",
+ [11756]="nsm",
+ [11757]="nsm",
+ [11758]="nsm",
+ [11759]="nsm",
+ [11760]="nsm",
+ [11761]="nsm",
+ [11762]="nsm",
+ [11763]="nsm",
+ [11764]="nsm",
+ [11765]="nsm",
+ [11766]="nsm",
+ [11767]="nsm",
+ [11768]="nsm",
+ [11769]="nsm",
+ [11770]="nsm",
+ [11771]="nsm",
+ [11772]="nsm",
+ [11773]="nsm",
+ [11774]="nsm",
+ [11775]="nsm",
+ [11776]="on",
+ [11777]="on",
+ [11778]="on",
+ [11779]="on",
+ [11780]="on",
+ [11781]="on",
+ [11782]="on",
+ [11783]="on",
+ [11784]="on",
+ [11785]="on",
+ [11786]="on",
+ [11787]="on",
+ [11788]="on",
+ [11789]="on",
+ [11790]="on",
+ [11791]="on",
+ [11792]="on",
+ [11793]="on",
+ [11794]="on",
+ [11795]="on",
+ [11796]="on",
+ [11797]="on",
+ [11798]="on",
+ [11799]="on",
+ [11800]="on",
+ [11801]="on",
+ [11802]="on",
+ [11803]="on",
+ [11804]="on",
+ [11805]="on",
+ [11806]="on",
+ [11807]="on",
+ [11808]="on",
+ [11809]="on",
+ [11810]="on",
+ [11811]="on",
+ [11812]="on",
+ [11813]="on",
+ [11814]="on",
+ [11815]="on",
+ [11816]="on",
+ [11817]="on",
+ [11818]="on",
+ [11819]="on",
+ [11820]="on",
+ [11821]="on",
+ [11822]="on",
+ [11823]="on",
+ [11824]="on",
+ [11825]="on",
+ [11826]="on",
+ [11827]="on",
+ [11828]="on",
+ [11829]="on",
+ [11830]="on",
+ [11831]="on",
+ [11832]="on",
+ [11833]="on",
+ [11834]="on",
+ [11835]="on",
+ [11836]="on",
+ [11837]="on",
+ [11838]="on",
+ [11839]="on",
+ [11840]="on",
+ [11841]="on",
+ [11842]="on",
+ [11843]="on",
+ [11844]="on",
+ [11845]="on",
+ [11846]="on",
+ [11847]="on",
+ [11848]="on",
+ [11849]="on",
+ [11904]="on",
+ [11905]="on",
+ [11906]="on",
+ [11907]="on",
+ [11908]="on",
+ [11909]="on",
+ [11910]="on",
+ [11911]="on",
+ [11912]="on",
+ [11913]="on",
+ [11914]="on",
+ [11915]="on",
+ [11916]="on",
+ [11917]="on",
+ [11918]="on",
+ [11919]="on",
+ [11920]="on",
+ [11921]="on",
+ [11922]="on",
+ [11923]="on",
+ [11924]="on",
+ [11925]="on",
+ [11926]="on",
+ [11927]="on",
+ [11928]="on",
+ [11929]="on",
+ [11931]="on",
+ [11932]="on",
+ [11933]="on",
+ [11934]="on",
+ [11935]="on",
+ [11936]="on",
+ [11937]="on",
+ [11938]="on",
+ [11939]="on",
+ [11940]="on",
+ [11941]="on",
+ [11942]="on",
+ [11943]="on",
+ [11944]="on",
+ [11945]="on",
+ [11946]="on",
+ [11947]="on",
+ [11948]="on",
+ [11949]="on",
+ [11950]="on",
+ [11951]="on",
+ [11952]="on",
+ [11953]="on",
+ [11954]="on",
+ [11955]="on",
+ [11956]="on",
+ [11957]="on",
+ [11958]="on",
+ [11959]="on",
+ [11960]="on",
+ [11961]="on",
+ [11962]="on",
+ [11963]="on",
+ [11964]="on",
+ [11965]="on",
+ [11966]="on",
+ [11967]="on",
+ [11968]="on",
+ [11969]="on",
+ [11970]="on",
+ [11971]="on",
+ [11972]="on",
+ [11973]="on",
+ [11974]="on",
+ [11975]="on",
+ [11976]="on",
+ [11977]="on",
+ [11978]="on",
+ [11979]="on",
+ [11980]="on",
+ [11981]="on",
+ [11982]="on",
+ [11983]="on",
+ [11984]="on",
+ [11985]="on",
+ [11986]="on",
+ [11987]="on",
+ [11988]="on",
+ [11989]="on",
+ [11990]="on",
+ [11991]="on",
+ [11992]="on",
+ [11993]="on",
+ [11994]="on",
+ [11995]="on",
+ [11996]="on",
+ [11997]="on",
+ [11998]="on",
+ [11999]="on",
+ [12000]="on",
+ [12001]="on",
+ [12002]="on",
+ [12003]="on",
+ [12004]="on",
+ [12005]="on",
+ [12006]="on",
+ [12007]="on",
+ [12008]="on",
+ [12009]="on",
+ [12010]="on",
+ [12011]="on",
+ [12012]="on",
+ [12013]="on",
+ [12014]="on",
+ [12015]="on",
+ [12016]="on",
+ [12017]="on",
+ [12018]="on",
+ [12019]="on",
+ [12032]="on",
+ [12033]="on",
+ [12034]="on",
+ [12035]="on",
+ [12036]="on",
+ [12037]="on",
+ [12038]="on",
+ [12039]="on",
+ [12040]="on",
+ [12041]="on",
+ [12042]="on",
+ [12043]="on",
+ [12044]="on",
+ [12045]="on",
+ [12046]="on",
+ [12047]="on",
+ [12048]="on",
+ [12049]="on",
+ [12050]="on",
+ [12051]="on",
+ [12052]="on",
+ [12053]="on",
+ [12054]="on",
+ [12055]="on",
+ [12056]="on",
+ [12057]="on",
+ [12058]="on",
+ [12059]="on",
+ [12060]="on",
+ [12061]="on",
+ [12062]="on",
+ [12063]="on",
+ [12064]="on",
+ [12065]="on",
+ [12066]="on",
+ [12067]="on",
+ [12068]="on",
+ [12069]="on",
+ [12070]="on",
+ [12071]="on",
+ [12072]="on",
+ [12073]="on",
+ [12074]="on",
+ [12075]="on",
+ [12076]="on",
+ [12077]="on",
+ [12078]="on",
+ [12079]="on",
+ [12080]="on",
+ [12081]="on",
+ [12082]="on",
+ [12083]="on",
+ [12084]="on",
+ [12085]="on",
+ [12086]="on",
+ [12087]="on",
+ [12088]="on",
+ [12089]="on",
+ [12090]="on",
+ [12091]="on",
+ [12092]="on",
+ [12093]="on",
+ [12094]="on",
+ [12095]="on",
+ [12096]="on",
+ [12097]="on",
+ [12098]="on",
+ [12099]="on",
+ [12100]="on",
+ [12101]="on",
+ [12102]="on",
+ [12103]="on",
+ [12104]="on",
+ [12105]="on",
+ [12106]="on",
+ [12107]="on",
+ [12108]="on",
+ [12109]="on",
+ [12110]="on",
+ [12111]="on",
+ [12112]="on",
+ [12113]="on",
+ [12114]="on",
+ [12115]="on",
+ [12116]="on",
+ [12117]="on",
+ [12118]="on",
+ [12119]="on",
+ [12120]="on",
+ [12121]="on",
+ [12122]="on",
+ [12123]="on",
+ [12124]="on",
+ [12125]="on",
+ [12126]="on",
+ [12127]="on",
+ [12128]="on",
+ [12129]="on",
+ [12130]="on",
+ [12131]="on",
+ [12132]="on",
+ [12133]="on",
+ [12134]="on",
+ [12135]="on",
+ [12136]="on",
+ [12137]="on",
+ [12138]="on",
+ [12139]="on",
+ [12140]="on",
+ [12141]="on",
+ [12142]="on",
+ [12143]="on",
+ [12144]="on",
+ [12145]="on",
+ [12146]="on",
+ [12147]="on",
+ [12148]="on",
+ [12149]="on",
+ [12150]="on",
+ [12151]="on",
+ [12152]="on",
+ [12153]="on",
+ [12154]="on",
+ [12155]="on",
+ [12156]="on",
+ [12157]="on",
+ [12158]="on",
+ [12159]="on",
+ [12160]="on",
+ [12161]="on",
+ [12162]="on",
+ [12163]="on",
+ [12164]="on",
+ [12165]="on",
+ [12166]="on",
+ [12167]="on",
+ [12168]="on",
+ [12169]="on",
+ [12170]="on",
+ [12171]="on",
+ [12172]="on",
+ [12173]="on",
+ [12174]="on",
+ [12175]="on",
+ [12176]="on",
+ [12177]="on",
+ [12178]="on",
+ [12179]="on",
+ [12180]="on",
+ [12181]="on",
+ [12182]="on",
+ [12183]="on",
+ [12184]="on",
+ [12185]="on",
+ [12186]="on",
+ [12187]="on",
+ [12188]="on",
+ [12189]="on",
+ [12190]="on",
+ [12191]="on",
+ [12192]="on",
+ [12193]="on",
+ [12194]="on",
+ [12195]="on",
+ [12196]="on",
+ [12197]="on",
+ [12198]="on",
+ [12199]="on",
+ [12200]="on",
+ [12201]="on",
+ [12202]="on",
+ [12203]="on",
+ [12204]="on",
+ [12205]="on",
+ [12206]="on",
+ [12207]="on",
+ [12208]="on",
+ [12209]="on",
+ [12210]="on",
+ [12211]="on",
+ [12212]="on",
+ [12213]="on",
+ [12214]="on",
+ [12215]="on",
+ [12216]="on",
+ [12217]="on",
+ [12218]="on",
+ [12219]="on",
+ [12220]="on",
+ [12221]="on",
+ [12222]="on",
+ [12223]="on",
+ [12224]="on",
+ [12225]="on",
+ [12226]="on",
+ [12227]="on",
+ [12228]="on",
+ [12229]="on",
+ [12230]="on",
+ [12231]="on",
+ [12232]="on",
+ [12233]="on",
+ [12234]="on",
+ [12235]="on",
+ [12236]="on",
+ [12237]="on",
+ [12238]="on",
+ [12239]="on",
+ [12240]="on",
+ [12241]="on",
+ [12242]="on",
+ [12243]="on",
+ [12244]="on",
+ [12245]="on",
+ [12272]="on",
+ [12273]="on",
+ [12274]="on",
+ [12275]="on",
+ [12276]="on",
+ [12277]="on",
+ [12278]="on",
+ [12279]="on",
+ [12280]="on",
+ [12281]="on",
+ [12282]="on",
+ [12283]="on",
+ [12288]="ws",
+ [12289]="on",
+ [12290]="on",
+ [12291]="on",
+ [12292]="on",
+ [12296]="on",
+ [12297]="on",
+ [12298]="on",
+ [12299]="on",
+ [12300]="on",
+ [12301]="on",
+ [12302]="on",
+ [12303]="on",
+ [12304]="on",
+ [12305]="on",
+ [12306]="on",
+ [12307]="on",
+ [12308]="on",
+ [12309]="on",
+ [12310]="on",
+ [12311]="on",
+ [12312]="on",
+ [12313]="on",
+ [12314]="on",
+ [12315]="on",
+ [12316]="on",
+ [12317]="on",
+ [12318]="on",
+ [12319]="on",
+ [12320]="on",
+ [12330]="nsm",
+ [12331]="nsm",
+ [12332]="nsm",
+ [12333]="nsm",
+ [12336]="on",
+ [12342]="on",
+ [12343]="on",
+ [12349]="on",
+ [12350]="on",
+ [12351]="on",
+ [12441]="nsm",
+ [12442]="nsm",
+ [12443]="on",
+ [12444]="on",
+ [12448]="on",
+ [12539]="on",
+ [12736]="on",
+ [12737]="on",
+ [12738]="on",
+ [12739]="on",
+ [12740]="on",
+ [12741]="on",
+ [12742]="on",
+ [12743]="on",
+ [12744]="on",
+ [12745]="on",
+ [12746]="on",
+ [12747]="on",
+ [12748]="on",
+ [12749]="on",
+ [12750]="on",
+ [12751]="on",
+ [12752]="on",
+ [12753]="on",
+ [12754]="on",
+ [12755]="on",
+ [12756]="on",
+ [12757]="on",
+ [12758]="on",
+ [12759]="on",
+ [12760]="on",
+ [12761]="on",
+ [12762]="on",
+ [12763]="on",
+ [12764]="on",
+ [12765]="on",
+ [12766]="on",
+ [12767]="on",
+ [12768]="on",
+ [12769]="on",
+ [12770]="on",
+ [12771]="on",
+ [12829]="on",
+ [12830]="on",
+ [12880]="on",
+ [12881]="on",
+ [12882]="on",
+ [12883]="on",
+ [12884]="on",
+ [12885]="on",
+ [12886]="on",
+ [12887]="on",
+ [12888]="on",
+ [12889]="on",
+ [12890]="on",
+ [12891]="on",
+ [12892]="on",
+ [12893]="on",
+ [12894]="on",
+ [12895]="on",
+ [12924]="on",
+ [12925]="on",
+ [12926]="on",
+ [12977]="on",
+ [12978]="on",
+ [12979]="on",
+ [12980]="on",
+ [12981]="on",
+ [12982]="on",
+ [12983]="on",
+ [12984]="on",
+ [12985]="on",
+ [12986]="on",
+ [12987]="on",
+ [12988]="on",
+ [12989]="on",
+ [12990]="on",
+ [12991]="on",
+ [13004]="on",
+ [13005]="on",
+ [13006]="on",
+ [13007]="on",
+ [13175]="on",
+ [13176]="on",
+ [13177]="on",
+ [13178]="on",
+ [13278]="on",
+ [13279]="on",
+ [13311]="on",
+ [19904]="on",
+ [19905]="on",
+ [19906]="on",
+ [19907]="on",
+ [19908]="on",
+ [19909]="on",
+ [19910]="on",
+ [19911]="on",
+ [19912]="on",
+ [19913]="on",
+ [19914]="on",
+ [19915]="on",
+ [19916]="on",
+ [19917]="on",
+ [19918]="on",
+ [19919]="on",
+ [19920]="on",
+ [19921]="on",
+ [19922]="on",
+ [19923]="on",
+ [19924]="on",
+ [19925]="on",
+ [19926]="on",
+ [19927]="on",
+ [19928]="on",
+ [19929]="on",
+ [19930]="on",
+ [19931]="on",
+ [19932]="on",
+ [19933]="on",
+ [19934]="on",
+ [19935]="on",
+ [19936]="on",
+ [19937]="on",
+ [19938]="on",
+ [19939]="on",
+ [19940]="on",
+ [19941]="on",
+ [19942]="on",
+ [19943]="on",
+ [19944]="on",
+ [19945]="on",
+ [19946]="on",
+ [19947]="on",
+ [19948]="on",
+ [19949]="on",
+ [19950]="on",
+ [19951]="on",
+ [19952]="on",
+ [19953]="on",
+ [19954]="on",
+ [19955]="on",
+ [19956]="on",
+ [19957]="on",
+ [19958]="on",
+ [19959]="on",
+ [19960]="on",
+ [19961]="on",
+ [19962]="on",
+ [19963]="on",
+ [19964]="on",
+ [19965]="on",
+ [19966]="on",
+ [19967]="on",
+ [42128]="on",
+ [42129]="on",
+ [42130]="on",
+ [42131]="on",
+ [42132]="on",
+ [42133]="on",
+ [42134]="on",
+ [42135]="on",
+ [42136]="on",
+ [42137]="on",
+ [42138]="on",
+ [42139]="on",
+ [42140]="on",
+ [42141]="on",
+ [42142]="on",
+ [42143]="on",
+ [42144]="on",
+ [42145]="on",
+ [42146]="on",
+ [42147]="on",
+ [42148]="on",
+ [42149]="on",
+ [42150]="on",
+ [42151]="on",
+ [42152]="on",
+ [42153]="on",
+ [42154]="on",
+ [42155]="on",
+ [42156]="on",
+ [42157]="on",
+ [42158]="on",
+ [42159]="on",
+ [42160]="on",
+ [42161]="on",
+ [42162]="on",
+ [42163]="on",
+ [42164]="on",
+ [42165]="on",
+ [42166]="on",
+ [42167]="on",
+ [42168]="on",
+ [42169]="on",
+ [42170]="on",
+ [42171]="on",
+ [42172]="on",
+ [42173]="on",
+ [42174]="on",
+ [42175]="on",
+ [42176]="on",
+ [42177]="on",
+ [42178]="on",
+ [42179]="on",
+ [42180]="on",
+ [42181]="on",
+ [42182]="on",
+ [42509]="on",
+ [42510]="on",
+ [42511]="on",
+ [42607]="nsm",
+ [42608]="nsm",
+ [42609]="nsm",
+ [42610]="nsm",
+ [42611]="on",
+ [42612]="nsm",
+ [42613]="nsm",
+ [42614]="nsm",
+ [42615]="nsm",
+ [42616]="nsm",
+ [42617]="nsm",
+ [42618]="nsm",
+ [42619]="nsm",
+ [42620]="nsm",
+ [42621]="nsm",
+ [42622]="on",
+ [42623]="on",
+ [42654]="nsm",
+ [42655]="nsm",
+ [42736]="nsm",
+ [42737]="nsm",
+ [42752]="on",
+ [42753]="on",
+ [42754]="on",
+ [42755]="on",
+ [42756]="on",
+ [42757]="on",
+ [42758]="on",
+ [42759]="on",
+ [42760]="on",
+ [42761]="on",
+ [42762]="on",
+ [42763]="on",
+ [42764]="on",
+ [42765]="on",
+ [42766]="on",
+ [42767]="on",
+ [42768]="on",
+ [42769]="on",
+ [42770]="on",
+ [42771]="on",
+ [42772]="on",
+ [42773]="on",
+ [42774]="on",
+ [42775]="on",
+ [42776]="on",
+ [42777]="on",
+ [42778]="on",
+ [42779]="on",
+ [42780]="on",
+ [42781]="on",
+ [42782]="on",
+ [42783]="on",
+ [42784]="on",
+ [42785]="on",
+ [42888]="on",
+ [43010]="nsm",
+ [43014]="nsm",
+ [43019]="nsm",
+ [43045]="nsm",
+ [43046]="nsm",
+ [43048]="on",
+ [43049]="on",
+ [43050]="on",
+ [43051]="on",
+ [43064]="et",
+ [43065]="et",
+ [43124]="on",
+ [43125]="on",
+ [43126]="on",
+ [43127]="on",
+ [43204]="nsm",
+ [43205]="nsm",
+ [43232]="nsm",
+ [43233]="nsm",
+ [43234]="nsm",
+ [43235]="nsm",
+ [43236]="nsm",
+ [43237]="nsm",
+ [43238]="nsm",
+ [43239]="nsm",
+ [43240]="nsm",
+ [43241]="nsm",
+ [43242]="nsm",
+ [43243]="nsm",
+ [43244]="nsm",
+ [43245]="nsm",
+ [43246]="nsm",
+ [43247]="nsm",
+ [43248]="nsm",
+ [43249]="nsm",
+ [43302]="nsm",
+ [43303]="nsm",
+ [43304]="nsm",
+ [43305]="nsm",
+ [43306]="nsm",
+ [43307]="nsm",
+ [43308]="nsm",
+ [43309]="nsm",
+ [43335]="nsm",
+ [43336]="nsm",
+ [43337]="nsm",
+ [43338]="nsm",
+ [43339]="nsm",
+ [43340]="nsm",
+ [43341]="nsm",
+ [43342]="nsm",
+ [43343]="nsm",
+ [43344]="nsm",
+ [43345]="nsm",
+ [43392]="nsm",
+ [43393]="nsm",
+ [43394]="nsm",
+ [43443]="nsm",
+ [43446]="nsm",
+ [43447]="nsm",
+ [43448]="nsm",
+ [43449]="nsm",
+ [43452]="nsm",
+ [43493]="nsm",
+ [43561]="nsm",
+ [43562]="nsm",
+ [43563]="nsm",
+ [43564]="nsm",
+ [43565]="nsm",
+ [43566]="nsm",
+ [43569]="nsm",
+ [43570]="nsm",
+ [43573]="nsm",
+ [43574]="nsm",
+ [43587]="nsm",
+ [43596]="nsm",
+ [43644]="nsm",
+ [43696]="nsm",
+ [43698]="nsm",
+ [43699]="nsm",
+ [43700]="nsm",
+ [43703]="nsm",
+ [43704]="nsm",
+ [43710]="nsm",
+ [43711]="nsm",
+ [43713]="nsm",
+ [43756]="nsm",
+ [43757]="nsm",
+ [43766]="nsm",
+ [44005]="nsm",
+ [44008]="nsm",
+ [44013]="nsm",
+ [64285]="r",
+ [64286]="nsm",
+ [64287]="r",
+ [64288]="r",
+ [64289]="r",
+ [64290]="r",
+ [64291]="r",
+ [64292]="r",
+ [64293]="r",
+ [64294]="r",
+ [64295]="r",
+ [64296]="r",
+ [64297]="es",
+ [64298]="r",
+ [64299]="r",
+ [64300]="r",
+ [64301]="r",
+ [64302]="r",
+ [64303]="r",
+ [64304]="r",
+ [64305]="r",
+ [64306]="r",
+ [64307]="r",
+ [64308]="r",
+ [64309]="r",
+ [64310]="r",
+ [64312]="r",
+ [64313]="r",
+ [64314]="r",
+ [64315]="r",
+ [64316]="r",
+ [64318]="r",
+ [64320]="r",
+ [64321]="r",
+ [64323]="r",
+ [64324]="r",
+ [64326]="r",
+ [64327]="r",
+ [64328]="r",
+ [64329]="r",
+ [64330]="r",
+ [64331]="r",
+ [64332]="r",
+ [64333]="r",
+ [64334]="r",
+ [64335]="r",
+ [64336]="al",
+ [64337]="al",
+ [64338]="al",
+ [64339]="al",
+ [64340]="al",
+ [64341]="al",
+ [64342]="al",
+ [64343]="al",
+ [64344]="al",
+ [64345]="al",
+ [64346]="al",
+ [64347]="al",
+ [64348]="al",
+ [64349]="al",
+ [64350]="al",
+ [64351]="al",
+ [64352]="al",
+ [64353]="al",
+ [64354]="al",
+ [64355]="al",
+ [64356]="al",
+ [64357]="al",
+ [64358]="al",
+ [64359]="al",
+ [64360]="al",
+ [64361]="al",
+ [64362]="al",
+ [64363]="al",
+ [64364]="al",
+ [64365]="al",
+ [64366]="al",
+ [64367]="al",
+ [64368]="al",
+ [64369]="al",
+ [64370]="al",
+ [64371]="al",
+ [64372]="al",
+ [64373]="al",
+ [64374]="al",
+ [64375]="al",
+ [64376]="al",
+ [64377]="al",
+ [64378]="al",
+ [64379]="al",
+ [64380]="al",
+ [64381]="al",
+ [64382]="al",
+ [64383]="al",
+ [64384]="al",
+ [64385]="al",
+ [64386]="al",
+ [64387]="al",
+ [64388]="al",
+ [64389]="al",
+ [64390]="al",
+ [64391]="al",
+ [64392]="al",
+ [64393]="al",
+ [64394]="al",
+ [64395]="al",
+ [64396]="al",
+ [64397]="al",
+ [64398]="al",
+ [64399]="al",
+ [64400]="al",
+ [64401]="al",
+ [64402]="al",
+ [64403]="al",
+ [64404]="al",
+ [64405]="al",
+ [64406]="al",
+ [64407]="al",
+ [64408]="al",
+ [64409]="al",
+ [64410]="al",
+ [64411]="al",
+ [64412]="al",
+ [64413]="al",
+ [64414]="al",
+ [64415]="al",
+ [64416]="al",
+ [64417]="al",
+ [64418]="al",
+ [64419]="al",
+ [64420]="al",
+ [64421]="al",
+ [64422]="al",
+ [64423]="al",
+ [64424]="al",
+ [64425]="al",
+ [64426]="al",
+ [64427]="al",
+ [64428]="al",
+ [64429]="al",
+ [64430]="al",
+ [64431]="al",
+ [64432]="al",
+ [64433]="al",
+ [64434]="al",
+ [64435]="al",
+ [64436]="al",
+ [64437]="al",
+ [64438]="al",
+ [64439]="al",
+ [64440]="al",
+ [64441]="al",
+ [64442]="al",
+ [64443]="al",
+ [64444]="al",
+ [64445]="al",
+ [64446]="al",
+ [64447]="al",
+ [64448]="al",
+ [64449]="al",
+ [64467]="al",
+ [64468]="al",
+ [64469]="al",
+ [64470]="al",
+ [64471]="al",
+ [64472]="al",
+ [64473]="al",
+ [64474]="al",
+ [64475]="al",
+ [64476]="al",
+ [64477]="al",
+ [64478]="al",
+ [64479]="al",
+ [64480]="al",
+ [64481]="al",
+ [64482]="al",
+ [64483]="al",
+ [64484]="al",
+ [64485]="al",
+ [64486]="al",
+ [64487]="al",
+ [64488]="al",
+ [64489]="al",
+ [64490]="al",
+ [64491]="al",
+ [64492]="al",
+ [64493]="al",
+ [64494]="al",
+ [64495]="al",
+ [64496]="al",
+ [64497]="al",
+ [64498]="al",
+ [64499]="al",
+ [64500]="al",
+ [64501]="al",
+ [64502]="al",
+ [64503]="al",
+ [64504]="al",
+ [64505]="al",
+ [64506]="al",
+ [64507]="al",
+ [64508]="al",
+ [64509]="al",
+ [64510]="al",
+ [64511]="al",
+ [64512]="al",
+ [64513]="al",
+ [64514]="al",
+ [64515]="al",
+ [64516]="al",
+ [64517]="al",
+ [64518]="al",
+ [64519]="al",
+ [64520]="al",
+ [64521]="al",
+ [64522]="al",
+ [64523]="al",
+ [64524]="al",
+ [64525]="al",
+ [64526]="al",
+ [64527]="al",
+ [64528]="al",
+ [64529]="al",
+ [64530]="al",
+ [64531]="al",
+ [64532]="al",
+ [64533]="al",
+ [64534]="al",
+ [64535]="al",
+ [64536]="al",
+ [64537]="al",
+ [64538]="al",
+ [64539]="al",
+ [64540]="al",
+ [64541]="al",
+ [64542]="al",
+ [64543]="al",
+ [64544]="al",
+ [64545]="al",
+ [64546]="al",
+ [64547]="al",
+ [64548]="al",
+ [64549]="al",
+ [64550]="al",
+ [64551]="al",
+ [64552]="al",
+ [64553]="al",
+ [64554]="al",
+ [64555]="al",
+ [64556]="al",
+ [64557]="al",
+ [64558]="al",
+ [64559]="al",
+ [64560]="al",
+ [64561]="al",
+ [64562]="al",
+ [64563]="al",
+ [64564]="al",
+ [64565]="al",
+ [64566]="al",
+ [64567]="al",
+ [64568]="al",
+ [64569]="al",
+ [64570]="al",
+ [64571]="al",
+ [64572]="al",
+ [64573]="al",
+ [64574]="al",
+ [64575]="al",
+ [64576]="al",
+ [64577]="al",
+ [64578]="al",
+ [64579]="al",
+ [64580]="al",
+ [64581]="al",
+ [64582]="al",
+ [64583]="al",
+ [64584]="al",
+ [64585]="al",
+ [64586]="al",
+ [64587]="al",
+ [64588]="al",
+ [64589]="al",
+ [64590]="al",
+ [64591]="al",
+ [64592]="al",
+ [64593]="al",
+ [64594]="al",
+ [64595]="al",
+ [64596]="al",
+ [64597]="al",
+ [64598]="al",
+ [64599]="al",
+ [64600]="al",
+ [64601]="al",
+ [64602]="al",
+ [64603]="al",
+ [64604]="al",
+ [64605]="al",
+ [64606]="al",
+ [64607]="al",
+ [64608]="al",
+ [64609]="al",
+ [64610]="al",
+ [64611]="al",
+ [64612]="al",
+ [64613]="al",
+ [64614]="al",
+ [64615]="al",
+ [64616]="al",
+ [64617]="al",
+ [64618]="al",
+ [64619]="al",
+ [64620]="al",
+ [64621]="al",
+ [64622]="al",
+ [64623]="al",
+ [64624]="al",
+ [64625]="al",
+ [64626]="al",
+ [64627]="al",
+ [64628]="al",
+ [64629]="al",
+ [64630]="al",
+ [64631]="al",
+ [64632]="al",
+ [64633]="al",
+ [64634]="al",
+ [64635]="al",
+ [64636]="al",
+ [64637]="al",
+ [64638]="al",
+ [64639]="al",
+ [64640]="al",
+ [64641]="al",
+ [64642]="al",
+ [64643]="al",
+ [64644]="al",
+ [64645]="al",
+ [64646]="al",
+ [64647]="al",
+ [64648]="al",
+ [64649]="al",
+ [64650]="al",
+ [64651]="al",
+ [64652]="al",
+ [64653]="al",
+ [64654]="al",
+ [64655]="al",
+ [64656]="al",
+ [64657]="al",
+ [64658]="al",
+ [64659]="al",
+ [64660]="al",
+ [64661]="al",
+ [64662]="al",
+ [64663]="al",
+ [64664]="al",
+ [64665]="al",
+ [64666]="al",
+ [64667]="al",
+ [64668]="al",
+ [64669]="al",
+ [64670]="al",
+ [64671]="al",
+ [64672]="al",
+ [64673]="al",
+ [64674]="al",
+ [64675]="al",
+ [64676]="al",
+ [64677]="al",
+ [64678]="al",
+ [64679]="al",
+ [64680]="al",
+ [64681]="al",
+ [64682]="al",
+ [64683]="al",
+ [64684]="al",
+ [64685]="al",
+ [64686]="al",
+ [64687]="al",
+ [64688]="al",
+ [64689]="al",
+ [64690]="al",
+ [64691]="al",
+ [64692]="al",
+ [64693]="al",
+ [64694]="al",
+ [64695]="al",
+ [64696]="al",
+ [64697]="al",
+ [64698]="al",
+ [64699]="al",
+ [64700]="al",
+ [64701]="al",
+ [64702]="al",
+ [64703]="al",
+ [64704]="al",
+ [64705]="al",
+ [64706]="al",
+ [64707]="al",
+ [64708]="al",
+ [64709]="al",
+ [64710]="al",
+ [64711]="al",
+ [64712]="al",
+ [64713]="al",
+ [64714]="al",
+ [64715]="al",
+ [64716]="al",
+ [64717]="al",
+ [64718]="al",
+ [64719]="al",
+ [64720]="al",
+ [64721]="al",
+ [64722]="al",
+ [64723]="al",
+ [64724]="al",
+ [64725]="al",
+ [64726]="al",
+ [64727]="al",
+ [64728]="al",
+ [64729]="al",
+ [64730]="al",
+ [64731]="al",
+ [64732]="al",
+ [64733]="al",
+ [64734]="al",
+ [64735]="al",
+ [64736]="al",
+ [64737]="al",
+ [64738]="al",
+ [64739]="al",
+ [64740]="al",
+ [64741]="al",
+ [64742]="al",
+ [64743]="al",
+ [64744]="al",
+ [64745]="al",
+ [64746]="al",
+ [64747]="al",
+ [64748]="al",
+ [64749]="al",
+ [64750]="al",
+ [64751]="al",
+ [64752]="al",
+ [64753]="al",
+ [64754]="al",
+ [64755]="al",
+ [64756]="al",
+ [64757]="al",
+ [64758]="al",
+ [64759]="al",
+ [64760]="al",
+ [64761]="al",
+ [64762]="al",
+ [64763]="al",
+ [64764]="al",
+ [64765]="al",
+ [64766]="al",
+ [64767]="al",
+ [64768]="al",
+ [64769]="al",
+ [64770]="al",
+ [64771]="al",
+ [64772]="al",
+ [64773]="al",
+ [64774]="al",
+ [64775]="al",
+ [64776]="al",
+ [64777]="al",
+ [64778]="al",
+ [64779]="al",
+ [64780]="al",
+ [64781]="al",
+ [64782]="al",
+ [64783]="al",
+ [64784]="al",
+ [64785]="al",
+ [64786]="al",
+ [64787]="al",
+ [64788]="al",
+ [64789]="al",
+ [64790]="al",
+ [64791]="al",
+ [64792]="al",
+ [64793]="al",
+ [64794]="al",
+ [64795]="al",
+ [64796]="al",
+ [64797]="al",
+ [64798]="al",
+ [64799]="al",
+ [64800]="al",
+ [64801]="al",
+ [64802]="al",
+ [64803]="al",
+ [64804]="al",
+ [64805]="al",
+ [64806]="al",
+ [64807]="al",
+ [64808]="al",
+ [64809]="al",
+ [64810]="al",
+ [64811]="al",
+ [64812]="al",
+ [64813]="al",
+ [64814]="al",
+ [64815]="al",
+ [64816]="al",
+ [64817]="al",
+ [64818]="al",
+ [64819]="al",
+ [64820]="al",
+ [64821]="al",
+ [64822]="al",
+ [64823]="al",
+ [64824]="al",
+ [64825]="al",
+ [64826]="al",
+ [64827]="al",
+ [64828]="al",
+ [64829]="al",
+ [64830]="on",
+ [64831]="on",
+ [64848]="al",
+ [64849]="al",
+ [64850]="al",
+ [64851]="al",
+ [64852]="al",
+ [64853]="al",
+ [64854]="al",
+ [64855]="al",
+ [64856]="al",
+ [64857]="al",
+ [64858]="al",
+ [64859]="al",
+ [64860]="al",
+ [64861]="al",
+ [64862]="al",
+ [64863]="al",
+ [64864]="al",
+ [64865]="al",
+ [64866]="al",
+ [64867]="al",
+ [64868]="al",
+ [64869]="al",
+ [64870]="al",
+ [64871]="al",
+ [64872]="al",
+ [64873]="al",
+ [64874]="al",
+ [64875]="al",
+ [64876]="al",
+ [64877]="al",
+ [64878]="al",
+ [64879]="al",
+ [64880]="al",
+ [64881]="al",
+ [64882]="al",
+ [64883]="al",
+ [64884]="al",
+ [64885]="al",
+ [64886]="al",
+ [64887]="al",
+ [64888]="al",
+ [64889]="al",
+ [64890]="al",
+ [64891]="al",
+ [64892]="al",
+ [64893]="al",
+ [64894]="al",
+ [64895]="al",
+ [64896]="al",
+ [64897]="al",
+ [64898]="al",
+ [64899]="al",
+ [64900]="al",
+ [64901]="al",
+ [64902]="al",
+ [64903]="al",
+ [64904]="al",
+ [64905]="al",
+ [64906]="al",
+ [64907]="al",
+ [64908]="al",
+ [64909]="al",
+ [64910]="al",
+ [64911]="al",
+ [64914]="al",
+ [64915]="al",
+ [64916]="al",
+ [64917]="al",
+ [64918]="al",
+ [64919]="al",
+ [64920]="al",
+ [64921]="al",
+ [64922]="al",
+ [64923]="al",
+ [64924]="al",
+ [64925]="al",
+ [64926]="al",
+ [64927]="al",
+ [64928]="al",
+ [64929]="al",
+ [64930]="al",
+ [64931]="al",
+ [64932]="al",
+ [64933]="al",
+ [64934]="al",
+ [64935]="al",
+ [64936]="al",
+ [64937]="al",
+ [64938]="al",
+ [64939]="al",
+ [64940]="al",
+ [64941]="al",
+ [64942]="al",
+ [64943]="al",
+ [64944]="al",
+ [64945]="al",
+ [64946]="al",
+ [64947]="al",
+ [64948]="al",
+ [64949]="al",
+ [64950]="al",
+ [64951]="al",
+ [64952]="al",
+ [64953]="al",
+ [64954]="al",
+ [64955]="al",
+ [64956]="al",
+ [64957]="al",
+ [64958]="al",
+ [64959]="al",
+ [64960]="al",
+ [64961]="al",
+ [64962]="al",
+ [64963]="al",
+ [64964]="al",
+ [64965]="al",
+ [64966]="al",
+ [64967]="al",
+ [65008]="al",
+ [65009]="al",
+ [65010]="al",
+ [65011]="al",
+ [65012]="al",
+ [65013]="al",
+ [65014]="al",
+ [65015]="al",
+ [65016]="al",
+ [65017]="al",
+ [65018]="al",
+ [65019]="al",
+ [65020]="al",
+ [65021]="on",
+ [65040]="on",
+ [65041]="on",
+ [65042]="on",
+ [65043]="on",
+ [65044]="on",
+ [65045]="on",
+ [65046]="on",
+ [65047]="on",
+ [65048]="on",
+ [65049]="on",
+ [65056]="nsm",
+ [65057]="nsm",
+ [65058]="nsm",
+ [65059]="nsm",
+ [65060]="nsm",
+ [65061]="nsm",
+ [65062]="nsm",
+ [65063]="nsm",
+ [65064]="nsm",
+ [65065]="nsm",
+ [65066]="nsm",
+ [65067]="nsm",
+ [65068]="nsm",
+ [65069]="nsm",
+ [65070]="nsm",
+ [65071]="nsm",
+ [65072]="on",
+ [65073]="on",
+ [65074]="on",
+ [65075]="on",
+ [65076]="on",
+ [65077]="on",
+ [65078]="on",
+ [65079]="on",
+ [65080]="on",
+ [65081]="on",
+ [65082]="on",
+ [65083]="on",
+ [65084]="on",
+ [65085]="on",
+ [65086]="on",
+ [65087]="on",
+ [65088]="on",
+ [65089]="on",
+ [65090]="on",
+ [65091]="on",
+ [65092]="on",
+ [65093]="on",
+ [65094]="on",
+ [65095]="on",
+ [65096]="on",
+ [65097]="on",
+ [65098]="on",
+ [65099]="on",
+ [65100]="on",
+ [65101]="on",
+ [65102]="on",
+ [65103]="on",
+ [65104]="cs",
+ [65105]="on",
+ [65106]="cs",
+ [65108]="on",
+ [65109]="cs",
+ [65110]="on",
+ [65111]="on",
+ [65112]="on",
+ [65113]="on",
+ [65114]="on",
+ [65115]="on",
+ [65116]="on",
+ [65117]="on",
+ [65118]="on",
+ [65119]="et",
+ [65120]="on",
+ [65121]="on",
+ [65122]="es",
+ [65123]="es",
+ [65124]="on",
+ [65125]="on",
+ [65126]="on",
+ [65128]="on",
+ [65129]="et",
+ [65130]="et",
+ [65131]="on",
+ [65136]="al",
+ [65137]="al",
+ [65138]="al",
+ [65139]="al",
+ [65140]="al",
+ [65142]="al",
+ [65143]="al",
+ [65144]="al",
+ [65145]="al",
+ [65146]="al",
+ [65147]="al",
+ [65148]="al",
+ [65149]="al",
+ [65150]="al",
+ [65151]="al",
+ [65152]="al",
+ [65153]="al",
+ [65154]="al",
+ [65155]="al",
+ [65156]="al",
+ [65157]="al",
+ [65158]="al",
+ [65159]="al",
+ [65160]="al",
+ [65161]="al",
+ [65162]="al",
+ [65163]="al",
+ [65164]="al",
+ [65165]="al",
+ [65166]="al",
+ [65167]="al",
+ [65168]="al",
+ [65169]="al",
+ [65170]="al",
+ [65171]="al",
+ [65172]="al",
+ [65173]="al",
+ [65174]="al",
+ [65175]="al",
+ [65176]="al",
+ [65177]="al",
+ [65178]="al",
+ [65179]="al",
+ [65180]="al",
+ [65181]="al",
+ [65182]="al",
+ [65183]="al",
+ [65184]="al",
+ [65185]="al",
+ [65186]="al",
+ [65187]="al",
+ [65188]="al",
+ [65189]="al",
+ [65190]="al",
+ [65191]="al",
+ [65192]="al",
+ [65193]="al",
+ [65194]="al",
+ [65195]="al",
+ [65196]="al",
+ [65197]="al",
+ [65198]="al",
+ [65199]="al",
+ [65200]="al",
+ [65201]="al",
+ [65202]="al",
+ [65203]="al",
+ [65204]="al",
+ [65205]="al",
+ [65206]="al",
+ [65207]="al",
+ [65208]="al",
+ [65209]="al",
+ [65210]="al",
+ [65211]="al",
+ [65212]="al",
+ [65213]="al",
+ [65214]="al",
+ [65215]="al",
+ [65216]="al",
+ [65217]="al",
+ [65218]="al",
+ [65219]="al",
+ [65220]="al",
+ [65221]="al",
+ [65222]="al",
+ [65223]="al",
+ [65224]="al",
+ [65225]="al",
+ [65226]="al",
+ [65227]="al",
+ [65228]="al",
+ [65229]="al",
+ [65230]="al",
+ [65231]="al",
+ [65232]="al",
+ [65233]="al",
+ [65234]="al",
+ [65235]="al",
+ [65236]="al",
+ [65237]="al",
+ [65238]="al",
+ [65239]="al",
+ [65240]="al",
+ [65241]="al",
+ [65242]="al",
+ [65243]="al",
+ [65244]="al",
+ [65245]="al",
+ [65246]="al",
+ [65247]="al",
+ [65248]="al",
+ [65249]="al",
+ [65250]="al",
+ [65251]="al",
+ [65252]="al",
+ [65253]="al",
+ [65254]="al",
+ [65255]="al",
+ [65256]="al",
+ [65257]="al",
+ [65258]="al",
+ [65259]="al",
+ [65260]="al",
+ [65261]="al",
+ [65262]="al",
+ [65263]="al",
+ [65264]="al",
+ [65265]="al",
+ [65266]="al",
+ [65267]="al",
+ [65268]="al",
+ [65269]="al",
+ [65270]="al",
+ [65271]="al",
+ [65272]="al",
+ [65273]="al",
+ [65274]="al",
+ [65275]="al",
+ [65276]="al",
+ [65279]="bn",
+ [65281]="on",
+ [65282]="on",
+ [65283]="et",
+ [65284]="et",
+ [65285]="et",
+ [65286]="on",
+ [65287]="on",
+ [65288]="on",
+ [65289]="on",
+ [65290]="on",
+ [65291]="es",
+ [65292]="cs",
+ [65293]="es",
+ [65294]="cs",
+ [65295]="cs",
+ [65296]="en",
+ [65297]="en",
+ [65298]="en",
+ [65299]="en",
+ [65300]="en",
+ [65301]="en",
+ [65302]="en",
+ [65303]="en",
+ [65304]="en",
+ [65305]="en",
+ [65306]="cs",
+ [65307]="on",
+ [65308]="on",
+ [65309]="on",
+ [65310]="on",
+ [65311]="on",
+ [65312]="on",
+ [65339]="on",
+ [65340]="on",
+ [65341]="on",
+ [65342]="on",
+ [65343]="on",
+ [65344]="on",
+ [65371]="on",
+ [65372]="on",
+ [65373]="on",
+ [65374]="on",
+ [65375]="on",
+ [65376]="on",
+ [65377]="on",
+ [65378]="on",
+ [65379]="on",
+ [65380]="on",
+ [65381]="on",
+ [65504]="et",
+ [65505]="et",
+ [65506]="on",
+ [65507]="on",
+ [65508]="on",
+ [65509]="et",
+ [65510]="et",
+ [65512]="on",
+ [65513]="on",
+ [65514]="on",
+ [65515]="on",
+ [65516]="on",
+ [65517]="on",
+ [65518]="on",
+ [65529]="on",
+ [65530]="on",
+ [65531]="on",
+ [65532]="on",
+ [65533]="on",
+ [65793]="on",
+ [65856]="on",
+ [65857]="on",
+ [65858]="on",
+ [65859]="on",
+ [65860]="on",
+ [65861]="on",
+ [65862]="on",
+ [65863]="on",
+ [65864]="on",
+ [65865]="on",
+ [65866]="on",
+ [65867]="on",
+ [65868]="on",
+ [65869]="on",
+ [65870]="on",
+ [65871]="on",
+ [65872]="on",
+ [65873]="on",
+ [65874]="on",
+ [65875]="on",
+ [65876]="on",
+ [65877]="on",
+ [65878]="on",
+ [65879]="on",
+ [65880]="on",
+ [65881]="on",
+ [65882]="on",
+ [65883]="on",
+ [65884]="on",
+ [65885]="on",
+ [65886]="on",
+ [65887]="on",
+ [65888]="on",
+ [65889]="on",
+ [65890]="on",
+ [65891]="on",
+ [65892]="on",
+ [65893]="on",
+ [65894]="on",
+ [65895]="on",
+ [65896]="on",
+ [65897]="on",
+ [65898]="on",
+ [65899]="on",
+ [65900]="on",
+ [65901]="on",
+ [65902]="on",
+ [65903]="on",
+ [65904]="on",
+ [65905]="on",
+ [65906]="on",
+ [65907]="on",
+ [65908]="on",
+ [65909]="on",
+ [65910]="on",
+ [65911]="on",
+ [65912]="on",
+ [65913]="on",
+ [65914]="on",
+ [65915]="on",
+ [65916]="on",
+ [65917]="on",
+ [65918]="on",
+ [65919]="on",
+ [65920]="on",
+ [65921]="on",
+ [65922]="on",
+ [65923]="on",
+ [65924]="on",
+ [65925]="on",
+ [65926]="on",
+ [65927]="on",
+ [65928]="on",
+ [65929]="on",
+ [65930]="on",
+ [65931]="on",
+ [65932]="on",
+ [65936]="on",
+ [65937]="on",
+ [65938]="on",
+ [65939]="on",
+ [65940]="on",
+ [65941]="on",
+ [65942]="on",
+ [65943]="on",
+ [65944]="on",
+ [65945]="on",
+ [65946]="on",
+ [65947]="on",
+ [65952]="on",
+ [66045]="nsm",
+ [66272]="nsm",
+ [66273]="en",
+ [66274]="en",
+ [66275]="en",
+ [66276]="en",
+ [66277]="en",
+ [66278]="en",
+ [66279]="en",
+ [66280]="en",
+ [66281]="en",
+ [66282]="en",
+ [66283]="en",
+ [66284]="en",
+ [66285]="en",
+ [66286]="en",
+ [66287]="en",
+ [66288]="en",
+ [66289]="en",
+ [66290]="en",
+ [66291]="en",
+ [66292]="en",
+ [66293]="en",
+ [66294]="en",
+ [66295]="en",
+ [66296]="en",
+ [66297]="en",
+ [66298]="en",
+ [66299]="en",
+ [66422]="nsm",
+ [66423]="nsm",
+ [66424]="nsm",
+ [66425]="nsm",
+ [66426]="nsm",
+ [67584]="r",
+ [67585]="r",
+ [67586]="r",
+ [67587]="r",
+ [67588]="r",
+ [67589]="r",
+ [67592]="r",
+ [67594]="r",
+ [67595]="r",
+ [67596]="r",
+ [67597]="r",
+ [67598]="r",
+ [67599]="r",
+ [67600]="r",
+ [67601]="r",
+ [67602]="r",
+ [67603]="r",
+ [67604]="r",
+ [67605]="r",
+ [67606]="r",
+ [67607]="r",
+ [67608]="r",
+ [67609]="r",
+ [67610]="r",
+ [67611]="r",
+ [67612]="r",
+ [67613]="r",
+ [67614]="r",
+ [67615]="r",
+ [67616]="r",
+ [67617]="r",
+ [67618]="r",
+ [67619]="r",
+ [67620]="r",
+ [67621]="r",
+ [67622]="r",
+ [67623]="r",
+ [67624]="r",
+ [67625]="r",
+ [67626]="r",
+ [67627]="r",
+ [67628]="r",
+ [67629]="r",
+ [67630]="r",
+ [67631]="r",
+ [67632]="r",
+ [67633]="r",
+ [67634]="r",
+ [67635]="r",
+ [67636]="r",
+ [67637]="r",
+ [67639]="r",
+ [67640]="r",
+ [67644]="r",
+ [67647]="r",
+ [67648]="r",
+ [67649]="r",
+ [67650]="r",
+ [67651]="r",
+ [67652]="r",
+ [67653]="r",
+ [67654]="r",
+ [67655]="r",
+ [67656]="r",
+ [67657]="r",
+ [67658]="r",
+ [67659]="r",
+ [67660]="r",
+ [67661]="r",
+ [67662]="r",
+ [67663]="r",
+ [67664]="r",
+ [67665]="r",
+ [67666]="r",
+ [67667]="r",
+ [67668]="r",
+ [67669]="r",
+ [67671]="r",
+ [67672]="r",
+ [67673]="r",
+ [67674]="r",
+ [67675]="r",
+ [67676]="r",
+ [67677]="r",
+ [67678]="r",
+ [67679]="r",
+ [67680]="r",
+ [67681]="r",
+ [67682]="r",
+ [67683]="r",
+ [67684]="r",
+ [67685]="r",
+ [67686]="r",
+ [67687]="r",
+ [67688]="r",
+ [67689]="r",
+ [67690]="r",
+ [67691]="r",
+ [67692]="r",
+ [67693]="r",
+ [67694]="r",
+ [67695]="r",
+ [67696]="r",
+ [67697]="r",
+ [67698]="r",
+ [67699]="r",
+ [67700]="r",
+ [67701]="r",
+ [67702]="r",
+ [67703]="r",
+ [67704]="r",
+ [67705]="r",
+ [67706]="r",
+ [67707]="r",
+ [67708]="r",
+ [67709]="r",
+ [67710]="r",
+ [67711]="r",
+ [67712]="r",
+ [67713]="r",
+ [67714]="r",
+ [67715]="r",
+ [67716]="r",
+ [67717]="r",
+ [67718]="r",
+ [67719]="r",
+ [67720]="r",
+ [67721]="r",
+ [67722]="r",
+ [67723]="r",
+ [67724]="r",
+ [67725]="r",
+ [67726]="r",
+ [67727]="r",
+ [67728]="r",
+ [67729]="r",
+ [67730]="r",
+ [67731]="r",
+ [67732]="r",
+ [67733]="r",
+ [67734]="r",
+ [67735]="r",
+ [67736]="r",
+ [67737]="r",
+ [67738]="r",
+ [67739]="r",
+ [67740]="r",
+ [67741]="r",
+ [67742]="r",
+ [67751]="r",
+ [67752]="r",
+ [67753]="r",
+ [67754]="r",
+ [67755]="r",
+ [67756]="r",
+ [67757]="r",
+ [67758]="r",
+ [67759]="r",
+ [67808]="r",
+ [67809]="r",
+ [67810]="r",
+ [67811]="r",
+ [67812]="r",
+ [67813]="r",
+ [67814]="r",
+ [67815]="r",
+ [67816]="r",
+ [67817]="r",
+ [67818]="r",
+ [67819]="r",
+ [67820]="r",
+ [67821]="r",
+ [67822]="r",
+ [67823]="r",
+ [67824]="r",
+ [67825]="r",
+ [67826]="r",
+ [67828]="r",
+ [67829]="r",
+ [67835]="r",
+ [67836]="r",
+ [67837]="r",
+ [67838]="r",
+ [67839]="r",
+ [67840]="r",
+ [67841]="r",
+ [67842]="r",
+ [67843]="r",
+ [67844]="r",
+ [67845]="r",
+ [67846]="r",
+ [67847]="r",
+ [67848]="r",
+ [67849]="r",
+ [67850]="r",
+ [67851]="r",
+ [67852]="r",
+ [67853]="r",
+ [67854]="r",
+ [67855]="r",
+ [67856]="r",
+ [67857]="r",
+ [67858]="r",
+ [67859]="r",
+ [67860]="r",
+ [67861]="r",
+ [67862]="r",
+ [67863]="r",
+ [67864]="r",
+ [67865]="r",
+ [67866]="r",
+ [67867]="r",
+ [67871]="on",
+ [67872]="r",
+ [67873]="r",
+ [67874]="r",
+ [67875]="r",
+ [67876]="r",
+ [67877]="r",
+ [67878]="r",
+ [67879]="r",
+ [67880]="r",
+ [67881]="r",
+ [67882]="r",
+ [67883]="r",
+ [67884]="r",
+ [67885]="r",
+ [67886]="r",
+ [67887]="r",
+ [67888]="r",
+ [67889]="r",
+ [67890]="r",
+ [67891]="r",
+ [67892]="r",
+ [67893]="r",
+ [67894]="r",
+ [67895]="r",
+ [67896]="r",
+ [67897]="r",
+ [67903]="r",
+ [67968]="r",
+ [67969]="r",
+ [67970]="r",
+ [67971]="r",
+ [67972]="r",
+ [67973]="r",
+ [67974]="r",
+ [67975]="r",
+ [67976]="r",
+ [67977]="r",
+ [67978]="r",
+ [67979]="r",
+ [67980]="r",
+ [67981]="r",
+ [67982]="r",
+ [67983]="r",
+ [67984]="r",
+ [67985]="r",
+ [67986]="r",
+ [67987]="r",
+ [67988]="r",
+ [67989]="r",
+ [67990]="r",
+ [67991]="r",
+ [67992]="r",
+ [67993]="r",
+ [67994]="r",
+ [67995]="r",
+ [67996]="r",
+ [67997]="r",
+ [67998]="r",
+ [67999]="r",
+ [68000]="r",
+ [68001]="r",
+ [68002]="r",
+ [68003]="r",
+ [68004]="r",
+ [68005]="r",
+ [68006]="r",
+ [68007]="r",
+ [68008]="r",
+ [68009]="r",
+ [68010]="r",
+ [68011]="r",
+ [68012]="r",
+ [68013]="r",
+ [68014]="r",
+ [68015]="r",
+ [68016]="r",
+ [68017]="r",
+ [68018]="r",
+ [68019]="r",
+ [68020]="r",
+ [68021]="r",
+ [68022]="r",
+ [68023]="r",
+ [68028]="r",
+ [68029]="r",
+ [68030]="r",
+ [68031]="r",
+ [68032]="r",
+ [68033]="r",
+ [68034]="r",
+ [68035]="r",
+ [68036]="r",
+ [68037]="r",
+ [68038]="r",
+ [68039]="r",
+ [68040]="r",
+ [68041]="r",
+ [68042]="r",
+ [68043]="r",
+ [68044]="r",
+ [68045]="r",
+ [68046]="r",
+ [68047]="r",
+ [68050]="r",
+ [68051]="r",
+ [68052]="r",
+ [68053]="r",
+ [68054]="r",
+ [68055]="r",
+ [68056]="r",
+ [68057]="r",
+ [68058]="r",
+ [68059]="r",
+ [68060]="r",
+ [68061]="r",
+ [68062]="r",
+ [68063]="r",
+ [68064]="r",
+ [68065]="r",
+ [68066]="r",
+ [68067]="r",
+ [68068]="r",
+ [68069]="r",
+ [68070]="r",
+ [68071]="r",
+ [68072]="r",
+ [68073]="r",
+ [68074]="r",
+ [68075]="r",
+ [68076]="r",
+ [68077]="r",
+ [68078]="r",
+ [68079]="r",
+ [68080]="r",
+ [68081]="r",
+ [68082]="r",
+ [68083]="r",
+ [68084]="r",
+ [68085]="r",
+ [68086]="r",
+ [68087]="r",
+ [68088]="r",
+ [68089]="r",
+ [68090]="r",
+ [68091]="r",
+ [68092]="r",
+ [68093]="r",
+ [68094]="r",
+ [68095]="r",
+ [68096]="r",
+ [68097]="nsm",
+ [68098]="nsm",
+ [68099]="nsm",
+ [68101]="nsm",
+ [68102]="nsm",
+ [68108]="nsm",
+ [68109]="nsm",
+ [68110]="nsm",
+ [68111]="nsm",
+ [68112]="r",
+ [68113]="r",
+ [68114]="r",
+ [68115]="r",
+ [68117]="r",
+ [68118]="r",
+ [68119]="r",
+ [68121]="r",
+ [68122]="r",
+ [68123]="r",
+ [68124]="r",
+ [68125]="r",
+ [68126]="r",
+ [68127]="r",
+ [68128]="r",
+ [68129]="r",
+ [68130]="r",
+ [68131]="r",
+ [68132]="r",
+ [68133]="r",
+ [68134]="r",
+ [68135]="r",
+ [68136]="r",
+ [68137]="r",
+ [68138]="r",
+ [68139]="r",
+ [68140]="r",
+ [68141]="r",
+ [68142]="r",
+ [68143]="r",
+ [68144]="r",
+ [68145]="r",
+ [68146]="r",
+ [68147]="r",
+ [68152]="nsm",
+ [68153]="nsm",
+ [68154]="nsm",
+ [68159]="nsm",
+ [68160]="r",
+ [68161]="r",
+ [68162]="r",
+ [68163]="r",
+ [68164]="r",
+ [68165]="r",
+ [68166]="r",
+ [68167]="r",
+ [68176]="r",
+ [68177]="r",
+ [68178]="r",
+ [68179]="r",
+ [68180]="r",
+ [68181]="r",
+ [68182]="r",
+ [68183]="r",
+ [68184]="r",
+ [68192]="r",
+ [68193]="r",
+ [68194]="r",
+ [68195]="r",
+ [68196]="r",
+ [68197]="r",
+ [68198]="r",
+ [68199]="r",
+ [68200]="r",
+ [68201]="r",
+ [68202]="r",
+ [68203]="r",
+ [68204]="r",
+ [68205]="r",
+ [68206]="r",
+ [68207]="r",
+ [68208]="r",
+ [68209]="r",
+ [68210]="r",
+ [68211]="r",
+ [68212]="r",
+ [68213]="r",
+ [68214]="r",
+ [68215]="r",
+ [68216]="r",
+ [68217]="r",
+ [68218]="r",
+ [68219]="r",
+ [68220]="r",
+ [68221]="r",
+ [68222]="r",
+ [68223]="r",
+ [68224]="r",
+ [68225]="r",
+ [68226]="r",
+ [68227]="r",
+ [68228]="r",
+ [68229]="r",
+ [68230]="r",
+ [68231]="r",
+ [68232]="r",
+ [68233]="r",
+ [68234]="r",
+ [68235]="r",
+ [68236]="r",
+ [68237]="r",
+ [68238]="r",
+ [68239]="r",
+ [68240]="r",
+ [68241]="r",
+ [68242]="r",
+ [68243]="r",
+ [68244]="r",
+ [68245]="r",
+ [68246]="r",
+ [68247]="r",
+ [68248]="r",
+ [68249]="r",
+ [68250]="r",
+ [68251]="r",
+ [68252]="r",
+ [68253]="r",
+ [68254]="r",
+ [68255]="r",
+ [68288]="r",
+ [68289]="r",
+ [68290]="r",
+ [68291]="r",
+ [68292]="r",
+ [68293]="r",
+ [68294]="r",
+ [68295]="r",
+ [68296]="r",
+ [68297]="r",
+ [68298]="r",
+ [68299]="r",
+ [68300]="r",
+ [68301]="r",
+ [68302]="r",
+ [68303]="r",
+ [68304]="r",
+ [68305]="r",
+ [68306]="r",
+ [68307]="r",
+ [68308]="r",
+ [68309]="r",
+ [68310]="r",
+ [68311]="r",
+ [68312]="r",
+ [68313]="r",
+ [68314]="r",
+ [68315]="r",
+ [68316]="r",
+ [68317]="r",
+ [68318]="r",
+ [68319]="r",
+ [68320]="r",
+ [68321]="r",
+ [68322]="r",
+ [68323]="r",
+ [68324]="r",
+ [68325]="nsm",
+ [68326]="nsm",
+ [68331]="r",
+ [68332]="r",
+ [68333]="r",
+ [68334]="r",
+ [68335]="r",
+ [68336]="r",
+ [68337]="r",
+ [68338]="r",
+ [68339]="r",
+ [68340]="r",
+ [68341]="r",
+ [68342]="r",
+ [68352]="r",
+ [68353]="r",
+ [68354]="r",
+ [68355]="r",
+ [68356]="r",
+ [68357]="r",
+ [68358]="r",
+ [68359]="r",
+ [68360]="r",
+ [68361]="r",
+ [68362]="r",
+ [68363]="r",
+ [68364]="r",
+ [68365]="r",
+ [68366]="r",
+ [68367]="r",
+ [68368]="r",
+ [68369]="r",
+ [68370]="r",
+ [68371]="r",
+ [68372]="r",
+ [68373]="r",
+ [68374]="r",
+ [68375]="r",
+ [68376]="r",
+ [68377]="r",
+ [68378]="r",
+ [68379]="r",
+ [68380]="r",
+ [68381]="r",
+ [68382]="r",
+ [68383]="r",
+ [68384]="r",
+ [68385]="r",
+ [68386]="r",
+ [68387]="r",
+ [68388]="r",
+ [68389]="r",
+ [68390]="r",
+ [68391]="r",
+ [68392]="r",
+ [68393]="r",
+ [68394]="r",
+ [68395]="r",
+ [68396]="r",
+ [68397]="r",
+ [68398]="r",
+ [68399]="r",
+ [68400]="r",
+ [68401]="r",
+ [68402]="r",
+ [68403]="r",
+ [68404]="r",
+ [68405]="r",
+ [68409]="on",
+ [68410]="on",
+ [68411]="on",
+ [68412]="on",
+ [68413]="on",
+ [68414]="on",
+ [68415]="on",
+ [68416]="r",
+ [68417]="r",
+ [68418]="r",
+ [68419]="r",
+ [68420]="r",
+ [68421]="r",
+ [68422]="r",
+ [68423]="r",
+ [68424]="r",
+ [68425]="r",
+ [68426]="r",
+ [68427]="r",
+ [68428]="r",
+ [68429]="r",
+ [68430]="r",
+ [68431]="r",
+ [68432]="r",
+ [68433]="r",
+ [68434]="r",
+ [68435]="r",
+ [68436]="r",
+ [68437]="r",
+ [68440]="r",
+ [68441]="r",
+ [68442]="r",
+ [68443]="r",
+ [68444]="r",
+ [68445]="r",
+ [68446]="r",
+ [68447]="r",
+ [68448]="r",
+ [68449]="r",
+ [68450]="r",
+ [68451]="r",
+ [68452]="r",
+ [68453]="r",
+ [68454]="r",
+ [68455]="r",
+ [68456]="r",
+ [68457]="r",
+ [68458]="r",
+ [68459]="r",
+ [68460]="r",
+ [68461]="r",
+ [68462]="r",
+ [68463]="r",
+ [68464]="r",
+ [68465]="r",
+ [68466]="r",
+ [68472]="r",
+ [68473]="r",
+ [68474]="r",
+ [68475]="r",
+ [68476]="r",
+ [68477]="r",
+ [68478]="r",
+ [68479]="r",
+ [68480]="r",
+ [68481]="r",
+ [68482]="r",
+ [68483]="r",
+ [68484]="r",
+ [68485]="r",
+ [68486]="r",
+ [68487]="r",
+ [68488]="r",
+ [68489]="r",
+ [68490]="r",
+ [68491]="r",
+ [68492]="r",
+ [68493]="r",
+ [68494]="r",
+ [68495]="r",
+ [68496]="r",
+ [68497]="r",
+ [68505]="r",
+ [68506]="r",
+ [68507]="r",
+ [68508]="r",
+ [68521]="r",
+ [68522]="r",
+ [68523]="r",
+ [68524]="r",
+ [68525]="r",
+ [68526]="r",
+ [68527]="r",
+ [68608]="r",
+ [68609]="r",
+ [68610]="r",
+ [68611]="r",
+ [68612]="r",
+ [68613]="r",
+ [68614]="r",
+ [68615]="r",
+ [68616]="r",
+ [68617]="r",
+ [68618]="r",
+ [68619]="r",
+ [68620]="r",
+ [68621]="r",
+ [68622]="r",
+ [68623]="r",
+ [68624]="r",
+ [68625]="r",
+ [68626]="r",
+ [68627]="r",
+ [68628]="r",
+ [68629]="r",
+ [68630]="r",
+ [68631]="r",
+ [68632]="r",
+ [68633]="r",
+ [68634]="r",
+ [68635]="r",
+ [68636]="r",
+ [68637]="r",
+ [68638]="r",
+ [68639]="r",
+ [68640]="r",
+ [68641]="r",
+ [68642]="r",
+ [68643]="r",
+ [68644]="r",
+ [68645]="r",
+ [68646]="r",
+ [68647]="r",
+ [68648]="r",
+ [68649]="r",
+ [68650]="r",
+ [68651]="r",
+ [68652]="r",
+ [68653]="r",
+ [68654]="r",
+ [68655]="r",
+ [68656]="r",
+ [68657]="r",
+ [68658]="r",
+ [68659]="r",
+ [68660]="r",
+ [68661]="r",
+ [68662]="r",
+ [68663]="r",
+ [68664]="r",
+ [68665]="r",
+ [68666]="r",
+ [68667]="r",
+ [68668]="r",
+ [68669]="r",
+ [68670]="r",
+ [68671]="r",
+ [68672]="r",
+ [68673]="r",
+ [68674]="r",
+ [68675]="r",
+ [68676]="r",
+ [68677]="r",
+ [68678]="r",
+ [68679]="r",
+ [68680]="r",
+ [68736]="r",
+ [68737]="r",
+ [68738]="r",
+ [68739]="r",
+ [68740]="r",
+ [68741]="r",
+ [68742]="r",
+ [68743]="r",
+ [68744]="r",
+ [68745]="r",
+ [68746]="r",
+ [68747]="r",
+ [68748]="r",
+ [68749]="r",
+ [68750]="r",
+ [68751]="r",
+ [68752]="r",
+ [68753]="r",
+ [68754]="r",
+ [68755]="r",
+ [68756]="r",
+ [68757]="r",
+ [68758]="r",
+ [68759]="r",
+ [68760]="r",
+ [68761]="r",
+ [68762]="r",
+ [68763]="r",
+ [68764]="r",
+ [68765]="r",
+ [68766]="r",
+ [68767]="r",
+ [68768]="r",
+ [68769]="r",
+ [68770]="r",
+ [68771]="r",
+ [68772]="r",
+ [68773]="r",
+ [68774]="r",
+ [68775]="r",
+ [68776]="r",
+ [68777]="r",
+ [68778]="r",
+ [68779]="r",
+ [68780]="r",
+ [68781]="r",
+ [68782]="r",
+ [68783]="r",
+ [68784]="r",
+ [68785]="r",
+ [68786]="r",
+ [68800]="r",
+ [68801]="r",
+ [68802]="r",
+ [68803]="r",
+ [68804]="r",
+ [68805]="r",
+ [68806]="r",
+ [68807]="r",
+ [68808]="r",
+ [68809]="r",
+ [68810]="r",
+ [68811]="r",
+ [68812]="r",
+ [68813]="r",
+ [68814]="r",
+ [68815]="r",
+ [68816]="r",
+ [68817]="r",
+ [68818]="r",
+ [68819]="r",
+ [68820]="r",
+ [68821]="r",
+ [68822]="r",
+ [68823]="r",
+ [68824]="r",
+ [68825]="r",
+ [68826]="r",
+ [68827]="r",
+ [68828]="r",
+ [68829]="r",
+ [68830]="r",
+ [68831]="r",
+ [68832]="r",
+ [68833]="r",
+ [68834]="r",
+ [68835]="r",
+ [68836]="r",
+ [68837]="r",
+ [68838]="r",
+ [68839]="r",
+ [68840]="r",
+ [68841]="r",
+ [68842]="r",
+ [68843]="r",
+ [68844]="r",
+ [68845]="r",
+ [68846]="r",
+ [68847]="r",
+ [68848]="r",
+ [68849]="r",
+ [68850]="r",
+ [68858]="r",
+ [68859]="r",
+ [68860]="r",
+ [68861]="r",
+ [68862]="r",
+ [68863]="r",
+ [69216]="an",
+ [69217]="an",
+ [69218]="an",
+ [69219]="an",
+ [69220]="an",
+ [69221]="an",
+ [69222]="an",
+ [69223]="an",
+ [69224]="an",
+ [69225]="an",
+ [69226]="an",
+ [69227]="an",
+ [69228]="an",
+ [69229]="an",
+ [69230]="an",
+ [69231]="an",
+ [69232]="an",
+ [69233]="an",
+ [69234]="an",
+ [69235]="an",
+ [69236]="an",
+ [69237]="an",
+ [69238]="an",
+ [69239]="an",
+ [69240]="an",
+ [69241]="an",
+ [69242]="an",
+ [69243]="an",
+ [69244]="an",
+ [69245]="an",
+ [69246]="an",
+ [69633]="nsm",
+ [69688]="nsm",
+ [69689]="nsm",
+ [69690]="nsm",
+ [69691]="nsm",
+ [69692]="nsm",
+ [69693]="nsm",
+ [69694]="nsm",
+ [69695]="nsm",
+ [69696]="nsm",
+ [69697]="nsm",
+ [69698]="nsm",
+ [69699]="nsm",
+ [69700]="nsm",
+ [69701]="nsm",
+ [69702]="nsm",
+ [69714]="on",
+ [69715]="on",
+ [69716]="on",
+ [69717]="on",
+ [69718]="on",
+ [69719]="on",
+ [69720]="on",
+ [69721]="on",
+ [69722]="on",
+ [69723]="on",
+ [69724]="on",
+ [69725]="on",
+ [69726]="on",
+ [69727]="on",
+ [69728]="on",
+ [69729]="on",
+ [69730]="on",
+ [69731]="on",
+ [69732]="on",
+ [69733]="on",
+ [69759]="nsm",
+ [69760]="nsm",
+ [69761]="nsm",
+ [69811]="nsm",
+ [69812]="nsm",
+ [69813]="nsm",
+ [69814]="nsm",
+ [69817]="nsm",
+ [69818]="nsm",
+ [69888]="nsm",
+ [69889]="nsm",
+ [69890]="nsm",
+ [69927]="nsm",
+ [69928]="nsm",
+ [69929]="nsm",
+ [69930]="nsm",
+ [69931]="nsm",
+ [69933]="nsm",
+ [69934]="nsm",
+ [69935]="nsm",
+ [69936]="nsm",
+ [69937]="nsm",
+ [69938]="nsm",
+ [69939]="nsm",
+ [69940]="nsm",
+ [70003]="nsm",
+ [70016]="nsm",
+ [70017]="nsm",
+ [70070]="nsm",
+ [70071]="nsm",
+ [70072]="nsm",
+ [70073]="nsm",
+ [70074]="nsm",
+ [70075]="nsm",
+ [70076]="nsm",
+ [70077]="nsm",
+ [70078]="nsm",
+ [70090]="nsm",
+ [70091]="nsm",
+ [70092]="nsm",
+ [70191]="nsm",
+ [70192]="nsm",
+ [70193]="nsm",
+ [70196]="nsm",
+ [70198]="nsm",
+ [70199]="nsm",
+ [70206]="nsm",
+ [70367]="nsm",
+ [70371]="nsm",
+ [70372]="nsm",
+ [70373]="nsm",
+ [70374]="nsm",
+ [70375]="nsm",
+ [70376]="nsm",
+ [70377]="nsm",
+ [70378]="nsm",
+ [70400]="nsm",
+ [70401]="nsm",
+ [70460]="nsm",
+ [70464]="nsm",
+ [70502]="nsm",
+ [70503]="nsm",
+ [70504]="nsm",
+ [70505]="nsm",
+ [70506]="nsm",
+ [70507]="nsm",
+ [70508]="nsm",
+ [70512]="nsm",
+ [70513]="nsm",
+ [70514]="nsm",
+ [70515]="nsm",
+ [70516]="nsm",
+ [70712]="nsm",
+ [70713]="nsm",
+ [70714]="nsm",
+ [70715]="nsm",
+ [70716]="nsm",
+ [70717]="nsm",
+ [70718]="nsm",
+ [70719]="nsm",
+ [70722]="nsm",
+ [70723]="nsm",
+ [70724]="nsm",
+ [70726]="nsm",
+ [70835]="nsm",
+ [70836]="nsm",
+ [70837]="nsm",
+ [70838]="nsm",
+ [70839]="nsm",
+ [70840]="nsm",
+ [70842]="nsm",
+ [70847]="nsm",
+ [70848]="nsm",
+ [70850]="nsm",
+ [70851]="nsm",
+ [71090]="nsm",
+ [71091]="nsm",
+ [71092]="nsm",
+ [71093]="nsm",
+ [71100]="nsm",
+ [71101]="nsm",
+ [71103]="nsm",
+ [71104]="nsm",
+ [71132]="nsm",
+ [71133]="nsm",
+ [71219]="nsm",
+ [71220]="nsm",
+ [71221]="nsm",
+ [71222]="nsm",
+ [71223]="nsm",
+ [71224]="nsm",
+ [71225]="nsm",
+ [71226]="nsm",
+ [71229]="nsm",
+ [71231]="nsm",
+ [71232]="nsm",
+ [71264]="on",
+ [71265]="on",
+ [71266]="on",
+ [71267]="on",
+ [71268]="on",
+ [71269]="on",
+ [71270]="on",
+ [71271]="on",
+ [71272]="on",
+ [71273]="on",
+ [71274]="on",
+ [71275]="on",
+ [71276]="on",
+ [71339]="nsm",
+ [71341]="nsm",
+ [71344]="nsm",
+ [71345]="nsm",
+ [71346]="nsm",
+ [71347]="nsm",
+ [71348]="nsm",
+ [71349]="nsm",
+ [71351]="nsm",
+ [71453]="nsm",
+ [71454]="nsm",
+ [71455]="nsm",
+ [71458]="nsm",
+ [71459]="nsm",
+ [71460]="nsm",
+ [71461]="nsm",
+ [71463]="nsm",
+ [71464]="nsm",
+ [71465]="nsm",
+ [71466]="nsm",
+ [71467]="nsm",
+ [72193]="nsm",
+ [72194]="nsm",
+ [72195]="nsm",
+ [72196]="nsm",
+ [72197]="nsm",
+ [72198]="nsm",
+ [72201]="nsm",
+ [72202]="nsm",
+ [72243]="nsm",
+ [72244]="nsm",
+ [72245]="nsm",
+ [72246]="nsm",
+ [72247]="nsm",
+ [72248]="nsm",
+ [72251]="nsm",
+ [72252]="nsm",
+ [72253]="nsm",
+ [72254]="nsm",
+ [72263]="nsm",
+ [72273]="nsm",
+ [72274]="nsm",
+ [72275]="nsm",
+ [72276]="nsm",
+ [72277]="nsm",
+ [72278]="nsm",
+ [72281]="nsm",
+ [72282]="nsm",
+ [72283]="nsm",
+ [72330]="nsm",
+ [72331]="nsm",
+ [72332]="nsm",
+ [72333]="nsm",
+ [72334]="nsm",
+ [72335]="nsm",
+ [72336]="nsm",
+ [72337]="nsm",
+ [72338]="nsm",
+ [72339]="nsm",
+ [72340]="nsm",
+ [72341]="nsm",
+ [72342]="nsm",
+ [72344]="nsm",
+ [72345]="nsm",
+ [72752]="nsm",
+ [72753]="nsm",
+ [72754]="nsm",
+ [72755]="nsm",
+ [72756]="nsm",
+ [72757]="nsm",
+ [72758]="nsm",
+ [72760]="nsm",
+ [72761]="nsm",
+ [72762]="nsm",
+ [72763]="nsm",
+ [72764]="nsm",
+ [72765]="nsm",
+ [72850]="nsm",
+ [72851]="nsm",
+ [72852]="nsm",
+ [72853]="nsm",
+ [72854]="nsm",
+ [72855]="nsm",
+ [72856]="nsm",
+ [72857]="nsm",
+ [72858]="nsm",
+ [72859]="nsm",
+ [72860]="nsm",
+ [72861]="nsm",
+ [72862]="nsm",
+ [72863]="nsm",
+ [72864]="nsm",
+ [72865]="nsm",
+ [72866]="nsm",
+ [72867]="nsm",
+ [72868]="nsm",
+ [72869]="nsm",
+ [72870]="nsm",
+ [72871]="nsm",
+ [72874]="nsm",
+ [72875]="nsm",
+ [72876]="nsm",
+ [72877]="nsm",
+ [72878]="nsm",
+ [72879]="nsm",
+ [72880]="nsm",
+ [72882]="nsm",
+ [72883]="nsm",
+ [72885]="nsm",
+ [72886]="nsm",
+ [73009]="nsm",
+ [73010]="nsm",
+ [73011]="nsm",
+ [73012]="nsm",
+ [73013]="nsm",
+ [73014]="nsm",
+ [73018]="nsm",
+ [73020]="nsm",
+ [73021]="nsm",
+ [73023]="nsm",
+ [73024]="nsm",
+ [73025]="nsm",
+ [73026]="nsm",
+ [73027]="nsm",
+ [73028]="nsm",
+ [73029]="nsm",
+ [73031]="nsm",
+ [92912]="nsm",
+ [92913]="nsm",
+ [92914]="nsm",
+ [92915]="nsm",
+ [92916]="nsm",
+ [92976]="nsm",
+ [92977]="nsm",
+ [92978]="nsm",
+ [92979]="nsm",
+ [92980]="nsm",
+ [92981]="nsm",
+ [92982]="nsm",
+ [94095]="nsm",
+ [94096]="nsm",
+ [94097]="nsm",
+ [94098]="nsm",
+ [113821]="nsm",
+ [113822]="nsm",
+ [113824]="bn",
+ [113825]="bn",
+ [113826]="bn",
+ [113827]="bn",
+ [119143]="nsm",
+ [119144]="nsm",
+ [119145]="nsm",
+ [119155]="bn",
+ [119156]="bn",
+ [119157]="bn",
+ [119158]="bn",
+ [119159]="bn",
+ [119160]="bn",
+ [119161]="bn",
+ [119162]="bn",
+ [119163]="nsm",
+ [119164]="nsm",
+ [119165]="nsm",
+ [119166]="nsm",
+ [119167]="nsm",
+ [119168]="nsm",
+ [119169]="nsm",
+ [119170]="nsm",
+ [119173]="nsm",
+ [119174]="nsm",
+ [119175]="nsm",
+ [119176]="nsm",
+ [119177]="nsm",
+ [119178]="nsm",
+ [119179]="nsm",
+ [119210]="nsm",
+ [119211]="nsm",
+ [119212]="nsm",
+ [119213]="nsm",
+ [119296]="on",
+ [119297]="on",
+ [119298]="on",
+ [119299]="on",
+ [119300]="on",
+ [119301]="on",
+ [119302]="on",
+ [119303]="on",
+ [119304]="on",
+ [119305]="on",
+ [119306]="on",
+ [119307]="on",
+ [119308]="on",
+ [119309]="on",
+ [119310]="on",
+ [119311]="on",
+ [119312]="on",
+ [119313]="on",
+ [119314]="on",
+ [119315]="on",
+ [119316]="on",
+ [119317]="on",
+ [119318]="on",
+ [119319]="on",
+ [119320]="on",
+ [119321]="on",
+ [119322]="on",
+ [119323]="on",
+ [119324]="on",
+ [119325]="on",
+ [119326]="on",
+ [119327]="on",
+ [119328]="on",
+ [119329]="on",
+ [119330]="on",
+ [119331]="on",
+ [119332]="on",
+ [119333]="on",
+ [119334]="on",
+ [119335]="on",
+ [119336]="on",
+ [119337]="on",
+ [119338]="on",
+ [119339]="on",
+ [119340]="on",
+ [119341]="on",
+ [119342]="on",
+ [119343]="on",
+ [119344]="on",
+ [119345]="on",
+ [119346]="on",
+ [119347]="on",
+ [119348]="on",
+ [119349]="on",
+ [119350]="on",
+ [119351]="on",
+ [119352]="on",
+ [119353]="on",
+ [119354]="on",
+ [119355]="on",
+ [119356]="on",
+ [119357]="on",
+ [119358]="on",
+ [119359]="on",
+ [119360]="on",
+ [119361]="on",
+ [119362]="nsm",
+ [119363]="nsm",
+ [119364]="nsm",
+ [119365]="on",
+ [119552]="on",
+ [119553]="on",
+ [119554]="on",
+ [119555]="on",
+ [119556]="on",
+ [119557]="on",
+ [119558]="on",
+ [119559]="on",
+ [119560]="on",
+ [119561]="on",
+ [119562]="on",
+ [119563]="on",
+ [119564]="on",
+ [119565]="on",
+ [119566]="on",
+ [119567]="on",
+ [119568]="on",
+ [119569]="on",
+ [119570]="on",
+ [119571]="on",
+ [119572]="on",
+ [119573]="on",
+ [119574]="on",
+ [119575]="on",
+ [119576]="on",
+ [119577]="on",
+ [119578]="on",
+ [119579]="on",
+ [119580]="on",
+ [119581]="on",
+ [119582]="on",
+ [119583]="on",
+ [119584]="on",
+ [119585]="on",
+ [119586]="on",
+ [119587]="on",
+ [119588]="on",
+ [119589]="on",
+ [119590]="on",
+ [119591]="on",
+ [119592]="on",
+ [119593]="on",
+ [119594]="on",
+ [119595]="on",
+ [119596]="on",
+ [119597]="on",
+ [119598]="on",
+ [119599]="on",
+ [119600]="on",
+ [119601]="on",
+ [119602]="on",
+ [119603]="on",
+ [119604]="on",
+ [119605]="on",
+ [119606]="on",
+ [119607]="on",
+ [119608]="on",
+ [119609]="on",
+ [119610]="on",
+ [119611]="on",
+ [119612]="on",
+ [119613]="on",
+ [119614]="on",
+ [119615]="on",
+ [119616]="on",
+ [119617]="on",
+ [119618]="on",
+ [119619]="on",
+ [119620]="on",
+ [119621]="on",
+ [119622]="on",
+ [119623]="on",
+ [119624]="on",
+ [119625]="on",
+ [119626]="on",
+ [119627]="on",
+ [119628]="on",
+ [119629]="on",
+ [119630]="on",
+ [119631]="on",
+ [119632]="on",
+ [119633]="on",
+ [119634]="on",
+ [119635]="on",
+ [119636]="on",
+ [119637]="on",
+ [119638]="on",
+ [120539]="on",
+ [120597]="on",
+ [120655]="on",
+ [120713]="on",
+ [120771]="on",
+ [120782]="en",
+ [120783]="en",
+ [120784]="en",
+ [120785]="en",
+ [120786]="en",
+ [120787]="en",
+ [120788]="en",
+ [120789]="en",
+ [120790]="en",
+ [120791]="en",
+ [120792]="en",
+ [120793]="en",
+ [120794]="en",
+ [120795]="en",
+ [120796]="en",
+ [120797]="en",
+ [120798]="en",
+ [120799]="en",
+ [120800]="en",
+ [120801]="en",
+ [120802]="en",
+ [120803]="en",
+ [120804]="en",
+ [120805]="en",
+ [120806]="en",
+ [120807]="en",
+ [120808]="en",
+ [120809]="en",
+ [120810]="en",
+ [120811]="en",
+ [120812]="en",
+ [120813]="en",
+ [120814]="en",
+ [120815]="en",
+ [120816]="en",
+ [120817]="en",
+ [120818]="en",
+ [120819]="en",
+ [120820]="en",
+ [120821]="en",
+ [120822]="en",
+ [120823]="en",
+ [120824]="en",
+ [120825]="en",
+ [120826]="en",
+ [120827]="en",
+ [120828]="en",
+ [120829]="en",
+ [120830]="en",
+ [120831]="en",
+ [121344]="nsm",
+ [121345]="nsm",
+ [121346]="nsm",
+ [121347]="nsm",
+ [121348]="nsm",
+ [121349]="nsm",
+ [121350]="nsm",
+ [121351]="nsm",
+ [121352]="nsm",
+ [121353]="nsm",
+ [121354]="nsm",
+ [121355]="nsm",
+ [121356]="nsm",
+ [121357]="nsm",
+ [121358]="nsm",
+ [121359]="nsm",
+ [121360]="nsm",
+ [121361]="nsm",
+ [121362]="nsm",
+ [121363]="nsm",
+ [121364]="nsm",
+ [121365]="nsm",
+ [121366]="nsm",
+ [121367]="nsm",
+ [121368]="nsm",
+ [121369]="nsm",
+ [121370]="nsm",
+ [121371]="nsm",
+ [121372]="nsm",
+ [121373]="nsm",
+ [121374]="nsm",
+ [121375]="nsm",
+ [121376]="nsm",
+ [121377]="nsm",
+ [121378]="nsm",
+ [121379]="nsm",
+ [121380]="nsm",
+ [121381]="nsm",
+ [121382]="nsm",
+ [121383]="nsm",
+ [121384]="nsm",
+ [121385]="nsm",
+ [121386]="nsm",
+ [121387]="nsm",
+ [121388]="nsm",
+ [121389]="nsm",
+ [121390]="nsm",
+ [121391]="nsm",
+ [121392]="nsm",
+ [121393]="nsm",
+ [121394]="nsm",
+ [121395]="nsm",
+ [121396]="nsm",
+ [121397]="nsm",
+ [121398]="nsm",
+ [121403]="nsm",
+ [121404]="nsm",
+ [121405]="nsm",
+ [121406]="nsm",
+ [121407]="nsm",
+ [121408]="nsm",
+ [121409]="nsm",
+ [121410]="nsm",
+ [121411]="nsm",
+ [121412]="nsm",
+ [121413]="nsm",
+ [121414]="nsm",
+ [121415]="nsm",
+ [121416]="nsm",
+ [121417]="nsm",
+ [121418]="nsm",
+ [121419]="nsm",
+ [121420]="nsm",
+ [121421]="nsm",
+ [121422]="nsm",
+ [121423]="nsm",
+ [121424]="nsm",
+ [121425]="nsm",
+ [121426]="nsm",
+ [121427]="nsm",
+ [121428]="nsm",
+ [121429]="nsm",
+ [121430]="nsm",
+ [121431]="nsm",
+ [121432]="nsm",
+ [121433]="nsm",
+ [121434]="nsm",
+ [121435]="nsm",
+ [121436]="nsm",
+ [121437]="nsm",
+ [121438]="nsm",
+ [121439]="nsm",
+ [121440]="nsm",
+ [121441]="nsm",
+ [121442]="nsm",
+ [121443]="nsm",
+ [121444]="nsm",
+ [121445]="nsm",
+ [121446]="nsm",
+ [121447]="nsm",
+ [121448]="nsm",
+ [121449]="nsm",
+ [121450]="nsm",
+ [121451]="nsm",
+ [121452]="nsm",
+ [121461]="nsm",
+ [121476]="nsm",
+ [121499]="nsm",
+ [121500]="nsm",
+ [121501]="nsm",
+ [121502]="nsm",
+ [121503]="nsm",
+ [121505]="nsm",
+ [121506]="nsm",
+ [121507]="nsm",
+ [121508]="nsm",
+ [121509]="nsm",
+ [121510]="nsm",
+ [121511]="nsm",
+ [121512]="nsm",
+ [121513]="nsm",
+ [121514]="nsm",
+ [121515]="nsm",
+ [121516]="nsm",
+ [121517]="nsm",
+ [121518]="nsm",
+ [121519]="nsm",
+ [122880]="nsm",
+ [122881]="nsm",
+ [122882]="nsm",
+ [122883]="nsm",
+ [122884]="nsm",
+ [122885]="nsm",
+ [122886]="nsm",
+ [122888]="nsm",
+ [122889]="nsm",
+ [122890]="nsm",
+ [122891]="nsm",
+ [122892]="nsm",
+ [122893]="nsm",
+ [122894]="nsm",
+ [122895]="nsm",
+ [122896]="nsm",
+ [122897]="nsm",
+ [122898]="nsm",
+ [122899]="nsm",
+ [122900]="nsm",
+ [122901]="nsm",
+ [122902]="nsm",
+ [122903]="nsm",
+ [122904]="nsm",
+ [122907]="nsm",
+ [122908]="nsm",
+ [122909]="nsm",
+ [122910]="nsm",
+ [122911]="nsm",
+ [122912]="nsm",
+ [122913]="nsm",
+ [122915]="nsm",
+ [122916]="nsm",
+ [122918]="nsm",
+ [122919]="nsm",
+ [122920]="nsm",
+ [122921]="nsm",
+ [122922]="nsm",
+ [124928]="r",
+ [124929]="r",
+ [124930]="r",
+ [124931]="r",
+ [124932]="r",
+ [124933]="r",
+ [124934]="r",
+ [124935]="r",
+ [124936]="r",
+ [124937]="r",
+ [124938]="r",
+ [124939]="r",
+ [124940]="r",
+ [124941]="r",
+ [124942]="r",
+ [124943]="r",
+ [124944]="r",
+ [124945]="r",
+ [124946]="r",
+ [124947]="r",
+ [124948]="r",
+ [124949]="r",
+ [124950]="r",
+ [124951]="r",
+ [124952]="r",
+ [124953]="r",
+ [124954]="r",
+ [124955]="r",
+ [124956]="r",
+ [124957]="r",
+ [124958]="r",
+ [124959]="r",
+ [124960]="r",
+ [124961]="r",
+ [124962]="r",
+ [124963]="r",
+ [124964]="r",
+ [124965]="r",
+ [124966]="r",
+ [124967]="r",
+ [124968]="r",
+ [124969]="r",
+ [124970]="r",
+ [124971]="r",
+ [124972]="r",
+ [124973]="r",
+ [124974]="r",
+ [124975]="r",
+ [124976]="r",
+ [124977]="r",
+ [124978]="r",
+ [124979]="r",
+ [124980]="r",
+ [124981]="r",
+ [124982]="r",
+ [124983]="r",
+ [124984]="r",
+ [124985]="r",
+ [124986]="r",
+ [124987]="r",
+ [124988]="r",
+ [124989]="r",
+ [124990]="r",
+ [124991]="r",
+ [124992]="r",
+ [124993]="r",
+ [124994]="r",
+ [124995]="r",
+ [124996]="r",
+ [124997]="r",
+ [124998]="r",
+ [124999]="r",
+ [125000]="r",
+ [125001]="r",
+ [125002]="r",
+ [125003]="r",
+ [125004]="r",
+ [125005]="r",
+ [125006]="r",
+ [125007]="r",
+ [125008]="r",
+ [125009]="r",
+ [125010]="r",
+ [125011]="r",
+ [125012]="r",
+ [125013]="r",
+ [125014]="r",
+ [125015]="r",
+ [125016]="r",
+ [125017]="r",
+ [125018]="r",
+ [125019]="r",
+ [125020]="r",
+ [125021]="r",
+ [125022]="r",
+ [125023]="r",
+ [125024]="r",
+ [125025]="r",
+ [125026]="r",
+ [125027]="r",
+ [125028]="r",
+ [125029]="r",
+ [125030]="r",
+ [125031]="r",
+ [125032]="r",
+ [125033]="r",
+ [125034]="r",
+ [125035]="r",
+ [125036]="r",
+ [125037]="r",
+ [125038]="r",
+ [125039]="r",
+ [125040]="r",
+ [125041]="r",
+ [125042]="r",
+ [125043]="r",
+ [125044]="r",
+ [125045]="r",
+ [125046]="r",
+ [125047]="r",
+ [125048]="r",
+ [125049]="r",
+ [125050]="r",
+ [125051]="r",
+ [125052]="r",
+ [125053]="r",
+ [125054]="r",
+ [125055]="r",
+ [125056]="r",
+ [125057]="r",
+ [125058]="r",
+ [125059]="r",
+ [125060]="r",
+ [125061]="r",
+ [125062]="r",
+ [125063]="r",
+ [125064]="r",
+ [125065]="r",
+ [125066]="r",
+ [125067]="r",
+ [125068]="r",
+ [125069]="r",
+ [125070]="r",
+ [125071]="r",
+ [125072]="r",
+ [125073]="r",
+ [125074]="r",
+ [125075]="r",
+ [125076]="r",
+ [125077]="r",
+ [125078]="r",
+ [125079]="r",
+ [125080]="r",
+ [125081]="r",
+ [125082]="r",
+ [125083]="r",
+ [125084]="r",
+ [125085]="r",
+ [125086]="r",
+ [125087]="r",
+ [125088]="r",
+ [125089]="r",
+ [125090]="r",
+ [125091]="r",
+ [125092]="r",
+ [125093]="r",
+ [125094]="r",
+ [125095]="r",
+ [125096]="r",
+ [125097]="r",
+ [125098]="r",
+ [125099]="r",
+ [125100]="r",
+ [125101]="r",
+ [125102]="r",
+ [125103]="r",
+ [125104]="r",
+ [125105]="r",
+ [125106]="r",
+ [125107]="r",
+ [125108]="r",
+ [125109]="r",
+ [125110]="r",
+ [125111]="r",
+ [125112]="r",
+ [125113]="r",
+ [125114]="r",
+ [125115]="r",
+ [125116]="r",
+ [125117]="r",
+ [125118]="r",
+ [125119]="r",
+ [125120]="r",
+ [125121]="r",
+ [125122]="r",
+ [125123]="r",
+ [125124]="r",
+ [125127]="r",
+ [125128]="r",
+ [125129]="r",
+ [125130]="r",
+ [125131]="r",
+ [125132]="r",
+ [125133]="r",
+ [125134]="r",
+ [125135]="r",
+ [125136]="nsm",
+ [125137]="nsm",
+ [125138]="nsm",
+ [125139]="nsm",
+ [125140]="nsm",
+ [125141]="nsm",
+ [125142]="nsm",
+ [125184]="r",
+ [125185]="r",
+ [125186]="r",
+ [125187]="r",
+ [125188]="r",
+ [125189]="r",
+ [125190]="r",
+ [125191]="r",
+ [125192]="r",
+ [125193]="r",
+ [125194]="r",
+ [125195]="r",
+ [125196]="r",
+ [125197]="r",
+ [125198]="r",
+ [125199]="r",
+ [125200]="r",
+ [125201]="r",
+ [125202]="r",
+ [125203]="r",
+ [125204]="r",
+ [125205]="r",
+ [125206]="r",
+ [125207]="r",
+ [125208]="r",
+ [125209]="r",
+ [125210]="r",
+ [125211]="r",
+ [125212]="r",
+ [125213]="r",
+ [125214]="r",
+ [125215]="r",
+ [125216]="r",
+ [125217]="r",
+ [125218]="r",
+ [125219]="r",
+ [125220]="r",
+ [125221]="r",
+ [125222]="r",
+ [125223]="r",
+ [125224]="r",
+ [125225]="r",
+ [125226]="r",
+ [125227]="r",
+ [125228]="r",
+ [125229]="r",
+ [125230]="r",
+ [125231]="r",
+ [125232]="r",
+ [125233]="r",
+ [125234]="r",
+ [125235]="r",
+ [125236]="r",
+ [125237]="r",
+ [125238]="r",
+ [125239]="r",
+ [125240]="r",
+ [125241]="r",
+ [125242]="r",
+ [125243]="r",
+ [125244]="r",
+ [125245]="r",
+ [125246]="r",
+ [125247]="r",
+ [125248]="r",
+ [125249]="r",
+ [125250]="r",
+ [125251]="r",
+ [125252]="nsm",
+ [125253]="nsm",
+ [125254]="nsm",
+ [125255]="nsm",
+ [125256]="nsm",
+ [125257]="nsm",
+ [125258]="nsm",
+ [125264]="r",
+ [125265]="r",
+ [125266]="r",
+ [125267]="r",
+ [125268]="r",
+ [125269]="r",
+ [125270]="r",
+ [125271]="r",
+ [125272]="r",
+ [125273]="r",
+ [125278]="r",
+ [125279]="r",
+ [126464]="al",
+ [126465]="al",
+ [126466]="al",
+ [126467]="al",
+ [126469]="al",
+ [126470]="al",
+ [126471]="al",
+ [126472]="al",
+ [126473]="al",
+ [126474]="al",
+ [126475]="al",
+ [126476]="al",
+ [126477]="al",
+ [126478]="al",
+ [126479]="al",
+ [126480]="al",
+ [126481]="al",
+ [126482]="al",
+ [126483]="al",
+ [126484]="al",
+ [126485]="al",
+ [126486]="al",
+ [126487]="al",
+ [126488]="al",
+ [126489]="al",
+ [126490]="al",
+ [126491]="al",
+ [126492]="al",
+ [126493]="al",
+ [126494]="al",
+ [126495]="al",
+ [126497]="al",
+ [126498]="al",
+ [126500]="al",
+ [126503]="al",
+ [126505]="al",
+ [126506]="al",
+ [126507]="al",
+ [126508]="al",
+ [126509]="al",
+ [126510]="al",
+ [126511]="al",
+ [126512]="al",
+ [126513]="al",
+ [126514]="al",
+ [126516]="al",
+ [126517]="al",
+ [126518]="al",
+ [126519]="al",
+ [126521]="al",
+ [126523]="al",
+ [126530]="al",
+ [126535]="al",
+ [126537]="al",
+ [126539]="al",
+ [126541]="al",
+ [126542]="al",
+ [126543]="al",
+ [126545]="al",
+ [126546]="al",
+ [126548]="al",
+ [126551]="al",
+ [126553]="al",
+ [126555]="al",
+ [126557]="al",
+ [126559]="al",
+ [126561]="al",
+ [126562]="al",
+ [126564]="al",
+ [126567]="al",
+ [126568]="al",
+ [126569]="al",
+ [126570]="al",
+ [126572]="al",
+ [126573]="al",
+ [126574]="al",
+ [126575]="al",
+ [126576]="al",
+ [126577]="al",
+ [126578]="al",
+ [126580]="al",
+ [126581]="al",
+ [126582]="al",
+ [126583]="al",
+ [126585]="al",
+ [126586]="al",
+ [126587]="al",
+ [126588]="al",
+ [126590]="al",
+ [126592]="al",
+ [126593]="al",
+ [126594]="al",
+ [126595]="al",
+ [126596]="al",
+ [126597]="al",
+ [126598]="al",
+ [126599]="al",
+ [126600]="al",
+ [126601]="al",
+ [126603]="al",
+ [126604]="al",
+ [126605]="al",
+ [126606]="al",
+ [126607]="al",
+ [126608]="al",
+ [126609]="al",
+ [126610]="al",
+ [126611]="al",
+ [126612]="al",
+ [126613]="al",
+ [126614]="al",
+ [126615]="al",
+ [126616]="al",
+ [126617]="al",
+ [126618]="al",
+ [126619]="al",
+ [126625]="al",
+ [126626]="al",
+ [126627]="al",
+ [126629]="al",
+ [126630]="al",
+ [126631]="al",
+ [126632]="al",
+ [126633]="al",
+ [126635]="al",
+ [126636]="al",
+ [126637]="al",
+ [126638]="al",
+ [126639]="al",
+ [126640]="al",
+ [126641]="al",
+ [126642]="al",
+ [126643]="al",
+ [126644]="al",
+ [126645]="al",
+ [126646]="al",
+ [126647]="al",
+ [126648]="al",
+ [126649]="al",
+ [126650]="al",
+ [126651]="al",
+ [126704]="on",
+ [126705]="on",
+ [126976]="on",
+ [126977]="on",
+ [126978]="on",
+ [126979]="on",
+ [126980]="on",
+ [126981]="on",
+ [126982]="on",
+ [126983]="on",
+ [126984]="on",
+ [126985]="on",
+ [126986]="on",
+ [126987]="on",
+ [126988]="on",
+ [126989]="on",
+ [126990]="on",
+ [126991]="on",
+ [126992]="on",
+ [126993]="on",
+ [126994]="on",
+ [126995]="on",
+ [126996]="on",
+ [126997]="on",
+ [126998]="on",
+ [126999]="on",
+ [127000]="on",
+ [127001]="on",
+ [127002]="on",
+ [127003]="on",
+ [127004]="on",
+ [127005]="on",
+ [127006]="on",
+ [127007]="on",
+ [127008]="on",
+ [127009]="on",
+ [127010]="on",
+ [127011]="on",
+ [127012]="on",
+ [127013]="on",
+ [127014]="on",
+ [127015]="on",
+ [127016]="on",
+ [127017]="on",
+ [127018]="on",
+ [127019]="on",
+ [127024]="on",
+ [127025]="on",
+ [127026]="on",
+ [127027]="on",
+ [127028]="on",
+ [127029]="on",
+ [127030]="on",
+ [127031]="on",
+ [127032]="on",
+ [127033]="on",
+ [127034]="on",
+ [127035]="on",
+ [127036]="on",
+ [127037]="on",
+ [127038]="on",
+ [127039]="on",
+ [127040]="on",
+ [127041]="on",
+ [127042]="on",
+ [127043]="on",
+ [127044]="on",
+ [127045]="on",
+ [127046]="on",
+ [127047]="on",
+ [127048]="on",
+ [127049]="on",
+ [127050]="on",
+ [127051]="on",
+ [127052]="on",
+ [127053]="on",
+ [127054]="on",
+ [127055]="on",
+ [127056]="on",
+ [127057]="on",
+ [127058]="on",
+ [127059]="on",
+ [127060]="on",
+ [127061]="on",
+ [127062]="on",
+ [127063]="on",
+ [127064]="on",
+ [127065]="on",
+ [127066]="on",
+ [127067]="on",
+ [127068]="on",
+ [127069]="on",
+ [127070]="on",
+ [127071]="on",
+ [127072]="on",
+ [127073]="on",
+ [127074]="on",
+ [127075]="on",
+ [127076]="on",
+ [127077]="on",
+ [127078]="on",
+ [127079]="on",
+ [127080]="on",
+ [127081]="on",
+ [127082]="on",
+ [127083]="on",
+ [127084]="on",
+ [127085]="on",
+ [127086]="on",
+ [127087]="on",
+ [127088]="on",
+ [127089]="on",
+ [127090]="on",
+ [127091]="on",
+ [127092]="on",
+ [127093]="on",
+ [127094]="on",
+ [127095]="on",
+ [127096]="on",
+ [127097]="on",
+ [127098]="on",
+ [127099]="on",
+ [127100]="on",
+ [127101]="on",
+ [127102]="on",
+ [127103]="on",
+ [127104]="on",
+ [127105]="on",
+ [127106]="on",
+ [127107]="on",
+ [127108]="on",
+ [127109]="on",
+ [127110]="on",
+ [127111]="on",
+ [127112]="on",
+ [127113]="on",
+ [127114]="on",
+ [127115]="on",
+ [127116]="on",
+ [127117]="on",
+ [127118]="on",
+ [127119]="on",
+ [127120]="on",
+ [127121]="on",
+ [127122]="on",
+ [127123]="on",
+ [127136]="on",
+ [127137]="on",
+ [127138]="on",
+ [127139]="on",
+ [127140]="on",
+ [127141]="on",
+ [127142]="on",
+ [127143]="on",
+ [127144]="on",
+ [127145]="on",
+ [127146]="on",
+ [127147]="on",
+ [127148]="on",
+ [127149]="on",
+ [127150]="on",
+ [127153]="on",
+ [127154]="on",
+ [127155]="on",
+ [127156]="on",
+ [127157]="on",
+ [127158]="on",
+ [127159]="on",
+ [127160]="on",
+ [127161]="on",
+ [127162]="on",
+ [127163]="on",
+ [127164]="on",
+ [127165]="on",
+ [127166]="on",
+ [127167]="on",
+ [127169]="on",
+ [127170]="on",
+ [127171]="on",
+ [127172]="on",
+ [127173]="on",
+ [127174]="on",
+ [127175]="on",
+ [127176]="on",
+ [127177]="on",
+ [127178]="on",
+ [127179]="on",
+ [127180]="on",
+ [127181]="on",
+ [127182]="on",
+ [127183]="on",
+ [127185]="on",
+ [127186]="on",
+ [127187]="on",
+ [127188]="on",
+ [127189]="on",
+ [127190]="on",
+ [127191]="on",
+ [127192]="on",
+ [127193]="on",
+ [127194]="on",
+ [127195]="on",
+ [127196]="on",
+ [127197]="on",
+ [127198]="on",
+ [127199]="on",
+ [127200]="on",
+ [127201]="on",
+ [127202]="on",
+ [127203]="on",
+ [127204]="on",
+ [127205]="on",
+ [127206]="on",
+ [127207]="on",
+ [127208]="on",
+ [127209]="on",
+ [127210]="on",
+ [127211]="on",
+ [127212]="on",
+ [127213]="on",
+ [127214]="on",
+ [127215]="on",
+ [127216]="on",
+ [127217]="on",
+ [127218]="on",
+ [127219]="on",
+ [127220]="on",
+ [127221]="on",
+ [127232]="en",
+ [127233]="en",
+ [127234]="en",
+ [127235]="en",
+ [127236]="en",
+ [127237]="en",
+ [127238]="en",
+ [127239]="en",
+ [127240]="en",
+ [127241]="en",
+ [127242]="en",
+ [127243]="on",
+ [127244]="on",
+ [127338]="on",
+ [127339]="on",
+ [127584]="on",
+ [127585]="on",
+ [127586]="on",
+ [127587]="on",
+ [127588]="on",
+ [127589]="on",
+ [127744]="on",
+ [127745]="on",
+ [127746]="on",
+ [127747]="on",
+ [127748]="on",
+ [127749]="on",
+ [127750]="on",
+ [127751]="on",
+ [127752]="on",
+ [127753]="on",
+ [127754]="on",
+ [127755]="on",
+ [127756]="on",
+ [127757]="on",
+ [127758]="on",
+ [127759]="on",
+ [127760]="on",
+ [127761]="on",
+ [127762]="on",
+ [127763]="on",
+ [127764]="on",
+ [127765]="on",
+ [127766]="on",
+ [127767]="on",
+ [127768]="on",
+ [127769]="on",
+ [127770]="on",
+ [127771]="on",
+ [127772]="on",
+ [127773]="on",
+ [127774]="on",
+ [127775]="on",
+ [127776]="on",
+ [127777]="on",
+ [127778]="on",
+ [127779]="on",
+ [127780]="on",
+ [127781]="on",
+ [127782]="on",
+ [127783]="on",
+ [127784]="on",
+ [127785]="on",
+ [127786]="on",
+ [127787]="on",
+ [127788]="on",
+ [127789]="on",
+ [127790]="on",
+ [127791]="on",
+ [127792]="on",
+ [127793]="on",
+ [127794]="on",
+ [127795]="on",
+ [127796]="on",
+ [127797]="on",
+ [127798]="on",
+ [127799]="on",
+ [127800]="on",
+ [127801]="on",
+ [127802]="on",
+ [127803]="on",
+ [127804]="on",
+ [127805]="on",
+ [127806]="on",
+ [127807]="on",
+ [127808]="on",
+ [127809]="on",
+ [127810]="on",
+ [127811]="on",
+ [127812]="on",
+ [127813]="on",
+ [127814]="on",
+ [127815]="on",
+ [127816]="on",
+ [127817]="on",
+ [127818]="on",
+ [127819]="on",
+ [127820]="on",
+ [127821]="on",
+ [127822]="on",
+ [127823]="on",
+ [127824]="on",
+ [127825]="on",
+ [127826]="on",
+ [127827]="on",
+ [127828]="on",
+ [127829]="on",
+ [127830]="on",
+ [127831]="on",
+ [127832]="on",
+ [127833]="on",
+ [127834]="on",
+ [127835]="on",
+ [127836]="on",
+ [127837]="on",
+ [127838]="on",
+ [127839]="on",
+ [127840]="on",
+ [127841]="on",
+ [127842]="on",
+ [127843]="on",
+ [127844]="on",
+ [127845]="on",
+ [127846]="on",
+ [127847]="on",
+ [127848]="on",
+ [127849]="on",
+ [127850]="on",
+ [127851]="on",
+ [127852]="on",
+ [127853]="on",
+ [127854]="on",
+ [127855]="on",
+ [127856]="on",
+ [127857]="on",
+ [127858]="on",
+ [127859]="on",
+ [127860]="on",
+ [127861]="on",
+ [127862]="on",
+ [127863]="on",
+ [127864]="on",
+ [127865]="on",
+ [127866]="on",
+ [127867]="on",
+ [127868]="on",
+ [127869]="on",
+ [127870]="on",
+ [127871]="on",
+ [127872]="on",
+ [127873]="on",
+ [127874]="on",
+ [127875]="on",
+ [127876]="on",
+ [127877]="on",
+ [127878]="on",
+ [127879]="on",
+ [127880]="on",
+ [127881]="on",
+ [127882]="on",
+ [127883]="on",
+ [127884]="on",
+ [127885]="on",
+ [127886]="on",
+ [127887]="on",
+ [127888]="on",
+ [127889]="on",
+ [127890]="on",
+ [127891]="on",
+ [127892]="on",
+ [127893]="on",
+ [127894]="on",
+ [127895]="on",
+ [127896]="on",
+ [127897]="on",
+ [127898]="on",
+ [127899]="on",
+ [127900]="on",
+ [127901]="on",
+ [127902]="on",
+ [127903]="on",
+ [127904]="on",
+ [127905]="on",
+ [127906]="on",
+ [127907]="on",
+ [127908]="on",
+ [127909]="on",
+ [127910]="on",
+ [127911]="on",
+ [127912]="on",
+ [127913]="on",
+ [127914]="on",
+ [127915]="on",
+ [127916]="on",
+ [127917]="on",
+ [127918]="on",
+ [127919]="on",
+ [127920]="on",
+ [127921]="on",
+ [127922]="on",
+ [127923]="on",
+ [127924]="on",
+ [127925]="on",
+ [127926]="on",
+ [127927]="on",
+ [127928]="on",
+ [127929]="on",
+ [127930]="on",
+ [127931]="on",
+ [127932]="on",
+ [127933]="on",
+ [127934]="on",
+ [127935]="on",
+ [127936]="on",
+ [127937]="on",
+ [127938]="on",
+ [127939]="on",
+ [127940]="on",
+ [127941]="on",
+ [127942]="on",
+ [127943]="on",
+ [127944]="on",
+ [127945]="on",
+ [127946]="on",
+ [127947]="on",
+ [127948]="on",
+ [127949]="on",
+ [127950]="on",
+ [127951]="on",
+ [127952]="on",
+ [127953]="on",
+ [127954]="on",
+ [127955]="on",
+ [127956]="on",
+ [127957]="on",
+ [127958]="on",
+ [127959]="on",
+ [127960]="on",
+ [127961]="on",
+ [127962]="on",
+ [127963]="on",
+ [127964]="on",
+ [127965]="on",
+ [127966]="on",
+ [127967]="on",
+ [127968]="on",
+ [127969]="on",
+ [127970]="on",
+ [127971]="on",
+ [127972]="on",
+ [127973]="on",
+ [127974]="on",
+ [127975]="on",
+ [127976]="on",
+ [127977]="on",
+ [127978]="on",
+ [127979]="on",
+ [127980]="on",
+ [127981]="on",
+ [127982]="on",
+ [127983]="on",
+ [127984]="on",
+ [127985]="on",
+ [127986]="on",
+ [127987]="on",
+ [127988]="on",
+ [127989]="on",
+ [127990]="on",
+ [127991]="on",
+ [127992]="on",
+ [127993]="on",
+ [127994]="on",
+ [127995]="on",
+ [127996]="on",
+ [127997]="on",
+ [127998]="on",
+ [127999]="on",
+ [128000]="on",
+ [128001]="on",
+ [128002]="on",
+ [128003]="on",
+ [128004]="on",
+ [128005]="on",
+ [128006]="on",
+ [128007]="on",
+ [128008]="on",
+ [128009]="on",
+ [128010]="on",
+ [128011]="on",
+ [128012]="on",
+ [128013]="on",
+ [128014]="on",
+ [128015]="on",
+ [128016]="on",
+ [128017]="on",
+ [128018]="on",
+ [128019]="on",
+ [128020]="on",
+ [128021]="on",
+ [128022]="on",
+ [128023]="on",
+ [128024]="on",
+ [128025]="on",
+ [128026]="on",
+ [128027]="on",
+ [128028]="on",
+ [128029]="on",
+ [128030]="on",
+ [128031]="on",
+ [128032]="on",
+ [128033]="on",
+ [128034]="on",
+ [128035]="on",
+ [128036]="on",
+ [128037]="on",
+ [128038]="on",
+ [128039]="on",
+ [128040]="on",
+ [128041]="on",
+ [128042]="on",
+ [128043]="on",
+ [128044]="on",
+ [128045]="on",
+ [128046]="on",
+ [128047]="on",
+ [128048]="on",
+ [128049]="on",
+ [128050]="on",
+ [128051]="on",
+ [128052]="on",
+ [128053]="on",
+ [128054]="on",
+ [128055]="on",
+ [128056]="on",
+ [128057]="on",
+ [128058]="on",
+ [128059]="on",
+ [128060]="on",
+ [128061]="on",
+ [128062]="on",
+ [128063]="on",
+ [128064]="on",
+ [128065]="on",
+ [128066]="on",
+ [128067]="on",
+ [128068]="on",
+ [128069]="on",
+ [128070]="on",
+ [128071]="on",
+ [128072]="on",
+ [128073]="on",
+ [128074]="on",
+ [128075]="on",
+ [128076]="on",
+ [128077]="on",
+ [128078]="on",
+ [128079]="on",
+ [128080]="on",
+ [128081]="on",
+ [128082]="on",
+ [128083]="on",
+ [128084]="on",
+ [128085]="on",
+ [128086]="on",
+ [128087]="on",
+ [128088]="on",
+ [128089]="on",
+ [128090]="on",
+ [128091]="on",
+ [128092]="on",
+ [128093]="on",
+ [128094]="on",
+ [128095]="on",
+ [128096]="on",
+ [128097]="on",
+ [128098]="on",
+ [128099]="on",
+ [128100]="on",
+ [128101]="on",
+ [128102]="on",
+ [128103]="on",
+ [128104]="on",
+ [128105]="on",
+ [128106]="on",
+ [128107]="on",
+ [128108]="on",
+ [128109]="on",
+ [128110]="on",
+ [128111]="on",
+ [128112]="on",
+ [128113]="on",
+ [128114]="on",
+ [128115]="on",
+ [128116]="on",
+ [128117]="on",
+ [128118]="on",
+ [128119]="on",
+ [128120]="on",
+ [128121]="on",
+ [128122]="on",
+ [128123]="on",
+ [128124]="on",
+ [128125]="on",
+ [128126]="on",
+ [128127]="on",
+ [128128]="on",
+ [128129]="on",
+ [128130]="on",
+ [128131]="on",
+ [128132]="on",
+ [128133]="on",
+ [128134]="on",
+ [128135]="on",
+ [128136]="on",
+ [128137]="on",
+ [128138]="on",
+ [128139]="on",
+ [128140]="on",
+ [128141]="on",
+ [128142]="on",
+ [128143]="on",
+ [128144]="on",
+ [128145]="on",
+ [128146]="on",
+ [128147]="on",
+ [128148]="on",
+ [128149]="on",
+ [128150]="on",
+ [128151]="on",
+ [128152]="on",
+ [128153]="on",
+ [128154]="on",
+ [128155]="on",
+ [128156]="on",
+ [128157]="on",
+ [128158]="on",
+ [128159]="on",
+ [128160]="on",
+ [128161]="on",
+ [128162]="on",
+ [128163]="on",
+ [128164]="on",
+ [128165]="on",
+ [128166]="on",
+ [128167]="on",
+ [128168]="on",
+ [128169]="on",
+ [128170]="on",
+ [128171]="on",
+ [128172]="on",
+ [128173]="on",
+ [128174]="on",
+ [128175]="on",
+ [128176]="on",
+ [128177]="on",
+ [128178]="on",
+ [128179]="on",
+ [128180]="on",
+ [128181]="on",
+ [128182]="on",
+ [128183]="on",
+ [128184]="on",
+ [128185]="on",
+ [128186]="on",
+ [128187]="on",
+ [128188]="on",
+ [128189]="on",
+ [128190]="on",
+ [128191]="on",
+ [128192]="on",
+ [128193]="on",
+ [128194]="on",
+ [128195]="on",
+ [128196]="on",
+ [128197]="on",
+ [128198]="on",
+ [128199]="on",
+ [128200]="on",
+ [128201]="on",
+ [128202]="on",
+ [128203]="on",
+ [128204]="on",
+ [128205]="on",
+ [128206]="on",
+ [128207]="on",
+ [128208]="on",
+ [128209]="on",
+ [128210]="on",
+ [128211]="on",
+ [128212]="on",
+ [128213]="on",
+ [128214]="on",
+ [128215]="on",
+ [128216]="on",
+ [128217]="on",
+ [128218]="on",
+ [128219]="on",
+ [128220]="on",
+ [128221]="on",
+ [128222]="on",
+ [128223]="on",
+ [128224]="on",
+ [128225]="on",
+ [128226]="on",
+ [128227]="on",
+ [128228]="on",
+ [128229]="on",
+ [128230]="on",
+ [128231]="on",
+ [128232]="on",
+ [128233]="on",
+ [128234]="on",
+ [128235]="on",
+ [128236]="on",
+ [128237]="on",
+ [128238]="on",
+ [128239]="on",
+ [128240]="on",
+ [128241]="on",
+ [128242]="on",
+ [128243]="on",
+ [128244]="on",
+ [128245]="on",
+ [128246]="on",
+ [128247]="on",
+ [128248]="on",
+ [128249]="on",
+ [128250]="on",
+ [128251]="on",
+ [128252]="on",
+ [128253]="on",
+ [128254]="on",
+ [128255]="on",
+ [128256]="on",
+ [128257]="on",
+ [128258]="on",
+ [128259]="on",
+ [128260]="on",
+ [128261]="on",
+ [128262]="on",
+ [128263]="on",
+ [128264]="on",
+ [128265]="on",
+ [128266]="on",
+ [128267]="on",
+ [128268]="on",
+ [128269]="on",
+ [128270]="on",
+ [128271]="on",
+ [128272]="on",
+ [128273]="on",
+ [128274]="on",
+ [128275]="on",
+ [128276]="on",
+ [128277]="on",
+ [128278]="on",
+ [128279]="on",
+ [128280]="on",
+ [128281]="on",
+ [128282]="on",
+ [128283]="on",
+ [128284]="on",
+ [128285]="on",
+ [128286]="on",
+ [128287]="on",
+ [128288]="on",
+ [128289]="on",
+ [128290]="on",
+ [128291]="on",
+ [128292]="on",
+ [128293]="on",
+ [128294]="on",
+ [128295]="on",
+ [128296]="on",
+ [128297]="on",
+ [128298]="on",
+ [128299]="on",
+ [128300]="on",
+ [128301]="on",
+ [128302]="on",
+ [128303]="on",
+ [128304]="on",
+ [128305]="on",
+ [128306]="on",
+ [128307]="on",
+ [128308]="on",
+ [128309]="on",
+ [128310]="on",
+ [128311]="on",
+ [128312]="on",
+ [128313]="on",
+ [128314]="on",
+ [128315]="on",
+ [128316]="on",
+ [128317]="on",
+ [128318]="on",
+ [128319]="on",
+ [128320]="on",
+ [128321]="on",
+ [128322]="on",
+ [128323]="on",
+ [128324]="on",
+ [128325]="on",
+ [128326]="on",
+ [128327]="on",
+ [128328]="on",
+ [128329]="on",
+ [128330]="on",
+ [128331]="on",
+ [128332]="on",
+ [128333]="on",
+ [128334]="on",
+ [128335]="on",
+ [128336]="on",
+ [128337]="on",
+ [128338]="on",
+ [128339]="on",
+ [128340]="on",
+ [128341]="on",
+ [128342]="on",
+ [128343]="on",
+ [128344]="on",
+ [128345]="on",
+ [128346]="on",
+ [128347]="on",
+ [128348]="on",
+ [128349]="on",
+ [128350]="on",
+ [128351]="on",
+ [128352]="on",
+ [128353]="on",
+ [128354]="on",
+ [128355]="on",
+ [128356]="on",
+ [128357]="on",
+ [128358]="on",
+ [128359]="on",
+ [128360]="on",
+ [128361]="on",
+ [128362]="on",
+ [128363]="on",
+ [128364]="on",
+ [128365]="on",
+ [128366]="on",
+ [128367]="on",
+ [128368]="on",
+ [128369]="on",
+ [128370]="on",
+ [128371]="on",
+ [128372]="on",
+ [128373]="on",
+ [128374]="on",
+ [128375]="on",
+ [128376]="on",
+ [128377]="on",
+ [128378]="on",
+ [128379]="on",
+ [128380]="on",
+ [128381]="on",
+ [128382]="on",
+ [128383]="on",
+ [128384]="on",
+ [128385]="on",
+ [128386]="on",
+ [128387]="on",
+ [128388]="on",
+ [128389]="on",
+ [128390]="on",
+ [128391]="on",
+ [128392]="on",
+ [128393]="on",
+ [128394]="on",
+ [128395]="on",
+ [128396]="on",
+ [128397]="on",
+ [128398]="on",
+ [128399]="on",
+ [128400]="on",
+ [128401]="on",
+ [128402]="on",
+ [128403]="on",
+ [128404]="on",
+ [128405]="on",
+ [128406]="on",
+ [128407]="on",
+ [128408]="on",
+ [128409]="on",
+ [128410]="on",
+ [128411]="on",
+ [128412]="on",
+ [128413]="on",
+ [128414]="on",
+ [128415]="on",
+ [128416]="on",
+ [128417]="on",
+ [128418]="on",
+ [128419]="on",
+ [128420]="on",
+ [128421]="on",
+ [128422]="on",
+ [128423]="on",
+ [128424]="on",
+ [128425]="on",
+ [128426]="on",
+ [128427]="on",
+ [128428]="on",
+ [128429]="on",
+ [128430]="on",
+ [128431]="on",
+ [128432]="on",
+ [128433]="on",
+ [128434]="on",
+ [128435]="on",
+ [128436]="on",
+ [128437]="on",
+ [128438]="on",
+ [128439]="on",
+ [128440]="on",
+ [128441]="on",
+ [128442]="on",
+ [128443]="on",
+ [128444]="on",
+ [128445]="on",
+ [128446]="on",
+ [128447]="on",
+ [128448]="on",
+ [128449]="on",
+ [128450]="on",
+ [128451]="on",
+ [128452]="on",
+ [128453]="on",
+ [128454]="on",
+ [128455]="on",
+ [128456]="on",
+ [128457]="on",
+ [128458]="on",
+ [128459]="on",
+ [128460]="on",
+ [128461]="on",
+ [128462]="on",
+ [128463]="on",
+ [128464]="on",
+ [128465]="on",
+ [128466]="on",
+ [128467]="on",
+ [128468]="on",
+ [128469]="on",
+ [128470]="on",
+ [128471]="on",
+ [128472]="on",
+ [128473]="on",
+ [128474]="on",
+ [128475]="on",
+ [128476]="on",
+ [128477]="on",
+ [128478]="on",
+ [128479]="on",
+ [128480]="on",
+ [128481]="on",
+ [128482]="on",
+ [128483]="on",
+ [128484]="on",
+ [128485]="on",
+ [128486]="on",
+ [128487]="on",
+ [128488]="on",
+ [128489]="on",
+ [128490]="on",
+ [128491]="on",
+ [128492]="on",
+ [128493]="on",
+ [128494]="on",
+ [128495]="on",
+ [128496]="on",
+ [128497]="on",
+ [128498]="on",
+ [128499]="on",
+ [128500]="on",
+ [128501]="on",
+ [128502]="on",
+ [128503]="on",
+ [128504]="on",
+ [128505]="on",
+ [128506]="on",
+ [128507]="on",
+ [128508]="on",
+ [128509]="on",
+ [128510]="on",
+ [128511]="on",
+ [128512]="on",
+ [128513]="on",
+ [128514]="on",
+ [128515]="on",
+ [128516]="on",
+ [128517]="on",
+ [128518]="on",
+ [128519]="on",
+ [128520]="on",
+ [128521]="on",
+ [128522]="on",
+ [128523]="on",
+ [128524]="on",
+ [128525]="on",
+ [128526]="on",
+ [128527]="on",
+ [128528]="on",
+ [128529]="on",
+ [128530]="on",
+ [128531]="on",
+ [128532]="on",
+ [128533]="on",
+ [128534]="on",
+ [128535]="on",
+ [128536]="on",
+ [128537]="on",
+ [128538]="on",
+ [128539]="on",
+ [128540]="on",
+ [128541]="on",
+ [128542]="on",
+ [128543]="on",
+ [128544]="on",
+ [128545]="on",
+ [128546]="on",
+ [128547]="on",
+ [128548]="on",
+ [128549]="on",
+ [128550]="on",
+ [128551]="on",
+ [128552]="on",
+ [128553]="on",
+ [128554]="on",
+ [128555]="on",
+ [128556]="on",
+ [128557]="on",
+ [128558]="on",
+ [128559]="on",
+ [128560]="on",
+ [128561]="on",
+ [128562]="on",
+ [128563]="on",
+ [128564]="on",
+ [128565]="on",
+ [128566]="on",
+ [128567]="on",
+ [128568]="on",
+ [128569]="on",
+ [128570]="on",
+ [128571]="on",
+ [128572]="on",
+ [128573]="on",
+ [128574]="on",
+ [128575]="on",
+ [128576]="on",
+ [128577]="on",
+ [128578]="on",
+ [128579]="on",
+ [128580]="on",
+ [128581]="on",
+ [128582]="on",
+ [128583]="on",
+ [128584]="on",
+ [128585]="on",
+ [128586]="on",
+ [128587]="on",
+ [128588]="on",
+ [128589]="on",
+ [128590]="on",
+ [128591]="on",
+ [128592]="on",
+ [128593]="on",
+ [128594]="on",
+ [128595]="on",
+ [128596]="on",
+ [128597]="on",
+ [128598]="on",
+ [128599]="on",
+ [128600]="on",
+ [128601]="on",
+ [128602]="on",
+ [128603]="on",
+ [128604]="on",
+ [128605]="on",
+ [128606]="on",
+ [128607]="on",
+ [128608]="on",
+ [128609]="on",
+ [128610]="on",
+ [128611]="on",
+ [128612]="on",
+ [128613]="on",
+ [128614]="on",
+ [128615]="on",
+ [128616]="on",
+ [128617]="on",
+ [128618]="on",
+ [128619]="on",
+ [128620]="on",
+ [128621]="on",
+ [128622]="on",
+ [128623]="on",
+ [128624]="on",
+ [128625]="on",
+ [128626]="on",
+ [128627]="on",
+ [128628]="on",
+ [128629]="on",
+ [128630]="on",
+ [128631]="on",
+ [128632]="on",
+ [128633]="on",
+ [128634]="on",
+ [128635]="on",
+ [128636]="on",
+ [128637]="on",
+ [128638]="on",
+ [128639]="on",
+ [128640]="on",
+ [128641]="on",
+ [128642]="on",
+ [128643]="on",
+ [128644]="on",
+ [128645]="on",
+ [128646]="on",
+ [128647]="on",
+ [128648]="on",
+ [128649]="on",
+ [128650]="on",
+ [128651]="on",
+ [128652]="on",
+ [128653]="on",
+ [128654]="on",
+ [128655]="on",
+ [128656]="on",
+ [128657]="on",
+ [128658]="on",
+ [128659]="on",
+ [128660]="on",
+ [128661]="on",
+ [128662]="on",
+ [128663]="on",
+ [128664]="on",
+ [128665]="on",
+ [128666]="on",
+ [128667]="on",
+ [128668]="on",
+ [128669]="on",
+ [128670]="on",
+ [128671]="on",
+ [128672]="on",
+ [128673]="on",
+ [128674]="on",
+ [128675]="on",
+ [128676]="on",
+ [128677]="on",
+ [128678]="on",
+ [128679]="on",
+ [128680]="on",
+ [128681]="on",
+ [128682]="on",
+ [128683]="on",
+ [128684]="on",
+ [128685]="on",
+ [128686]="on",
+ [128687]="on",
+ [128688]="on",
+ [128689]="on",
+ [128690]="on",
+ [128691]="on",
+ [128692]="on",
+ [128693]="on",
+ [128694]="on",
+ [128695]="on",
+ [128696]="on",
+ [128697]="on",
+ [128698]="on",
+ [128699]="on",
+ [128700]="on",
+ [128701]="on",
+ [128702]="on",
+ [128703]="on",
+ [128704]="on",
+ [128705]="on",
+ [128706]="on",
+ [128707]="on",
+ [128708]="on",
+ [128709]="on",
+ [128710]="on",
+ [128711]="on",
+ [128712]="on",
+ [128713]="on",
+ [128714]="on",
+ [128715]="on",
+ [128716]="on",
+ [128717]="on",
+ [128718]="on",
+ [128719]="on",
+ [128720]="on",
+ [128721]="on",
+ [128722]="on",
+ [128723]="on",
+ [128724]="on",
+ [128736]="on",
+ [128737]="on",
+ [128738]="on",
+ [128739]="on",
+ [128740]="on",
+ [128741]="on",
+ [128742]="on",
+ [128743]="on",
+ [128744]="on",
+ [128745]="on",
+ [128746]="on",
+ [128747]="on",
+ [128748]="on",
+ [128752]="on",
+ [128753]="on",
+ [128754]="on",
+ [128755]="on",
+ [128756]="on",
+ [128757]="on",
+ [128758]="on",
+ [128759]="on",
+ [128760]="on",
+ [128768]="on",
+ [128769]="on",
+ [128770]="on",
+ [128771]="on",
+ [128772]="on",
+ [128773]="on",
+ [128774]="on",
+ [128775]="on",
+ [128776]="on",
+ [128777]="on",
+ [128778]="on",
+ [128779]="on",
+ [128780]="on",
+ [128781]="on",
+ [128782]="on",
+ [128783]="on",
+ [128784]="on",
+ [128785]="on",
+ [128786]="on",
+ [128787]="on",
+ [128788]="on",
+ [128789]="on",
+ [128790]="on",
+ [128791]="on",
+ [128792]="on",
+ [128793]="on",
+ [128794]="on",
+ [128795]="on",
+ [128796]="on",
+ [128797]="on",
+ [128798]="on",
+ [128799]="on",
+ [128800]="on",
+ [128801]="on",
+ [128802]="on",
+ [128803]="on",
+ [128804]="on",
+ [128805]="on",
+ [128806]="on",
+ [128807]="on",
+ [128808]="on",
+ [128809]="on",
+ [128810]="on",
+ [128811]="on",
+ [128812]="on",
+ [128813]="on",
+ [128814]="on",
+ [128815]="on",
+ [128816]="on",
+ [128817]="on",
+ [128818]="on",
+ [128819]="on",
+ [128820]="on",
+ [128821]="on",
+ [128822]="on",
+ [128823]="on",
+ [128824]="on",
+ [128825]="on",
+ [128826]="on",
+ [128827]="on",
+ [128828]="on",
+ [128829]="on",
+ [128830]="on",
+ [128831]="on",
+ [128832]="on",
+ [128833]="on",
+ [128834]="on",
+ [128835]="on",
+ [128836]="on",
+ [128837]="on",
+ [128838]="on",
+ [128839]="on",
+ [128840]="on",
+ [128841]="on",
+ [128842]="on",
+ [128843]="on",
+ [128844]="on",
+ [128845]="on",
+ [128846]="on",
+ [128847]="on",
+ [128848]="on",
+ [128849]="on",
+ [128850]="on",
+ [128851]="on",
+ [128852]="on",
+ [128853]="on",
+ [128854]="on",
+ [128855]="on",
+ [128856]="on",
+ [128857]="on",
+ [128858]="on",
+ [128859]="on",
+ [128860]="on",
+ [128861]="on",
+ [128862]="on",
+ [128863]="on",
+ [128864]="on",
+ [128865]="on",
+ [128866]="on",
+ [128867]="on",
+ [128868]="on",
+ [128869]="on",
+ [128870]="on",
+ [128871]="on",
+ [128872]="on",
+ [128873]="on",
+ [128874]="on",
+ [128875]="on",
+ [128876]="on",
+ [128877]="on",
+ [128878]="on",
+ [128879]="on",
+ [128880]="on",
+ [128881]="on",
+ [128882]="on",
+ [128883]="on",
+ [128896]="on",
+ [128897]="on",
+ [128898]="on",
+ [128899]="on",
+ [128900]="on",
+ [128901]="on",
+ [128902]="on",
+ [128903]="on",
+ [128904]="on",
+ [128905]="on",
+ [128906]="on",
+ [128907]="on",
+ [128908]="on",
+ [128909]="on",
+ [128910]="on",
+ [128911]="on",
+ [128912]="on",
+ [128913]="on",
+ [128914]="on",
+ [128915]="on",
+ [128916]="on",
+ [128917]="on",
+ [128918]="on",
+ [128919]="on",
+ [128920]="on",
+ [128921]="on",
+ [128922]="on",
+ [128923]="on",
+ [128924]="on",
+ [128925]="on",
+ [128926]="on",
+ [128927]="on",
+ [128928]="on",
+ [128929]="on",
+ [128930]="on",
+ [128931]="on",
+ [128932]="on",
+ [128933]="on",
+ [128934]="on",
+ [128935]="on",
+ [128936]="on",
+ [128937]="on",
+ [128938]="on",
+ [128939]="on",
+ [128940]="on",
+ [128941]="on",
+ [128942]="on",
+ [128943]="on",
+ [128944]="on",
+ [128945]="on",
+ [128946]="on",
+ [128947]="on",
+ [128948]="on",
+ [128949]="on",
+ [128950]="on",
+ [128951]="on",
+ [128952]="on",
+ [128953]="on",
+ [128954]="on",
+ [128955]="on",
+ [128956]="on",
+ [128957]="on",
+ [128958]="on",
+ [128959]="on",
+ [128960]="on",
+ [128961]="on",
+ [128962]="on",
+ [128963]="on",
+ [128964]="on",
+ [128965]="on",
+ [128966]="on",
+ [128967]="on",
+ [128968]="on",
+ [128969]="on",
+ [128970]="on",
+ [128971]="on",
+ [128972]="on",
+ [128973]="on",
+ [128974]="on",
+ [128975]="on",
+ [128976]="on",
+ [128977]="on",
+ [128978]="on",
+ [128979]="on",
+ [128980]="on",
+ [129024]="on",
+ [129025]="on",
+ [129026]="on",
+ [129027]="on",
+ [129028]="on",
+ [129029]="on",
+ [129030]="on",
+ [129031]="on",
+ [129032]="on",
+ [129033]="on",
+ [129034]="on",
+ [129035]="on",
+ [129040]="on",
+ [129041]="on",
+ [129042]="on",
+ [129043]="on",
+ [129044]="on",
+ [129045]="on",
+ [129046]="on",
+ [129047]="on",
+ [129048]="on",
+ [129049]="on",
+ [129050]="on",
+ [129051]="on",
+ [129052]="on",
+ [129053]="on",
+ [129054]="on",
+ [129055]="on",
+ [129056]="on",
+ [129057]="on",
+ [129058]="on",
+ [129059]="on",
+ [129060]="on",
+ [129061]="on",
+ [129062]="on",
+ [129063]="on",
+ [129064]="on",
+ [129065]="on",
+ [129066]="on",
+ [129067]="on",
+ [129068]="on",
+ [129069]="on",
+ [129070]="on",
+ [129071]="on",
+ [129072]="on",
+ [129073]="on",
+ [129074]="on",
+ [129075]="on",
+ [129076]="on",
+ [129077]="on",
+ [129078]="on",
+ [129079]="on",
+ [129080]="on",
+ [129081]="on",
+ [129082]="on",
+ [129083]="on",
+ [129084]="on",
+ [129085]="on",
+ [129086]="on",
+ [129087]="on",
+ [129088]="on",
+ [129089]="on",
+ [129090]="on",
+ [129091]="on",
+ [129092]="on",
+ [129093]="on",
+ [129094]="on",
+ [129095]="on",
+ [129104]="on",
+ [129105]="on",
+ [129106]="on",
+ [129107]="on",
+ [129108]="on",
+ [129109]="on",
+ [129110]="on",
+ [129111]="on",
+ [129112]="on",
+ [129113]="on",
+ [129120]="on",
+ [129121]="on",
+ [129122]="on",
+ [129123]="on",
+ [129124]="on",
+ [129125]="on",
+ [129126]="on",
+ [129127]="on",
+ [129128]="on",
+ [129129]="on",
+ [129130]="on",
+ [129131]="on",
+ [129132]="on",
+ [129133]="on",
+ [129134]="on",
+ [129135]="on",
+ [129136]="on",
+ [129137]="on",
+ [129138]="on",
+ [129139]="on",
+ [129140]="on",
+ [129141]="on",
+ [129142]="on",
+ [129143]="on",
+ [129144]="on",
+ [129145]="on",
+ [129146]="on",
+ [129147]="on",
+ [129148]="on",
+ [129149]="on",
+ [129150]="on",
+ [129151]="on",
+ [129152]="on",
+ [129153]="on",
+ [129154]="on",
+ [129155]="on",
+ [129156]="on",
+ [129157]="on",
+ [129158]="on",
+ [129159]="on",
+ [129168]="on",
+ [129169]="on",
+ [129170]="on",
+ [129171]="on",
+ [129172]="on",
+ [129173]="on",
+ [129174]="on",
+ [129175]="on",
+ [129176]="on",
+ [129177]="on",
+ [129178]="on",
+ [129179]="on",
+ [129180]="on",
+ [129181]="on",
+ [129182]="on",
+ [129183]="on",
+ [129184]="on",
+ [129185]="on",
+ [129186]="on",
+ [129187]="on",
+ [129188]="on",
+ [129189]="on",
+ [129190]="on",
+ [129191]="on",
+ [129192]="on",
+ [129193]="on",
+ [129194]="on",
+ [129195]="on",
+ [129196]="on",
+ [129197]="on",
+ [129280]="on",
+ [129281]="on",
+ [129282]="on",
+ [129283]="on",
+ [129284]="on",
+ [129285]="on",
+ [129286]="on",
+ [129287]="on",
+ [129288]="on",
+ [129289]="on",
+ [129290]="on",
+ [129291]="on",
+ [129296]="on",
+ [129297]="on",
+ [129298]="on",
+ [129299]="on",
+ [129300]="on",
+ [129301]="on",
+ [129302]="on",
+ [129303]="on",
+ [129304]="on",
+ [129305]="on",
+ [129306]="on",
+ [129307]="on",
+ [129308]="on",
+ [129309]="on",
+ [129310]="on",
+ [129311]="on",
+ [129312]="on",
+ [129313]="on",
+ [129314]="on",
+ [129315]="on",
+ [129316]="on",
+ [129317]="on",
+ [129318]="on",
+ [129319]="on",
+ [129320]="on",
+ [129321]="on",
+ [129322]="on",
+ [129323]="on",
+ [129324]="on",
+ [129325]="on",
+ [129326]="on",
+ [129327]="on",
+ [129328]="on",
+ [129329]="on",
+ [129330]="on",
+ [129331]="on",
+ [129332]="on",
+ [129333]="on",
+ [129334]="on",
+ [129335]="on",
+ [129336]="on",
+ [129337]="on",
+ [129338]="on",
+ [129339]="on",
+ [129340]="on",
+ [129341]="on",
+ [129342]="on",
+ [129344]="on",
+ [129345]="on",
+ [129346]="on",
+ [129347]="on",
+ [129348]="on",
+ [129349]="on",
+ [129350]="on",
+ [129351]="on",
+ [129352]="on",
+ [129353]="on",
+ [129354]="on",
+ [129355]="on",
+ [129356]="on",
+ [129360]="on",
+ [129361]="on",
+ [129362]="on",
+ [129363]="on",
+ [129364]="on",
+ [129365]="on",
+ [129366]="on",
+ [129367]="on",
+ [129368]="on",
+ [129369]="on",
+ [129370]="on",
+ [129371]="on",
+ [129372]="on",
+ [129373]="on",
+ [129374]="on",
+ [129375]="on",
+ [129376]="on",
+ [129377]="on",
+ [129378]="on",
+ [129379]="on",
+ [129380]="on",
+ [129381]="on",
+ [129382]="on",
+ [129383]="on",
+ [129384]="on",
+ [129385]="on",
+ [129386]="on",
+ [129387]="on",
+ [129408]="on",
+ [129409]="on",
+ [129410]="on",
+ [129411]="on",
+ [129412]="on",
+ [129413]="on",
+ [129414]="on",
+ [129415]="on",
+ [129416]="on",
+ [129417]="on",
+ [129418]="on",
+ [129419]="on",
+ [129420]="on",
+ [129421]="on",
+ [129422]="on",
+ [129423]="on",
+ [129424]="on",
+ [129425]="on",
+ [129426]="on",
+ [129427]="on",
+ [129428]="on",
+ [129429]="on",
+ [129430]="on",
+ [129431]="on",
+ [129472]="on",
+ [129488]="on",
+ [129489]="on",
+ [129490]="on",
+ [129491]="on",
+ [129492]="on",
+ [129493]="on",
+ [129494]="on",
+ [129495]="on",
+ [129496]="on",
+ [129497]="on",
+ [129498]="on",
+ [129499]="on",
+ [129500]="on",
+ [129501]="on",
+ [129502]="on",
+ [129503]="on",
+ [129504]="on",
+ [129505]="on",
+ [129506]="on",
+ [129507]="on",
+ [129508]="on",
+ [129509]="on",
+ [129510]="on",
+ [917505]="bn",
+ [917536]="bn",
+ [917537]="bn",
+ [917538]="bn",
+ [917539]="bn",
+ [917540]="bn",
+ [917541]="bn",
+ [917542]="bn",
+ [917543]="bn",
+ [917544]="bn",
+ [917545]="bn",
+ [917546]="bn",
+ [917547]="bn",
+ [917548]="bn",
+ [917549]="bn",
+ [917550]="bn",
+ [917551]="bn",
+ [917552]="bn",
+ [917553]="bn",
+ [917554]="bn",
+ [917555]="bn",
+ [917556]="bn",
+ [917557]="bn",
+ [917558]="bn",
+ [917559]="bn",
+ [917560]="bn",
+ [917561]="bn",
+ [917562]="bn",
+ [917563]="bn",
+ [917564]="bn",
+ [917565]="bn",
+ [917566]="bn",
+ [917567]="bn",
+ [917568]="bn",
+ [917569]="bn",
+ [917570]="bn",
+ [917571]="bn",
+ [917572]="bn",
+ [917573]="bn",
+ [917574]="bn",
+ [917575]="bn",
+ [917576]="bn",
+ [917577]="bn",
+ [917578]="bn",
+ [917579]="bn",
+ [917580]="bn",
+ [917581]="bn",
+ [917582]="bn",
+ [917583]="bn",
+ [917584]="bn",
+ [917585]="bn",
+ [917586]="bn",
+ [917587]="bn",
+ [917588]="bn",
+ [917589]="bn",
+ [917590]="bn",
+ [917591]="bn",
+ [917592]="bn",
+ [917593]="bn",
+ [917594]="bn",
+ [917595]="bn",
+ [917596]="bn",
+ [917597]="bn",
+ [917598]="bn",
+ [917599]="bn",
+ [917600]="bn",
+ [917601]="bn",
+ [917602]="bn",
+ [917603]="bn",
+ [917604]="bn",
+ [917605]="bn",
+ [917606]="bn",
+ [917607]="bn",
+ [917608]="bn",
+ [917609]="bn",
+ [917610]="bn",
+ [917611]="bn",
+ [917612]="bn",
+ [917613]="bn",
+ [917614]="bn",
+ [917615]="bn",
+ [917616]="bn",
+ [917617]="bn",
+ [917618]="bn",
+ [917619]="bn",
+ [917620]="bn",
+ [917621]="bn",
+ [917622]="bn",
+ [917623]="bn",
+ [917624]="bn",
+ [917625]="bn",
+ [917626]="bn",
+ [917627]="bn",
+ [917628]="bn",
+ [917629]="bn",
+ [917630]="bn",
+ [917631]="bn",
+ },
+ ["mirrors"]={
+ [40]=41,
+ [41]=40,
+ [60]=62,
+ [62]=60,
+ [91]=93,
+ [93]=91,
+ [123]=125,
+ [125]=123,
+ [171]=187,
+ [187]=171,
+ [3898]=3899,
+ [3899]=3898,
+ [3900]=3901,
+ [3901]=3900,
+ [5787]=5788,
+ [5788]=5787,
+ [8249]=8250,
+ [8250]=8249,
+ [8261]=8262,
+ [8262]=8261,
+ [8317]=8318,
+ [8318]=8317,
+ [8333]=8334,
+ [8334]=8333,
+ [8712]=8715,
+ [8713]=8716,
+ [8714]=8717,
+ [8715]=8712,
+ [8716]=8713,
+ [8717]=8714,
+ [8725]=10741,
+ [8764]=8765,
+ [8765]=8764,
+ [8771]=8909,
+ [8786]=8787,
+ [8787]=8786,
+ [8788]=8789,
+ [8789]=8788,
+ [8804]=8805,
+ [8805]=8804,
+ [8806]=8807,
+ [8807]=8806,
+ [8808]=8809,
+ [8809]=8808,
+ [8810]=8811,
+ [8811]=8810,
+ [8814]=8815,
+ [8815]=8814,
+ [8816]=8817,
+ [8817]=8816,
+ [8818]=8819,
+ [8819]=8818,
+ [8820]=8821,
+ [8821]=8820,
+ [8822]=8823,
+ [8823]=8822,
+ [8824]=8825,
+ [8825]=8824,
+ [8826]=8827,
+ [8827]=8826,
+ [8828]=8829,
+ [8829]=8828,
+ [8830]=8831,
+ [8831]=8830,
+ [8832]=8833,
+ [8833]=8832,
+ [8834]=8835,
+ [8835]=8834,
+ [8836]=8837,
+ [8837]=8836,
+ [8838]=8839,
+ [8839]=8838,
+ [8840]=8841,
+ [8841]=8840,
+ [8842]=8843,
+ [8843]=8842,
+ [8847]=8848,
+ [8848]=8847,
+ [8849]=8850,
+ [8850]=8849,
+ [8856]=10680,
+ [8866]=8867,
+ [8867]=8866,
+ [8870]=10974,
+ [8872]=10980,
+ [8873]=10979,
+ [8875]=10981,
+ [8880]=8881,
+ [8881]=8880,
+ [8882]=8883,
+ [8883]=8882,
+ [8884]=8885,
+ [8885]=8884,
+ [8886]=8887,
+ [8887]=8886,
+ [8905]=8906,
+ [8906]=8905,
+ [8907]=8908,
+ [8908]=8907,
+ [8909]=8771,
+ [8912]=8913,
+ [8913]=8912,
+ [8918]=8919,
+ [8919]=8918,
+ [8920]=8921,
+ [8921]=8920,
+ [8922]=8923,
+ [8923]=8922,
+ [8924]=8925,
+ [8925]=8924,
+ [8926]=8927,
+ [8927]=8926,
+ [8928]=8929,
+ [8929]=8928,
+ [8930]=8931,
+ [8931]=8930,
+ [8932]=8933,
+ [8933]=8932,
+ [8934]=8935,
+ [8935]=8934,
+ [8936]=8937,
+ [8937]=8936,
+ [8938]=8939,
+ [8939]=8938,
+ [8940]=8941,
+ [8941]=8940,
+ [8944]=8945,
+ [8945]=8944,
+ [8946]=8954,
+ [8947]=8955,
+ [8948]=8956,
+ [8950]=8957,
+ [8951]=8958,
+ [8954]=8946,
+ [8955]=8947,
+ [8956]=8948,
+ [8957]=8950,
+ [8958]=8951,
+ [8968]=8969,
+ [8969]=8968,
+ [8970]=8971,
+ [8971]=8970,
+ [9001]=9002,
+ [9002]=9001,
+ [10088]=10089,
+ [10089]=10088,
+ [10090]=10091,
+ [10091]=10090,
+ [10092]=10093,
+ [10093]=10092,
+ [10094]=10095,
+ [10095]=10094,
+ [10096]=10097,
+ [10097]=10096,
+ [10098]=10099,
+ [10099]=10098,
+ [10100]=10101,
+ [10101]=10100,
+ [10179]=10180,
+ [10180]=10179,
+ [10181]=10182,
+ [10182]=10181,
+ [10184]=10185,
+ [10185]=10184,
+ [10187]=10189,
+ [10189]=10187,
+ [10197]=10198,
+ [10198]=10197,
+ [10205]=10206,
+ [10206]=10205,
+ [10210]=10211,
+ [10211]=10210,
+ [10212]=10213,
+ [10213]=10212,
+ [10214]=10215,
+ [10215]=10214,
+ [10216]=10217,
+ [10217]=10216,
+ [10218]=10219,
+ [10219]=10218,
+ [10220]=10221,
+ [10221]=10220,
+ [10222]=10223,
+ [10223]=10222,
+ [10627]=10628,
+ [10628]=10627,
+ [10629]=10630,
+ [10630]=10629,
+ [10631]=10632,
+ [10632]=10631,
+ [10633]=10634,
+ [10634]=10633,
+ [10635]=10636,
+ [10636]=10635,
+ [10637]=10640,
+ [10638]=10639,
+ [10639]=10638,
+ [10640]=10637,
+ [10641]=10642,
+ [10642]=10641,
+ [10643]=10644,
+ [10644]=10643,
+ [10645]=10646,
+ [10646]=10645,
+ [10647]=10648,
+ [10648]=10647,
+ [10680]=8856,
+ [10688]=10689,
+ [10689]=10688,
+ [10692]=10693,
+ [10693]=10692,
+ [10703]=10704,
+ [10704]=10703,
+ [10705]=10706,
+ [10706]=10705,
+ [10708]=10709,
+ [10709]=10708,
+ [10712]=10713,
+ [10713]=10712,
+ [10714]=10715,
+ [10715]=10714,
+ [10741]=8725,
+ [10744]=10745,
+ [10745]=10744,
+ [10748]=10749,
+ [10749]=10748,
+ [10795]=10796,
+ [10796]=10795,
+ [10797]=10798,
+ [10798]=10797,
+ [10804]=10805,
+ [10805]=10804,
+ [10812]=10813,
+ [10813]=10812,
+ [10852]=10853,
+ [10853]=10852,
+ [10873]=10874,
+ [10874]=10873,
+ [10877]=10878,
+ [10878]=10877,
+ [10879]=10880,
+ [10880]=10879,
+ [10881]=10882,
+ [10882]=10881,
+ [10883]=10884,
+ [10884]=10883,
+ [10891]=10892,
+ [10892]=10891,
+ [10897]=10898,
+ [10898]=10897,
+ [10899]=10900,
+ [10900]=10899,
+ [10901]=10902,
+ [10902]=10901,
+ [10903]=10904,
+ [10904]=10903,
+ [10905]=10906,
+ [10906]=10905,
+ [10907]=10908,
+ [10908]=10907,
+ [10913]=10914,
+ [10914]=10913,
+ [10918]=10919,
+ [10919]=10918,
+ [10920]=10921,
+ [10921]=10920,
+ [10922]=10923,
+ [10923]=10922,
+ [10924]=10925,
+ [10925]=10924,
+ [10927]=10928,
+ [10928]=10927,
+ [10931]=10932,
+ [10932]=10931,
+ [10939]=10940,
+ [10940]=10939,
+ [10941]=10942,
+ [10942]=10941,
+ [10943]=10944,
+ [10944]=10943,
+ [10945]=10946,
+ [10946]=10945,
+ [10947]=10948,
+ [10948]=10947,
+ [10949]=10950,
+ [10950]=10949,
+ [10957]=10958,
+ [10958]=10957,
+ [10959]=10960,
+ [10960]=10959,
+ [10961]=10962,
+ [10962]=10961,
+ [10963]=10964,
+ [10964]=10963,
+ [10965]=10966,
+ [10966]=10965,
+ [10974]=8870,
+ [10979]=8873,
+ [10980]=8872,
+ [10981]=8875,
+ [10988]=10989,
+ [10989]=10988,
+ [10999]=11000,
+ [11000]=10999,
+ [11001]=11002,
+ [11002]=11001,
+ [11778]=11779,
+ [11779]=11778,
+ [11780]=11781,
+ [11781]=11780,
+ [11785]=11786,
+ [11786]=11785,
+ [11788]=11789,
+ [11789]=11788,
+ [11804]=11805,
+ [11805]=11804,
+ [11808]=11809,
+ [11809]=11808,
+ [11810]=11811,
+ [11811]=11810,
+ [11812]=11813,
+ [11813]=11812,
+ [11814]=11815,
+ [11815]=11814,
+ [11816]=11817,
+ [11817]=11816,
+ [12296]=12297,
+ [12297]=12296,
+ [12298]=12299,
+ [12299]=12298,
+ [12300]=12301,
+ [12301]=12300,
+ [12302]=12303,
+ [12303]=12302,
+ [12304]=12305,
+ [12305]=12304,
+ [12308]=12309,
+ [12309]=12308,
+ [12310]=12311,
+ [12311]=12310,
+ [12312]=12313,
+ [12313]=12312,
+ [12314]=12315,
+ [12315]=12314,
+ [65113]=65114,
+ [65114]=65113,
+ [65115]=65116,
+ [65116]=65115,
+ [65117]=65118,
+ [65118]=65117,
+ [65124]=65125,
+ [65125]=65124,
+ [65288]=65289,
+ [65289]=65288,
+ [65308]=65310,
+ [65310]=65308,
+ [65339]=65341,
+ [65341]=65339,
+ [65371]=65373,
+ [65373]=65371,
+ [65375]=65376,
+ [65376]=65375,
+ [65378]=65379,
+ [65379]=65378,
+ },
+ ["textclasses"]={
+ [40]="open",
+ [41]="close",
+ [60]="open",
+ [62]="close",
+ [91]="open",
+ [93]="close",
+ [123]="open",
+ [125]="close",
+ [171]="open",
+ [187]="close",
+ [8249]="open",
+ [8250]="close",
+ [8317]="open",
+ [8318]="close",
+ [8333]="open",
+ [8334]="close",
+ [10647]="open",
+ [10648]="close",
+ [65113]="open",
+ [65114]="close",
+ [65115]="open",
+ [65116]="close",
+ [65117]="open",
+ [65118]="close",
+ [65124]="open",
+ [65125]="close",
+ [65288]="open",
+ [65289]="close",
+ [65308]="open",
+ [65310]="close",
+ [65339]="open",
+ [65341]="close",
+ [65371]="open",
+ [65373]="close",
+ [65375]="open",
+ [65376]="close",
+ [65378]="open",
+ [65379]="close",
+ },
+}
diff --git a/context/data/textadept/context/data/scite-context-data-context.lua b/context/data/textadept/context/data/scite-context-data-context.lua
index 15ce97796..afb6565eb 100644
--- a/context/data/textadept/context/data/scite-context-data-context.lua
+++ b/context/data/textadept/context/data/scite-context-data-context.lua
@@ -1,4 +1,4 @@
return {
- ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plustwohundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "maxcardminusone", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxcount", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "ctdcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "hyphenasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "mathexheight", "mathemwidth", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "muquad", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifelsemode", "doifmodeelse", "doifnotmode", "startmodeset", "stopmodeset", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifelseallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "everystarttext", "everystoptext", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "definemode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "lrm", "rlm", "bidilre", "bidirle", "bidipop", "bidilro", "bidirlo", "breakablethinspace", "nobreakspace", "nonbreakablespace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "enquad", "emquad", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj", "optionalspace", "asciispacechar", "softhyphen", "Ux", "eUx", "Umathaccents", "parfillleftskip", "parfillrightskip" },
- ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "texdefinition", "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "strippedcsname", "checkedstrippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthsargumenttrue", "sixthargumentfalse", "sixtsargumenttrue", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "startpickupmath", "stoppickupmath", "reqno", "mathortext", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", "normalbaselineskip", "normallineskip", "normallineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "ignoreparskip", "forcestrutdepth", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "setexpandeddummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "installctxfunctioncall", "installprotectedctxfunction", "installprotectedctxfunctioncall", "installctxscanner", "installctxscannercall", "resetctxscanner", "installprotectedctxscanner", "installprotectedctxscannercall", "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand", "carryoverpar", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "checkedlefttoright", "checkedrighttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "dirlre", "dirrle", "dirlro", "dirrlo", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "frule", "compoundhyphenpenalty", "start", "stop" },
+ ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "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", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "directionlefttoright", "directionrighttoleft", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "contextformat", "contextversion", "contextkind", "contextlmtxmode", "contextmark", "mksuffix", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "ctdcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "leftparentasciicode", "rightparentasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "hyphenasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "mathexheight", "mathemwidth", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "muquad", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifelsemode", "doifmodeelse", "doifnotmode", "startmodeset", "stopmodeset", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifelseallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", "doifelsedocumentvariable", "doifdocumentvariableelse", "doifdocumentvariable", "doifnotdocumentvariable", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "everystarttext", "everystoptext", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "definemode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "lrm", "rlm", "bidilre", "bidirle", "bidipop", "bidilro", "bidirlo", "breakablethinspace", "nobreakspace", "nonbreakablespace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "enquad", "emquad", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj", "optionalspace", "asciispacechar", "softhyphen", "Ux", "eUx", "Umathaccents", "parfillleftskip", "parfillrightskip" },
+ ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "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", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "autorule", "strippedcsname", "checkedstrippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthargumenttrue", "sixthargumentfalse", "sixthargumenttrue", "seventhargumentfalse", "seventhargumenttrue", "vkern", "hkern", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "foundtrue", "foundfalse", "inlineordisplaymath", "indisplaymath", "forcedisplaymath", "startforceddisplaymath", "stopforceddisplaymath", "startpickupmath", "stoppickupmath", "reqno", "mathortext", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "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", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "privatescratchcounter", "scratchdimen", "globalscratchdimen", "privatescratchdimen", "scratchskip", "globalscratchskip", "privatescratchskip", "scratchmuskip", "globalscratchmuskip", "privatescratchmuskip", "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", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchcounterfour", "scratchcounterfive", "scratchcountersix", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchdimenfour", "scratchdimenfive", "scratchdimensix", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchskipfour", "scratchskipfive", "scratchskipsix", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchmuskipfour", "scratchmuskipfive", "scratchmuskipsix", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchtoksfour", "scratchtoksfive", "scratchtokssix", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchboxfour", "scratchboxfive", "scratchboxsix", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchmin", "scratchmax", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "firstinset", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", "doifelsenextoptional", "doifnextoptionalelse", "doifelsenextoptionalcs", "doifnextoptionalcselse", "doifelsefastoptionalcheck", "doiffastoptionalcheckelse", "doifelsefastoptionalcheckcs", "doiffastoptionalcheckcselse", "doifelsenextbgroup", "doifnextbgroupelse", "doifelsenextbgroupcs", "doifnextbgroupcselse", "doifelsenextparenthesis", "doifnextparenthesiselse", "doifelseundefined", "doifundefinedelse", "doifelsedefined", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifnothingelse", "doifelsesomething", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifvaluenothingelse", "doifelsedimension", "doifdimensionelse", "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", "doifelseassignment", "doifassignmentelse", "docheckassignment", "doifelseassignmentcs", "doifassignmentelsecs", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "emspace", "charspace", "nbsp", "crlf", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "obeyedtab", "obeyedpage", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "removepunctuation", "ignoreparskip", "forcestrutdepth", "onlynonbreakablespace", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "setexpandeddummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "firstoftwounexpanded", "secondoftwounexpanded", "firstofthreeunexpanded", "secondofthreeunexpanded", "thirdofthreeunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "fastloopindex", "fastloopfinal", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "onlypdfobjectcompression", "nopdfobjectcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doifelsefirstchar", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "offinterlineskip", "oninterlineskip", "nointerlineskip", "strut", "halfstrut", "quarterstrut", "depthstrut", "halflinestrut", "noheightstrut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "strutgap", "begstrut", "endstrut", "lineheight", "leftboundary", "rightboundary", "signalcharacter", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "normalsuperscript", "normalsubscript", "normalnosuperscript", "normalnosubscript", "superscript", "subscript", "nosuperscript", "nosubscript", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "pushmathstyle", "popmathstyle", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expelsedoif", "expdoif", "expdoifnot", "expdoifelsecommon", "expdoifcommonelse", "expdoifelseinset", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "installctxfunction", "installprotectedctxfunction", "installprotectedctxscanner", "installctxscanner", "resetctxscanner", "cldprocessfile", "cldloadfile", "cldloadviafile", "cldcontext", "cldcommand", "carryoverpar", "lastlinewidth", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "lefttoright", "righttoleft", "checkedlefttoright", "checkedrighttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "dirlre", "dirrle", "dirlro", "dirrlo", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath", "break", "nobreak", "allowbreak", "goodbreak", "nospace", "nospacing", "dospacing", "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "naturaltpack", "reversehbox", "reversevbox", "reversevtop", "reversehpack", "reversevpack", "reversetpack", "frule", "compoundhyphenpenalty", "start", "stop" },
} \ No newline at end of file
diff --git a/context/data/textadept/context/data/scite-context-data-interfaces.lua b/context/data/textadept/context/data/scite-context-data-interfaces.lua
index 14036ae5d..6547cad51 100644
--- a/context/data/textadept/context/data/scite-context-data-interfaces.lua
+++ b/context/data/textadept/context/data/scite-context-data-interfaces.lua
@@ -1,11 +1,11 @@
return {
- ["common"]={ "AEacute", "AEligature", "AEmacron", "AMSTEX", "Aacute", "Abreve", "Abreveacute", "Abrevedotbelow", "Abrevegrave", "Abrevehook", "Abrevetilde", "Acaron", "Acircumflex", "Acircumflexacute", "Acircumflexdotbelow", "Acircumflexgrave", "Acircumflexhook", "Acircumflextilde", "Adiaeresis", "Adiaeresismacron", "Adotaccent", "Adotaccentmacron", "Adotbelow", "Adoublegrave", "AfterPar", "Agrave", "Ahook", "Ainvertedbreve", "Alpha", "Alphabeticnumerals", "AmSTeX", "Amacron", "And", "Angstrom", "Aogonek", "Aring", "Aringacute", "Arrowvert", "Astroke", "Atilde", "BeforePar", "Beta", "Bhook", "Big", "Bigg", "Biggl", "Biggm", "Biggr", "Bigl", "Bigm", "Bigr", "Box", "Bumpeq", "CONTEXT", "Cacute", "Cap", "Caps", "Ccaron", "Ccedilla", "Ccircumflex", "Cdotaccent", "Character", "Characters", "Chi", "Chook", "ConTeXt", "Context", "ConvertConstantAfter", "ConvertToConstant", "Cstroke", "Cup", "DZcaronligature", "DZligature", "Dafrican", "Dcaron", "Ddownarrow", "Delta", "Dhook", "Doteq", "Downarrow", "Dstroke", "Dzcaronligature", "Dzligature", "ETEX", "Eacute", "Ebreve", "Ecaron", "Ecedilla", "Ecircumflex", "Ecircumflexacute", "Ecircumflexdotbelow", "Ecircumflexgrave", "Ecircumflexhook", "Ecircumflextilde", "Ediaeresis", "Edotaccent", "Edotbelow", "Edoublegrave", "Egrave", "Ehook", "Einvertedbreve", "Emacron", "Eogonek", "Epsilon", "Eta", "Eth", "Etilde", "Eulerconst", "EveryLine", "EveryPar", "Fhook", "Finv", "Gacute", "Game", "Gamma", "Gbreve", "Gcaron", "Gcircumflex", "Gcommaaccent", "Gdotaccent", "GetPar", "Ghook", "GotoPar", "Greeknumerals", "Gstroke", "Hat", "Hcaron", "Hcircumflex", "Hstroke", "IJligature", "INRSTEX", "Iacute", "Ibreve", "Icaron", "Icircumflex", "Idiaeresis", "Idotaccent", "Idotbelow", "Idoublegrave", "Igrave", "Ihook", "Iinvertedbreve", "Im", "Imacron", "Iogonek", "Iota", "Istroke", "Itilde", "Jcircumflex", "Join", "Kappa", "Kcaron", "Kcommaaccent", "Khook", "LAMSTEX", "LATEX", "LJligature", "LUAJITTEX", "LUATEX", "LaTeX", "Lacute", "LamSTeX", "Lambda", "Lbar", "Lcaron", "Lcommaaccent", "Ldotmiddle", "Ldsh", "Leftarrow", "Leftrightarrow", "Ljligature", "Lleftarrow", "Longleftarrow", "Longleftrightarrow", "Longmapsfrom", "Longmapsto", "Longrightarrow", "Lsh", "Lstroke", "Lua", "LuaTeX", "LuajitTeX", "METAFONT", "METAFUN", "METAPOST", "MKII", "MKIV", "MKIX", "MKVI", "MKXI", "MONTH", "MONTHLONG", "MONTHSHORT", "MPII", "MPIV", "MPVI", "MPanchor", "MPbetex", "MPc", "MPcode", "MPcolor", "MPcoloronly", "MPcolumn", "MPd", "MPdrawing", "MPfontsizehskip", "MPgetmultipars", "MPgetmultishape", "MPgetposboxes", "MPh", "MPinclusions", "MPleftskip", "MPll", "MPlr", "MPls", "MPmenubuttons", "MPn", "MPoptions", "MPoverlayanchor", "MPp", "MPpage", "MPpardata", "MPplus", "MPpos", "MPpositiongraphic", "MPposset", "MPr", "MPrawvar", "MPregion", "MPrest", "MPrightskip", "MPrs", "MPstring", "MPtext", "MPtransparency", "MPul", "MPur", "MPv", "MPvar", "MPvariable", "MPvv", "MPw", "MPwhd", "MPx", "MPxy", "MPxywhd", "MPy", "Mapsfrom", "Mapsto", "MetaFont", "MetaFun", "MetaPost", "Mu", "NJligature", "Nacute", "Ncaron", "Ncommaaccent", "Nearrow", "Neng", "Ngrave", "Njligature", "NormalizeFontHeight", "NormalizeFontWidth", "NormalizeTextHeight", "NormalizeTextWidth", "Ntilde", "Nu", "Numbers", "Nwarrow", "OEligature", "Oacute", "Obreve", "Ocaron", "Ocircumflex", "Ocircumflexacute", "Ocircumflexdotbelow", "Ocircumflexgrave", "Ocircumflexhook", "Ocircumflextilde", "Odiaeresis", "Odiaeresismacron", "Odotaccent", "Odotaccentmacron", "Odotbelow", "Odoublegrave", "Ograve", "Ohook", "Ohorn", "Ohornacute", "Ohorndotbelow", "Ohorngrave", "Ohornhook", "Ohorntilde", "Ohungarumlaut", "Oinvertedbreve", "Omacron", "Omega", "Omicron", "Oogonek", "Oogonekmacron", "Ostroke", "Ostrokeacute", "Otilde", "Otildemacron", "P", "PDFETEX", "PDFTEX", "PDFcolor", "PICTEX", "PPCHTEX", "PPCHTeX", "PRAGMA", "Phi", "Phook", "Pi", "PiCTeX", "Plankconst", "PointsToBigPoints", "PointsToReal", "PointsToWholeBigPoints", "PropertyLine", "Psi", "PtToCm", "Racute", "Rcaron", "Rcommaaccent", "Rdoublegrave", "Rdsh", "Re", "ReadFile", "Relbar", "Rho", "Rightarrow", "Rinvertedbreve", "Romannumerals", "Rrightarrow", "Rsh", "S", "Sacute", "ScaledPointsToBigPoints", "ScaledPointsToWholeBigPoints", "Scaron", "Scedilla", "Schwa", "Scircumflex", "Scommaaccent", "Searrow", "Sigma", "Smallcapped", "Subset", "Supset", "Swarrow", "TABLE", "TEX", "TaBlE", "Tau", "Tcaron", "Tcedilla", "Tcommaaccent", "TeX", "TheNormalizedFontSize", "Theta", "Thook", "Thorn", "TransparencyHack", "Tstroke", "Uacute", "Ubreve", "Ucaron", "Ucircumflex", "Udiaeresis", "Udiaeresisacute", "Udiaeresiscaron", "Udiaeresisgrave", "Udiaeresismacron", "Udotbelow", "Udoublegrave", "Ugrave", "Uhook", "Uhorn", "Uhornacute", "Uhorndotbelow", "Uhorngrave", "Uhornhook", "Uhorntilde", "Uhungarumlaut", "Uinvertedbreve", "Umacron", "Uogonek", "Uparrow", "Updownarrow", "Upsilon", "Uring", "Utilde", "Uuparrow", "VDash", "Vdash", "VerboseNumber", "Vert", "Vvdash", "WEEKDAY", "WORD", "WORDS", "Wcircumflex", "WidthSpanningText", "Word", "Words", "XETEX", "XeTeX", "Xi", "Yacute", "Ycircumflex", "Ydiaeresis", "Ydotbelow", "Ygrave", "Yhook", "Ymacron", "Ytilde", "Zacute", "Zcaron", "Zdotaccent", "Zeta", "Zhook", "Zstroke", "aacute", "abbreviation", "abjadnaivenumerals", "abjadnodotnumerals", "abjadnumerals", "about", "abreve", "abreveacute", "abrevedotbelow", "abrevegrave", "abrevehook", "abrevetilde", "acaron", "acircumflex", "acircumflexacute", "acircumflexdotbelow", "acircumflexgrave", "acircumflexhook", "acircumflextilde", "activatespacehandler", "actuarial", "acute", "acwopencirclearrow", "adaptcollector", "adaptfontfeature", "adaptlayout", "adaptpapersize", "addfeature", "addfontpath", "addtoJSpreamble", "addtocommalist", "addvalue", "adiaeresis", "adiaeresismacron", "adotaccent", "adotaccentmacron", "adotbelow", "adoublegrave", "aeacute", "aeligature", "aemacron", "afghanicurrency", "aftersplitstring", "aftertestandsplitstring", "agrave", "ahook", "ainvertedbreve", "aleph", "alignbottom", "aligned", "alignedbox", "alignedline", "alignhere", "alignmentcharacter", "allinputpaths", "alpha", "alphabeticnumerals", "alwayscitation", "alwayscite", "amacron", "amalg", "ampersand", "anchor", "angle", "aogonek", "appendetoks", "appendgvalue", "appendtocommalist", "appendtoks", "appendtoksonce", "appendvalue", "apply", "applyalternativestyle", "applyprocessor", "applytocharacters", "applytofirstcharacter", "applytosplitstringchar", "applytosplitstringcharspaced", "applytosplitstringline", "applytosplitstringlinespaced", "applytosplitstringword", "applytosplitstringwordspaced", "applytowords", "approx", "approxEq", "approxeq", "approxnEq", "arabicakbar", "arabicalayhe", "arabicallah", "arabicallallahou", "arabicasterisk", "arabicbasmalah", "arabiccomma", "arabiccuberoot", "arabicdateseparator", "arabicdecimals", "arabicdisputedendofayah", "arabicendofayah", "arabicexnumerals", "arabicfootnotemarker", "arabicfourthroot", "arabichighain", "arabichighalayheassallam", "arabichigheqala", "arabichighesala", "arabichighfootnotemarker", "arabichighjeem", "arabichighlamalef", "arabichighmadda", "arabichighmeemlong", "arabichighmeemshort", "arabichighnisf", "arabichighnoon", "arabichighnoonkasra", "arabichighqaf", "arabichighqif", "arabichighradiallahouanhu", "arabichighrahmatullahalayhe", "arabichighrubc", "arabichighsad", "arabichighsajda", "arabichighsakta", "arabichighsallallahou", "arabichighseen", "arabichighsmallsafha", "arabichightah", "arabichightakhallus", "arabichighthalatha", "arabichighwaqf", "arabichighyeh", "arabichighzain", "arabicjallajalalouhou", "arabiclettermark", "arabiclowmeemlong", "arabiclownoonkasra", "arabiclowseen", "arabicmisra", "arabicmuhammad", "arabicnumber", "arabicnumberabove", "arabicnumerals", "arabicparenleft", "arabicparenright", "arabicpercent", "arabicperiod", "arabicpermille", "arabicpertenthousand", "arabicpoeticverse", "arabicqala", "arabicquestion", "arabicrasoul", "arabicray", "arabicrialsign", "arabicsafha", "arabicsajdah", "arabicsalla", "arabicsamvat", "arabicsanah", "arabicsemicolon", "arabicshighthreedots", "arabicslcm", "arabicstartofrubc", "arabictripledot", "arabicvowelwaw", "arabicvowelyeh", "arabicwasallam", "arg", "aring", "aringacute", "arrowvert", "asciistr", "aside", "assignalfadimension", "assigndimen", "assigndimension", "assignifempty", "assigntranslation", "assignvalue", "assignwidth", "assumelongusagecs", "ast", "astype", "asymp", "at", "atilde", "atleftmargin", "atpage", "atrightmargin", "attachment", "autocap", "autodirhbox", "autodirvbox", "autodirvtop", "autoinsertnextspace", "autointegral", "automathematics", "autosetups", "availablehsize", "averagecharwidth", "backepsilon", "background", "backgroundimage", "backgroundimagefill", "backgroundline", "backprime", "backsim", "backslash", "bar", "barleftarrow", "barleftarrowrightarrowbar", "barovernorthwestarrow", "barwedge", "basegrid", "baselinebottom", "baselineleftbox", "baselinemiddlebox", "baselinerightbox", "bbordermatrix", "bbox", "because", "beforesplitstring", "beforetestandsplitstring", "beta", "beth", "between", "bhook", "big", "bigbodyfont", "bigcap", "bigcirc", "bigcircle", "bigcup", "bigdiamond", "bigg", "bigger", "biggl", "biggm", "biggr", "bigl", "bigm", "bigodot", "bigoplus", "bigotimes", "bigr", "bigskip", "bigsqcap", "bigsqcup", "bigsquare", "bigstar", "bigtimes", "bigtriangledown", "bigtriangleup", "bigudot", "biguplus", "bigvee", "bigwedge", "binom", "bitmapimage", "blacklozenge", "blackrule", "blackrules", "blacksquare", "blacktriangle", "blacktriangledown", "blacktriangleleft", "blacktriangleright", "blank", "blap", "bleed", "bleedheight", "bleedwidth", "blockligatures", "blockquote", "blocksynctexfile", "bodyfontenvironmentlist", "bodyfontsize", "bold", "boldface", "bolditalic", "boldslanted", "bookmark", "booleanmodevalue", "bordermatrix", "bot", "bottombox", "bottomleftbox", "bottomrightbox", "bowtie", "boxcursor", "boxdot", "boxmarker", "boxminus", "boxofsize", "boxplus", "boxreference", "boxtimes", "bpos", "breakablethinspace", "breakhere", "breve", "bstroke", "btxabbreviatedjournal", "btxaddjournal", "btxalwayscitation", "btxauthorfield", "btxdetail", "btxdirect", "btxdoif", "btxdoifcombiinlistelse", "btxdoifelse", "btxdoifelsecombiinlist", "btxdoifelsesameasprevious", "btxdoifelsesameaspreviouschecked", "btxdoifelseuservariable", "btxdoifnot", "btxdoifsameaspreviouscheckedelse", "btxdoifsameaspreviouselse", "btxdoifuservariableelse", "btxexpandedjournal", "btxfield", "btxfieldname", "btxfieldtype", "btxfirstofrange", "btxflush", "btxflushauthor", "btxflushauthorinverted", "btxflushauthorinvertedshort", "btxflushauthorname", "btxflushauthornormal", "btxflushauthornormalshort", "btxflushsuffix", "btxfoundname", "btxfoundtype", "btxhiddencitation", "btxhybridcite", "btxlabellanguage", "btxlabeltext", "btxlistcitation", "btxloadjournalist", "btxoneorrange", "btxremapauthor", "btxsavejournalist", "btxsetup", "btxsingularorplural", "btxsingularplural", "btxtextcitation", "buildmathaccent", "buildtextaccent", "buildtextbottomcomma", "buildtextbottomdot", "buildtextcedilla", "buildtextgrave", "buildtextmacron", "buildtextognek", "bullet", "button", "cacute", "calligraphic", "camel", "cap", "carriagereturn", "catcodetablename", "cbox", "ccaron", "ccedilla", "ccircumflex", "ccurl", "cdot", "cdotaccent", "cdotp", "cdots", "centeraligned", "centerbox", "centerdot", "centeredbox", "centeredlastline", "centerednextbox", "centerline", "cfrac", "chapter", "character", "characters", "chardescription", "charwidthlanguage", "check", "checkcharacteralign", "checkedchar", "checkedfiller", "checkedstrippedcsname", "checkinjector", "checkmark", "checknextindentation", "checknextinjector", "checkpage", "checkparameters", "checkpreviousinjector", "checksoundtrack", "checktwopassdata", "checkvariables", "chem", "chemical", "chemicalbottext", "chemicalmidtext", "chemicalsymbol", "chemicaltext", "chemicaltoptext", "chi", "chineseallnumerals", "chinesecapnumerals", "chinesenumerals", "chook", "circ", "circeq", "circlearrowleft", "circlearrowright", "circledR", "circledS", "circledast", "circledcirc", "circleddash", "circledequals", "circleonrightarrow", "citation", "cite", "clap", "classfont", "cldcommand", "cldcontext", "cldloadfile", "cldprocessfile", "cleftarrow", "clip", "clonefield", "clubsuit", "collect", "collectedtext", "collectexpanded", "colon", "coloncolonequals", "colonequals", "color", "colorbar", "colorcomponents", "colored", "coloronly", "colorvalue", "column", "columnbreak", "combinepages", "commalistelement", "commalistsentence", "commalistsize", "comment", "comparecolorgroup", "comparedimension", "comparedimensioneps", "comparepalet", "complement", "completebtxrendering", "completecontent", "completeindex", "completelist", "completelistofabbreviations", "completelistofchemicals", "completelistoffigures", "completelistofgraphics", "completelistofintermezzi", "completelistoflogos", "completelistofpublications", "completelistofsorts", "completelistofsynonyms", "completelistoftables", "completepagenumber", "completeregister", "complexes", "complexorsimple", "complexorsimpleempty", "component", "composedcollector", "composedlayer", "compresult", "cong", "constantdimen", "constantdimenargument", "constantemptyargument", "constantnumber", "constantnumberargument", "contentreference", "continuednumber", "continueifinputfile", "convertargument", "convertcommand", "convertedcounter", "converteddimen", "convertedsubcounter", "convertmonth", "convertnumber", "convertvalue", "convertvboxtohbox", "coprod", "copyboxfromcache", "copybtxlabeltext", "copyfield", "copyheadtext", "copylabeltext", "copymathlabeltext", "copyoperatortext", "copypages", "copyparameters", "copyposition", "copyprefixtext", "copyright", "copysuffixtext", "copytaglabeltext", "copyunittext", "correctwhitespace", "countersubs", "counttoken", "counttokens", "cramped", "crampedclap", "crampedllap", "crampedrlap", "crightarrow", "crightoverleftarrow", "cstroke", "ctop", "ctxcommand", "ctxdirectcommand", "ctxdirectlua", "ctxfunction", "ctxlatecommand", "ctxlatelua", "ctxloadluafile", "ctxlua", "ctxluabuffer", "ctxluacode", "ctxreport", "ctxsprint", "cup", "curlyeqprec", "curlyeqsucc", "curlyvee", "curlywedge", "currentassignmentlistkey", "currentassignmentlistvalue", "currentbtxuservariable", "currentcommalistitem", "currentcomponent", "currentdate", "currentenvironment", "currentfeaturetest", "currentheadnumber", "currentinterface", "currentlanguage", "currentlistentrydestinationattribute", "currentlistentrylimitedtext", "currentlistentrynumber", "currentlistentrypagenumber", "currentlistentryreferenceattribute", "currentlistentrytitle", "currentlistentrytitlerendered", "currentlistsymbol", "currentmainlanguage", "currentmessagetext", "currentmoduleparameter", "currentoutputstream", "currentproduct", "currentproject", "currentregime", "currentregisterpageuserdata", "currentresponses", "currenttime", "currentvalue", "currentxtablecolumn", "currentxtablerow", "curvearrowleft", "curvearrowright", "cwopencirclearrow", "cyrillicA", "cyrillicAE", "cyrillicAbreve", "cyrillicAdiaeresis", "cyrillicB", "cyrillicBIGYUS", "cyrillicBIGYUSiotified", "cyrillicC", "cyrillicCH", "cyrillicCHEDC", "cyrillicCHEDCabkhasian", "cyrillicCHEabkhasian", "cyrillicCHEdiaeresis", "cyrillicCHEkhakassian", "cyrillicCHEvertstroke", "cyrillicD", "cyrillicDASIAPNEUMATA", "cyrillicDJE", "cyrillicDZE", "cyrillicDZEabkhasian", "cyrillicDZHE", "cyrillicE", "cyrillicELtail", "cyrillicEMtail", "cyrillicENDC", "cyrillicENGHE", "cyrillicENhook", "cyrillicENtail", "cyrillicEREV", "cyrillicERY", "cyrillicERtick", "cyrillicEbreve", "cyrillicEdiaeresis", "cyrillicEgrave", "cyrillicEiotified", "cyrillicF", "cyrillicFITA", "cyrillicG", "cyrillicGHEmidhook", "cyrillicGHEstroke", "cyrillicGHEupturn", "cyrillicGJE", "cyrillicH", "cyrillicHA", "cyrillicHADC", "cyrillicHRDSN", "cyrillicI", "cyrillicIE", "cyrillicII", "cyrillicISHRT", "cyrillicISHRTtail", "cyrillicIZHITSA", "cyrillicIZHITSAdoublegrave", "cyrillicIdiaeresis", "cyrillicIgrave", "cyrillicImacron", "cyrillicJE", "cyrillicK", "cyrillicKADC", "cyrillicKAbashkir", "cyrillicKAhook", "cyrillicKAstroke", "cyrillicKAvertstroke", "cyrillicKJE", "cyrillicKOPPA", "cyrillicKSI", "cyrillicL", "cyrillicLITTLEYUS", "cyrillicLITTLEYUSiotified", "cyrillicLJE", "cyrillicM", "cyrillicN", "cyrillicNJE", "cyrillicO", "cyrillicOMEGA", "cyrillicOMEGAround", "cyrillicOMEGAtitlo", "cyrillicOT", "cyrillicObarred", "cyrillicObarreddiaeresis", "cyrillicOdiaeresis", "cyrillicP", "cyrillicPALATALIZATION", "cyrillicPALOCHKA", "cyrillicPEmidhook", "cyrillicPSI", "cyrillicPSILIPNEUMATA", "cyrillicR", "cyrillicS", "cyrillicSCHWA", "cyrillicSCHWAdiaeresis", "cyrillicSDSC", "cyrillicSEMISOFT", "cyrillicSFTSN", "cyrillicSH", "cyrillicSHCH", "cyrillicSHHA", "cyrillicT", "cyrillicTEDC", "cyrillicTETSE", "cyrillicTITLO", "cyrillicTSHE", "cyrillicU", "cyrillicUK", "cyrillicUSHRT", "cyrillicUdiaeresis", "cyrillicUdoubleacute", "cyrillicUmacron", "cyrillicV", "cyrillicYA", "cyrillicYAT", "cyrillicYERUdiaeresis", "cyrillicYI", "cyrillicYO", "cyrillicYU", "cyrillicYstr", "cyrillicYstrstroke", "cyrillicZ", "cyrillicZDSC", "cyrillicZEdiaeresis", "cyrillicZH", "cyrillicZHEbreve", "cyrillicZHEdescender", "cyrillicZHEdiaeresis", "cyrillica", "cyrillicabreve", "cyrillicadiaeresis", "cyrillicae", "cyrillicb", "cyrillicbigyus", "cyrillicbigyusiotified", "cyrillicc", "cyrillicch", "cyrilliccheabkhasian", "cyrillicchedc", "cyrillicchedcabkhasian", "cyrillicchediaeresis", "cyrillicchekhakassian", "cyrillicchevertstroke", "cyrillicd", "cyrillicdje", "cyrillicdze", "cyrillicdzeabkhasian", "cyrillicdzhe", "cyrillice", "cyrillicebreve", "cyrillicediaeresis", "cyrillicegrave", "cyrilliceiotified", "cyrilliceltail", "cyrillicemtail", "cyrillicendc", "cyrillicenghe", "cyrillicenhook", "cyrillicentail", "cyrillicerev", "cyrillicertick", "cyrillicery", "cyrillicf", "cyrillicfita", "cyrillicg", "cyrillicghemidhook", "cyrillicghestroke", "cyrillicgheupturn", "cyrillicgje", "cyrillich", "cyrillicha", "cyrillichadc", "cyrillichrdsn", "cyrillici", "cyrillicidiaeresis", "cyrillicie", "cyrillicigrave", "cyrillicii", "cyrillicimacron", "cyrillicishrt", "cyrillicishrttail", "cyrillicizhitsa", "cyrillicizhitsadoublegrave", "cyrillicje", "cyrillick", "cyrillickabashkir", "cyrillickadc", "cyrillickahook", "cyrillickastroke", "cyrillickavertstroke", "cyrillickje", "cyrillickoppa", "cyrillicksi", "cyrillicl", "cyrilliclittleyus", "cyrilliclittleyusiotified", "cyrilliclje", "cyrillicm", "cyrillicn", "cyrillicnje", "cyrillico", "cyrillicobarred", "cyrillicobarreddiaeresis", "cyrillicodiaeresis", "cyrillicomega", "cyrillicomegaround", "cyrillicomegatitlo", "cyrillicot", "cyrillicp", "cyrillicpemidhook", "cyrillicpsi", "cyrillicr", "cyrillics", "cyrillicschwa", "cyrillicschwadiaeresis", "cyrillicsdsc", "cyrillicsemisoft", "cyrillicsftsn", "cyrillicsh", "cyrillicshch", "cyrillicshha", "cyrillict", "cyrillictedc", "cyrillictetse", "cyrillictshe", "cyrillicu", "cyrillicudiaeresis", "cyrillicudoubleacute", "cyrillicuk", "cyrillicumacron", "cyrillicushrt", "cyrillicv", "cyrillicya", "cyrillicyat", "cyrillicyerudiaeresis", "cyrillicyi", "cyrillicyo", "cyrillicystr", "cyrillicystrstroke", "cyrillicyu", "cyrillicz", "cyrilliczdsc", "cyrilliczediaeresis", "cyrilliczh", "cyrilliczhebreve", "cyrilliczhedescender", "cyrilliczhediaeresis", "d", "dag", "dagger", "daleth", "dasharrow", "dashedleftarrow", "dashedrightarrow", "dashv", "datasetvariable", "date", "dayoftheweek", "dayspermonth", "dbinom", "dcaron", "dcurl", "ddag", "ddagger", "dddot", "ddot", "ddots", "decrement", "decrementcounter", "decrementedcounter", "decrementpagenumber", "decrementsubpagenumber", "decrementvalue", "defaultinterface", "defaultobjectpage", "defaultobjectreference", "defcatcodecommand", "defconvertedargument", "defconvertedcommand", "defconvertedvalue", "define", "defineMPinstance", "defineTABLEsetup", "defineaccent", "defineactivecharacter", "definealternativestyle", "defineanchor", "defineattachment", "defineattribute", "definebackground", "definebar", "defineblock", "definebodyfont", "definebodyfontenvironment", "definebodyfontswitch", "definebreakpoint", "definebreakpoints", "definebtx", "definebtxdataset", "definebtxregister", "definebtxrendering", "definebuffer", "definebutton", "definecapitals", "definecharacter", "definecharacterkerning", "definecharacterspacing", "definechemical", "definechemicals", "definechemicalsymbol", "definecollector", "definecolor", "definecolorgroup", "definecolumnbreak", "definecombination", "definecombinedlist", "definecommand", "definecomment", "definecomplexorsimple", "definecomplexorsimpleempty", "defineconversion", "defineconversionset", "definecounter", "definedataset", "definedelimitedtext", "definedeq", "definedescription", "definedfont", "defineeffect", "defineenumeration", "defineexpandable", "defineexternalfigure", "definefallbackfamily", "definefield", "definefieldbody", "definefieldbodyset", "definefieldcategory", "definefieldstack", "definefiguresymbol", "definefileconstant", "definefilefallback", "definefilesynonym", "definefiller", "definefirstline", "definefittingpage", "definefloat", "definefont", "definefontalternative", "definefontfallback", "definefontfamily", "definefontfamilypreset", "definefontfeature", "definefontfile", "definefontsize", "definefontsolution", "definefontstyle", "definefontsynonym", "defineformula", "defineformulaalternative", "defineformulaframed", "defineframed", "defineframedcontent", "defineframedtable", "defineframedtext", "definefrozenfont", "defineglobalcolor", "definegraphictypesynonym", "definegridsnapping", "definehbox", "definehead", "defineheadalternative", "definehelp", "definehigh", "definehighlight", "definehspace", "definehypenationfeatures", "defineindentedtext", "defineindenting", "defineinitial", "defineinsertion", "defineinteraction", "defineinteractionbar", "defineinteractionmenu", "defineinterfaceconstant", "defineinterfaceelement", "defineinterfacevariable", "defineinterlinespace", "defineintermediatecolor", "defineitemgroup", "defineitems", "definelabel", "definelabelclass", "definelayer", "definelayerpreset", "definelayout", "definelinefiller", "definelinenote", "definelinenumbering", "definelines", "definelist", "definelistalternative", "definelistextra", "definelow", "definelowhigh", "definelowmidhigh", "definemakeup", "definemarginblock", "definemargindata", "definemarker", "definemarking", "definemathaccent", "definemathalignment", "definemathcases", "definemathcommand", "definemathdouble", "definemathdoubleextensible", "definemathematics", "definemathextensible", "definemathfence", "definemathfraction", "definemathframed", "definemathmatrix", "definemathornament", "definemathover", "definemathoverextensible", "definemathovertextextensible", "definemathradical", "definemathstackers", "definemathstyle", "definemathtriplet", "definemathunder", "definemathunderextensible", "definemathundertextextensible", "definemathunstacked", "definemeasure", "definemessageconstant", "definemixedcolumns", "definemode", "definemultitonecolor", "definenamedcolor", "definenamespace", "definenarrower", "definenote", "defineornament", "defineoutputroutine", "defineoutputroutinecommand", "defineoverlay", "definepage", "definepagebreak", "definepagechecker", "definepagegrid", "definepagegridarea", "definepagegridspan", "definepageinjection", "definepageinjectionalternative", "definepageshift", "definepagestate", "definepairedbox", "definepalet", "definepapersize", "defineparagraph", "defineparagraphs", "defineparallel", "defineparbuilder", "defineplacement", "definepositioning", "defineprefixset", "defineprocesscolor", "defineprocessor", "defineprofile", "defineprogram", "definepushbutton", "definepushsymbol", "definereference", "definereferenceformat", "defineregister", "definerenderingwindow", "defineresetset", "definescale", "definescript", "definesection", "definesectionblock", "definesectionlevels", "defineselector", "defineseparatorset", "defineshift", "definesidebar", "definesort", "definesorting", "definespotcolor", "definestartstop", "definestyle", "definestyleinstance", "definesubfield", "definesubformula", "definesymbol", "definesynonym", "definesynonyms", "definesystemattribute", "definesystemconstant", "definesystemvariable", "definetabletemplate", "definetabulate", "definetabulation", "definetext", "definetextbackground", "definetextflow", "definetooltip", "definetransparency", "definetwopasslist", "definetype", "definetypeface", "definetypescriptprefix", "definetypescriptsynonym", "definetypesetting", "definetyping", "defineunit", "defineviewerlayer", "definevspace", "definevspacing", "definevspacingamount", "definextable", "delimited", "delimitedtext", "delta", "depthofstring", "depthonlybox", "depthspanningtext", "depthstrut", "determineheadnumber", "determinelistcharacteristics", "determinenoflines", "determineregistercharacteristics", "devanagarinumerals", "dfrac", "dhook", "diameter", "diamond", "diamondsuit", "differentialD", "differentiald", "digamma", "digits", "dimensiontocount", "directboxfromcache", "directcolor", "directcolored", "directconvertedcounter", "directcopyboxfromcache", "directdummyparameter", "directgetboxllx", "directgetboxlly", "directhighlight", "directlocalframed", "directluacode", "directselect", "directsetbar", "directsetup", "directsymbol", "directvspacing", "dis", "disabledirectives", "disableexperiments", "disablemode", "disableoutputstream", "disableparpositions", "disableregime", "disabletrackers", "displaymath", "displaymathematics", "displaymessage", "distributedhsize", "div", "dividedsize", "divideontimes", "divides", "doadaptleftskip", "doadaptrightskip", "doaddfeature", "doassign", "doassignempty", "doboundtext", "docheckassignment", "docheckedpagestate", "docheckedpair", "documentvariable", "dodoubleargument", "dodoubleargumentwithset", "dodoubleempty", "dodoubleemptywithset", "dodoublegroupempty", "doeassign", "doexpandedrecurse", "dofastloopcs", "dogetattribute", "dogetattributeid", "dogetcommacommandelement", "dogobbledoubleempty", "dogobblesingleempty", "doif", "doifMPgraphicelse", "doifallcommon", "doifallcommonelse", "doifalldefinedelse", "doifallmodes", "doifallmodeselse", "doifassignmentelse", "doifblackelse", "doifbothsides", "doifbothsidesoverruled", "doifboxelse", "doifbufferelse", "doifcolor", "doifcolorelse", "doifcommandhandler", "doifcommandhandlerelse", "doifcommon", "doifcommonelse", "doifcontent", "doifconversiondefinedelse", "doifconversionnumberelse", "doifcounter", "doifcounterelse", "doifcurrentfonthasfeatureelse", "doifdefined", "doifdefinedcounter", "doifdefinedcounterelse", "doifdefinedelse", "doifdimensionelse", "doifdimenstringelse", "doifdocumentargument", "doifdocumentargumentelse", "doifdocumentfilename", "doifdocumentfilenameelse", "doifdrawingblackelse", "doifelse", "doifelseMPgraphic", "doifelseallcommon", "doifelsealldefined", "doifelseallmodes", "doifelseassignment", "doifelseblack", "doifelsebox", "doifelseboxincache", "doifelsebuffer", "doifelsecolor", "doifelsecommandhandler", "doifelsecommon", "doifelseconversiondefined", "doifelseconversionnumber", "doifelsecounter", "doifelsecurrentfonthasfeature", "doifelsecurrentsortingused", "doifelsecurrentsynonymshown", "doifelsecurrentsynonymused", "doifelsedefined", "doifelsedefinedcounter", "doifelsedimension", "doifelsedimenstring", "doifelsedocumentargument", "doifelsedocumentfilename", "doifelsedrawingblack", "doifelseempty", "doifelseemptyvalue", "doifelseemptyvariable", "doifelseenv", "doifelsefastoptionalcheck", "doifelsefastoptionalcheckcs", "doifelsefieldbody", "doifelsefieldcategory", "doifelsefigure", "doifelsefile", "doifelsefiledefined", "doifelsefileexists", "doifelsefirstchar", "doifelseflagged", "doifelsefontchar", "doifelsefontpresent", "doifelsefontsynonym", "doifelsehasspace", "doifelsehelp", "doifelseincsname", "doifelseinelement", "doifelseinputfile", "doifelseinsertion", "doifelseinset", "doifelseinstring", "doifelseinsymbolset", "doifelseintoks", "doifelseintwopassdata", "doifelseitalic", "doifelselanguage", "doifelselayerdata", "doifelselayoutdefined", "doifelselayoutsomeline", "doifelselayouttextline", "doifelseleapyear", "doifelselist", "doifelselocation", "doifelselocfile", "doifelsemainfloatbody", "doifelsemarkedpage", "doifelsemarking", "doifelsemeaning", "doifelsemessage", "doifelsemode", "doifelsenextbgroup", "doifelsenextbgroupcs", "doifelsenextchar", "doifelsenextoptional", "doifelsenextoptionalcs", "doifelsenextparenthesis", "doifelsenonzeropositive", "doifelsenoteonsamepage", "doifelsenothing", "doifelsenumber", "doifelseobjectfound", "doifelseobjectreferencefound", "doifelseoddpage", "doifelseoddpagefloat", "doifelseoldercontext", "doifelseolderversion", "doifelseoverlapping", "doifelseoverlay", "doifelseparallel", "doifelseparentfile", "doifelsepath", "doifelsepathexists", "doifelsepatterns", "doifelseposition", "doifelsepositionaction", "doifelsepositiononpage", "doifelsepositionsonsamepage", "doifelsepositionsonthispage", "doifelsepositionsused", "doifelsereferencefound", "doifelserightpagefloat", "doifelserighttoleftinbox", "doifelsesamelinereference", "doifelsesamestring", "doifelsesetups", "doifelsesomebackground", "doifelsesomespace", "doifelsesomething", "doifelsesometoks", "doifelsestringinstring", "doifelsestructurelisthasnumber", "doifelsestructurelisthaspage", "doifelsesymboldefined", "doifelsesymbolset", "doifelsetext", "doifelsetextflow", "doifelsetextflowcollector", "doifelsetopofpage", "doifelsetypingfile", "doifelseundefined", "doifelseurldefined", "doifelsevalue", "doifelsevaluenothing", "doifelsevariable", "doifempty", "doifemptyelse", "doifemptytoks", "doifemptyvalue", "doifemptyvalueelse", "doifemptyvariable", "doifemptyvariableelse", "doifenv", "doifenvelse", "doiffastoptionalcheckcselse", "doiffastoptionalcheckelse", "doiffieldbodyelse", "doiffieldcategoryelse", "doiffigureelse", "doiffile", "doiffiledefinedelse", "doiffileelse", "doiffileexistselse", "doiffirstcharelse", "doifflaggedelse", "doiffontcharelse", "doiffontpresentelse", "doiffontsynonymelse", "doifhasspaceelse", "doifhelpelse", "doifincsnameelse", "doifinelementelse", "doifinputfileelse", "doifinsertionelse", "doifinset", "doifinsetelse", "doifinstring", "doifinstringelse", "doifinsymbolset", "doifinsymbolsetelse", "doifintokselse", "doifintwopassdataelse", "doifitalicelse", "doiflanguageelse", "doiflayerdataelse", "doiflayoutdefinedelse", "doiflayoutsomelineelse", "doiflayouttextlineelse", "doifleapyearelse", "doiflistelse", "doiflocationelse", "doiflocfileelse", "doifmainfloatbodyelse", "doifmarkingelse", "doifmeaningelse", "doifmessageelse", "doifmode", "doifmodeelse", "doifnextbgroupcselse", "doifnextbgroupelse", "doifnextcharelse", "doifnextoptionalcselse", "doifnextoptionalelse", "doifnextparenthesiselse", "doifnonzeropositiveelse", "doifnot", "doifnotallcommon", "doifnotallmodes", "doifnotcommandhandler", "doifnotcommon", "doifnotcounter", "doifnotdocumentargument", "doifnotdocumentfilename", "doifnotempty", "doifnotemptyvalue", "doifnotemptyvariable", "doifnotenv", "doifnoteonsamepageelse", "doifnotescollected", "doifnotfile", "doifnotflagged", "doifnothing", "doifnothingelse", "doifnotinset", "doifnotinsidesplitfloat", "doifnotinstring", "doifnotmode", "doifnotnumber", "doifnotsamestring", "doifnotsetups", "doifnotvalue", "doifnotvariable", "doifnumber", "doifnumberelse", "doifobjectfoundelse", "doifobjectreferencefoundelse", "doifoddpageelse", "doifoddpagefloatelse", "doifoldercontextelse", "doifolderversionelse", "doifoverlappingelse", "doifoverlayelse", "doifparallelelse", "doifparentfileelse", "doifpathelse", "doifpathexistselse", "doifpatternselse", "doifposition", "doifpositionaction", "doifpositionactionelse", "doifpositionelse", "doifpositiononpageelse", "doifpositionsonsamepageelse", "doifpositionsonthispageelse", "doifpositionsusedelse", "doifreferencefoundelse", "doifrightpagefloatelse", "doifrighttoleftinboxelse", "doifsamelinereferenceelse", "doifsamestring", "doifsamestringelse", "doifsetups", "doifsetupselse", "doifsomebackground", "doifsomebackgroundelse", "doifsomespaceelse", "doifsomething", "doifsomethingelse", "doifsometoks", "doifsometokselse", "doifstringinstringelse", "doifstructurelisthasnumberelse", "doifstructurelisthaspageelse", "doifsymboldefinedelse", "doifsymbolsetelse", "doiftext", "doiftextelse", "doiftextflowcollectorelse", "doiftextflowelse", "doiftopofpageelse", "doiftypingfileelse", "doifundefined", "doifundefinedcounter", "doifundefinedelse", "doifurldefinedelse", "doifvalue", "doifvalueelse", "doifvaluenothing", "doifvaluenothingelse", "doifvaluesomething", "doifvariable", "doifvariableelse", "doindentation", "dollar", "doloop", "doloopoverlist", "donothing", "dontconvertfont", "dontleavehmode", "dontpermitspacesbetweengroups", "dopositionaction", "doprocesslocalsetups", "doquadrupleargument", "doquadrupleempty", "doquadruplegroupempty", "doquintupleargument", "doquintupleempty", "doquintuplegroupempty", "dorechecknextindentation", "dorecurse", "dorepeatwithcommand", "doreplacefeature", "doresetandafffeature", "doresetattribute", "dorotatebox", "dosetattribute", "dosetleftskipadaption", "dosetrightskipadaption", "dosetupcheckedinterlinespace", "doseventupleargument", "doseventupleempty", "dosingleargument", "dosingleempty", "dosinglegroupempty", "dosixtupleargument", "dosixtupleempty", "dostepwiserecurse", "dosubtractfeature", "dot", "doteq", "doteqdot", "dotfskip", "dotlessI", "dotlessJ", "dotlessi", "dotlessj", "dotlessjstroke", "dotminus", "dotoks", "dotplus", "dotripleargument", "dotripleargumentwithset", "dotripleempty", "dotripleemptywithset", "dotriplegroupempty", "dots", "dottedcircle", "dottedrightarrow", "doublebar", "doublebond", "doublebrace", "doublebracket", "doublecap", "doublecup", "doubleparent", "doubleprime", "doubleverticalbar", "dowith", "dowithnextbox", "dowithnextboxcontent", "dowithnextboxcontentcs", "dowithnextboxcs", "dowithpargument", "dowithrange", "dowithwargument", "downarrow", "downdasharrow", "downdownarrows", "downharpoonleft", "downharpoonright", "downuparrows", "downwhitearrow", "downzigzagarrow", "dpofstring", "dstroke", "dtail", "dummydigit", "dummyparameter", "dzcaronligature", "dzligature", "eTeX", "eacute", "ebreve", "ecaron", "ecedilla", "ecircumflex", "ecircumflexacute", "ecircumflexdotbelow", "ecircumflexgrave", "ecircumflexhook", "ecircumflextilde", "edefconvertedargument", "ediaeresis", "edotaccent", "edotbelow", "edoublegrave", "efcmaxheight", "efcmaxwidth", "efcminheight", "efcminwidth", "efcparameter", "effect", "egrave", "ehook", "einvertedbreve", "elapsedseconds", "elapsedtime", "eleftarrowfill", "eleftharpoondownfill", "eleftharpoonupfill", "eleftrightarrowfill", "ell", "em", "emacron", "emdash", "emphasisboldface", "emphasistypeface", "emptylines", "emptyset", "emquad", "emspace", "enabledirectives", "enableexperiments", "enablemode", "enableoutputstream", "enableparpositions", "enableregime", "enabletrackers", "endash", "endnote", "enquad", "enskip", "enspace", "env", "environment", "envvar", "eogonek", "eoverbarfill", "eoverbracefill", "eoverbracketfill", "eoverparentfill", "epos", "epsilon", "eq", "eqcirc", "eqeq", "eqeqeq", "eqgtr", "eqless", "eqsim", "eqslantgtr", "eqslantless", "equaldigits", "equalscolon", "equiv", "erightarrowfill", "erightharpoondownfill", "erightharpoonupfill", "eta", "eth", "ethiopic", "etilde", "etwoheadrightarrowfill", "eunderbarfill", "eunderbracefill", "eunderbracketfill", "eunderparentfill", "exclamdown", "executeifdefined", "exists", "exitloop", "exitloopnow", "expandcheckedcsname", "expanded", "expandfontsynonym", "expdoif", "expdoifcommonelse", "expdoifelse", "expdoifelsecommon", "expdoifelseinset", "expdoifinsetelse", "expdoifnot", "exponentiale", "externalfigure", "externalfigurecollectionmaxheight", "externalfigurecollectionmaxwidth", "externalfigurecollectionminheight", "externalfigurecollectionminwidth", "externalfigurecollectionparameter", "fakebox", "fallingdotseq", "fastdecrement", "fastincrement", "fastlocalframed", "fastloopfinal", "fastloopindex", "fastscale", "fastsetup", "fastsetupwithargument", "fastsetupwithargumentswapped", "fastswitchtobodyfont", "fastsxsy", "feature", "fence", "fenced", "fetchallmarkings", "fetchallmarks", "fetchmark", "fetchmarking", "fetchonemark", "fetchonemarking", "fetchruntinecommand", "fetchtwomarkings", "fetchtwomarks", "ffiligature", "ffligature", "fflligature", "fhook", "field", "fieldbody", "fieldstack", "fifthoffivearguments", "fifthofsixarguments", "figurefilename", "figurefilepath", "figurefiletype", "figurefullname", "figureheight", "figurenaturalheight", "figurenaturalwidth", "figurespace", "figuresymbol", "figurewidth", "filename", "filigature", "filledhboxb", "filledhboxc", "filledhboxg", "filledhboxk", "filledhboxm", "filledhboxr", "filledhboxy", "filler", "fillinline", "fillinrules", "fillintext", "filterfromnext", "filterfromvalue", "filterpages", "filterreference", "findtwopassdata", "finishregisterentry", "firstcharacter", "firstcounter", "firstcountervalue", "firstoffivearguments", "firstoffourarguments", "firstofoneargument", "firstofoneunexpanded", "firstofsixarguments", "firstofthreearguments", "firstofthreeunexpanded", "firstoftwoarguments", "firstoftwounexpanded", "firstrealpage", "firstrealpagenumber", "firstsubcountervalue", "firstsubpage", "firstsubpagenumber", "firstuserpage", "firstuserpagenumber", "fitfield", "fitfieldframed", "fittopbaselinegrid", "fiveeighths", "fivesixths", "fixedspace", "fixedspaces", "flag", "flat", "flligature", "floatuserdataparameter", "flushbox", "flushboxregister", "flushcollector", "flushedrightlastline", "flushlayer", "flushlocalfloats", "flushnextbox", "flushnotes", "flushoutputstream", "flushshapebox", "flushtextflow", "flushtokens", "flushtoks", "fontalternative", "fontbody", "fontchar", "fontcharbyindex", "fontclass", "fontclassname", "fontface", "fontfeaturelist", "fontsize", "fontstyle", "footnote", "footnotetext", "forall", "forcecharacterstripping", "forcelocalfloats", "forgeteverypar", "forgetparameters", "forgetragged", "formula", "formulanumber", "foundbox", "fourfifths", "fourperemspace", "fourthoffivearguments", "fourthoffourarguments", "fourthofsixarguments", "frac", "framed", "frameddimension", "framedparameter", "framedtext", "freezedimenmacro", "freezemeasure", "frenchspacing", "from", "fromlinenote", "frown", "frozenhbox", "frule", "gacute", "gamma", "gbreve", "gcaron", "gcircumflex", "gcommaaccent", "gdefconvertedargument", "gdefconvertedcommand", "gdotaccent", "ge", "geq", "geqq", "geqslant", "getMPdrawing", "getMPlayer", "getboxfromcache", "getboxllx", "getboxlly", "getbuffer", "getbufferdata", "getcommacommandsize", "getcommalistsize", "getdayoftheweek", "getdayspermonth", "getdefinedbuffer", "getdocumentargument", "getdocumentargumentdefault", "getdocumentfilename", "getdummyparameters", "getemptyparameters", "geteparameters", "getexpandedparameters", "getfiguredimensions", "getfirstcharacter", "getfirsttwopassdata", "getfromcommacommand", "getfromcommalist", "getfromtwopassdata", "getglyphdirect", "getglyphstyled", "getgparameters", "getlasttwopassdata", "getlocalfloat", "getlocalfloats", "getmarking", "getmessage", "getnamedglyphdirect", "getnamedglyphstyled", "getnamedtwopassdatalist", "getnaturaldimensions", "getnoflines", "getobject", "getobjectdimensions", "getpaletsize", "getparameters", "getprivatechar", "getprivateslot", "getrandomcount", "getrandomdimen", "getrandomfloat", "getrandomnumber", "getrandomseed", "getraweparameters", "getrawgparameters", "getrawnoflines", "getrawparameters", "getrawxparameters", "getreference", "getreferenceentry", "getroundednoflines", "gets", "getsubstring", "gettwopassdata", "gettwopassdatalist", "getuvalue", "getvalue", "getvariable", "getvariabledefault", "getxparameters", "gg", "ggg", "gggtr", "gimel", "globaldisablemode", "globalenablemode", "globalletempty", "globalpopbox", "globalpopmacro", "globalpreventmode", "globalprocesscommalist", "globalpushbox", "globalpushmacro", "globalswapcounts", "globalswapdimens", "globalswapmacros", "globalundefine", "glyphfontfile", "gnapprox", "gneqq", "gnsim", "gobbledoubleempty", "gobbleeightarguments", "gobblefivearguments", "gobblefiveoptionals", "gobblefourarguments", "gobblefouroptionals", "gobbleninearguments", "gobbleoneargument", "gobbleoneoptional", "gobblesevenarguments", "gobblesingleempty", "gobblesixarguments", "gobblespacetokens", "gobbletenarguments", "gobblethreearguments", "gobblethreeoptionals", "gobbletwoarguments", "gobbletwooptionals", "gobbleuntil", "gobbleuntilrelax", "godown", "goto", "gotobox", "gotopage", "grabbufferdata", "grabbufferdatadirect", "grabuntil", "grave", "graycolor", "grayvalue", "greedysplitstring", "greekAlpha", "greekAlphadasia", "greekAlphadasiaperispomeni", "greekAlphadasiatonos", "greekAlphadasiavaria", "greekAlphaiotasub", "greekAlphaiotasubdasia", "greekAlphaiotasubdasiaperispomeni", "greekAlphaiotasubdasiatonos", "greekAlphaiotasubdasiavaria", "greekAlphaiotasubpsili", "greekAlphaiotasubpsiliperispomeni", "greekAlphaiotasubpsilitonos", "greekAlphaiotasubpsilivaria", "greekAlphamacron", "greekAlphapsili", "greekAlphapsiliperispomeni", "greekAlphapsilitonos", "greekAlphapsilivaria", "greekAlphatonos", "greekAlphavaria", "greekAlphavrachy", "greekBeta", "greekChi", "greekCoronis", "greekDelta", "greekEpsilon", "greekEpsilondasia", "greekEpsilondasiatonos", "greekEpsilondasiavaria", "greekEpsilonpsili", "greekEpsilonpsilitonos", "greekEpsilonpsilivaria", "greekEpsilontonos", "greekEpsilonvaria", "greekEta", "greekEtadasia", "greekEtadasiaperispomeni", "greekEtadasiatonos", "greekEtadasiavaria", "greekEtaiotasub", "greekEtaiotasubdasia", "greekEtaiotasubdasiaperispomeni", "greekEtaiotasubdasiatonos", "greekEtaiotasubdasiavaria", "greekEtaiotasubpsili", "greekEtaiotasubpsiliperispomeni", "greekEtaiotasubpsilitonos", "greekEtaiotasubpsilivaria", "greekEtapsili", "greekEtapsiliperispomeni", "greekEtapsilitonos", "greekEtapsilivaria", "greekEtatonos", "greekEtavaria", "greekGamma", "greekIota", "greekIotadasia", "greekIotadasiaperispomeni", "greekIotadasiatonos", "greekIotadasiavaria", "greekIotadialytika", "greekIotamacron", "greekIotapsili", "greekIotapsiliperispomeni", "greekIotapsilitonos", "greekIotapsilivaria", "greekIotatonos", "greekIotavaria", "greekIotavrachy", "greekKappa", "greekLambda", "greekMu", "greekNu", "greekOmega", "greekOmegadasia", "greekOmegadasiaperispomeni", "greekOmegadasiatonos", "greekOmegadasiavaria", "greekOmegaiotasub", "greekOmegaiotasubdasia", "greekOmegaiotasubdasiaperispomeni", "greekOmegaiotasubdasiatonos", "greekOmegaiotasubdasiavaria", "greekOmegaiotasubpsili", "greekOmegaiotasubpsiliperispomeni", "greekOmegaiotasubpsilitonos", "greekOmegaiotasubpsilivaria", "greekOmegapsili", "greekOmegapsiliperispomeni", "greekOmegapsilitonos", "greekOmegapsilivaria", "greekOmegatonos", "greekOmegavaria", "greekOmicron", "greekOmicrondasia", "greekOmicrondasiatonos", "greekOmicrondasiavaria", "greekOmicronpsili", "greekOmicronpsilitonos", "greekOmicronpsilivaria", "greekOmicrontonos", "greekOmicronvaria", "greekPhi", "greekPi", "greekPsi", "greekRho", "greekRhodasia", "greekSigma", "greekSigmalunate", "greekTau", "greekTheta", "greekUpsilon", "greekUpsilondasia", "greekUpsilondasiaperispomeni", "greekUpsilondasiatonos", "greekUpsilondasiavaria", "greekUpsilondialytika", "greekUpsilonmacron", "greekUpsilontonos", "greekUpsilonvaria", "greekUpsilonvrachy", "greekXi", "greekZeta", "greekalpha", "greekalphadasia", "greekalphadasiaperispomeni", "greekalphadasiatonos", "greekalphadasiavaria", "greekalphaiotasub", "greekalphaiotasubdasia", "greekalphaiotasubdasiaperispomeni", "greekalphaiotasubdasiatonos", "greekalphaiotasubdasiavaria", "greekalphaiotasubperispomeni", "greekalphaiotasubpsili", "greekalphaiotasubpsiliperispomeni", "greekalphaiotasubpsilitonos", "greekalphaiotasubpsilivaria", "greekalphaiotasubtonos", "greekalphaiotasubvaria", "greekalphamacron", "greekalphaoxia", "greekalphaperispomeni", "greekalphapsili", "greekalphapsiliperispomeni", "greekalphapsilitonos", "greekalphapsilivaria", "greekalphatonos", "greekalphavaria", "greekalphavrachy", "greekbeta", "greekchi", "greekdasia", "greekdasiaperispomeni", "greekdasiatonos", "greekdasiavaria", "greekdelta", "greekdialytikaperispomeni", "greekdialytikatonos", "greekdialytikavaria", "greekdigamma", "greekepsilon", "greekepsilonalt", "greekepsilondasia", "greekepsilondasiatonos", "greekepsilondasiavaria", "greekepsilonoxia", "greekepsilonpsili", "greekepsilonpsilitonos", "greekepsilonpsilivaria", "greekepsilontonos", "greekepsilonvaria", "greeketa", "greeketadasia", "greeketadasiaperispomeni", "greeketadasiatonos", "greeketadasiavaria", "greeketaiotasub", "greeketaiotasubdasia", "greeketaiotasubdasiaperispomeni", "greeketaiotasubdasiatonos", "greeketaiotasubdasiavaria", "greeketaiotasubperispomeni", "greeketaiotasubpsili", "greeketaiotasubpsiliperispomeni", "greeketaiotasubpsilitonos", "greeketaiotasubpsilivaria", "greeketaiotasubtonos", "greeketaiotasubvaria", "greeketaoxia", "greeketaperispomeni", "greeketapsili", "greeketapsiliperispomeni", "greeketapsilitonos", "greeketapsilivaria", "greeketatonos", "greeketavaria", "greekfinalsigma", "greekgamma", "greekiota", "greekiotadasia", "greekiotadasiaperispomeni", "greekiotadasiatonos", "greekiotadasiavaria", "greekiotadialytika", "greekiotadialytikaperispomeni", "greekiotadialytikatonos", "greekiotadialytikavaria", "greekiotamacron", "greekiotaoxia", "greekiotaperispomeni", "greekiotapsili", "greekiotapsiliperispomeni", "greekiotapsilitonos", "greekiotapsilivaria", "greekiotatonos", "greekiotavaria", "greekiotavrachy", "greekkappa", "greekkoppa", "greeklambda", "greekmu", "greeknu", "greeknumerals", "greeknumkoppa", "greekomega", "greekomegadasia", "greekomegadasiaperispomeni", "greekomegadasiatonos", "greekomegadasiavaria", "greekomegaiotasub", "greekomegaiotasubdasia", "greekomegaiotasubdasiaperispomeni", "greekomegaiotasubdasiatonos", "greekomegaiotasubdasiavaria", "greekomegaiotasubperispomeni", "greekomegaiotasubpsili", "greekomegaiotasubpsiliperispomeni", "greekomegaiotasubpsilitonos", "greekomegaiotasubpsilivaria", "greekomegaiotasubtonos", "greekomegaiotasubvaria", "greekomegaoxia", "greekomegaperispomeni", "greekomegapsili", "greekomegapsiliperispomeni", "greekomegapsilitonos", "greekomegapsilivaria", "greekomegatonos", "greekomegavaria", "greekomicron", "greekomicrondasia", "greekomicrondasiatonos", "greekomicrondasiavaria", "greekomicronoxia", "greekomicronpsili", "greekomicronpsilitonos", "greekomicronpsilivaria", "greekomicrontonos", "greekomicronvaria", "greekoxia", "greekperispomeni", "greekphi", "greekphialt", "greekpi", "greekpialt", "greekprosgegrammeni", "greekpsi", "greekpsili", "greekpsiliperispomeni", "greekpsilitonos", "greekpsilivaria", "greekrho", "greekrhoalt", "greekrhodasia", "greekrhopsili", "greeksampi", "greeksigma", "greeksigmalunate", "greekstigma", "greektau", "greektheta", "greekthetaalt", "greektonos", "greekupsilon", "greekupsilondasia", "greekupsilondasiaperispomeni", "greekupsilondasiatonos", "greekupsilondasiavaria", "greekupsilondiaeresis", "greekupsilondialytikaperispomeni", "greekupsilondialytikatonos", "greekupsilondialytikavaria", "greekupsilonmacron", "greekupsilonoxia", "greekupsilonperispomeni", "greekupsilonpsili", "greekupsilonpsiliperispomeni", "greekupsilonpsilitonos", "greekupsilonpsilivaria", "greekupsilontonos", "greekupsilonvaria", "greekupsilonvrachy", "greekvaria", "greekxi", "greekzeta", "grid", "groupedcommand", "gsetboxllx", "gsetboxlly", "gstroke", "gt", "gtrapprox", "gtrdot", "gtreqless", "gtreqqless", "gtrless", "gtrsim", "guilsingleleft", "guilsingleright", "gujaratinumerals", "gurmurkhinumerals", "hairline", "hairspace", "halflinestrut", "halfstrut", "halfwaybox", "handletokens", "handwritten", "hangul", "hanzi", "hash", "hat", "hbar", "hboxofvbox", "hboxreference", "hcaron", "hcircumflex", "hdofstring", "headhbox", "headlanguage", "headnumber", "headnumbercontent", "headnumberdistance", "headnumberwidth", "headreferenceattributes", "headsetupspacing", "headtext", "headtextcontent", "headtextdistance", "headtexts", "headtextwidth", "headvbox", "headwidth", "heartsuit", "hebrewAlef", "hebrewAyin", "hebrewBet", "hebrewDalet", "hebrewGimel", "hebrewHe", "hebrewHet", "hebrewKaf", "hebrewKaffinal", "hebrewLamed", "hebrewMem", "hebrewMemfinal", "hebrewNun", "hebrewNunfinal", "hebrewPe", "hebrewPefinal", "hebrewQof", "hebrewResh", "hebrewSamekh", "hebrewShin", "hebrewTav", "hebrewTet", "hebrewTsadi", "hebrewTsadifinal", "hebrewVav", "hebrewYod", "hebrewZayin", "heightanddepthofstring", "heightofstring", "heightspanningtext", "helptext", "hglue", "hiddenbar", "hiddencitation", "hiddencite", "hideblocks", "high", "highlight", "highordinalstr", "hilo", "himilo", "hl", "hookleftarrow", "hookrightarrow", "horizontalgrowingbar", "horizontalpositionbar", "hphantom", "hpos", "hsizefraction", "hslash", "hsmash", "hsmashbox", "hsmashed", "hspace", "hstroke", "htdpofstring", "htofstring", "hyphen", "hyphenatedcoloredword", "hyphenatedfile", "hyphenatedfilename", "hyphenatedhbox", "hyphenatedpar", "hyphenatedurl", "hyphenatedword", "iacute", "ibox", "ibreve", "icaron", "icircumflex", "ideographichalffillspace", "ideographicspace", "idiaeresis", "idotaccent", "idotbelow", "idoublegrave", "ifassignment", "iff", "ifinobject", "ifinoutputstream", "ifparameters", "iftrialtypesetting", "ignoreimplicitspaces", "ignorevalue", "igrave", "ihook", "iiiint", "iiiintop", "iiint", "iiintop", "iint", "iintop", "iinvertedbreve", "ijligature", "imacron", "imaginaryi", "imaginaryj", "imath", "immediatesavetwopassdata", "impliedby", "implies", "imply", "in", "includemenu", "includeversioninfo", "increment", "incrementcounter", "incrementedcounter", "incrementpagenumber", "incrementsubpagenumber", "incrementvalue", "indentation", "index", "infofont", "infofontbold", "inframed", "infty", "infull", "inheritparameter", "inhibitblank", "ininner", "ininneredge", "ininnermargin", "initializeboxstack", "inleft", "inleftedge", "inleftmargin", "inline", "inlinebuffer", "inlinedbox", "inlinemath", "inlinemathematics", "inlinemessage", "inlineordisplaymath", "inlineprettyprintbuffer", "inlinerange", "inmargin", "inmframed", "innerflushshapebox", "inother", "inouter", "inouteredge", "inoutermargin", "input", "inputfilebarename", "inputfilename", "inputfilerealsuffix", "inputfilesuffix", "inputgivenfile", "inright", "inrightedge", "inrightmargin", "insertpages", "installactionhandler", "installactivecharacter", "installanddefineactivecharacter", "installattributestack", "installautocommandhandler", "installautosetuphandler", "installbasicautosetuphandler", "installbasicparameterhandler", "installbottomframerenderer", "installcommandhandler", "installcorenamespace", "installdefinehandler", "installdefinitionset", "installdefinitionsetmember", "installdirectcommandhandler", "installdirectparameterhandler", "installdirectparametersethandler", "installdirectsetuphandler", "installdirectstyleandcolorhandler", "installframedautocommandhandler", "installframedcommandhandler", "installlanguage", "installleftframerenderer", "installnamespace", "installoutputroutine", "installpagearrangement", "installparameterhandler", "installparameterhashhandler", "installparametersethandler", "installparentinjector", "installrightframerenderer", "installrootparameterhandler", "installsetuphandler", "installsetuponlycommandhandler", "installshipoutmethod", "installsimplecommandhandler", "installsimpleframedcommandhandler", "installstyleandcolorhandler", "installswitchcommandhandler", "installswitchsetuphandler", "installtexdirective", "installtextracker", "installtopframerenderer", "installunitsseparator", "installunitsspace", "installversioninfo", "int", "intclockwise", "integerrounding", "integers", "interactionbar", "interactionbuttons", "interactionmenu", "intercal", "intertext", "intop", "invisibletimes", "invokepageheandler", "iogonek", "iota", "istltdir", "istrtdir", "italic", "italicbold", "italiccorrection", "italicface", "item", "items", "itemtag", "itilde", "jcaron", "jcircumflex", "jmath", "jobfilename", "jobfilesuffix", "kap", "kappa", "kcaron", "kcommaaccent", "keepblocks", "keeplinestogether", "keepunwantedspaces", "kerncharacters", "khook", "kkra", "koreancirclenumerals", "koreannumerals", "koreannumeralsc", "koreannumeralsp", "koreanparentnumerals", "lVert", "labellanguage", "labeltext", "labeltexts", "lacute", "lambda", "lambdabar", "land", "langle", "language", "languageCharacters", "languagecharacters", "languagecharwidth", "lastcounter", "lastcountervalue", "lastdigit", "lastlinewidth", "lastnaturalboxdp", "lastnaturalboxht", "lastnaturalboxwd", "lastpredefinedsymbol", "lastrealpage", "lastrealpagenumber", "lastsubcountervalue", "lastsubpage", "lastsubpagenumber", "lasttwodigits", "lastuserpage", "lastuserpagenumber", "lateluacode", "latin", "layeredtext", "layerheight", "layerwidth", "lazysavetaggedtwopassdata", "lazysavetwopassdata", "lbar", "lbox", "lbrace", "lbracket", "lcaron", "lceil", "lcommaaccent", "lcurl", "ldotmiddle", "ldotp", "ldots", "le", "leadsto", "left", "leftaligned", "leftarrow", "leftarrowtail", "leftarrowtriangle", "leftbottombox", "leftbox", "leftdasharrow", "leftguillemot", "leftharpoondown", "leftharpoonup", "lefthbox", "leftheadtext", "leftlabeltext", "leftleftarrows", "leftline", "leftmathlabeltext", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "leftrightarrow", "leftrightarrows", "leftrightarrowtriangle", "leftrightharpoons", "leftrightsquigarrow", "leftskipadaption", "leftsquigarrow", "leftsubguillemot", "leftthreetimes", "lefttopbox", "lefttoright", "lefttorighthbox", "lefttorightvbox", "lefttorightvtop", "leftwavearrow", "leftwhitearrow", "leq", "leqq", "leqslant", "lessapprox", "lessdot", "lesseqgtr", "lesseqqgtr", "lessgtr", "lesssim", "letbeundefined", "letcatcodecommand", "letcscsname", "letcsnamecs", "letcsnamecsname", "letdummyparameter", "letempty", "letgvalue", "letgvalueempty", "letgvalurelax", "letterampersand", "letterat", "letterbackslash", "letterbar", "letterbgroup", "letterclosebrace", "lettercolon", "letterdollar", "letterdoublequote", "letteregroup", "letterescape", "letterexclamationmark", "letterhash", "letterhat", "letterleftbrace", "letterleftbracket", "letterleftparenthesis", "letterless", "lettermore", "letteropenbrace", "letterpercent", "letterquestionmark", "letterrightbrace", "letterrightbracket", "letterrightparenthesis", "lettersinglequote", "letterslash", "letterspacing", "lettertilde", "letterunderscore", "letvalue", "letvalueempty", "letvaluerelax", "lfence", "lfloor", "lgroup", "lhbox", "lhooknwarrow", "lhooksearrow", "limitatefirstline", "limitatelines", "limitatetext", "line", "linefeed", "linenote", "linespanningtext", "linethickness", "linterval", "listcitation", "listcite", "listlength", "listnamespaces", "ljligature", "ll", "llangle", "llap", "llbracket", "llcorner", "lll", "llless", "lmoustache", "lnapprox", "lneq", "lneqq", "lnot", "lnsim", "loadanyfile", "loadanyfileonce", "loadbtxdefinitionfile", "loadbtxreplacementfile", "loadcldfile", "loadcldfileonce", "loadfontgoodies", "loadluafile", "loadluafileonce", "loadspellchecklist", "loadtexfile", "loadtexfileonce", "loadtypescriptfile", "localframed", "localframedwithsettings", "localhsize", "localpopbox", "localpopmacro", "localpushbox", "localpushmacro", "localundefine", "locatedfilepath", "locatefilepath", "locfilename", "logo", "lohi", "lointerval", "lomihi", "longleftarrow", "longleftrightarrow", "longmapsfrom", "longmapsto", "longrightarrow", "longrightsquigarrow", "looparrowleft", "looparrowright", "lor", "low", "lowerbox", "lowercased", "lowercasestring", "lowerleftdoubleninequote", "lowerleftsingleninequote", "lowerrightdoubleninequote", "lowerrightsingleninequote", "lozenge", "lparent", "lrcorner", "lrointerval", "lrtbbox", "lstroke", "lt", "ltimes", "ltop", "luaTeX", "luacode", "luaconditional", "luaenvironment", "luaexpanded", "luaexpr", "luafunction", "luajitTeX", "luamajorversion", "luaminorversion", "luaparameterset", "luasetup", "luaversion", "lvert", "m", "mLeftarrow", "mLeftrightarrow", "mRightarrow", "mainlanguage", "makecharacteractive", "makerawcommalist", "makestrutofbox", "maltese", "mapfontsize", "mapsdown", "mapsfrom", "mapsto", "mapsup", "margindata", "margintext", "markcontent", "marking", "markinjector", "markpage", "mat", "math", "mathampersand", "mathbf", "mathbi", "mathblackboard", "mathbs", "mathdefault", "mathdollar", "mathdouble", "mathematics", "mathfraktur", "mathfunction", "mathhash", "mathhyphen", "mathit", "mathitalic", "mathlabellanguage", "mathlabeltext", "mathlabeltexts", "mathop", "mathover", "mathpercent", "mathrm", "mathscript", "mathsl", "mathss", "mathtext", "mathtextbf", "mathtextbi", "mathtextbs", "mathtextit", "mathtextsl", "mathtexttf", "mathtf", "mathtriplet", "mathtt", "mathunder", "mathupright", "mathword", "mathwordbf", "mathwordbi", "mathwordbs", "mathwordit", "mathwordsl", "mathwordtf", "maxaligned", "mbox", "mcframed", "measure", "measured", "measuredangle", "measuredeq", "medskip", "medspace", "menubutton", "mequal", "message", "metaTeX", "mfence", "mframed", "mfunction", "mfunctionlabeltext", "mhbox", "mho", "mhookleftarrow", "mhookrightarrow", "mid", "midaligned", "middle", "middlealigned", "middlebox", "midhbox", "midsubsentence", "minimalhbox", "minus", "minuscolon", "mirror", "mixedcaps", "mkvibuffer", "mleftarrow", "mleftharpoondown", "mleftharpoonup", "mleftrightarrow", "mleftrightharpoons", "mmapsto", "models", "moduleparameter", "molecule", "mono", "monobold", "mononormal", "month", "monthlong", "monthshort", "mp", "mprandomnumber", "mrel", "mrightarrow", "mrightharpoondown", "mrightharpoonup", "mrightleftharpoons", "mrightoverleftarrow", "mtext", "mtriplerel", "mtwoheadleftarrow", "mtwoheadrightarrow", "mu", "multimap", "nHdownarrow", "nHuparrow", "nLeftarrow", "nLeftrightarrow", "nRightarrow", "nVDash", "nVdash", "nVleftarrow", "nVleftrightarrow", "nVrightarrow", "nabla", "nacute", "namedheadnumber", "namedstructureheadlocation", "namedstructureuservariable", "namedstructurevariable", "namedtaggedlabeltexts", "napostrophe", "napprox", "napproxEq", "narrownobreakspace", "nasymp", "natural", "naturalhbox", "naturalhpack", "naturalnumbers", "naturalvbox", "naturalvcenter", "naturalvpack", "naturalvtop", "naturalwd", "ncaron", "ncommaaccent", "ncong", "ncurl", "ndivides", "ne", "nearrow", "neg", "negatecolorbox", "negated", "negativesign", "negthinspace", "neng", "neq", "nequiv", "neswarrow", "newattribute", "newcatcodetable", "newcounter", "newevery", "newfrenchspacing", "newmode", "newsignal", "newsystemmode", "nexists", "nextbox", "nextboxdp", "nextboxht", "nextboxhtdp", "nextboxwd", "nextcounter", "nextcountervalue", "nextdepth", "nextparagraphs", "nextrealpage", "nextrealpagenumber", "nextsubcountervalue", "nextsubpage", "nextsubpagenumber", "nextuserpage", "nextuserpagenumber", "ngeq", "ngrave", "ngtr", "ngtrless", "ngtrsim", "ni", "nihongo", "nin", "njligature", "nleftarrow", "nleftrightarrow", "nleq", "nless", "nlessgtr", "nlesssim", "nmid", "nni", "nobar", "nobreakspace", "nocap", "nocitation", "nocite", "nodetostring", "noffigurepages", "noflines", "noflocalfloats", "noheaderandfooterlines", "noheightstrut", "noindentation", "noitem", "nonfrenchspacing", "nonmathematics", "normal", "normalboldface", "normalframedwithsettings", "normalitalicface", "normalizebodyfontsize", "normalizedfontsize", "normalizefontdepth", "normalizefontheight", "normalizefontline", "normalizefontwidth", "normalizetextdepth", "normalizetextheight", "normalizetextline", "normalizetextwidth", "normalslantedface", "normaltypeface", "nospace", "not", "note", "notesymbol", "notin", "notopandbottomlines", "notragged", "nowns", "nparallel", "nprec", "npreccurlyeq", "nrightarrow", "nsim", "nsimeq", "nsqsubseteq", "nsqsupseteq", "nsubset", "nsubseteq", "nsucc", "nsucccurlyeq", "nsupset", "nsupseteq", "ntilde", "ntimes", "ntriangleleft", "ntrianglelefteq", "ntriangleright", "ntrianglerighteq", "nu", "numberofpoints", "numbers", "nvDash", "nvdash", "nvleftarrow", "nvleftrightarrow", "nvrightarrow", "nwarrow", "nwsearrow", "oacute", "obeydepth", "objectdepth", "objectheight", "objectmargin", "objectwidth", "obox", "obreve", "ocaron", "ocircumflex", "ocircumflexacute", "ocircumflexdotbelow", "ocircumflexgrave", "ocircumflexhook", "ocircumflextilde", "odiaeresis", "odiaeresismacron", "odot", "odotaccent", "odotaccentmacron", "odotbelow", "odoublegrave", "oeligature", "offset", "offsetbox", "ograve", "ohm", "ohook", "ohorn", "ohornacute", "ohorndotbelow", "ohorngrave", "ohornhook", "ohorntilde", "ohungarumlaut", "oiiint", "oiint", "oint", "ointclockwise", "ointctrclockwise", "oinvertedbreve", "omacron", "omega", "omicron", "ominus", "onedigitrounding", "oneeighth", "onefifth", "onehalf", "onequarter", "onesixth", "onesuperior", "onethird", "oogonek", "oogonekmacron", "operatorlanguage", "operatortext", "oplus", "ordfeminine", "ordinaldaynumber", "ordinalstr", "ordmasculine", "ornamenttext", "oslash", "ostroke", "ostrokeacute", "otilde", "otildemacron", "otimes", "outputfilename", "outputstreambox", "outputstreamcopy", "outputstreamunvbox", "outputstreamunvcopy", "over", "overbar", "overbars", "overbarunderbar", "overbrace", "overbraceunderbrace", "overbracket", "overbracketunderbracket", "overlaybutton", "overlaycolor", "overlaydepth", "overlayfigure", "overlayheight", "overlaylinecolor", "overlaylinewidth", "overlayoffset", "overlayrollbutton", "overlaywidth", "overleftarrow", "overloaderror", "overparent", "overparentunderparent", "overrightarrow", "overset", "overstrike", "overstrikes", "owns", "page", "pagearea", "pagebreak", "pagefigure", "pagegridspanwidth", "pageinjection", "pagenumber", "pagereference", "pagestaterealpage", "paletsize", "paragraphmark", "parallel", "part", "partial", "pdfTeX", "pdfactualtext", "pdfbackendactualtext", "pdfbackendcurrentresources", "pdfbackendsetcatalog", "pdfbackendsetcolorspace", "pdfbackendsetextgstate", "pdfbackendsetinfo", "pdfbackendsetname", "pdfbackendsetpageattribute", "pdfbackendsetpageresource", "pdfbackendsetpagesattribute", "pdfbackendsetpattern", "pdfbackendsetshade", "pdfcolor", "pdfeTeX", "percent", "percentdimen", "periodcentered", "periods", "permitcaretescape", "permitcircumflexescape", "permitspacesbetweengroups", "perp", "persiandecimals", "persiandecimalseparator", "persiannumerals", "persianthousandsseparator", "perthousand", "phantom", "phantombox", "phi", "phook", "pi", "pickupgroupedcommand", "pitchfork", "placeattachments", "placebookmarks", "placebtxrendering", "placechemical", "placecitation", "placecombinedlist", "placecomments", "placecontent", "placecurrentformulanumber", "placedbox", "placefigure", "placefloat", "placefloatwithsetups", "placefootnotes", "placeformula", "placeframed", "placegraphic", "placeheadnumber", "placeheadtext", "placehelp", "placeindex", "placeinitial", "placeintermezzo", "placelayer", "placelayeredtext", "placelegend", "placelist", "placelistofabbreviations", "placelistofchemicals", "placelistoffigures", "placelistofgraphics", "placelistofintermezzi", "placelistoflogos", "placelistofpublications", "placelistofsorts", "placelistofsynonyms", "placelistoftables", "placelocalfootnotes", "placelocalnotes", "placement", "placenamedfloat", "placenamedformula", "placenotes", "placeongrid", "placeontopofeachother", "placepagenumber", "placepairedbox", "placeparallel", "placerawlist", "placeregister", "placerenderingwindow", "placesidebyside", "placesubformula", "placetable", "pm", "popattribute", "popmacro", "popmode", "popsystemmode", "position", "positionoverlay", "positionregionoverlay", "positivesign", "postponenotes", "prec", "precapprox", "preccurlyeq", "preceq", "preceqq", "precnapprox", "precneq", "precneqq", "precnsim", "precsim", "predefinedfont", "predefinefont", "predefinesymbol", "prefixedpagenumber", "prefixlanguage", "prefixtext", "prependetoks", "prependgvalue", "prependtocommalist", "prependtoks", "prependtoksonce", "prependvalue", "presetbtxlabeltext", "presetdocument", "presetfieldsymbols", "presetheadtext", "presetlabeltext", "presetmathlabeltext", "presetoperatortext", "presetprefixtext", "presetsuffixtext", "presettaglabeltext", "presetunittext", "pretocommalist", "prettyprintbuffer", "prevcounter", "prevcountervalue", "preventmode", "prevrealpage", "prevrealpagenumber", "prevsubcountervalue", "prevsubpage", "prevsubpagenumber", "prevuserpage", "prevuserpagenumber", "prime", "primes", "procent", "processMPbuffer", "processMPfigurefile", "processaction", "processallactionsinset", "processassignlist", "processassignmentcommand", "processassignmentlist", "processbetween", "processblocks", "processbodyfontenvironmentlist", "processcolorcomponents", "processcommacommand", "processcommalist", "processcommalistwithparameters", "processcontent", "processfile", "processfilemany", "processfilenone", "processfileonce", "processfirstactioninset", "processisolatedchars", "processisolatedwords", "processlinetablebuffer", "processlinetablefile", "processlist", "processmonth", "processranges", "processseparatedlist", "processtexbuffer", "processtokens", "processuntil", "processxtablebuffer", "processyear", "prod", "product", "profiledbox", "profilegivenbox", "program", "project", "propto", "pseudoMixedCapped", "pseudoSmallCapped", "pseudoSmallcapped", "pseudosmallcapped", "psi", "punctuationspace", "purenumber", "pushattribute", "pushbutton", "pushmacro", "pushmode", "pushoutputstream", "pushsystemmode", "putboxincache", "putnextboxincache", "qquad", "quad", "quadrupleprime", "quads", "quarterstrut", "questiondown", "questionedeq", "quitcommalist", "quitprevcommalist", "quittypescriptscanning", "quotation", "quote", "quotedbl", "quotedblbase", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "quotesingle", "quotesinglebase", "rVert", "racute", "raggedbottom", "raggedcenter", "raggedleft", "raggedright", "raggedwidecenter", "raisebox", "randomizetext", "randomnumber", "rangle", "rationals", "rawcounter", "rawcountervalue", "rawdate", "rawdoifelseinset", "rawdoifinset", "rawdoifinsetelse", "rawgetparameters", "rawprocessaction", "rawprocesscommacommand", "rawprocesscommalist", "rawstructurelistuservariable", "rawsubcountervalue", "rbox", "rbrace", "rbracket", "rcaron", "rceil", "rcommaaccent", "rdoublegrave", "readfile", "readfixfile", "readjobfile", "readlocfile", "readsetfile", "readsysfile", "readtexfile", "readxmlfile", "realSmallCapped", "realSmallcapped", "realpagenumber", "reals", "realsmallcapped", "recursedepth", "recurselevel", "recursestring", "redoconvertfont", "ref", "reference", "referenceprefix", "referring", "registerattachment", "registerctxluafile", "registered", "registerexternalfigure", "registerfontclass", "registerhyphenationexception", "registerhyphenationpattern", "registermenubuttons", "registersort", "registersynonym", "registerunit", "regular", "relatemarking", "relateparameterhandlers", "relaxvalueifundefined", "relbar", "remainingcharacters", "remark", "removebottomthings", "removedepth", "removefromcommalist", "removelastskip", "removelastspace", "removemarkedcontent", "removepunctuation", "removesubstring", "removetoks", "removeunwantedspaces", "replacefeature", "replaceincommalist", "replaceword", "rescan", "rescanwithsetup", "resetMPdrawing", "resetMPenvironment", "resetMPinstance", "resetallattributes", "resetandaddfeature", "resetbar", "resetboxesincache", "resetbreakpoints", "resetbuffer", "resetcharacteralign", "resetcharacterkerning", "resetcharacterspacing", "resetcharacterstripping", "resetcollector", "resetcounter", "resetdigitsmanipulation", "resetdirection", "resetfeature", "resetflag", "resetfontcolorsheme", "resetfontfallback", "resetfontsolution", "resethyphenationfeatures", "resetinjector", "resetinteractionmenu", "resetitaliccorrection", "resetlayer", "resetlocalfloats", "resetmarker", "resetmarking", "resetmode", "resetpagenumber", "resetparallel", "resetpath", "resetpenalties", "resetprofile", "resetrecurselevel", "resetreference", "resetreplacement", "resetscript", "resetsetups", "resetshownsynonyms", "resetsubpagenumber", "resetsymbolset", "resetsystemmode", "resettimer", "resettrackers", "resettrialtypesetting", "resetusedsortings", "resetusedsynonyms", "resetuserpagenumber", "resetvalue", "resetvisualizers", "reshapebox", "resolvedglyphdirect", "resolvedglyphstyled", "restartcounter", "restorebox", "restorecatcodes", "restorecounter", "restorecurrentattributes", "restoreendofline", "restoreglobalbodyfont", "restriction", "reusableMPgraphic", "reuseMPgraphic", "reuserandomseed", "reverseddoubleprime", "reversedprime", "reversedtripleprime", "revivefeature", "rfence", "rfloor", "rgroup", "rhbox", "rho", "rhooknearrow", "rhookswarrow", "right", "rightaligned", "rightangle", "rightarrow", "rightarrowbar", "rightarrowtail", "rightarrowtriangle", "rightbottombox", "rightbox", "rightdasharrow", "rightguillemot", "rightharpoondown", "rightharpoonup", "righthbox", "rightheadtext", "rightlabeltext", "rightleftarrows", "rightleftharpoons", "rightline", "rightmathlabeltext", "rightorleftpageaction", "rightrightarrows", "rightskipadaption", "rightsquigarrow", "rightsubguillemot", "rightthreearrows", "rightthreetimes", "righttoleft", "righttolefthbox", "righttoleftvbox", "righttoleftvtop", "righttopbox", "rightwavearrow", "rightwhitearrow", "ring", "rinterval", "rinvertedbreve", "risingdotseq", "rlap", "rlointerval", "rmoustache", "rneq", "robustaddtocommalist", "robustdoifelseinset", "robustdoifinsetelse", "robustpretocommalist", "rointerval", "rollbutton", "roman", "romanC", "romanD", "romanI", "romanII", "romanIII", "romanIV", "romanIX", "romanL", "romanM", "romanV", "romanVI", "romanVII", "romanVIII", "romanX", "romanXI", "romanXII", "romanc", "romand", "romani", "romanii", "romaniii", "romaniv", "romanix", "romanl", "romanm", "romannumerals", "romanv", "romanvi", "romanvii", "romanviii", "romanx", "romanxi", "romanxii", "rootradical", "rotate", "rparent", "rrangle", "rrbracket", "rrointerval", "rtimes", "rtop", "ruledhbox", "ruledhpack", "ruledmbox", "ruledtopv", "ruledtpack", "ruledvbox", "ruledvpack", "ruledvtop", "runMPbuffer", "runninghbox", "rvert", "sacute", "safechar", "samplefile", "sans", "sansbold", "sansnormal", "sansserif", "savebox", "savebtxdataset", "savebuffer", "savecounter", "savecurrentattributes", "savenormalmeaning", "savetaggedtwopassdata", "savetwopassdata", "sbox", "scale", "scaron", "scedilla", "schwa", "schwahook", "scircumflex", "scommaaccent", "screen", "searrow", "secondoffivearguments", "secondoffourarguments", "secondofsixarguments", "secondofthreearguments", "secondofthreeunexpanded", "secondoftwoarguments", "secondoftwounexpanded", "section", "sectionmark", "seeindex", "select", "selectblocks", "serializecommalist", "serializedcommalist", "serif", "serifbold", "serifnormal", "setJSpreamble", "setMPlayer", "setMPpositiongraphic", "setMPpositiongraphicrange", "setMPtext", "setMPvariable", "setMPvariables", "setbar", "setbigbodyfont", "setboxllx", "setboxlly", "setbreakpoints", "setcapstrut", "setcatcodetable", "setcharacteralign", "setcharactercasing", "setcharactercleaning", "setcharacterkerning", "setcharacterspacing", "setcharacterstripping", "setcharstrut", "setcollector", "setcolormodell", "setcounter", "setcounterown", "setcurrentfontclass", "setdataset", "setdefaultpenalties", "setdigitsmanipulation", "setdirection", "setdocumentargument", "setdocumentargumentdefault", "setdocumentfilename", "setdummyparameter", "setelementexporttag", "setemeasure", "setevalue", "setevariable", "setevariables", "setfirstline", "setflag", "setfont", "setfontcolorsheme", "setfontfeature", "setfontsolution", "setfontstrut", "setgmeasure", "setgvalue", "setgvariable", "setgvariables", "sethboxregister", "sethyphenatedurlafter", "sethyphenatedurlbefore", "sethyphenatedurlnormal", "sethyphenationfeatures", "setinitial", "setinjector", "setinteraction", "setinterfacecommand", "setinterfaceconstant", "setinterfaceelement", "setinterfacemessage", "setinterfacevariable", "setinternalrendering", "setitaliccorrection", "setlayer", "setlayerframed", "setlayertext", "setlinefiller", "setlocalhsize", "setmainbodyfont", "setmainparbuilder", "setmarker", "setmarking", "setmathstyle", "setmeasure", "setmessagetext", "setminus", "setmode", "setnostrut", "setnote", "setnotetext", "setobject", "setoldstyle", "setpagegrid", "setpagereference", "setpagestate", "setpagestaterealpageno", "setpenalties", "setpercentdimen", "setposition", "setpositionbox", "setpositiondata", "setpositiondataplus", "setpositiononly", "setpositionplus", "setpositionstrut", "setprofile", "setrandomseed", "setreference", "setreferencedobject", "setregisterentry", "setreplacement", "setrigidcolumnbalance", "setrigidcolumnhsize", "setscript", "setsectionblock", "setsimplecolumnhsize", "setsmallbodyfont", "setsmallcaps", "setstackbox", "setstructurepageregister", "setstrut", "setsuperiors", "setsystemmode", "settabular", "settaggedmetadata", "settextcontent", "settightobject", "settightreferencedobject", "settightunreferencedobject", "settrialtypesetting", "setuevalue", "setugvalue", "setunreferencedobject", "setup", "setupMPgraphics", "setupMPinstance", "setupMPpage", "setupMPvariables", "setupTABLE", "setupTEXpage", "setupalign", "setupalternativestyles", "setuparranging", "setupattachment", "setupattachments", "setupbackend", "setupbackground", "setupbackgrounds", "setupbar", "setupbars", "setupblackrules", "setupblank", "setupbleeding", "setupblock", "setupbodyfont", "setupbookmark", "setupbottom", "setupbottomtexts", "setupbtx", "setupbtxdataset", "setupbtxlabeltext", "setupbtxlist", "setupbtxregister", "setupbtxrendering", "setupbuffer", "setupbutton", "setupcapitals", "setupcaption", "setupcaptions", "setupcharacterkerning", "setupcharacterspacing", "setupchemical", "setupchemicalframed", "setupclipping", "setupcollector", "setupcolor", "setupcolors", "setupcolumns", "setupcolumnspan", "setupcombination", "setupcombinedlist", "setupcomment", "setupcontent", "setupcounter", "setupdataset", "setupdelimitedtext", "setupdescription", "setupdirections", "setupdocument", "setupeffect", "setupenumeration", "setupenumerations", "setupenv", "setupexport", "setupexternalfigure", "setupexternalsoundtracks", "setupfield", "setupfieldbody", "setupfieldcategory", "setupfieldcontentframed", "setupfieldlabelframed", "setupfields", "setupfieldtotalframed", "setupfiller", "setupfillinlines", "setupfillinrules", "setupfirstline", "setupfittingpage", "setupfloat", "setupfloatcaption", "setupfloats", "setupfloatsplitting", "setupfontexpansion", "setupfontprotrusion", "setupfonts", "setupfontsolution", "setupfooter", "setupfootertexts", "setupforms", "setupformula", "setupformulae", "setupformulaframed", "setupframed", "setupframedcontent", "setupframedtable", "setupframedtablecolumn", "setupframedtablerow", "setupframedtext", "setupframedtexts", "setupglobalreferenceprefix", "setuphead", "setupheadalternative", "setupheader", "setupheadertexts", "setupheadnumber", "setupheads", "setupheadtext", "setuphelp", "setuphigh", "setuphighlight", "setuphyphenation", "setuphyphenmark", "setupindentedtext", "setupindenting", "setupindex", "setupinitial", "setupinsertion", "setupinteraction", "setupinteractionbar", "setupinteractionmenu", "setupinteractionscreen", "setupinterlinespace", "setupitaliccorrection", "setupitemgroup", "setupitemizations", "setupitemize", "setupitems", "setuplabel", "setuplabeltext", "setuplanguage", "setuplayer", "setuplayeredtext", "setuplayout", "setuplayouttext", "setuplegend", "setuplinefiller", "setuplinefillers", "setuplinenote", "setuplinenumbering", "setuplines", "setuplinetable", "setuplinewidth", "setuplist", "setuplistalternative", "setuplistextra", "setuplocalfloats", "setuplocalinterlinespace", "setuplow", "setuplowhigh", "setuplowmidhigh", "setupmakeup", "setupmarginblock", "setupmargindata", "setupmarginframed", "setupmarginrule", "setupmarginrules", "setupmarking", "setupmathalignment", "setupmathcases", "setupmathematics", "setupmathfence", "setupmathfraction", "setupmathfractions", "setupmathframed", "setupmathlabeltext", "setupmathmatrix", "setupmathornament", "setupmathradical", "setupmathstackers", "setupmathstyle", "setupmixedcolumns", "setupmodule", "setupnarrower", "setupnotation", "setupnotations", "setupnote", "setupnotes", "setupoffset", "setupoffsetbox", "setupoperatortext", "setupoppositeplacing", "setupoutputroutine", "setuppagechecker", "setuppagecomment", "setuppagegrid", "setuppagegridarea", "setuppagegridareatext", "setuppagegridlines", "setuppagegridspan", "setuppagegridstart", "setuppageinjection", "setuppageinjectionalternative", "setuppagenumber", "setuppagenumbering", "setuppageshift", "setuppagestate", "setuppagetransitions", "setuppairedbox", "setuppalet", "setuppaper", "setuppapersize", "setupparagraph", "setupparagraphintro", "setupparagraphnumbering", "setupparagraphs", "setupparallel", "setupperiods", "setupplacement", "setuppositionbar", "setuppositioning", "setupprefixtext", "setupprocessor", "setupprofile", "setupprograms", "setupquotation", "setupquote", "setuprealpagenumber", "setupreferenceformat", "setupreferenceprefix", "setupreferencestructureprefix", "setupreferencing", "setupregister", "setupregisters", "setuprenderingwindow", "setuprotate", "setups", "setupscale", "setupscript", "setupscripts", "setupsectionblock", "setupselector", "setupshift", "setupsidebar", "setupsorting", "setupspacing", "setupspellchecking", "setupstartstop", "setupstretched", "setupstruts", "setupstyle", "setupsubformula", "setupsubformulas", "setupsubpagenumber", "setupsuffixtext", "setupsymbolset", "setupsynctex", "setupsynonyms", "setuptables", "setuptabulate", "setuptabulation", "setuptagging", "setuptaglabeltext", "setuptext", "setuptextbackground", "setuptextflow", "setuptextrules", "setuptexttexts", "setupthinrules", "setuptolerance", "setuptooltip", "setuptop", "setuptoptexts", "setuptype", "setuptyping", "setupunit", "setupunittext", "setupurl", "setupuserpagenumber", "setupversion", "setupviewerlayer", "setupvspacing", "setupwhitespace", "setupwithargument", "setupwithargumentswapped", "setupxml", "setupxtable", "setuvalue", "setuxvalue", "setvalue", "setvariable", "setvariables", "setvboxregister", "setvisualizerfont", "setvtopregister", "setwidthof", "setxmeasure", "setxvalue", "setxvariable", "setxvariables", "seveneighths", "sfrac", "shapedhbox", "sharp", "shiftdown", "shiftup", "showallmakeup", "showattributes", "showbodyfont", "showbodyfontenvironment", "showboxes", "showbtxdatasetauthors", "showbtxdatasetcompleteness", "showbtxdatasetfields", "showbtxfields", "showbtxhashedauthors", "showbtxtables", "showchardata", "showcharratio", "showcolor", "showcolorbar", "showcolorcomponents", "showcolorgroup", "showcolorset", "showcolorstruts", "showcounter", "showdirectives", "showdirsinmargin", "showedebuginfo", "showexperiments", "showfont", "showfontdata", "showfontitalics", "showfontkerns", "showfontparameters", "showfontstrip", "showfontstyle", "showframe", "showglyphs", "showgrid", "showgridsnapping", "showhelp", "showhyphenationtrace", "showhyphens", "showinjector", "showjustification", "showkerning", "showlayout", "showlayoutcomponents", "showligature", "showligatures", "showlogcategories", "showmakeup", "showmargins", "showmessage", "showminimalbaseline", "shownextbox", "showotfcomposition", "showpalet", "showparentchain", "showprint", "showsetups", "showsetupsdefinition", "showstruts", "showsymbolset", "showtimer", "showtokens", "showtrackers", "showvalue", "showvariable", "showwarning", "sigma", "sim", "simeq", "simplealignedbox", "simplealignedboxplus", "simplealignedspreadbox", "simplegroupedcommand", "simplereversealignedbox", "simplereversealignedboxplus", "singalcharacteralign", "singlebond", "singleverticalbar", "sixperemspace", "sixthofsixarguments", "slanted", "slantedbold", "slantedface", "slash", "slicepages", "slong", "slovenianNumerals", "sloveniannumerals", "small", "smallbodyfont", "smallbold", "smallbolditalic", "smallboldslanted", "smallcappedcharacters", "smallcappedromannumerals", "smaller", "smallitalicbold", "smallnormal", "smallskip", "smallslanted", "smallslantedbold", "smalltype", "smash", "smashbox", "smashboxed", "smashedhbox", "smashedvbox", "smile", "snaptogrid", "softhyphen", "solidus", "someheadnumber", "somekindoftab", "someline", "somelocalfloat", "somenamedheadnumber", "someplace", "somewhere", "space", "spadesuit", "spanishNumerals", "spanishnumerals", "speech", "sphericalangle", "splitatasterisk", "splitatcolon", "splitatcolons", "splitatcomma", "splitatperiod", "splitdfrac", "splitfilename", "splitfloat", "splitfrac", "splitoffbase", "splitofffull", "splitoffkind", "splitoffname", "splitoffpath", "splitoffroot", "splitofftokens", "splitofftype", "splitstring", "spreadhbox", "sqcap", "sqcup", "sqrt", "sqsubset", "sqsubseteq", "sqsubsetneq", "sqsupset", "sqsupseteq", "sqsupsetneq", "square", "squaredots", "ssharp", "stackrel", "star", "stareq", "startJScode", "startJSpreamble", "startLUA", "startMP", "startMPclip", "startMPcode", "startMPdefinitions", "startMPdrawing", "startMPenvironment", "startMPextensions", "startMPinclusions", "startMPinitializations", "startMPpage", "startMPpositiongraphic", "startMPpositionmethod", "startMPrun", "startPARSEDXML", "startTABLE", "startTABLEbody", "startTABLEfoot", "startTABLEhead", "startTABLEnext", "startTC", "startTD", "startTDs", "startTEX", "startTEXpage", "startTH", "startTN", "startTR", "startTRs", "startTX", "startTY", "startXML", "startalign", "startalignment", "startallmodes", "startappendices", "startarrangedpages", "startaside", "startattachment", "startbackground", "startbackmatter", "startbar", "startbbordermatrix", "startbitmapimage", "startblockquote", "startbodymatter", "startbordermatrix", "startboxedcolumns", "startbtxlabeltext", "startbtxrenderingdefinitions", "startbuffer", "startcases", "startcatcodetable", "startcenteraligned", "startchapter", "startcharacteralign", "startcheckedfences", "startchemical", "startchemicaltext", "startcollect", "startcollecting", "startcolor", "startcolorintent", "startcoloronly", "startcolorset", "startcolumns", "startcolumnspan", "startcombination", "startcomment", "startcomponent", "startcontextcode", "startcontextdefinitioncode", "startctxfunction", "startctxfunctiondefinition", "startcurrentcolor", "startcurrentlistentrywrapper", "startdelimited", "startdelimitedtext", "startdisplaymath", "startdmath", "startdocument", "starteffect", "startelement", "startembeddedxtable", "startendnote", "startendofline", "startenvironment", "startexceptions", "startexpanded", "startexpandedcollect", "startextendedcatcodetable", "startexternalfigurecollection", "startfact", "startfigure", "startfiguretext", "startfittingpage", "startfixed", "startfloatcombination", "startfont", "startfontclass", "startfontsolution", "startfootnote", "startformula", "startformulas", "startframed", "startframedcell", "startframedcontent", "startframedrow", "startframedtable", "startframedtext", "startfrontmatter", "startgoto", "startgraphictext", "startgridsnapping", "starthanging", "starthbox", "starthboxestohbox", "starthboxregister", "starthead", "startheadtext", "starthelptext", "starthiding", "starthighlight", "starthyphenation", "startimath", "startindentation", "startindentedtext", "startinteraction", "startinteractionmenu", "startinterface", "startintermezzotext", "startintertext", "startitem", "startitemgroup", "startitemgroupcolumns", "startitemize", "startknockout", "startlabeltext", "startlayout", "startleftaligned", "startlegend", "startline", "startlinealignment", "startlinecorrection", "startlinefiller", "startlinenote", "startlinenumbering", "startlines", "startlinetable", "startlinetablebody", "startlinetablecell", "startlinetablehead", "startlocalfootnotes", "startlocalheadsetup", "startlocallinecorrection", "startlocalnotes", "startlocalsetups", "startlua", "startluacode", "startluaparameterset", "startluasetups", "startmakeup", "startmarginblock", "startmarginrule", "startmarkedcontent", "startmathalignment", "startmathcases", "startmathlabeltext", "startmathmatrix", "startmathmode", "startmathstyle", "startmatrices", "startmatrix", "startmaxaligned", "startmdformula", "startmidaligned", "startmiddlealigned", "startmiddlemakeup", "startmixedcolumns", "startmode", "startmodeset", "startmodule", "startmoduletestsection", "startmpformula", "startnamedsection", "startnamedsubformulas", "startnarrow", "startnarrower", "startnegative", "startnicelyfilledbox", "startnointerference", "startnotallmodes", "startnotext", "startnotmode", "startoperatortext", "startopposite", "startoutputstream", "startoverlay", "startoverprint", "startpacked", "startpagecomment", "startpagefigure", "startpagegrid", "startpagegridspan", "startpagelayout", "startpagemakeup", "startpar", "startparagraph", "startparagraphs", "startparagraphscell", "startparbuilder", "startpart", "startpath", "startplacechemical", "startplacefigure", "startplacefloat", "startplaceformula", "startplacegraphic", "startplaceintermezzo", "startplacelegend", "startplacepairedbox", "startplacetable", "startpositioning", "startpositionoverlay", "startpositive", "startpostponing", "startprefixtext", "startprocessassignmentcommand", "startprocessassignmentlist", "startprocesscommacommand", "startprocesscommalist", "startproduct", "startproject", "startprotect", "startprotectedcolors", "startpublication", "startpunctuation", "startquotation", "startquote", "startrandomized", "startrandomseed", "startrawsetups", "startreadingfile", "startreferenceprefix", "startregime", "startregister", "startreusableMPgraphic", "startrightaligned", "startscript", "startsdformula", "startsection", "startsectionblock", "startsectionblockenvironment", "startsectionlevel", "startsetups", "startshapebox", "startshift", "startsidebar", "startsimplecolumns", "startspecialitem", "startspeech", "startspformula", "startsplitformula", "startspread", "startstandardmakeup", "startstartstop", "startstaticMPfigure", "startstaticMPgraphic", "startstrictinspectnextcharacter", "startstructurepageregister", "startstrut", "startstyle", "startsubformulas", "startsubject", "startsubjectlevel", "startsubsection", "startsubsentence", "startsubstack", "startsubsubject", "startsubsubsection", "startsubsubsubject", "startsubsubsubsection", "startsubsubsubsubject", "startsubsubsubsubsection", "startsubsubsubsubsubject", "startsuffixtext", "startsymbolset", "starttable", "starttablehead", "starttables", "starttabletail", "starttabletext", "starttabulate", "starttabulatehead", "starttabulatetail", "starttagged", "starttaglabeltext", "starttexcode", "starttexdefinition", "starttext", "starttextbackground", "starttextbackgroundmanual", "starttextcolor", "starttextcolorintent", "starttextflow", "starttextmakeup", "starttextrule", "starttitle", "starttokens", "starttransparent", "starttypescript", "starttypescriptcollection", "starttyping", "startuniqueMPgraphic", "startuniqueMPpagegraphic", "startunittext", "startunpacked", "startusableMPgraphic", "startuseMPgraphic", "startusemathstyleparameter", "startusingbtxspecification", "startvbox", "startvboxregister", "startvboxtohbox", "startvboxtohboxseparator", "startviewerlayer", "startvtop", "startvtopregister", "startxcell", "startxcellgroup", "startxgroup", "startxmldisplayverbatim", "startxmlinlineverbatim", "startxmlraw", "startxmlsetups", "startxrow", "startxrowgroup", "startxtable", "startxtablebody", "startxtablefoot", "startxtablehead", "startxtablenext", "stligature", "stopJScode", "stopJSpreamble", "stopLUA", "stopMP", "stopMPclip", "stopMPcode", "stopMPdefinitions", "stopMPdrawing", "stopMPenvironment", "stopMPextensions", "stopMPinclusions", "stopMPinitializations", "stopMPpage", "stopMPpositiongraphic", "stopMPpositionmethod", "stopMPrun", "stopPARSEDXML", "stopTABLE", "stopTABLEbody", "stopTABLEfoot", "stopTABLEhead", "stopTABLEnext", "stopTC", "stopTD", "stopTDs", "stopTEX", "stopTEXpage", "stopTH", "stopTN", "stopTR", "stopTRs", "stopTX", "stopTY", "stopXML", "stopalign", "stopalignment", "stopallmodes", "stopappendices", "stoparrangedpages", "stopaside", "stopattachment", "stopbackground", "stopbackmatter", "stopbar", "stopbbordermatrix", "stopbitmapimage", "stopblockquote", "stopbodymatter", "stopbordermatrix", "stopboxedcolumns", "stopbtxlabeltext", "stopbtxrenderingdefinitions", "stopbuffer", "stopcases", "stopcatcodetable", "stopcenteraligned", "stopchapter", "stopcharacteralign", "stopcheckedfences", "stopchemical", "stopchemicaltext", "stopcollect", "stopcollecting", "stopcolor", "stopcolorintent", "stopcoloronly", "stopcolorset", "stopcolumns", "stopcolumnspan", "stopcombination", "stopcomment", "stopcomponent", "stopcontextcode", "stopcontextdefinitioncode", "stopctxfunction", "stopctxfunctiondefinition", "stopcurrentcolor", "stopcurrentlistentrywrapper", "stopdelimited", "stopdelimitedtext", "stopdisplaymath", "stopdmath", "stopdocument", "stopeffect", "stopelement", "stopembeddedxtable", "stopendnote", "stopendofline", "stopenvironment", "stopexceptions", "stopexpanded", "stopexpandedcollect", "stopextendedcatcodetable", "stopexternalfigurecollection", "stopfact", "stopfigure", "stopfiguretext", "stopfittingpage", "stopfixed", "stopfloatcombination", "stopfont", "stopfontclass", "stopfontsolution", "stopfootnote", "stopformula", "stopformulas", "stopframed", "stopframedcell", "stopframedcontent", "stopframedrow", "stopframedtable", "stopframedtext", "stopfrontmatter", "stopgoto", "stopgraphictext", "stopgridsnapping", "stophanging", "stophbox", "stophboxestohbox", "stophboxregister", "stophead", "stopheadtext", "stophelptext", "stophiding", "stophighlight", "stophyphenation", "stopimath", "stopindentation", "stopindentedtext", "stopinteraction", "stopinteractionmenu", "stopinterface", "stopintermezzotext", "stopintertext", "stopitem", "stopitemgroup", "stopitemgroupcolumns", "stopitemize", "stopknockout", "stoplabeltext", "stoplayout", "stopleftaligned", "stoplegend", "stopline", "stoplinealignment", "stoplinecorrection", "stoplinefiller", "stoplinenote", "stoplinenumbering", "stoplines", "stoplinetable", "stoplinetablebody", "stoplinetablecell", "stoplinetablehead", "stoplocalfootnotes", "stoplocalheadsetup", "stoplocallinecorrection", "stoplocalnotes", "stoplocalsetups", "stoplua", "stopluacode", "stopluaparameterset", "stopluasetups", "stopmakeup", "stopmarginblock", "stopmarginrule", "stopmarkedcontent", "stopmathalignment", "stopmathcases", "stopmathlabeltext", "stopmathmatrix", "stopmathmode", "stopmathstyle", "stopmatrices", "stopmatrix", "stopmaxaligned", "stopmdformula", "stopmidaligned", "stopmiddlealigned", "stopmiddlemakeup", "stopmixedcolumns", "stopmode", "stopmodeset", "stopmodule", "stopmoduletestsection", "stopmpformula", "stopnamedsection", "stopnamedsubformulas", "stopnarrow", "stopnarrower", "stopnegative", "stopnicelyfilledbox", "stopnointerference", "stopnotallmodes", "stopnotext", "stopnotmode", "stopoperatortext", "stopopposite", "stopoutputstream", "stopoverlay", "stopoverprint", "stoppacked", "stoppagecomment", "stoppagefigure", "stoppagegrid", "stoppagegridspan", "stoppagelayout", "stoppagemakeup", "stoppar", "stopparagraph", "stopparagraphs", "stopparagraphscell", "stopparbuilder", "stoppart", "stoppath", "stopplacechemical", "stopplacefigure", "stopplacefloat", "stopplaceformula", "stopplacegraphic", "stopplaceintermezzo", "stopplacelegend", "stopplacepairedbox", "stopplacetable", "stoppositioning", "stoppositionoverlay", "stoppositive", "stoppostponing", "stopprefixtext", "stopprocessassignmentcommand", "stopprocessassignmentlist", "stopprocesscommacommand", "stopprocesscommalist", "stopproduct", "stopproject", "stopprotect", "stopprotectedcolors", "stoppublication", "stoppunctuation", "stopquotation", "stopquote", "stoprandomized", "stoprandomseed", "stoprawsetups", "stopreadingfile", "stopreferenceprefix", "stopregime", "stopregister", "stopreusableMPgraphic", "stoprightaligned", "stopscript", "stopsdformula", "stopsection", "stopsectionblock", "stopsectionblockenvironment", "stopsectionlevel", "stopsetups", "stopshapebox", "stopshift", "stopsidebar", "stopsimplecolumns", "stopspecialitem", "stopspeech", "stopspformula", "stopsplitformula", "stopspread", "stopstandardmakeup", "stopstartstop", "stopstaticMPfigure", "stopstaticMPgraphic", "stopstrictinspectnextcharacter", "stopstructurepageregister", "stopstrut", "stopstyle", "stopsubformulas", "stopsubject", "stopsubjectlevel", "stopsubsection", "stopsubsentence", "stopsubstack", "stopsubsubject", "stopsubsubsection", "stopsubsubsubject", "stopsubsubsubsection", "stopsubsubsubsubject", "stopsubsubsubsubsection", "stopsubsubsubsubsubject", "stopsuffixtext", "stopsymbolset", "stoptable", "stoptablehead", "stoptables", "stoptabletail", "stoptabletext", "stoptabulate", "stoptabulatehead", "stoptabulatetail", "stoptagged", "stoptaglabeltext", "stoptexcode", "stoptexdefinition", "stoptext", "stoptextbackground", "stoptextbackgroundmanual", "stoptextcolor", "stoptextcolorintent", "stoptextflow", "stoptextmakeup", "stoptextrule", "stoptitle", "stoptokens", "stoptransparent", "stoptypescript", "stoptypescriptcollection", "stoptyping", "stopuniqueMPgraphic", "stopuniqueMPpagegraphic", "stopunittext", "stopunpacked", "stopusableMPgraphic", "stopuseMPgraphic", "stopusemathstyleparameter", "stopusingbtxspecification", "stopvbox", "stopvboxregister", "stopvboxtohbox", "stopvboxtohboxseparator", "stopviewerlayer", "stopvtop", "stopvtopregister", "stopxcell", "stopxcellgroup", "stopxgroup", "stopxmldisplayverbatim", "stopxmlinlineverbatim", "stopxmlraw", "stopxmlsetups", "stopxrow", "stopxrowgroup", "stopxtable", "stopxtablebody", "stopxtablefoot", "stopxtablehead", "stopxtablenext", "stretched", "strictdoifelsenextoptional", "strictdoifnextoptionalelse", "stripcharacter", "strippedcsname", "stripspaces", "structurelistuservariable", "structurenumber", "structuretitle", "structureuservariable", "structurevariable", "strut", "strutdp", "strutgap", "strutht", "struthtdp", "struttedbox", "strutwd", "style", "styleinstance", "subject", "subpagenumber", "subsection", "subsentence", "subset", "subseteq", "subseteqq", "subsetneq", "subsetneqq", "substituteincommalist", "subsubject", "subsubsection", "subsubsubject", "subsubsubsection", "subsubsubsubject", "subsubsubsubsection", "subsubsubsubsubject", "subtractfeature", "succ", "succapprox", "succcurlyeq", "succeq", "succeqq", "succnapprox", "succneq", "succneqq", "succnsim", "succsim", "suffixlanguage", "suffixtext", "sum", "supset", "supseteq", "supseteqq", "supsetneq", "supsetneqq", "surd", "surdradical", "swapcounts", "swapdimens", "swapface", "swapmacros", "swaptypeface", "swarrow", "switchstyleonly", "switchtobodyfont", "switchtocolor", "switchtointerlinespace", "symbol", "symbolreference", "synchronizeblank", "synchronizeindenting", "synchronizemarking", "synchronizeoutputstreams", "synchronizestrut", "synchronizewhitespace", "synctexblockfilename", "synctexresetfilename", "synctexsetfilename", "systemlog", "systemlogfirst", "systemloglast", "systemsetups", "tLeftarrow", "tLeftrightarrow", "tRightarrow", "tabulateautoline", "tabulateautorule", "tabulateline", "tabulaterule", "taggedctxcommand", "taggedlabeltexts", "taglabellanguage", "taglabeltext", "tau", "tbinom", "tbox", "tcaron", "tcedilla", "tcommaaccent", "tcurl", "tequal", "test", "testandsplitstring", "testcolumn", "testfeature", "testfeatureonce", "testpage", "testpageonly", "testpagesync", "testtokens", "tex", "texdefinition", "texsetup", "textAngstrom", "textacute", "textampersand", "textasciicircum", "textasciitilde", "textat", "textbackslash", "textbar", "textbottomcomma", "textbottomdot", "textbraceleft", "textbraceright", "textbreve", "textbrokenbar", "textbullet", "textcaron", "textcedilla", "textcelsius", "textcent", "textcircledP", "textcircumflex", "textcitation", "textcite", "textcomma", "textcontrolspace", "textcurrency", "textdag", "textddag", "textdegree", "textdiaeresis", "textdiv", "textdollar", "textdong", "textdotaccent", "textellipsis", "texteuro", "textflowcollector", "textfraction", "textgrave", "texthash", "texthorizontalbar", "texthungarumlaut", "texthyphen", "textkelvin", "textlognot", "textmacron", "textmath", "textmho", "textminus", "textmu", "textmultiply", "textnumero", "textogonek", "textohm", "textormathchar", "textounce", "textpercent", "textperiod", "textplus", "textpm", "textreference", "textring", "textrule", "textslash", "textsterling", "texttilde", "textunderscore", "textvisiblespace", "textyen", "thai", "thainumerals", "thefirstcharacter", "thenormalizedbodyfontsize", "therefore", "theremainingcharacters", "theta", "thickspace", "thinrule", "thinrules", "thinspace", "thirdoffivearguments", "thirdoffourarguments", "thirdofsixarguments", "thirdofthreearguments", "thirdofthreeunexpanded", "thook", "thookleftarrow", "thookrightarrow", "thorn", "threedigitrounding", "threeeighths", "threefifths", "threeperemspace", "threequarter", "threesuperior", "tibetannumerals", "tightlayer", "tilde", "times", "tinyfont", "title", "tlap", "tleftarrow", "tleftharpoondown", "tleftharpoonup", "tleftrightarrow", "tleftrightharpoons", "tmapsto", "to", "tochar", "tolinenote", "tooltip", "top", "topbox", "topleftbox", "toplinebox", "toprightbox", "topskippedbox", "tracecatcodetables", "tracedfontname", "traceoutputroutines", "tracepositions", "trademark", "translate", "transparencycomponents", "transparent", "trel", "triangle", "triangledown", "triangleleft", "triangleq", "triangleright", "trightarrow", "trightharpoondown", "trightharpoonup", "trightleftharpoons", "trightoverleftarrow", "triplebond", "tripleprime", "tripleverticalbar", "truefilename", "truefontname", "tstroke", "ttraggedright", "ttriplerel", "ttwoheadleftarrow", "ttwoheadrightarrow", "turnediota", "twodigitrounding", "twofifths", "twoheaddownarrow", "twoheadleftarrow", "twoheadrightarrow", "twoheadrightarrowtail", "twoheaduparrow", "twosuperior", "twothirds", "tx", "txx", "typ", "type", "typebuffer", "typedefinedbuffer", "typeface", "typefile", "typeinlinebuffer", "typescriptone", "typescriptprefix", "typescriptthree", "typescripttwo", "typesetbuffer", "typesetfile", "uacute", "ubreve", "ucaron", "ucircumflex", "uconvertnumber", "udiaeresis", "udiaeresisacute", "udiaeresiscaron", "udiaeresisgrave", "udiaeresismacron", "udotbelow", "udots", "udoublegrave", "uedcatcodecommand", "ugrave", "uhook", "uhorn", "uhornacute", "uhorndotbelow", "uhorngrave", "uhornhook", "uhorntilde", "uhungarumlaut", "uinvertedbreve", "ulcorner", "umacron", "undefinevalue", "undepthed", "underbar", "underbars", "underbrace", "underbracket", "underdash", "underdashes", "underdot", "underdots", "underleftarrow", "underparent", "underrandom", "underrandoms", "underrightarrow", "underset", "understrike", "understrikes", "undoassign", "unexpandeddocumentvariable", "unframed", "unhhbox", "unihex", "uniqueMPgraphic", "uniqueMPpagegraphic", "unit", "unitlanguage", "unitshigh", "unitslow", "unittext", "unknown", "unprotected", "unregisterhyphenationpattern", "unspaceafter", "unspaceargument", "unspaced", "unspacestring", "untexargument", "untexcommand", "uogonek", "upand", "uparrow", "updasharrow", "updownarrow", "updownarrowbar", "updownarrows", "upharpoonleft", "upharpoonright", "uplus", "uppercased", "uppercasestring", "upperleftdoubleninequote", "upperleftdoublesixquote", "upperleftsingleninequote", "upperleftsinglesixquote", "upperrightdoubleninequote", "upperrightdoublesixquote", "upperrightsingleninequote", "upperrightsinglesixquote", "upsilon", "upuparrows", "upwhitearrow", "urcorner", "uring", "url", "useJSscripts", "useMPenvironmentbuffer", "useMPgraphic", "useMPlibrary", "useMPrun", "useMPvariables", "useURL", "usealignparameter", "useblankparameter", "useblocks", "usebodyfont", "usebodyfontparameter", "usebtxdataset", "usebtxdefinitions", "usecitation", "usecolors", "usecomponent", "usedirectory", "usedummycolorparameter", "usedummystyleandcolor", "usedummystyleparameter", "useenvironment", "useexternaldocument", "useexternalfigure", "useexternalrendering", "useexternalsoundtrack", "usefigurebase", "usefile", "usegridparameter", "useindentingparameter", "useindentnextparameter", "useinterlinespaceparameter", "uselanguageparameter", "useluamodule", "usemathstyleparameter", "usemodule", "useproduct", "useprofileparameter", "useproject", "usereferenceparameter", "userpagenumber", "usesetupsparameter", "usestaticMPfigure", "usesubpath", "usesymbols", "usetexmodule", "usetypescript", "usetypescriptfile", "useurl", "usezipfile", "utfchar", "utflower", "utfupper", "utilde", "utilityregisterlength", "vDash", "varTheta", "varepsilon", "varkappa", "varnothing", "varphi", "varpi", "varrho", "varsigma", "vartheta", "vboxreference", "vdash", "vdots", "vec", "vee", "veebar", "veeeq", "verbatim", "verbatimstring", "verbosenumber", "version", "vert", "verticalgrowingbar", "verticalpositionbar", "veryraggedcenter", "veryraggedleft", "veryraggedright", "vglue", "viewerlayer", "vl", "vphantom", "vpos", "vsmash", "vsmashbox", "vsmashed", "vspace", "vspacing", "wcircumflex", "wdofstring", "wedge", "wedgeeq", "weekday", "whitearrowupfrombar", "widehat", "widetilde", "widthofstring", "widthspanningtext", "withoutpt", "word", "wordright", "words", "wordtonumber", "wp", "wr", "writebetweenlist", "writedatatolist", "writestatus", "writetolist", "xLeftarrow", "xLeftrightarrow", "xRightarrow", "xdefconvertedargument", "xequal", "xfrac", "xhookleftarrow", "xhookrightarrow", "xi", "xleftarrow", "xleftharpoondown", "xleftharpoonup", "xleftrightarrow", "xleftrightharpoons", "xmapsto", "xmladdindex", "xmlafterdocumentsetup", "xmlaftersetup", "xmlall", "xmlappenddocumentsetup", "xmlappendsetup", "xmlapplyselectors", "xmlatt", "xmlattdef", "xmlattribute", "xmlattributedef", "xmlbadinclusions", "xmlbeforedocumentsetup", "xmlbeforesetup", "xmlchainatt", "xmlchainattdef", "xmlchecknamespace", "xmlcommand", "xmlconcat", "xmlconcatrange", "xmlcontext", "xmlcount", "xmldefaulttotext", "xmldirectives", "xmldirectivesafter", "xmldirectivesbefore", "xmldisplayverbatim", "xmldoif", "xmldoifelse", "xmldoifelseempty", "xmldoifelseselfempty", "xmldoifelsetext", "xmldoifelsevalue", "xmldoifnot", "xmldoifnotselfempty", "xmldoifnottext", "xmldoifselfempty", "xmldoiftext", "xmlelement", "xmlfilter", "xmlfirst", "xmlflush", "xmlflushcontext", "xmlflushdocumentsetups", "xmlflushlinewise", "xmlflushpure", "xmlflushspacewise", "xmlflushtext", "xmlinclude", "xmlinclusion", "xmlinclusions", "xmlinfo", "xmlinjector", "xmlinlineprettyprint", "xmlinlineprettyprinttext", "xmlinlineverbatim", "xmlinstalldirective", "xmllast", "xmllastatt", "xmllastmatch", "xmllastpar", "xmlloadbuffer", "xmlloaddata", "xmlloaddirectives", "xmlloadfile", "xmlloadonly", "xmlmain", "xmlmapvalue", "xmlname", "xmlnamespace", "xmlnonspace", "xmlpar", "xmlparam", "xmlpath", "xmlpos", "xmlposition", "xmlprependdocumentsetup", "xmlprependsetup", "xmlprettyprint", "xmlprettyprinttext", "xmlprocessbuffer", "xmlprocessdata", "xmlprocessfile", "xmlpure", "xmlraw", "xmlrefatt", "xmlregistereddocumentsetups", "xmlregisteredsetups", "xmlregisterns", "xmlremapname", "xmlremapnamespace", "xmlremovedocumentsetup", "xmlremovesetup", "xmlresetdocumentsetups", "xmlresetinjectors", "xmlresetsetups", "xmlsave", "xmlsetatt", "xmlsetattribute", "xmlsetentity", "xmlsetfunction", "xmlsetinjectors", "xmlsetpar", "xmlsetparam", "xmlsetsetup", "xmlsetup", "xmlshow", "xmlsnippet", "xmlstrip", "xmlstripnolines", "xmlstripped", "xmlstrippednolines", "xmltag", "xmltexentity", "xmltext", "xmltobuffer", "xmltobufferverbose", "xmltofile", "xmlvalue", "xmlverbatim", "xrel", "xrightarrow", "xrightharpoondown", "xrightharpoonup", "xrightleftharpoons", "xrightoverleftarrow", "xsplitstring", "xtriplerel", "xtwoheadleftarrow", "xtwoheadrightarrow", "xxfrac", "xypos", "yacute", "ycircumflex", "ydiaeresis", "ydotbelow", "yen", "ygrave", "yhook", "ymacron", "ytilde", "zacute", "zcaron", "zdotaccent", "zerowidthnobreakspace", "zerowidthspace", "zeta", "zhook", "zstroke", "zwj", "zwnj" },
- ["cs"]={ "Cisla", "Kap", "MESIC", "Rimskecislice", "SLOVA", "SLOVO", "Slova", "Slovo", "VSEDNIDEN", "Znak", "Znaky", "aktualnicislonadpisu", "aktualnidatum", "barevnalista", "barva", "cernalinka", "cernelinky", "cisla", "cislonadpisu", "cislorovnice", "cislostrany", "datum", "definuj", "definujakcent", "definujbarvu", "definujblok", "definujbloksekce", "definujbuffer", "definujfont", "definujformatodkazu", "definujhbox", "definujinterakcnimenu", "definujkombinovanyseznam", "definujkonverzi", "definujnadpis", "definujobrazeksymbol", "definujodkaz", "definujodstavce", "definujopis", "definujoramovani", "definujoramovanytext", "definujpaletu", "definujplvouciobjekt", "definujpodpole", "definujpole", "definujpopis", "definujpopisek", "definujprekryv", "definujprikaz", "definujprofil", "definujprogram", "definujprostredizakladnihofontu", "definujrejstrik", "definujsablonutabulky", "definujsekci", "definujseznam", "definujskupinubarev", "definujstartstop", "definujstyl", "definujstylfontu", "definujsymbol", "definujsynonumumfontu", "definujsynonyma", "definujtabelaci", "definujtext", "definujtrideni", "definujupravu", "definujvelikostpapiru", "definujvycet", "definujzakladnifont", "definujzasobnikpoli", "definujznaceni", "definujznak", "delkaseznamu", "externiobraz", "hlavnijazyk", "hodnotabarvy", "instalacejazyka", "interakcnilista", "interakcnitlacitka", "interaktivnimenu", "jazyk", "jdidolu", "jdina", "jdinabox", "jdinastranu", "klonujpole", "komponenta", "konvertujcislo", "kopirujpole", "korekcebilehomista", "matematika", "meritko", "mesic", "mezera", "mrizka", "nastavbarvu", "nastavbarvy", "nastavbilamista", "nastavblok", "nastavbloksekce", "nastavbuffer", "nastavcernelinky", "nastavcislonadpisu", "nastavcislostrany", "nastavcislovaniodstavcu", "nastavcislovaniradku", "nastavcislovanistran", "nastavcitaci", "nastavdeleniplvoucichobjektu", "nastavdelitko", "nastavdolnitexty", "nastavhorejsek", "nastavhornitexty", "nastavinterakci", "nastavinterakcnilistu", "nastavinterakcnimenu", "nastavinterakcniobrazovku", "nastavjazyk", "nastavkapitalky", "nastavkombinovanyseznam", "nastavkomentar", "nastavkomentarstrany", "nastavmarginalnilinky", "nastavmeziradkovoumezeru", "nastavnadpis", "nastavnadpisy", "nastavodkazovani", "nastavodsazovani", "nastavodstavce", "nastavopis", "nastavoramovanetexty", "nastavoramovani", "nastavorez", "nastavotoceni", "nastavpaletu", "nastavplvouciobjekt", "nastavplvouciobjekty", "nastavpodcislostrany", "nastavpole", "nastavpolozky", "nastavpopisek", "nastavpopisky", "nastavpozadi", "nastavprechodstrany", "nastavpreskok", "nastavprogramy", "nastavradkovani", "nastavradky", "nastavrejstrik", "nastavrovnice", "nastavsadusymbolu", "nastavseznam", "nastavsirkucary", "nastavsloupce", "nastavspodek", "nastavsynonyma", "nastavtabelaci", "nastavtabulky", "nastavtenkelinky", "nastavtext", "nastavtextovelinky", "nastavtexttexty", "nastavtextyupati", "nastavtextyzahlavi", "nastavtoleranci", "nastavtrideni", "nastavtype", "nastavumisteniprotejsku", "nastavumistovani", "nastavupati", "nastavupravu", "nastavurl", "nastavusporadani", "nastavvelikostpapiru", "nastavvsechnapole", "nastavvycty", "nastavvyplnovelinky", "nastavvyplnoveradky", "nastavvzhled", "nastavzahlavi", "nastavzakladnifont", "nastavzarovnani", "nastavznaceni", "nastavzuzeni", "nastrane", "nejakyradek", "nekde", "neznamo", "nivy", "nizky", "nokap", "obrazovka", "odkaz", "odkaznastranu", "odkaznatext", "odkazujici", "opis", "opissoubor", "oramovani", "oref", "orez", "otocit", "oznaceni", "pis", "plnezneni", "pole", "polozka", "polozky", "porovnejpaletu", "porovnejskupinubarev", "pozadi", "pozice", "poznamka", "pref", "prelozit", "prepninazakladnifont", "preskoc", "prizpusobivepole", "prizpusobvzhled", "produkt", "projekt", "prostredi", "resetznaceni", "rimskecislice", "rozdelplvouciobjekt", "roztazene", "schovejbloky", "sedabarva", "sloupec", "slovovpravo", "stanovcharakteristickuseznamu", "stanovcislonadpisu", "startbarva", "startinteraktivnimenu", "startjdina", "startkomponenta", "startmarginalnilinka", "startnadpis", "startoramovani", "startpolozka", "startpozadi", "startprodukt", "startprojekt", "startprostredi", "startpublikace", "startradek", "starttextovalinka", "startumistirovnici", "startzarovnanonastred", "startzarovnanovlevo", "startzarovnanovpravo", "startzhustene", "stopbarva", "stopinteraktivnimenu", "stopjdina", "stopkomponenta", "stopmarginalnilinka", "stopnadpis", "stoporamovani", "stoppolozka", "stoppozadi", "stopprodukt", "stopprojekt", "stopprostredi", "stoppublikace", "stopradek", "stoptextovalinka", "stopumistirovnici", "stopzarovnanonastred", "stopzarovnanovlevo", "stopzarovnanovpravo", "stopzhustene", "strana", "tecky", "tenkalinka", "tenkelinky", "textovalinka", "tlacitko", "tlacitkomenu", "tloustkacary", "tref", "tvrdamezera", "tvrdemezery", "ukazbarvu", "ukazmrizku", "ukaznastaveni", "ukazpaletu", "ukazpodpery", "ukazpostredizakladnihofontu", "ukazramecek", "ukazsadusymbolu", "ukazskupinubarev", "ukazupravu", "ukazvytisk", "ukazvzhled", "ukazzakladnifont", "umistikombinovanyseznam", "umistilokalnipoznamkypodcarou", "umistinadsebe", "umistinamrizku", "umistipodrovnici", "umistipoznamkypodcarou", "umistirejstrik", "umistirovnici", "umistiseznam", "umistivedlesebe", "umistizalozky", "urcicharakteristikurejstriku", "uzijJSscripts", "uzijURL", "uzijadresar", "uzijbloky", "uzijexternidokument", "uzijexterniobraz", "uzijexternizvuk", "uzijmodul", "uzijsymbol", "uzijurl", "verze", "vlasovalinka", "vradku", "vsedniden", "vyberbloky", "vyplnenytext", "vyplnovelinky", "vyplnovyradek", "vysoky", "zachovejbloky", "zadnamezera", "zadnehorniadolniradky", "zadnezahlaviaupati", "zalozka", "zapisdoseznamu", "zapismeziseznam", "zaramovani", "zarovnanonastred", "zarovnanovlevo", "zarovnanovpravo", "zasobnikpoli", "ziskejbuffer", "ziskejznaceni", "znaceni", "znak", "znaky", "zpracujbloky", "zrcadlit", "zref" },
- ["de"]={ "Buchstabe", "Buchstaben", "Kap", "MONAT", "Roemischezahlen", "WOCHENTAG", "WOERTER", "WORT", "Woerter", "Wort", "Ziffern", "amgitterausrichten", "aufseite", "ausfuelltext", "ausschnitt", "bearbeitebloecke", "behaltebloecke", "bei", "bemerkung", "benutzeverzeichnis", "beschriftung", "bestimmekopfnummer", "bestimmelistencharakeristika", "bestimmeregistercharakteristika", "bildschirm", "blanko", "buchstabe", "buchstaben", "datum", "defineschriftsynonym", "definiereabbsymbol", "definiereabsaetze", "definiereabschnitt", "definiereabschnittsblock", "definiereakzent", "definierebefehl", "definierebeschreibung", "definierebeschriftung", "definiereblock", "definierefarbe", "definierefarbengruppe", "definierefeld", "definierefeldstapel", "definierefliesstext", "definierefliesstextumgebung", "definieregleitobjekt", "definierehbox", "definiereinteraktionsmenue", "definierekonversion", "definierelabel", "definiereliste", "definieren", "definierenummerierung", "definiereoverlay", "definierepalette", "definierepapierformat", "definiereprofil", "definiereprogramme", "definierepuffer", "definierereferenz", "definierereferenzformat", "definiereregister", "definiereschrift", "definiereschriftstil", "definieresortieren", "definierestartstop", "definierestil", "definieresubfeld", "definieresymbol", "definieresynonyme", "definieretabellenvorlage", "definieretabulator", "definieretext", "definieretippen", "definiereueberschrift", "definiereumbruch", "definiereumrahmt", "definiereumrahmtertext", "definierezeichen", "definierezusammengestellteliste", "drehen", "duennelinie", "duennerumriss", "einezeile", "externeabbildung", "farbbalken", "farbe", "farbewert", "feld", "feldstapel", "festesspatium", "format", "formelnummer", "gefuelltesrechteck", "gefuelltezeile", "gestreckt", "gitter", "graufarbe", "haarlinie", "hauptsprache", "heutigesdatum", "heutigeskopfnummer", "hintergrund", "hoch", "holebeschriftung", "holepuffer", "imumriss", "installieresprache", "interaktionsbalken", "interaktionsknopfe", "interaktionsmenue", "inzeile", "irgendwo", "keinekopfundfusszeilen", "keinspatium", "keinzeilenobenundunten", "klonierefeld", "knopf", "komponente", "konvertierezahl", "kopfnummer", "kopierefeld", "korrigierezwischenraum", "liniendicke", "linksbuendig", "listenlaenge", "mathematik", "menueknopf", "monat", "nachunten", "nokap", "notiz", "passelayoutan", "passendfeld", "platzierebookmarks", "platziereformel", "platzierefussnoten", "platziereliste", "platzierelokalefussnoten", "platzierenebeneinander", "platziereregister", "platziereuntereinander", "platziereunterformel", "platzierezusammengestellteliste", "pos", "posten", "produkt", "programm", "projekt", "punkt", "rechteck", "rechtecke", "rechtsbuendig", "referenz", "referieren", "roemischezahlen", "ruecksetztenbeschriftung", "schreibezurliste", "schreibezwischenliste", "seite", "seitenreferenz", "seitenummer", "settext", "spalte", "spatium", "spiegeln", "sprache", "startfarbe", "starthintergrund", "startinteraktionsmenue", "startkleinerdurchschuss", "startkomponente", "startkopf", "startlinksbuendig", "startmarginallinie", "startplatziereformel", "startpos", "startprodukt", "startprojekt", "startpublikation", "startrechtsbuendig", "starttextlinie", "startumgebung", "startumrahmt", "startzeile", "startzentriert", "startzu", "stelleabsaetzeein", "stelleabsatznummerierungein", "stelleabschnittsblockein", "stelleanordnenein", "stelleaufzaehlungenein", "stelleausrichtungein", "stelleausschnittein", "stellebeschreibungein", "stellebeschriftungein", "stellebilderunterschriftein", "stellebildunterschriftein", "stellebindestrichein", "stelleblankoein", "stelleblockein", "stelledrehenein", "stelleduennerumrissein", "stelleeinziehenein", "stelleengerein", "stellefarbeein", "stellefarbenein", "stellefeldein", "stellefelderin", "stellefliesstextein", "stelleformelnein", "stellefusszeileein", "stellefusszeilentextein", "stellegefuelltesrechteckein", "stellegefuelltezeileein", "stellegegenueberplatzierenein", "stellegleitobjekteein", "stellegleitobjektein", "stellehintergruendeein", "stellehintergrundein", "stelleinteraktionein", "stelleinteraktionsbalkenein", "stelleinteraktionsbildschirmein", "stelleinteraktionsmenueein", "stellekommentarein", "stellekopfzahlein", "stellekopfzeileein", "stellekopfzeilentextein", "stellelayoutein", "stellelinienbreiteein", "stellelisteein", "stellemarginallinieein", "stellenobenein", "stellepaletteein", "stellepapierformatein", "stelleplatziegeteiltegleitobjekt", "stellepositionierenein", "stellepostenein", "stelleprogrammein", "stellepufferein", "stellerechteckein", "stellereferenzierenein", "stelleregisterein", "stelleseitenkommentarein", "stelleseitennummerein", "stelleseitennummeriernungein", "stelleseitenuebergangein", "stellesortierenein", "stellespaltenein", "stellespatiumein", "stellespracheein", "stellesymbolsetein", "stellesynonymein", "stelletabellenein", "stelletabulatorein", "stelletextein", "stelletextobenein", "stelletexttexteein", "stelletextumrissein", "stelletextuntenein", "stelletipein", "stelletippenein", "stelletoleranzein", "stelleueberschriftein", "stelleueberschriftenein", "stelleumbruchein", "stelleumrahmtein", "stelleumrahmtetexteein", "stelleuntenein", "stelleunterseitennummerein", "stelleurlein", "stelleversalienein", "stellezeilenabstandein", "stellezeilenein", "stellezeilennumerierungein", "stellezitierenein", "stellezusammengestelltelisteein", "stellezwischenraumein", "stopfarbe", "stophintergrund", "stopinteraktionsmenue", "stopkleinerdurchschuss", "stopkomponente", "stopkopf", "stoplinksbuendig", "stopmarginallinie", "stopplatziereformel", "stoppos", "stopprodukt", "stopprojekt", "stoppublikation", "stoprechtsbuendig", "stoptextlinie", "stopumgebung", "stopumrahmt", "stopzeile", "stopzentriert", "stopzu", "teilegleitobjekt", "textlinie", "textreferenz", "tief", "tiho", "tip", "tippedatei", "tippen", "tippepuffer", "ueber", "uebersetzten", "umgebung", "umrahmt", "unbekant", "verbergebloecke", "vergleichefarbengruppe", "vergleichepalette", "verwendeJSscript", "verwendeURL", "verwendebloecke", "verwendeexteresdokument", "verwendeexterneabbildung", "verwendeexternestonstueck", "verwendemodul", "verwendesymbole", "verwendeurl", "volleswort", "von", "waehlebloeckeaus", "wechselezumfliesstext", "wochentag", "wortrechts", "zeigedruck", "zeigeeinstellungen", "zeigefarbe", "zeigefarbengruppe", "zeigefliesstext", "zeigefliesstextumgebung", "zeigegitter", "zeigelayout", "zeigepalette", "zeigerahmen", "zeigestruts", "zeigeumbruch", "zentriert", "ziffern", "zu", "zurbox", "zurseite" },
+ ["common"]={ "AEacute", "AEligature", "AEmacron", "AMSTEX", "Aacute", "Abreve", "Abreveacute", "Abrevedotbelow", "Abrevegrave", "Abrevehook", "Abrevetilde", "Acaron", "Acircumflex", "Acircumflexacute", "Acircumflexdotbelow", "Acircumflexgrave", "Acircumflexhook", "Acircumflextilde", "Adiaeresis", "Adiaeresismacron", "Adotaccent", "Adotaccentmacron", "Adotbelow", "Adoublegrave", "AfterPar", "Agrave", "Ahook", "Ainvertedbreve", "Alpha", "Alphabeticnumerals", "AmSTeX", "Amacron", "And", "Angstrom", "Aogonek", "Aring", "Aringacute", "Arrowvert", "Astroke", "Atilde", "BeforePar", "Beta", "Bhook", "Big", "Bigg", "Biggl", "Biggm", "Biggr", "Bigl", "Bigm", "Bigr", "Box", "Bumpeq", "CONTEXT", "Cacute", "Cap", "Caps", "Ccaron", "Ccedilla", "Ccircumflex", "Cdotaccent", "Character", "Characters", "Chi", "Chook", "ConTeXt", "Context", "ConvertConstantAfter", "ConvertToConstant", "Cstroke", "Cup", "DZcaronligature", "DZligature", "Dafrican", "Dcaron", "Ddownarrow", "Delta", "Dhook", "Doteq", "Downarrow", "Dstroke", "Dzcaronligature", "Dzligature", "ETEX", "Eacute", "Ebreve", "Ecaron", "Ecedilla", "Ecircumflex", "Ecircumflexacute", "Ecircumflexdotbelow", "Ecircumflexgrave", "Ecircumflexhook", "Ecircumflextilde", "Ediaeresis", "Edotaccent", "Edotbelow", "Edoublegrave", "Egrave", "Ehook", "Einvertedbreve", "Emacron", "Eogonek", "Epsilon", "Eta", "Eth", "Etilde", "Eulerconst", "EveryLine", "EveryPar", "Fhook", "Finv", "Gacute", "Game", "Gamma", "Gbreve", "Gcaron", "Gcircumflex", "Gcommaaccent", "Gdotaccent", "GetPar", "Ghook", "GotoPar", "Greeknumerals", "Gstroke", "Hat", "Hcaron", "Hcircumflex", "Hstroke", "IJligature", "INRSTEX", "Iacute", "Ibreve", "Icaron", "Icircumflex", "Idiaeresis", "Idotaccent", "Idotbelow", "Idoublegrave", "Igrave", "Ihook", "Iinvertedbreve", "Im", "Imacron", "Iogonek", "Iota", "Istroke", "Itilde", "Jcircumflex", "Join", "Kappa", "Kcaron", "Kcommaaccent", "Khook", "LAMSTEX", "LATEX", "LJligature", "LUAJITTEX", "LUATEX", "LaTeX", "Lacute", "LamSTeX", "Lambda", "Lbar", "Lcaron", "Lcommaaccent", "Ldotmiddle", "Ldsh", "Leftarrow", "Leftrightarrow", "Ljligature", "Lleftarrow", "Longleftarrow", "Longleftrightarrow", "Longmapsfrom", "Longmapsto", "Longrightarrow", "Lsh", "Lstroke", "Lua", "LuaTeX", "LuajitTeX", "METAFONT", "METAFUN", "METAPOST", "MKII", "MKIV", "MKIX", "MKVI", "MKXI", "MONTH", "MONTHLONG", "MONTHSHORT", "MPII", "MPIV", "MPVI", "MPanchor", "MPbetex", "MPc", "MPcode", "MPcolor", "MPcoloronly", "MPcolumn", "MPd", "MPdrawing", "MPfontsizehskip", "MPgetmultipars", "MPgetmultishape", "MPgetposboxes", "MPh", "MPinclusions", "MPleftskip", "MPll", "MPlr", "MPls", "MPmenubuttons", "MPn", "MPoptions", "MPoverlayanchor", "MPp", "MPpage", "MPpardata", "MPplus", "MPpos", "MPpositiongraphic", "MPposset", "MPr", "MPrawvar", "MPregion", "MPrest", "MPrightskip", "MPrs", "MPstring", "MPtext", "MPtransparency", "MPul", "MPur", "MPv", "MPvar", "MPvariable", "MPvv", "MPw", "MPwhd", "MPx", "MPxy", "MPxywhd", "MPy", "Mapsfrom", "Mapsto", "MetaFont", "MetaFun", "MetaPost", "Mu", "NJligature", "Nacute", "Ncaron", "Ncommaaccent", "Nearrow", "Neng", "Ngrave", "Njligature", "NormalizeFontHeight", "NormalizeFontWidth", "NormalizeTextHeight", "NormalizeTextWidth", "Ntilde", "Nu", "Numbers", "Nwarrow", "OEligature", "Oacute", "Obreve", "Ocaron", "Ocircumflex", "Ocircumflexacute", "Ocircumflexdotbelow", "Ocircumflexgrave", "Ocircumflexhook", "Ocircumflextilde", "Odiaeresis", "Odiaeresismacron", "Odotaccent", "Odotaccentmacron", "Odotbelow", "Odoublegrave", "Ograve", "Ohook", "Ohorn", "Ohornacute", "Ohorndotbelow", "Ohorngrave", "Ohornhook", "Ohorntilde", "Ohungarumlaut", "Oinvertedbreve", "Omacron", "Omega", "Omicron", "Oogonek", "Oogonekmacron", "Ostroke", "Ostrokeacute", "Otilde", "Otildemacron", "P", "PDFETEX", "PDFTEX", "PDFcolor", "PICTEX", "PPCHTEX", "PPCHTeX", "PRAGMA", "Phi", "Phook", "Pi", "PiCTeX", "Plankconst", "PointsToBigPoints", "PointsToReal", "PointsToWholeBigPoints", "PropertyLine", "Psi", "PtToCm", "Racute", "Rcaron", "Rcommaaccent", "Rdoublegrave", "Rdsh", "Re", "ReadFile", "Relbar", "Rho", "Rightarrow", "Rinvertedbreve", "Romannumerals", "Rrightarrow", "Rsh", "S", "Sacute", "ScaledPointsToBigPoints", "ScaledPointsToWholeBigPoints", "Scaron", "Scedilla", "Schwa", "Scircumflex", "Scommaaccent", "Searrow", "Sigma", "Smallcapped", "Subset", "Supset", "Swarrow", "TABLE", "TEX", "TaBlE", "Tau", "Tcaron", "Tcedilla", "Tcommaaccent", "TeX", "TheNormalizedFontSize", "Theta", "Thook", "Thorn", "TransparencyHack", "Tstroke", "Uacute", "Ubreve", "Ucaron", "Ucircumflex", "Udiaeresis", "Udiaeresisacute", "Udiaeresiscaron", "Udiaeresisgrave", "Udiaeresismacron", "Udotbelow", "Udoublegrave", "Ugrave", "Uhook", "Uhorn", "Uhornacute", "Uhorndotbelow", "Uhorngrave", "Uhornhook", "Uhorntilde", "Uhungarumlaut", "Uinvertedbreve", "Umacron", "Uogonek", "Uparrow", "Updownarrow", "Upsilon", "Uring", "Utilde", "Uuparrow", "VDash", "Vdash", "VerboseNumber", "Vert", "Vvdash", "WEEKDAY", "WORD", "WORDS", "Wcircumflex", "WidthSpanningText", "Word", "Words", "XETEX", "XeTeX", "Xi", "Yacute", "Ycircumflex", "Ydiaeresis", "Ydotbelow", "Ygrave", "Yhook", "Ymacron", "Ytilde", "Zacute", "Zcaron", "Zdotaccent", "Zeta", "Zhook", "Zstroke", "aacute", "abbreviation", "abjadnaivenumerals", "abjadnodotnumerals", "abjadnumerals", "about", "abreve", "abreveacute", "abrevedotbelow", "abrevegrave", "abrevehook", "abrevetilde", "acaron", "acircumflex", "acircumflexacute", "acircumflexdotbelow", "acircumflexgrave", "acircumflexhook", "acircumflextilde", "activatespacehandler", "actuarial", "acute", "acwopencirclearrow", "adaptcollector", "adaptfontfeature", "adaptlayout", "adaptpapersize", "addfeature", "addfontpath", "addtoJSpreamble", "addtocommalist", "addvalue", "adiaeresis", "adiaeresismacron", "adotaccent", "adotaccentmacron", "adotbelow", "adoublegrave", "aeacute", "aeligature", "aemacron", "afghanicurrency", "aftersplitstring", "aftertestandsplitstring", "agrave", "ahook", "ainvertedbreve", "aleph", "alignbottom", "aligned", "alignedbox", "alignedline", "alignhere", "alignmentcharacter", "allinputpaths", "alpha", "alphabeticnumerals", "alwayscitation", "alwayscite", "amacron", "amalg", "ampersand", "anchor", "angle", "aogonek", "appendetoks", "appendgvalue", "appendtocommalist", "appendtoks", "appendtoksonce", "appendvalue", "apply", "applyalternativestyle", "applyprocessor", "applytocharacters", "applytofirstcharacter", "applytosplitstringchar", "applytosplitstringcharspaced", "applytosplitstringline", "applytosplitstringlinespaced", "applytosplitstringword", "applytosplitstringwordspaced", "applytowords", "approx", "approxEq", "approxeq", "approxnEq", "arabicakbar", "arabicalayhe", "arabicallah", "arabicallallahou", "arabicasterisk", "arabicbasmalah", "arabiccomma", "arabiccuberoot", "arabicdateseparator", "arabicdecimals", "arabicdisputedendofayah", "arabicendofayah", "arabicexnumerals", "arabicfootnotemarker", "arabicfourthroot", "arabichighain", "arabichighalayheassallam", "arabichigheqala", "arabichighesala", "arabichighfootnotemarker", "arabichighjeem", "arabichighlamalef", "arabichighmadda", "arabichighmeemlong", "arabichighmeemshort", "arabichighnisf", "arabichighnoon", "arabichighnoonkasra", "arabichighqaf", "arabichighqif", "arabichighradiallahouanhu", "arabichighrahmatullahalayhe", "arabichighrubc", "arabichighsad", "arabichighsajda", "arabichighsakta", "arabichighsallallahou", "arabichighseen", "arabichighsmallsafha", "arabichightah", "arabichightakhallus", "arabichighthalatha", "arabichighwaqf", "arabichighyeh", "arabichighzain", "arabicjallajalalouhou", "arabiclettermark", "arabiclowmeemlong", "arabiclownoonkasra", "arabiclowseen", "arabicmisra", "arabicmuhammad", "arabicnumber", "arabicnumberabove", "arabicnumerals", "arabicparenleft", "arabicparenright", "arabicpercent", "arabicperiod", "arabicpermille", "arabicpertenthousand", "arabicpoeticverse", "arabicqala", "arabicquestion", "arabicrasoul", "arabicray", "arabicrialsign", "arabicsafha", "arabicsajdah", "arabicsalla", "arabicsamvat", "arabicsanah", "arabicsemicolon", "arabicshighthreedots", "arabicslcm", "arabicstartofrubc", "arabictripledot", "arabicvowelwaw", "arabicvowelyeh", "arabicwasallam", "arg", "aring", "aringacute", "arrowvert", "asciistr", "aside", "assignalfadimension", "assigndimen", "assigndimension", "assignifempty", "assigntranslation", "assignvalue", "assignwidth", "assumelongusagecs", "ast", "astype", "asymp", "at", "atilde", "atleftmargin", "atpage", "atrightmargin", "attachment", "autocap", "autodirhbox", "autodirvbox", "autodirvtop", "autoinsertnextspace", "autointegral", "automathematics", "autopagestaterealpage", "autopagestaterealpageorder", "autosetups", "availablehsize", "averagecharwidth", "backepsilon", "background", "backgroundimage", "backgroundimagefill", "backgroundline", "backprime", "backsim", "backslash", "bar", "barleftarrow", "barleftarrowrightarrowbar", "barovernorthwestarrow", "barwedge", "basegrid", "baselinebottom", "baselineleftbox", "baselinemiddlebox", "baselinerightbox", "bbordermatrix", "bbox", "because", "beforesplitstring", "beforetestandsplitstring", "beta", "beth", "between", "bhook", "big", "bigbodyfont", "bigcap", "bigcirc", "bigcircle", "bigcup", "bigdiamond", "bigg", "bigger", "biggl", "biggm", "biggr", "bigl", "bigm", "bigodot", "bigoplus", "bigotimes", "bigr", "bigskip", "bigsqcap", "bigsqcup", "bigsquare", "bigstar", "bigtimes", "bigtriangledown", "bigtriangleup", "bigudot", "biguplus", "bigvee", "bigwedge", "binom", "bitmapimage", "blacklozenge", "blackrule", "blackrules", "blacksquare", "blacktriangle", "blacktriangledown", "blacktriangleleft", "blacktriangleright", "blank", "blap", "bleed", "bleedheight", "bleedwidth", "blockligatures", "blockquote", "blocksynctexfile", "blockuservariable", "bodyfontenvironmentlist", "bodyfontsize", "bold", "boldface", "bolditalic", "boldslanted", "bookmark", "booleanmodevalue", "bordermatrix", "bot", "bottombox", "bottomleftbox", "bottomrightbox", "bowtie", "boxcursor", "boxdot", "boxmarker", "boxminus", "boxofsize", "boxplus", "boxreference", "boxtimes", "bpos", "breakablethinspace", "breakhere", "breve", "bstroke", "btxabbreviatedjournal", "btxaddjournal", "btxalwayscitation", "btxauthorfield", "btxdetail", "btxdirect", "btxdoif", "btxdoifcombiinlistelse", "btxdoifelse", "btxdoifelsecombiinlist", "btxdoifelsesameasprevious", "btxdoifelsesameaspreviouschecked", "btxdoifelseuservariable", "btxdoifnot", "btxdoifsameaspreviouscheckedelse", "btxdoifsameaspreviouselse", "btxdoifuservariableelse", "btxexpandedjournal", "btxfield", "btxfieldname", "btxfieldtype", "btxfirstofrange", "btxflush", "btxflushauthor", "btxflushauthorinverted", "btxflushauthorinvertedshort", "btxflushauthorname", "btxflushauthornormal", "btxflushauthornormalshort", "btxflushsuffix", "btxfoundname", "btxfoundtype", "btxhiddencitation", "btxhybridcite", "btxlabellanguage", "btxlabeltext", "btxlistcitation", "btxloadjournalist", "btxoneorrange", "btxremapauthor", "btxsavejournalist", "btxsetup", "btxsingularorplural", "btxsingularplural", "btxtextcitation", "buildmathaccent", "buildtextaccent", "buildtextbottomcomma", "buildtextbottomdot", "buildtextcedilla", "buildtextgrave", "buildtextmacron", "buildtextognek", "bullet", "button", "cacute", "calligraphic", "camel", "cap", "carriagereturn", "catcodetablename", "cbox", "ccaron", "ccedilla", "ccircumflex", "ccurl", "cdot", "cdotaccent", "cdotp", "cdots", "centeraligned", "centerbox", "centerdot", "centeredbox", "centeredlastline", "centerednextbox", "centerline", "cfrac", "chapter", "character", "characters", "chardescription", "charwidthlanguage", "check", "checkcharacteralign", "checkedblank", "checkedchar", "checkedfiller", "checkedstrippedcsname", "checkinjector", "checkmark", "checknextindentation", "checknextinjector", "checkpage", "checkparameters", "checkpreviousinjector", "checksoundtrack", "checktwopassdata", "checkvariables", "chem", "chemical", "chemicalbottext", "chemicalmidtext", "chemicalsymbol", "chemicaltext", "chemicaltoptext", "chi", "chineseallnumerals", "chinesecapnumerals", "chinesenumerals", "chook", "circ", "circeq", "circlearrowleft", "circlearrowright", "circledR", "circledS", "circledast", "circledcirc", "circleddash", "circledequals", "circleonrightarrow", "citation", "cite", "clap", "classfont", "cldcommand", "cldcontext", "cldloadfile", "cldprocessfile", "cleftarrow", "clip", "clippedoverlayimage", "clonefield", "clubsuit", "collect", "collectedtext", "collectexpanded", "colon", "coloncolonequals", "colonequals", "color", "colorbar", "colorcomponents", "colored", "coloronly", "colorvalue", "column", "columnbreak", "columnsetspanwidth", "combinepages", "commalistelement", "commalistsentence", "commalistsize", "comment", "comparecolorgroup", "comparedimension", "comparedimensioneps", "comparepalet", "complement", "completebtxrendering", "completecontent", "completeindex", "completelist", "completelistofabbreviations", "completelistofchemicals", "completelistoffigures", "completelistofgraphics", "completelistofintermezzi", "completelistoflogos", "completelistofpublications", "completelistofsorts", "completelistofsynonyms", "completelistoftables", "completepagenumber", "completeregister", "complexes", "complexorsimple", "complexorsimpleempty", "component", "composedcollector", "composedlayer", "compresult", "cong", "constantdimen", "constantdimenargument", "constantemptyargument", "constantnumber", "constantnumberargument", "contentreference", "continuednumber", "continueifinputfile", "convertargument", "convertcommand", "convertedcounter", "converteddimen", "convertedsubcounter", "convertmonth", "convertnumber", "convertvalue", "convertvboxtohbox", "coprod", "copyboxfromcache", "copybtxlabeltext", "copyfield", "copyheadtext", "copylabeltext", "copymathlabeltext", "copyoperatortext", "copypages", "copyparameters", "copyposition", "copyprefixtext", "copyright", "copysetups", "copysuffixtext", "copytaglabeltext", "copyunittext", "correctwhitespace", "countersubs", "counttoken", "counttokens", "cramped", "crampedclap", "crampedllap", "crampedrlap", "crightarrow", "crightoverleftarrow", "cstroke", "ctop", "ctxcommand", "ctxdirectcommand", "ctxdirectlua", "ctxfunction", "ctxlatecommand", "ctxlatelua", "ctxloadluafile", "ctxlua", "ctxluabuffer", "ctxluacode", "ctxreport", "ctxsprint", "cup", "curlyeqprec", "curlyeqsucc", "curlyvee", "curlywedge", "currentassignmentlistkey", "currentassignmentlistvalue", "currentbtxuservariable", "currentcommalistitem", "currentcomponent", "currentdate", "currentenvironment", "currentfeaturetest", "currentheadnumber", "currentinterface", "currentlanguage", "currentlistentrydestinationattribute", "currentlistentrylimitedtext", "currentlistentrynumber", "currentlistentrypagenumber", "currentlistentryreferenceattribute", "currentlistentrytitle", "currentlistentrytitlerendered", "currentlistsymbol", "currentmainlanguage", "currentmessagetext", "currentmoduleparameter", "currentoutputstream", "currentproduct", "currentproject", "currentregime", "currentregisterpageuserdata", "currentresponses", "currenttime", "currentvalue", "currentxtablecolumn", "currentxtablerow", "curvearrowleft", "curvearrowright", "cwopencirclearrow", "cyrillicA", "cyrillicAE", "cyrillicAbreve", "cyrillicAdiaeresis", "cyrillicB", "cyrillicBIGYUS", "cyrillicBIGYUSiotified", "cyrillicC", "cyrillicCH", "cyrillicCHEDC", "cyrillicCHEDCabkhasian", "cyrillicCHEabkhasian", "cyrillicCHEdiaeresis", "cyrillicCHEkhakassian", "cyrillicCHEvertstroke", "cyrillicD", "cyrillicDASIAPNEUMATA", "cyrillicDJE", "cyrillicDZE", "cyrillicDZEabkhasian", "cyrillicDZHE", "cyrillicE", "cyrillicELtail", "cyrillicEMtail", "cyrillicENDC", "cyrillicENGHE", "cyrillicENhook", "cyrillicENtail", "cyrillicEREV", "cyrillicERY", "cyrillicERtick", "cyrillicEbreve", "cyrillicEdiaeresis", "cyrillicEgrave", "cyrillicEiotified", "cyrillicF", "cyrillicFITA", "cyrillicG", "cyrillicGHEmidhook", "cyrillicGHEstroke", "cyrillicGHEupturn", "cyrillicGJE", "cyrillicH", "cyrillicHA", "cyrillicHADC", "cyrillicHRDSN", "cyrillicI", "cyrillicIE", "cyrillicII", "cyrillicISHRT", "cyrillicISHRTtail", "cyrillicIZHITSA", "cyrillicIZHITSAdoublegrave", "cyrillicIdiaeresis", "cyrillicIgrave", "cyrillicImacron", "cyrillicJE", "cyrillicK", "cyrillicKADC", "cyrillicKAbashkir", "cyrillicKAhook", "cyrillicKAstroke", "cyrillicKAvertstroke", "cyrillicKJE", "cyrillicKOPPA", "cyrillicKSI", "cyrillicL", "cyrillicLITTLEYUS", "cyrillicLITTLEYUSiotified", "cyrillicLJE", "cyrillicM", "cyrillicN", "cyrillicNJE", "cyrillicO", "cyrillicOMEGA", "cyrillicOMEGAround", "cyrillicOMEGAtitlo", "cyrillicOT", "cyrillicObarred", "cyrillicObarreddiaeresis", "cyrillicOdiaeresis", "cyrillicP", "cyrillicPALATALIZATION", "cyrillicPALOCHKA", "cyrillicPEmidhook", "cyrillicPSI", "cyrillicPSILIPNEUMATA", "cyrillicR", "cyrillicS", "cyrillicSCHWA", "cyrillicSCHWAdiaeresis", "cyrillicSDSC", "cyrillicSEMISOFT", "cyrillicSFTSN", "cyrillicSH", "cyrillicSHCH", "cyrillicSHHA", "cyrillicT", "cyrillicTEDC", "cyrillicTETSE", "cyrillicTITLO", "cyrillicTSHE", "cyrillicU", "cyrillicUK", "cyrillicUSHRT", "cyrillicUdiaeresis", "cyrillicUdoubleacute", "cyrillicUmacron", "cyrillicV", "cyrillicYA", "cyrillicYAT", "cyrillicYERUdiaeresis", "cyrillicYI", "cyrillicYO", "cyrillicYU", "cyrillicYstr", "cyrillicYstrstroke", "cyrillicZ", "cyrillicZDSC", "cyrillicZEdiaeresis", "cyrillicZH", "cyrillicZHEbreve", "cyrillicZHEdescender", "cyrillicZHEdiaeresis", "cyrillica", "cyrillicabreve", "cyrillicadiaeresis", "cyrillicae", "cyrillicb", "cyrillicbigyus", "cyrillicbigyusiotified", "cyrillicc", "cyrillicch", "cyrilliccheabkhasian", "cyrillicchedc", "cyrillicchedcabkhasian", "cyrillicchediaeresis", "cyrillicchekhakassian", "cyrillicchevertstroke", "cyrillicd", "cyrillicdje", "cyrillicdze", "cyrillicdzeabkhasian", "cyrillicdzhe", "cyrillice", "cyrillicebreve", "cyrillicediaeresis", "cyrillicegrave", "cyrilliceiotified", "cyrilliceltail", "cyrillicemtail", "cyrillicendc", "cyrillicenghe", "cyrillicenhook", "cyrillicentail", "cyrillicerev", "cyrillicertick", "cyrillicery", "cyrillicf", "cyrillicfita", "cyrillicg", "cyrillicghemidhook", "cyrillicghestroke", "cyrillicgheupturn", "cyrillicgje", "cyrillich", "cyrillicha", "cyrillichadc", "cyrillichrdsn", "cyrillici", "cyrillicidiaeresis", "cyrillicie", "cyrillicigrave", "cyrillicii", "cyrillicimacron", "cyrillicishrt", "cyrillicishrttail", "cyrillicizhitsa", "cyrillicizhitsadoublegrave", "cyrillicje", "cyrillick", "cyrillickabashkir", "cyrillickadc", "cyrillickahook", "cyrillickastroke", "cyrillickavertstroke", "cyrillickje", "cyrillickoppa", "cyrillicksi", "cyrillicl", "cyrilliclittleyus", "cyrilliclittleyusiotified", "cyrilliclje", "cyrillicm", "cyrillicn", "cyrillicnje", "cyrillico", "cyrillicobarred", "cyrillicobarreddiaeresis", "cyrillicodiaeresis", "cyrillicomega", "cyrillicomegaround", "cyrillicomegatitlo", "cyrillicot", "cyrillicp", "cyrillicpemidhook", "cyrillicpsi", "cyrillicr", "cyrillics", "cyrillicschwa", "cyrillicschwadiaeresis", "cyrillicsdsc", "cyrillicsemisoft", "cyrillicsftsn", "cyrillicsh", "cyrillicshch", "cyrillicshha", "cyrillict", "cyrillictedc", "cyrillictetse", "cyrillictshe", "cyrillicu", "cyrillicudiaeresis", "cyrillicudoubleacute", "cyrillicuk", "cyrillicumacron", "cyrillicushrt", "cyrillicv", "cyrillicya", "cyrillicyat", "cyrillicyerudiaeresis", "cyrillicyi", "cyrillicyo", "cyrillicystr", "cyrillicystrstroke", "cyrillicyu", "cyrillicz", "cyrilliczdsc", "cyrilliczediaeresis", "cyrilliczh", "cyrilliczhebreve", "cyrilliczhedescender", "cyrilliczhediaeresis", "d", "dag", "dagger", "daleth", "dasharrow", "dashedleftarrow", "dashedrightarrow", "dashv", "datasetvariable", "date", "dayoftheweek", "dayspermonth", "dbinom", "dcaron", "dcurl", "ddag", "ddagger", "dddot", "ddot", "ddots", "decrement", "decrementcounter", "decrementedcounter", "decrementpagenumber", "decrementsubpagenumber", "decrementvalue", "defaultinterface", "defaultobjectpage", "defaultobjectreference", "defcatcodecommand", "defconvertedargument", "defconvertedcommand", "defconvertedvalue", "define", "defineMPinstance", "defineTABLEsetup", "defineaccent", "defineactivecharacter", "definealternativestyle", "defineanchor", "defineattachment", "defineattribute", "definebackground", "definebar", "defineblock", "definebodyfont", "definebodyfontenvironment", "definebodyfontswitch", "definebreakpoint", "definebreakpoints", "definebtx", "definebtxdataset", "definebtxregister", "definebtxrendering", "definebuffer", "definebutton", "definecapitals", "definecharacter", "definecharacterkerning", "definecharacterspacing", "definechemical", "definechemicals", "definechemicalsymbol", "definecollector", "definecolor", "definecolorgroup", "definecolumnbreak", "definecolumnset", "definecolumnsetarea", "definecolumnsetspan", "definecombination", "definecombinedlist", "definecommand", "definecomment", "definecomplexorsimple", "definecomplexorsimpleempty", "defineconversion", "defineconversionset", "definecounter", "definedataset", "definedelimitedtext", "definedeq", "definedescription", "definedfont", "defineeffect", "defineenumeration", "defineexpandable", "defineexternalfigure", "definefacingfloat", "definefallbackfamily", "definefield", "definefieldbody", "definefieldbodyset", "definefieldcategory", "definefieldstack", "definefiguresymbol", "definefileconstant", "definefilefallback", "definefilesynonym", "definefiller", "definefirstline", "definefittingpage", "definefloat", "definefont", "definefontalternative", "definefontfallback", "definefontfamily", "definefontfamilypreset", "definefontfeature", "definefontfile", "definefontsize", "definefontsolution", "definefontstyle", "definefontsynonym", "defineformula", "defineformulaalternative", "defineformulaframed", "defineframed", "defineframedcontent", "defineframedtable", "defineframedtext", "definefrozenfont", "defineglobalcolor", "definegraphictypesynonym", "definegridsnapping", "definehbox", "definehead", "defineheadalternative", "definehelp", "definehigh", "definehighlight", "definehspace", "definehypenationfeatures", "defineindentedtext", "defineindenting", "defineinitial", "defineinsertion", "defineinteraction", "defineinteractionbar", "defineinteractionmenu", "defineinterfaceconstant", "defineinterfaceelement", "defineinterfacevariable", "defineinterlinespace", "defineintermediatecolor", "defineitemgroup", "defineitems", "definelabel", "definelabelclass", "definelayer", "definelayerpreset", "definelayout", "definelinefiller", "definelinenote", "definelinenumbering", "definelines", "definelist", "definelistalternative", "definelistextra", "definelow", "definelowhigh", "definelowmidhigh", "definemakeup", "definemarginblock", "definemargindata", "definemarker", "definemarking", "definemathaccent", "definemathalignment", "definemathcases", "definemathcommand", "definemathdouble", "definemathdoubleextensible", "definemathematics", "definemathextensible", "definemathfence", "definemathfraction", "definemathframed", "definemathmatrix", "definemathornament", "definemathover", "definemathoverextensible", "definemathovertextextensible", "definemathradical", "definemathstackers", "definemathstyle", "definemathtriplet", "definemathunder", "definemathunderextensible", "definemathundertextextensible", "definemathunstacked", "definemeasure", "definemessageconstant", "definemixedcolumns", "definemode", "definemultitonecolor", "definenamedcolor", "definenamespace", "definenarrower", "definenote", "defineornament", "defineoutputroutine", "defineoutputroutinecommand", "defineoverlay", "definepage", "definepagebreak", "definepagechecker", "definepagecolumns", "definepageinjection", "definepageinjectionalternative", "definepageshift", "definepagestate", "definepairedbox", "definepalet", "definepapersize", "defineparagraph", "defineparagraphs", "defineparallel", "defineparbuilder", "defineperiodkerning", "defineplacement", "definepositioning", "defineprefixset", "defineprocesscolor", "defineprocessor", "defineprofile", "defineprogram", "definepushbutton", "definepushsymbol", "definereference", "definereferenceformat", "defineregister", "definerenderingwindow", "defineresetset", "defineruby", "definescale", "definescript", "definesection", "definesectionblock", "definesectionlevels", "defineselector", "defineseparatorset", "defineshift", "definesidebar", "definesort", "definesorting", "definespotcolor", "definestartstop", "definestyle", "definestyleinstance", "definesubfield", "definesubformula", "definesymbol", "definesynonym", "definesynonyms", "definesystemattribute", "definesystemconstant", "definesystemvariable", "definetabletemplate", "definetabulate", "definetabulation", "definetext", "definetextbackground", "definetextflow", "definetokenlist", "definetooltip", "definetransparency", "definetwopasslist", "definetype", "definetypeface", "definetypescriptprefix", "definetypescriptsynonym", "definetypesetting", "definetyping", "defineunit", "defineuserdata", "defineuserdataalternative", "defineviewerlayer", "definevspace", "definevspacing", "definevspacingamount", "definextable", "delimited", "delimitedtext", "delta", "depthofstring", "depthonlybox", "depthspanningtext", "depthstrut", "determineheadnumber", "determinelistcharacteristics", "determinenoflines", "determineregistercharacteristics", "devanagarinumerals", "dfrac", "dhook", "diameter", "diamond", "diamondsuit", "differentialD", "differentiald", "digamma", "digits", "dimensiontocount", "directboxfromcache", "directcolor", "directcolored", "directconvertedcounter", "directcopyboxfromcache", "directdummyparameter", "directgetboxllx", "directgetboxlly", "directhighlight", "directlocalframed", "directluacode", "directselect", "directsetbar", "directsetup", "directsymbol", "directvspacing", "dis", "disabledirectives", "disableexperiments", "disablemode", "disableoutputstream", "disableparpositions", "disableregime", "disabletrackers", "displaymath", "displaymathematics", "displaymessage", "distributedhsize", "div", "dividedsize", "divideontimes", "divides", "doadaptleftskip", "doadaptrightskip", "doaddfeature", "doassign", "doassignempty", "doboundtext", "docheckassignment", "docheckedpagestate", "docheckedpair", "documentvariable", "dodoubleargument", "dodoubleargumentwithset", "dodoubleempty", "dodoubleemptywithset", "dodoublegroupempty", "doeassign", "doexpandedrecurse", "dofastloopcs", "dogetattribute", "dogetattributeid", "dogetcommacommandelement", "dogobbledoubleempty", "dogobblesingleempty", "doif", "doifMPgraphicelse", "doifallcommon", "doifallcommonelse", "doifalldefinedelse", "doifallmodes", "doifallmodeselse", "doifassignmentelse", "doifassignmentelsecs", "doifblackelse", "doifbothsides", "doifbothsidesoverruled", "doifboxelse", "doifbufferelse", "doifcolor", "doifcolorelse", "doifcommandhandler", "doifcommandhandlerelse", "doifcommon", "doifcommonelse", "doifcontent", "doifconversiondefinedelse", "doifconversionnumberelse", "doifcounter", "doifcounterelse", "doifcurrentfonthasfeatureelse", "doifdefined", "doifdefinedcounter", "doifdefinedcounterelse", "doifdefinedelse", "doifdimensionelse", "doifdimenstringelse", "doifdocumentargument", "doifdocumentargumentelse", "doifdocumentfilename", "doifdocumentfilenameelse", "doifdocumentvariable", "doifdocumentvariableelse", "doifdrawingblackelse", "doifelse", "doifelseMPgraphic", "doifelseallcommon", "doifelsealldefined", "doifelseallmodes", "doifelseassignment", "doifelseassignmentcs", "doifelseblack", "doifelsebox", "doifelseboxincache", "doifelsebuffer", "doifelsecolor", "doifelsecommandhandler", "doifelsecommon", "doifelseconversiondefined", "doifelseconversionnumber", "doifelsecounter", "doifelsecurrentfonthasfeature", "doifelsecurrentsortingused", "doifelsecurrentsynonymshown", "doifelsecurrentsynonymused", "doifelsedefined", "doifelsedefinedcounter", "doifelsedimension", "doifelsedimenstring", "doifelsedocumentargument", "doifelsedocumentfilename", "doifelsedocumentvariable", "doifelsedrawingblack", "doifelseempty", "doifelseemptyvalue", "doifelseemptyvariable", "doifelseenv", "doifelsefastoptionalcheck", "doifelsefastoptionalcheckcs", "doifelsefieldbody", "doifelsefieldcategory", "doifelsefigure", "doifelsefile", "doifelsefiledefined", "doifelsefileexists", "doifelsefirstchar", "doifelseflagged", "doifelsefontchar", "doifelsefontfeature", "doifelsefontpresent", "doifelsefontsynonym", "doifelseframed", "doifelsehasspace", "doifelsehelp", "doifelseincsname", "doifelseinelement", "doifelseinputfile", "doifelseinsertion", "doifelseinset", "doifelseinstring", "doifelseinsymbolset", "doifelseintoks", "doifelseintwopassdata", "doifelseitalic", "doifelselanguage", "doifelselayerdata", "doifelselayoutdefined", "doifelselayoutsomeline", "doifelselayouttextline", "doifelseleapyear", "doifelselist", "doifelselocation", "doifelselocfile", "doifelsemainfloatbody", "doifelsemarkedpage", "doifelsemarking", "doifelsemeaning", "doifelsemessage", "doifelsemode", "doifelsenextbgroup", "doifelsenextbgroupcs", "doifelsenextchar", "doifelsenextoptional", "doifelsenextoptionalcs", "doifelsenextparenthesis", "doifelsenonzeropositive", "doifelsenoteonsamepage", "doifelsenothing", "doifelsenumber", "doifelseobjectfound", "doifelseobjectreferencefound", "doifelseoddpage", "doifelseoddpagefloat", "doifelseoldercontext", "doifelseolderversion", "doifelseoverlapping", "doifelseoverlay", "doifelseparallel", "doifelseparentfile", "doifelsepath", "doifelsepathexists", "doifelsepatterns", "doifelseposition", "doifelsepositionaction", "doifelsepositiononpage", "doifelsepositionsonsamepage", "doifelsepositionsonthispage", "doifelsepositionsused", "doifelsereferencefound", "doifelserightpage", "doifelserightpagefloat", "doifelserighttoleftinbox", "doifelsesamelinereference", "doifelsesamestring", "doifelsesetups", "doifelsesomebackground", "doifelsesomespace", "doifelsesomething", "doifelsesometoks", "doifelsestringinstring", "doifelsestructurelisthasnumber", "doifelsestructurelisthaspage", "doifelsesymboldefined", "doifelsesymbolset", "doifelsetext", "doifelsetextflow", "doifelsetextflowcollector", "doifelsetopofpage", "doifelsetypingfile", "doifelseundefined", "doifelseurldefined", "doifelsevalue", "doifelsevaluenothing", "doifelsevariable", "doifempty", "doifemptyelse", "doifemptytoks", "doifemptyvalue", "doifemptyvalueelse", "doifemptyvariable", "doifemptyvariableelse", "doifenv", "doifenvelse", "doiffastoptionalcheckcselse", "doiffastoptionalcheckelse", "doiffieldbodyelse", "doiffieldcategoryelse", "doiffigureelse", "doiffile", "doiffiledefinedelse", "doiffileelse", "doiffileexistselse", "doiffirstcharelse", "doifflaggedelse", "doiffontcharelse", "doiffontfeatureelse", "doiffontpresentelse", "doiffontsynonymelse", "doifhasspaceelse", "doifhelpelse", "doifincsnameelse", "doifinelementelse", "doifinputfileelse", "doifinsertionelse", "doifinset", "doifinsetelse", "doifinstring", "doifinstringelse", "doifinsymbolset", "doifinsymbolsetelse", "doifintokselse", "doifintwopassdataelse", "doifitalicelse", "doiflanguageelse", "doiflayerdataelse", "doiflayoutdefinedelse", "doiflayoutsomelineelse", "doiflayouttextlineelse", "doifleapyearelse", "doiflistelse", "doiflocationelse", "doiflocfileelse", "doifmainfloatbodyelse", "doifmarkingelse", "doifmeaningelse", "doifmessageelse", "doifmode", "doifmodeelse", "doifnextbgroupcselse", "doifnextbgroupelse", "doifnextcharelse", "doifnextoptionalcselse", "doifnextoptionalelse", "doifnextparenthesiselse", "doifnonzeropositiveelse", "doifnot", "doifnotallcommon", "doifnotallmodes", "doifnotcommandhandler", "doifnotcommon", "doifnotcounter", "doifnotdocumentargument", "doifnotdocumentfilename", "doifnotdocumentvariable", "doifnotempty", "doifnotemptyvalue", "doifnotemptyvariable", "doifnotenv", "doifnoteonsamepageelse", "doifnotescollected", "doifnotfile", "doifnotflagged", "doifnothing", "doifnothingelse", "doifnotinset", "doifnotinsidesplitfloat", "doifnotinstring", "doifnotmode", "doifnotnumber", "doifnotsamestring", "doifnotsetups", "doifnotvalue", "doifnotvariable", "doifnumber", "doifnumberelse", "doifobjectfoundelse", "doifobjectreferencefoundelse", "doifoddpageelse", "doifoddpagefloatelse", "doifoldercontextelse", "doifolderversionelse", "doifoverlappingelse", "doifoverlayelse", "doifparallelelse", "doifparentfileelse", "doifpathelse", "doifpathexistselse", "doifpatternselse", "doifposition", "doifpositionaction", "doifpositionactionelse", "doifpositionelse", "doifpositiononpageelse", "doifpositionsonsamepageelse", "doifpositionsonthispageelse", "doifpositionsusedelse", "doifreferencefoundelse", "doifrightpagefloatelse", "doifrighttoleftinboxelse", "doifsamelinereferenceelse", "doifsamestring", "doifsamestringelse", "doifsetups", "doifsetupselse", "doifsomebackground", "doifsomebackgroundelse", "doifsomespaceelse", "doifsomething", "doifsomethingelse", "doifsometoks", "doifsometokselse", "doifstringinstringelse", "doifstructurelisthasnumberelse", "doifstructurelisthaspageelse", "doifsymboldefinedelse", "doifsymbolsetelse", "doiftext", "doiftextelse", "doiftextflowcollectorelse", "doiftextflowelse", "doiftopofpageelse", "doiftypingfileelse", "doifundefined", "doifundefinedcounter", "doifundefinedelse", "doifunknownfontfeature", "doifurldefinedelse", "doifvalue", "doifvalueelse", "doifvaluenothing", "doifvaluenothingelse", "doifvaluesomething", "doifvariable", "doifvariableelse", "doindentation", "dollar", "doloop", "doloopoverlist", "donothing", "dontconvertfont", "dontleavehmode", "dontpermitspacesbetweengroups", "dopositionaction", "doprocesslocalsetups", "doquadrupleargument", "doquadrupleempty", "doquadruplegroupempty", "doquintupleargument", "doquintupleempty", "doquintuplegroupempty", "dorechecknextindentation", "dorecurse", "dorepeatwithcommand", "doreplacefeature", "doresetandafffeature", "doresetattribute", "dorotatebox", "dosetattribute", "dosetleftskipadaption", "dosetrightskipadaption", "dosetupcheckedinterlinespace", "doseventupleargument", "doseventupleempty", "dosingleargument", "dosingleempty", "dosinglegroupempty", "dosixtupleargument", "dosixtupleempty", "dostepwiserecurse", "dosubtractfeature", "dot", "doteq", "doteqdot", "dotfskip", "dotlessI", "dotlessJ", "dotlessi", "dotlessj", "dotlessjstroke", "dotminus", "dotoks", "dotplus", "dotripleargument", "dotripleargumentwithset", "dotripleempty", "dotripleemptywithset", "dotriplegroupempty", "dots", "dottedcircle", "dottedrightarrow", "doublebar", "doublebond", "doublebrace", "doublebracket", "doublecap", "doublecup", "doubleparent", "doubleprime", "doubleverticalbar", "dowith", "dowithnextbox", "dowithnextboxcontent", "dowithnextboxcontentcs", "dowithnextboxcs", "dowithpargument", "dowithrange", "dowithwargument", "downarrow", "downdasharrow", "downdownarrows", "downharpoonleft", "downharpoonright", "downuparrows", "downwhitearrow", "downzigzagarrow", "dpofstring", "dstroke", "dtail", "dummydigit", "dummyparameter", "dzcaronligature", "dzligature", "eTeX", "eacute", "ebreve", "ecaron", "ecedilla", "ecircumflex", "ecircumflexacute", "ecircumflexdotbelow", "ecircumflexgrave", "ecircumflexhook", "ecircumflextilde", "edefconvertedargument", "ediaeresis", "edotaccent", "edotbelow", "edoublegrave", "efcmaxheight", "efcmaxwidth", "efcminheight", "efcminwidth", "efcparameter", "effect", "egrave", "ehook", "einvertedbreve", "elapsedseconds", "elapsedtime", "eleftarrowfill", "eleftharpoondownfill", "eleftharpoonupfill", "eleftrightarrowfill", "ell", "em", "emacron", "emdash", "emphasisboldface", "emphasistypeface", "emptylines", "emptyset", "emquad", "emspace", "enabledirectives", "enableexperiments", "enablemode", "enableoutputstream", "enableparpositions", "enableregime", "enabletrackers", "endash", "endnote", "enquad", "enskip", "enspace", "env", "environment", "envvar", "eogonek", "eoverbarfill", "eoverbracefill", "eoverbracketfill", "eoverparentfill", "epos", "epsilon", "eq", "eqcirc", "eqeq", "eqeqeq", "eqgtr", "eqless", "eqsim", "eqslantgtr", "eqslantless", "equaldigits", "equalscolon", "equiv", "erightarrowfill", "erightharpoondownfill", "erightharpoonupfill", "eta", "eth", "ethiopic", "etilde", "etwoheadrightarrowfill", "eunderbarfill", "eunderbracefill", "eunderbracketfill", "eunderparentfill", "exclamdown", "executeifdefined", "exists", "exitloop", "exitloopnow", "expandcheckedcsname", "expanded", "expandeddoif", "expandeddoifelse", "expandeddoifnot", "expandfontsynonym", "expdoif", "expdoifcommonelse", "expdoifelse", "expdoifelsecommon", "expdoifelseinset", "expdoifinsetelse", "expdoifnot", "exponentiale", "externalfigure", "externalfigurecollectionmaxheight", "externalfigurecollectionmaxwidth", "externalfigurecollectionminheight", "externalfigurecollectionminwidth", "externalfigurecollectionparameter", "fakebox", "fallingdotseq", "fastdecrement", "fastincrement", "fastlocalframed", "fastloopfinal", "fastloopindex", "fastscale", "fastsetup", "fastsetupwithargument", "fastsetupwithargumentswapped", "fastswitchtobodyfont", "fastsxsy", "feature", "fence", "fenced", "fetchallmarkings", "fetchallmarks", "fetchmark", "fetchmarking", "fetchonemark", "fetchonemarking", "fetchruntinecommand", "fetchtwomarkings", "fetchtwomarks", "ffiligature", "ffligature", "fflligature", "fhook", "field", "fieldbody", "fieldstack", "fifthoffivearguments", "fifthofsixarguments", "figurefilename", "figurefilepath", "figurefiletype", "figurefullname", "figureheight", "figurenaturalheight", "figurenaturalwidth", "figurespace", "figuresymbol", "figurewidth", "filename", "filigature", "filledhboxb", "filledhboxc", "filledhboxg", "filledhboxk", "filledhboxm", "filledhboxr", "filledhboxy", "filler", "fillinline", "fillinrules", "fillintext", "fillupto", "filterfromnext", "filterfromvalue", "filterpages", "filterreference", "findtwopassdata", "finishregisterentry", "firstcharacter", "firstcounter", "firstcountervalue", "firstinlist", "firstoffivearguments", "firstoffourarguments", "firstofoneargument", "firstofoneunexpanded", "firstofsixarguments", "firstofthreearguments", "firstofthreeunexpanded", "firstoftwoarguments", "firstoftwounexpanded", "firstrealpage", "firstrealpagenumber", "firstsubcountervalue", "firstsubpage", "firstsubpagenumber", "firstuserpage", "firstuserpagenumber", "fitfield", "fitfieldframed", "fittopbaselinegrid", "fiveeighths", "fivesixths", "fixedspace", "fixedspaces", "flag", "flat", "flligature", "floatuserdataparameter", "flushbox", "flushboxregister", "flushcollector", "flushedrightlastline", "flushlayer", "flushlocalfloats", "flushnextbox", "flushnotes", "flushoutputstream", "flushshapebox", "flushtextflow", "flushtokens", "flushtoks", "fontalternative", "fontbody", "fontchar", "fontcharbyindex", "fontclass", "fontclassname", "fontface", "fontfeaturelist", "fontsize", "fontstyle", "footnote", "footnotetext", "forall", "forcecharacterstripping", "forcelocalfloats", "forgeteverypar", "forgetparameters", "forgetparskip", "forgetragged", "formula", "formulanumber", "foundbox", "fourfifths", "fourperemspace", "fourthoffivearguments", "fourthoffourarguments", "fourthofsixarguments", "frac", "framed", "frameddimension", "framedparameter", "framedtext", "freezedimenmacro", "freezemeasure", "frenchspacing", "from", "fromlinenote", "frown", "frozenhbox", "frule", "gacute", "gamma", "gbreve", "gcaron", "gcircumflex", "gcommaaccent", "gdefconvertedargument", "gdefconvertedcommand", "gdotaccent", "ge", "geq", "geqq", "geqslant", "getMPdrawing", "getMPlayer", "getboxfromcache", "getboxllx", "getboxlly", "getbuffer", "getbufferdata", "getcommacommandsize", "getcommalistsize", "getdayoftheweek", "getdayspermonth", "getdefinedbuffer", "getdocumentargument", "getdocumentargumentdefault", "getdocumentfilename", "getdummyparameters", "getemptyparameters", "geteparameters", "getexpandedparameters", "getfiguredimensions", "getfirstcharacter", "getfirsttwopassdata", "getfromcommacommand", "getfromcommalist", "getfromtwopassdata", "getglyphdirect", "getglyphstyled", "getgparameters", "getinlineuserdata", "getlasttwopassdata", "getlocalfloat", "getlocalfloats", "getmarking", "getmessage", "getnamedglyphdirect", "getnamedglyphstyled", "getnamedtwopassdatalist", "getnaturaldimensions", "getnoflines", "getobject", "getobjectdimensions", "getpaletsize", "getparameters", "getprivatechar", "getprivateslot", "getrandomcount", "getrandomdimen", "getrandomfloat", "getrandomnumber", "getrandomseed", "getraweparameters", "getrawgparameters", "getrawnoflines", "getrawparameters", "getrawxparameters", "getreference", "getreferenceentry", "getroundednoflines", "gets", "getsubstring", "gettokenlist", "gettwopassdata", "gettwopassdatalist", "getuserdata", "getuvalue", "getvalue", "getvariable", "getvariabledefault", "getxparameters", "gg", "ggg", "gggtr", "gimel", "globaldisablemode", "globalenablemode", "globalletempty", "globalpopbox", "globalpopmacro", "globalpreventmode", "globalprocesscommalist", "globalpushbox", "globalpushmacro", "globalswapcounts", "globalswapdimens", "globalswapmacros", "globalundefine", "glyphfontfile", "gnapprox", "gneqq", "gnsim", "gobbledoubleempty", "gobbleeightarguments", "gobblefivearguments", "gobblefiveoptionals", "gobblefourarguments", "gobblefouroptionals", "gobbleninearguments", "gobbleoneargument", "gobbleoneoptional", "gobblesevenarguments", "gobblesingleempty", "gobblesixarguments", "gobblespacetokens", "gobbletenarguments", "gobblethreearguments", "gobblethreeoptionals", "gobbletwoarguments", "gobbletwooptionals", "gobbleuntil", "gobbleuntilrelax", "godown", "goto", "gotobox", "gotopage", "grabbufferdata", "grabbufferdatadirect", "grabuntil", "grave", "graycolor", "grayvalue", "greedysplitstring", "greekAlpha", "greekAlphadasia", "greekAlphadasiaperispomeni", "greekAlphadasiatonos", "greekAlphadasiavaria", "greekAlphaiotasub", "greekAlphaiotasubdasia", "greekAlphaiotasubdasiaperispomeni", "greekAlphaiotasubdasiatonos", "greekAlphaiotasubdasiavaria", "greekAlphaiotasubpsili", "greekAlphaiotasubpsiliperispomeni", "greekAlphaiotasubpsilitonos", "greekAlphaiotasubpsilivaria", "greekAlphamacron", "greekAlphapsili", "greekAlphapsiliperispomeni", "greekAlphapsilitonos", "greekAlphapsilivaria", "greekAlphatonos", "greekAlphavaria", "greekAlphavrachy", "greekBeta", "greekChi", "greekCoronis", "greekDelta", "greekEpsilon", "greekEpsilondasia", "greekEpsilondasiatonos", "greekEpsilondasiavaria", "greekEpsilonpsili", "greekEpsilonpsilitonos", "greekEpsilonpsilivaria", "greekEpsilontonos", "greekEpsilonvaria", "greekEta", "greekEtadasia", "greekEtadasiaperispomeni", "greekEtadasiatonos", "greekEtadasiavaria", "greekEtaiotasub", "greekEtaiotasubdasia", "greekEtaiotasubdasiaperispomeni", "greekEtaiotasubdasiatonos", "greekEtaiotasubdasiavaria", "greekEtaiotasubpsili", "greekEtaiotasubpsiliperispomeni", "greekEtaiotasubpsilitonos", "greekEtaiotasubpsilivaria", "greekEtapsili", "greekEtapsiliperispomeni", "greekEtapsilitonos", "greekEtapsilivaria", "greekEtatonos", "greekEtavaria", "greekGamma", "greekIota", "greekIotadasia", "greekIotadasiaperispomeni", "greekIotadasiatonos", "greekIotadasiavaria", "greekIotadialytika", "greekIotamacron", "greekIotapsili", "greekIotapsiliperispomeni", "greekIotapsilitonos", "greekIotapsilivaria", "greekIotatonos", "greekIotavaria", "greekIotavrachy", "greekKappa", "greekLambda", "greekMu", "greekNu", "greekOmega", "greekOmegadasia", "greekOmegadasiaperispomeni", "greekOmegadasiatonos", "greekOmegadasiavaria", "greekOmegaiotasub", "greekOmegaiotasubdasia", "greekOmegaiotasubdasiaperispomeni", "greekOmegaiotasubdasiatonos", "greekOmegaiotasubdasiavaria", "greekOmegaiotasubpsili", "greekOmegaiotasubpsiliperispomeni", "greekOmegaiotasubpsilitonos", "greekOmegaiotasubpsilivaria", "greekOmegapsili", "greekOmegapsiliperispomeni", "greekOmegapsilitonos", "greekOmegapsilivaria", "greekOmegatonos", "greekOmegavaria", "greekOmicron", "greekOmicrondasia", "greekOmicrondasiatonos", "greekOmicrondasiavaria", "greekOmicronpsili", "greekOmicronpsilitonos", "greekOmicronpsilivaria", "greekOmicrontonos", "greekOmicronvaria", "greekPhi", "greekPi", "greekPsi", "greekRho", "greekRhodasia", "greekSigma", "greekSigmalunate", "greekTau", "greekTheta", "greekUpsilon", "greekUpsilondasia", "greekUpsilondasiaperispomeni", "greekUpsilondasiatonos", "greekUpsilondasiavaria", "greekUpsilondialytika", "greekUpsilonmacron", "greekUpsilontonos", "greekUpsilonvaria", "greekUpsilonvrachy", "greekXi", "greekZeta", "greekalpha", "greekalphadasia", "greekalphadasiaperispomeni", "greekalphadasiatonos", "greekalphadasiavaria", "greekalphaiotasub", "greekalphaiotasubdasia", "greekalphaiotasubdasiaperispomeni", "greekalphaiotasubdasiatonos", "greekalphaiotasubdasiavaria", "greekalphaiotasubperispomeni", "greekalphaiotasubpsili", "greekalphaiotasubpsiliperispomeni", "greekalphaiotasubpsilitonos", "greekalphaiotasubpsilivaria", "greekalphaiotasubtonos", "greekalphaiotasubvaria", "greekalphamacron", "greekalphaoxia", "greekalphaperispomeni", "greekalphapsili", "greekalphapsiliperispomeni", "greekalphapsilitonos", "greekalphapsilivaria", "greekalphatonos", "greekalphavaria", "greekalphavrachy", "greekbeta", "greekbetaalt", "greekchi", "greekdasia", "greekdasiaperispomeni", "greekdasiatonos", "greekdasiavaria", "greekdelta", "greekdialytikaperispomeni", "greekdialytikatonos", "greekdialytikavaria", "greekdigamma", "greekepsilon", "greekepsilonalt", "greekepsilondasia", "greekepsilondasiatonos", "greekepsilondasiavaria", "greekepsilonoxia", "greekepsilonpsili", "greekepsilonpsilitonos", "greekepsilonpsilivaria", "greekepsilontonos", "greekepsilonvaria", "greeketa", "greeketadasia", "greeketadasiaperispomeni", "greeketadasiatonos", "greeketadasiavaria", "greeketaiotasub", "greeketaiotasubdasia", "greeketaiotasubdasiaperispomeni", "greeketaiotasubdasiatonos", "greeketaiotasubdasiavaria", "greeketaiotasubperispomeni", "greeketaiotasubpsili", "greeketaiotasubpsiliperispomeni", "greeketaiotasubpsilitonos", "greeketaiotasubpsilivaria", "greeketaiotasubtonos", "greeketaiotasubvaria", "greeketaoxia", "greeketaperispomeni", "greeketapsili", "greeketapsiliperispomeni", "greeketapsilitonos", "greeketapsilivaria", "greeketatonos", "greeketavaria", "greekfinalsigma", "greekgamma", "greekiota", "greekiotadasia", "greekiotadasiaperispomeni", "greekiotadasiatonos", "greekiotadasiavaria", "greekiotadialytika", "greekiotadialytikaperispomeni", "greekiotadialytikatonos", "greekiotadialytikavaria", "greekiotamacron", "greekiotaoxia", "greekiotaperispomeni", "greekiotapsili", "greekiotapsiliperispomeni", "greekiotapsilitonos", "greekiotapsilivaria", "greekiotatonos", "greekiotavaria", "greekiotavrachy", "greekkappa", "greekkoppa", "greeklambda", "greekmu", "greeknu", "greeknumerals", "greeknumkoppa", "greekomega", "greekomegadasia", "greekomegadasiaperispomeni", "greekomegadasiatonos", "greekomegadasiavaria", "greekomegaiotasub", "greekomegaiotasubdasia", "greekomegaiotasubdasiaperispomeni", "greekomegaiotasubdasiatonos", "greekomegaiotasubdasiavaria", "greekomegaiotasubperispomeni", "greekomegaiotasubpsili", "greekomegaiotasubpsiliperispomeni", "greekomegaiotasubpsilitonos", "greekomegaiotasubpsilivaria", "greekomegaiotasubtonos", "greekomegaiotasubvaria", "greekomegaoxia", "greekomegaperispomeni", "greekomegapsili", "greekomegapsiliperispomeni", "greekomegapsilitonos", "greekomegapsilivaria", "greekomegatonos", "greekomegavaria", "greekomicron", "greekomicrondasia", "greekomicrondasiatonos", "greekomicrondasiavaria", "greekomicronoxia", "greekomicronpsili", "greekomicronpsilitonos", "greekomicronpsilivaria", "greekomicrontonos", "greekomicronvaria", "greekoxia", "greekperispomeni", "greekphi", "greekphialt", "greekpi", "greekpialt", "greekprosgegrammeni", "greekpsi", "greekpsili", "greekpsiliperispomeni", "greekpsilitonos", "greekpsilivaria", "greekrho", "greekrhoalt", "greekrhodasia", "greekrhopsili", "greeksampi", "greeksigma", "greeksigmalunate", "greekstigma", "greektau", "greektheta", "greekthetaalt", "greektonos", "greekupsilon", "greekupsilondasia", "greekupsilondasiaperispomeni", "greekupsilondasiatonos", "greekupsilondasiavaria", "greekupsilondiaeresis", "greekupsilondialytikaperispomeni", "greekupsilondialytikatonos", "greekupsilondialytikavaria", "greekupsilonmacron", "greekupsilonoxia", "greekupsilonperispomeni", "greekupsilonpsili", "greekupsilonpsiliperispomeni", "greekupsilonpsilitonos", "greekupsilonpsilivaria", "greekupsilontonos", "greekupsilonvaria", "greekupsilonvrachy", "greekvaria", "greekxi", "greekzeta", "grid", "groupedcommand", "gsetboxllx", "gsetboxlly", "gstroke", "gt", "gtrapprox", "gtrdot", "gtreqless", "gtreqqless", "gtrless", "gtrsim", "guilsingleleft", "guilsingleright", "gujaratinumerals", "gurmurkhinumerals", "hairline", "hairspace", "halflinestrut", "halfstrut", "halfwaybox", "handletokens", "handwritten", "hangul", "hanzi", "hash", "hat", "hbar", "hboxofvbox", "hboxreference", "hcaron", "hcircumflex", "hdofstring", "headhbox", "headlanguage", "headnumber", "headnumbercontent", "headnumberdistance", "headnumberwidth", "headreferenceattributes", "headsetupspacing", "headtext", "headtextcontent", "headtextdistance", "headtexts", "headtextwidth", "headvbox", "headwidth", "heartsuit", "hebrewAlef", "hebrewAyin", "hebrewBet", "hebrewDalet", "hebrewGimel", "hebrewHe", "hebrewHet", "hebrewKaf", "hebrewKaffinal", "hebrewLamed", "hebrewMem", "hebrewMemfinal", "hebrewNun", "hebrewNunfinal", "hebrewPe", "hebrewPefinal", "hebrewQof", "hebrewResh", "hebrewSamekh", "hebrewShin", "hebrewTav", "hebrewTet", "hebrewTsadi", "hebrewTsadifinal", "hebrewVav", "hebrewYod", "hebrewZayin", "heightanddepthofstring", "heightofstring", "heightspanningtext", "helptext", "hglue", "hiddenbar", "hiddencitation", "hiddencite", "hideblocks", "high", "highlight", "highordinalstr", "hilo", "himilo", "hl", "hookleftarrow", "hookrightarrow", "horizontalgrowingbar", "horizontalpositionbar", "hphantom", "hpos", "hsizefraction", "hslash", "hsmash", "hsmashbox", "hsmashed", "hspace", "hstroke", "htdpofstring", "htofstring", "hyphen", "hyphenatedcoloredword", "hyphenatedfile", "hyphenatedfilename", "hyphenatedhbox", "hyphenatedpar", "hyphenatedurl", "hyphenatedword", "iacute", "ibox", "ibreve", "icaron", "icircumflex", "ideographichalffillspace", "ideographicspace", "idiaeresis", "idotaccent", "idotbelow", "idoublegrave", "ifassignment", "iff", "ifinobject", "ifinoutputstream", "ifparameters", "iftrialtypesetting", "ignoreimplicitspaces", "ignoretagsinexport", "ignorevalue", "igrave", "ihook", "iiiint", "iiiintop", "iiint", "iiintop", "iint", "iintop", "iinvertedbreve", "ijligature", "imacron", "imaginaryi", "imaginaryj", "imath", "immediatesavetwopassdata", "impliedby", "implies", "imply", "in", "includemenu", "includeversioninfo", "increment", "incrementcounter", "incrementedcounter", "incrementpagenumber", "incrementsubpagenumber", "incrementvalue", "indentation", "index", "infofont", "infofontbold", "inframed", "infty", "infull", "inheritparameter", "inhibitblank", "ininner", "ininneredge", "ininnermargin", "initializeboxstack", "inleft", "inleftedge", "inleftmargin", "inline", "inlinebuffer", "inlinedbox", "inlinemath", "inlinemathematics", "inlinemessage", "inlineordisplaymath", "inlineprettyprintbuffer", "inlinerange", "inmargin", "inmframed", "innerflushshapebox", "inother", "inouter", "inouteredge", "inoutermargin", "input", "inputfilebarename", "inputfilename", "inputfilerealsuffix", "inputfilesuffix", "inputgivenfile", "inright", "inrightedge", "inrightmargin", "insertpages", "installactionhandler", "installactivecharacter", "installanddefineactivecharacter", "installattributestack", "installautocommandhandler", "installautosetuphandler", "installbasicautosetuphandler", "installbasicparameterhandler", "installbottomframerenderer", "installcommandhandler", "installcorenamespace", "installdefinehandler", "installdefinitionset", "installdefinitionsetmember", "installdirectcommandhandler", "installdirectparameterhandler", "installdirectparametersethandler", "installdirectsetuphandler", "installdirectstyleandcolorhandler", "installframedautocommandhandler", "installframedcommandhandler", "installglobalmacrostack", "installlanguage", "installleftframerenderer", "installmacrostack", "installnamespace", "installoutputroutine", "installpagearrangement", "installparameterhandler", "installparameterhashhandler", "installparametersethandler", "installparentinjector", "installrightframerenderer", "installrootparameterhandler", "installsetuphandler", "installsetuponlycommandhandler", "installshipoutmethod", "installsimplecommandhandler", "installsimpleframedcommandhandler", "installstyleandcolorhandler", "installswitchcommandhandler", "installswitchsetuphandler", "installtexdirective", "installtextracker", "installtopframerenderer", "installunitsseparator", "installunitsspace", "installversioninfo", "int", "intclockwise", "integerrounding", "integers", "interactionbar", "interactionbuttons", "interactionmenu", "intercal", "intertext", "intop", "invisibletimes", "invokepageheandler", "iogonek", "iota", "istltdir", "istrtdir", "italic", "italicbold", "italiccorrection", "italicface", "item", "items", "itemtag", "itilde", "jcaron", "jcircumflex", "jmath", "jobfilename", "jobfilesuffix", "kap", "kappa", "kcaron", "kcommaaccent", "keepblocks", "keeplinestogether", "keepunwantedspaces", "kerncharacters", "khook", "kkra", "koreancirclenumerals", "koreannumerals", "koreannumeralsc", "koreannumeralsp", "koreanparentnumerals", "lVert", "labellanguage", "labeltext", "labeltexts", "lacute", "lambda", "lambdabar", "land", "langle", "language", "languageCharacters", "languagecharacters", "languagecharwidth", "lastcounter", "lastcountervalue", "lastdigit", "lastlinewidth", "lastnaturalboxdp", "lastnaturalboxht", "lastnaturalboxwd", "lastpredefinedsymbol", "lastrealpage", "lastrealpagenumber", "lastsubcountervalue", "lastsubpage", "lastsubpagenumber", "lasttwodigits", "lastuserpage", "lastuserpagenumber", "lateluacode", "latin", "layeredtext", "layerheight", "layerwidth", "lazysavetaggedtwopassdata", "lazysavetwopassdata", "lbar", "lbox", "lbrace", "lbracket", "lcaron", "lceil", "lcommaaccent", "lcurl", "ldotmiddle", "ldotp", "ldots", "le", "leadsto", "left", "leftaligned", "leftarrow", "leftarrowtail", "leftarrowtriangle", "leftbottombox", "leftbox", "leftdasharrow", "leftguillemot", "leftharpoondown", "leftharpoonup", "lefthbox", "leftheadtext", "leftlabeltext", "leftleftarrows", "leftline", "leftmathlabeltext", "leftorrighthbox", "leftorrightvbox", "leftorrightvtop", "leftrightarrow", "leftrightarrows", "leftrightarrowtriangle", "leftrightharpoons", "leftrightsquigarrow", "leftskipadaption", "leftsquigarrow", "leftsubguillemot", "leftthreetimes", "lefttopbox", "lefttoright", "lefttorighthbox", "lefttorightvbox", "lefttorightvtop", "leftwavearrow", "leftwhitearrow", "leq", "leqq", "leqslant", "lessapprox", "lessdot", "lesseqgtr", "lesseqqgtr", "lessgtr", "lesssim", "letbeundefined", "letcatcodecommand", "letcscsname", "letcsnamecs", "letcsnamecsname", "letdummyparameter", "letempty", "letgvalue", "letgvalueempty", "letgvalurelax", "letterampersand", "letterat", "letterbackslash", "letterbar", "letterbgroup", "letterclosebrace", "lettercolon", "letterdollar", "letterdoublequote", "letteregroup", "letterescape", "letterexclamationmark", "letterhash", "letterhat", "letterleftbrace", "letterleftbracket", "letterleftparenthesis", "letterless", "lettermore", "letteropenbrace", "letterpercent", "letterquestionmark", "letterrightbrace", "letterrightbracket", "letterrightparenthesis", "lettersinglequote", "letterslash", "letterspacing", "lettertilde", "letterunderscore", "letvalue", "letvalueempty", "letvaluerelax", "lfence", "lfloor", "lgroup", "lhbox", "lhooknwarrow", "lhooksearrow", "limitatefirstline", "limitatelines", "limitatetext", "line", "linebox", "linefeed", "linenote", "linespanningtext", "linethickness", "linterval", "listcitation", "listcite", "listlength", "listnamespaces", "ljligature", "ll", "llangle", "llap", "llbracket", "llcorner", "lll", "llless", "lmoustache", "lnapprox", "lneq", "lneqq", "lnot", "lnsim", "loadanyfile", "loadanyfileonce", "loadbtxdefinitionfile", "loadbtxreplacementfile", "loadcldfile", "loadcldfileonce", "loadfontgoodies", "loadluafile", "loadluafileonce", "loadspellchecklist", "loadtexfile", "loadtexfileonce", "loadtypescriptfile", "localframed", "localframedwithsettings", "localhsize", "localpopbox", "localpopmacro", "localpushbox", "localpushmacro", "localundefine", "locatedfilepath", "locatefilepath", "locfilename", "logo", "lohi", "lointerval", "lomihi", "longleftarrow", "longleftrightarrow", "longmapsfrom", "longmapsto", "longrightarrow", "longrightsquigarrow", "looparrowleft", "looparrowright", "lor", "low", "lowerbox", "lowercased", "lowercasestring", "lowerleftdoubleninequote", "lowerleftsingleninequote", "lowerrightdoubleninequote", "lowerrightsingleninequote", "lozenge", "lparent", "lrcorner", "lrointerval", "lrtbbox", "lstroke", "lt", "ltimes", "ltop", "luaTeX", "luacode", "luaconditional", "luaenvironment", "luaexpanded", "luaexpr", "luafunction", "luajitTeX", "luamajorversion", "luaminorversion", "luaparameterset", "luasetup", "luaversion", "lvert", "m", "mLeftarrow", "mLeftrightarrow", "mRightarrow", "mainlanguage", "makecharacteractive", "makerawcommalist", "makestrutofbox", "maltese", "mapfontsize", "mapsdown", "mapsfrom", "mapsto", "mapsup", "margindata", "margintext", "markcontent", "markedpages", "marking", "markinjector", "markpage", "mat", "math", "mathampersand", "mathbf", "mathbi", "mathblackboard", "mathbs", "mathdefault", "mathdollar", "mathdouble", "mathematics", "mathfraktur", "mathfunction", "mathhash", "mathhyphen", "mathit", "mathitalic", "mathlabellanguage", "mathlabeltext", "mathlabeltexts", "mathop", "mathover", "mathpercent", "mathrm", "mathscript", "mathsl", "mathss", "mathtext", "mathtextbf", "mathtextbi", "mathtextbs", "mathtextit", "mathtextsl", "mathtexttf", "mathtf", "mathtriplet", "mathtt", "mathunder", "mathupright", "mathword", "mathwordbf", "mathwordbi", "mathwordbs", "mathwordit", "mathwordsl", "mathwordtf", "maxaligned", "mbox", "mcframed", "measure", "measured", "measuredangle", "measuredeq", "medskip", "medspace", "menubutton", "mequal", "message", "metaTeX", "mfence", "mframed", "mfunction", "mfunctionlabeltext", "mhbox", "mho", "mhookleftarrow", "mhookrightarrow", "mid", "midaligned", "middle", "middlealigned", "middlebox", "midhbox", "midsubsentence", "minimalhbox", "minus", "minuscolon", "mirror", "mixedcaps", "mkvibuffer", "mleftarrow", "mleftharpoondown", "mleftharpoonup", "mleftrightarrow", "mleftrightharpoons", "mmapsto", "models", "moduleparameter", "molecule", "mono", "monobold", "mononormal", "month", "monthlong", "monthshort", "mp", "mprandomnumber", "mrel", "mrightarrow", "mrightharpoondown", "mrightharpoonup", "mrightleftharpoons", "mrightoverleftarrow", "mtext", "mtriplerel", "mtwoheadleftarrow", "mtwoheadrightarrow", "mu", "multimap", "nHdownarrow", "nHuparrow", "nLeftarrow", "nLeftrightarrow", "nRightarrow", "nVDash", "nVdash", "nVleftarrow", "nVleftrightarrow", "nVrightarrow", "nabla", "nacute", "namedheadnumber", "namedstructureheadlocation", "namedstructureuservariable", "namedstructurevariable", "namedtaggedlabeltexts", "napostrophe", "napprox", "napproxEq", "narrownobreakspace", "nasymp", "natural", "naturalhbox", "naturalhpack", "naturalnumbers", "naturalvbox", "naturalvcenter", "naturalvpack", "naturalvtop", "naturalwd", "ncaron", "ncommaaccent", "ncong", "ncurl", "ndivides", "ne", "nearrow", "neg", "negatecolorbox", "negated", "negativesign", "negemspace", "negenspace", "negthinspace", "neng", "neq", "nequiv", "neswarrow", "newattribute", "newcatcodetable", "newcounter", "newevery", "newfrenchspacing", "newmode", "newsignal", "newsystemmode", "nexists", "nextbox", "nextboxdp", "nextboxht", "nextboxhtdp", "nextboxwd", "nextcounter", "nextcountervalue", "nextdepth", "nextparagraphs", "nextrealpage", "nextrealpagenumber", "nextsubcountervalue", "nextsubpage", "nextsubpagenumber", "nextuserpage", "nextuserpagenumber", "ngeq", "ngrave", "ngtr", "ngtrless", "ngtrsim", "ni", "nihongo", "nin", "njligature", "nleftarrow", "nleftrightarrow", "nleq", "nless", "nlessgtr", "nlesssim", "nmid", "nni", "nobar", "nobreakspace", "nocap", "nocharacteralign", "nocitation", "nocite", "nodetostring", "noffigurepages", "noflines", "noflocalfloats", "noheaderandfooterlines", "noheightstrut", "noindentation", "noitem", "nonfrenchspacing", "nonmathematics", "normal", "normalboldface", "normalframedwithsettings", "normalitalicface", "normalizebodyfontsize", "normalizedfontsize", "normalizefontdepth", "normalizefontheight", "normalizefontline", "normalizefontwidth", "normalizetextdepth", "normalizetextheight", "normalizetextline", "normalizetextwidth", "normalslantedface", "normaltypeface", "nospace", "not", "note", "notesymbol", "notin", "notopandbottomlines", "notragged", "nowns", "nparallel", "nprec", "npreccurlyeq", "nrightarrow", "nsim", "nsimeq", "nsqsubseteq", "nsqsupseteq", "nsubset", "nsubseteq", "nsucc", "nsucccurlyeq", "nsupset", "nsupseteq", "ntilde", "ntimes", "ntriangleleft", "ntrianglelefteq", "ntriangleright", "ntrianglerighteq", "nu", "numberofpoints", "numbers", "nvDash", "nvdash", "nvleftarrow", "nvleftrightarrow", "nvrightarrow", "nwarrow", "nwsearrow", "oacute", "obeydepth", "objectdepth", "objectheight", "objectmargin", "objectwidth", "obox", "obreve", "ocaron", "ocircumflex", "ocircumflexacute", "ocircumflexdotbelow", "ocircumflexgrave", "ocircumflexhook", "ocircumflextilde", "odiaeresis", "odiaeresismacron", "odot", "odotaccent", "odotaccentmacron", "odotbelow", "odoublegrave", "oeligature", "offset", "offsetbox", "ograve", "ohm", "ohook", "ohorn", "ohornacute", "ohorndotbelow", "ohorngrave", "ohornhook", "ohorntilde", "ohungarumlaut", "oiiint", "oiint", "oint", "ointclockwise", "ointctrclockwise", "oinvertedbreve", "omacron", "omega", "omicron", "ominus", "onedigitrounding", "oneeighth", "onefifth", "onehalf", "onequarter", "onesixth", "onesuperior", "onethird", "oogonek", "oogonekmacron", "operatorlanguage", "operatortext", "oplus", "ordfeminine", "ordinaldaynumber", "ordinalstr", "ordmasculine", "ornamenttext", "oslash", "ostroke", "ostrokeacute", "otilde", "otildemacron", "otimes", "outputfilename", "outputstreambox", "outputstreamcopy", "outputstreamunvbox", "outputstreamunvcopy", "over", "overbar", "overbars", "overbarunderbar", "overbrace", "overbraceunderbrace", "overbracket", "overbracketunderbracket", "overlaybutton", "overlaycolor", "overlaydepth", "overlayfigure", "overlayheight", "overlayimage", "overlaylinecolor", "overlaylinewidth", "overlayoffset", "overlayrollbutton", "overlaywidth", "overleftarrow", "overloaderror", "overparent", "overparentunderparent", "overrightarrow", "overset", "overstrike", "overstrikes", "owns", "page", "pagearea", "pagebreak", "pagefigure", "pageinjection", "pagenumber", "pagereference", "pagestaterealpage", "pagestaterealpageorder", "paletsize", "paragraphmark", "parallel", "part", "partial", "pdfTeX", "pdfactualtext", "pdfbackendactualtext", "pdfbackendcurrentresources", "pdfbackendsetcatalog", "pdfbackendsetcolorspace", "pdfbackendsetextgstate", "pdfbackendsetinfo", "pdfbackendsetname", "pdfbackendsetpageattribute", "pdfbackendsetpageresource", "pdfbackendsetpagesattribute", "pdfbackendsetpattern", "pdfbackendsetshade", "pdfcolor", "pdfeTeX", "percent", "percentdimen", "periodcentered", "periods", "permitcaretescape", "permitcircumflexescape", "permitspacesbetweengroups", "perp", "persiandecimals", "persiandecimalseparator", "persiannumerals", "persianthousandsseparator", "perthousand", "phantom", "phantombox", "phi", "phook", "pi", "pickupgroupedcommand", "pitchfork", "placeattachments", "placebookmarks", "placebtxrendering", "placechemical", "placecitation", "placecombinedlist", "placecomments", "placecontent", "placecurrentformulanumber", "placedbox", "placefigure", "placefloat", "placefloatwithsetups", "placefootnotes", "placeformula", "placeframed", "placegraphic", "placeheadnumber", "placeheadtext", "placehelp", "placeindex", "placeinitial", "placeintermezzo", "placelayer", "placelayeredtext", "placelegend", "placelist", "placelistofabbreviations", "placelistofchemicals", "placelistoffigures", "placelistofgraphics", "placelistofintermezzi", "placelistoflogos", "placelistofpublications", "placelistofsorts", "placelistofsynonyms", "placelistoftables", "placelocalfootnotes", "placelocalnotes", "placement", "placenamedfloat", "placenamedformula", "placenotes", "placeongrid", "placeontopofeachother", "placepagenumber", "placepairedbox", "placeparallel", "placerawlist", "placeregister", "placerenderingwindow", "placesidebyside", "placesubformula", "placetable", "pm", "popattribute", "popmacro", "popmode", "popsystemmode", "position", "positionoverlay", "positionregionoverlay", "positivesign", "postponenotes", "prec", "precapprox", "preccurlyeq", "preceq", "preceqq", "precnapprox", "precneq", "precneqq", "precnsim", "precsim", "predefinedfont", "predefinefont", "predefinesymbol", "prefixedpagenumber", "prefixlanguage", "prefixtext", "prependetoks", "prependgvalue", "prependtocommalist", "prependtoks", "prependtoksonce", "prependvalue", "prerollblank", "presetbtxlabeltext", "presetdocument", "presetfieldsymbols", "presetheadtext", "presetlabeltext", "presetmathlabeltext", "presetoperatortext", "presetprefixtext", "presetsuffixtext", "presettaglabeltext", "presetunittext", "pretocommalist", "prettyprintbuffer", "prevcounter", "prevcountervalue", "preventmode", "prevrealpage", "prevrealpagenumber", "prevsubcountervalue", "prevsubpage", "prevsubpagenumber", "prevuserpage", "prevuserpagenumber", "prime", "primes", "procent", "processMPbuffer", "processMPfigurefile", "processaction", "processallactionsinset", "processassignlist", "processassignmentcommand", "processassignmentlist", "processbetween", "processblocks", "processbodyfontenvironmentlist", "processcolorcomponents", "processcommacommand", "processcommalist", "processcommalistwithparameters", "processcontent", "processfile", "processfilemany", "processfilenone", "processfileonce", "processfirstactioninset", "processisolatedchars", "processisolatedwords", "processlinetablebuffer", "processlinetablefile", "processlist", "processmonth", "processranges", "processseparatedlist", "processtexbuffer", "processtokens", "processuntil", "processxtablebuffer", "processyear", "prod", "product", "profiledbox", "profilegivenbox", "program", "project", "propto", "pseudoMixedCapped", "pseudoSmallCapped", "pseudoSmallcapped", "pseudosmallcapped", "psi", "punctuationspace", "purenumber", "pushattribute", "pushbutton", "pushmacro", "pushmode", "pushoutputstream", "pushsystemmode", "putboxincache", "putnextboxincache", "qquad", "quad", "quadrupleprime", "quads", "quarterstrut", "questiondown", "questionedeq", "quitcommalist", "quitprevcommalist", "quittypescriptscanning", "quotation", "quote", "quotedbl", "quotedblbase", "quotedblleft", "quotedblright", "quoteleft", "quoteright", "quotesingle", "quotesinglebase", "rVert", "racute", "raggedbottom", "raggedcenter", "raggedleft", "raggedright", "raggedwidecenter", "raisebox", "randomizetext", "randomnumber", "rangle", "rationals", "rawcounter", "rawcountervalue", "rawdate", "rawdoifelseinset", "rawdoifinset", "rawdoifinsetelse", "rawgetparameters", "rawprocessaction", "rawprocesscommacommand", "rawprocesscommalist", "rawstructurelistuservariable", "rawsubcountervalue", "rbox", "rbrace", "rbracket", "rcaron", "rceil", "rcommaaccent", "rdoublegrave", "readfile", "readfixfile", "readjobfile", "readlocfile", "readsetfile", "readsysfile", "readtexfile", "readxmlfile", "realSmallCapped", "realSmallcapped", "realpagenumber", "reals", "realsmallcapped", "recursedepth", "recurselevel", "recursestring", "redoconvertfont", "ref", "reference", "referenceprefix", "referring", "registerattachment", "registerctxluafile", "registered", "registerexternalfigure", "registerfontclass", "registerhyphenationexception", "registerhyphenationpattern", "registermenubuttons", "registersort", "registersynonym", "registerunit", "regular", "relatemarking", "relateparameterhandlers", "relaxvalueifundefined", "relbar", "remainingcharacters", "remark", "removebottomthings", "removedepth", "removefromcommalist", "removelastskip", "removelastspace", "removemarkedcontent", "removepunctuation", "removesubstring", "removetoks", "removeunwantedspaces", "replacefeature", "replaceincommalist", "replaceword", "rescan", "rescanwithsetup", "resetMPdrawing", "resetMPenvironment", "resetMPinstance", "resetallattributes", "resetandaddfeature", "resetbar", "resetboxesincache", "resetbreakpoints", "resetbuffer", "resetcharacteralign", "resetcharacterkerning", "resetcharacterspacing", "resetcharacterstripping", "resetcollector", "resetcounter", "resetdigitsmanipulation", "resetdirection", "resetfeature", "resetflag", "resetfontcolorsheme", "resetfontfallback", "resetfontsolution", "resethyphenationfeatures", "resetinjector", "resetinteractionmenu", "resetitaliccorrection", "resetlayer", "resetlocalfloats", "resetmarker", "resetmarking", "resetmode", "resetpagenumber", "resetparallel", "resetpath", "resetpenalties", "resetperiodkerning", "resetprofile", "resetrecurselevel", "resetreference", "resetreplacement", "resetscript", "resetsetups", "resetshownsynonyms", "resetsubpagenumber", "resetsymbolset", "resetsystemmode", "resettimer", "resettokenlist", "resettrackers", "resettrialtypesetting", "resetusedsortings", "resetusedsynonyms", "resetuserpagenumber", "resetvalue", "resetvisualizers", "reshapebox", "resolvedglyphdirect", "resolvedglyphstyled", "restartcounter", "restorebox", "restorecatcodes", "restorecounter", "restorecurrentattributes", "restoreendofline", "restoreglobalbodyfont", "restriction", "reusableMPgraphic", "reuseMPgraphic", "reuserandomseed", "reverseddoubleprime", "reversedprime", "reversedtripleprime", "revivefeature", "rfence", "rfloor", "rgroup", "rhbox", "rho", "rhooknearrow", "rhookswarrow", "right", "rightaligned", "rightangle", "rightarrow", "rightarrowbar", "rightarrowtail", "rightarrowtriangle", "rightbottombox", "rightbox", "rightdasharrow", "rightguillemot", "rightharpoondown", "rightharpoonup", "righthbox", "rightheadtext", "rightlabeltext", "rightleftarrows", "rightleftharpoons", "rightline", "rightmathlabeltext", "rightorleftpageaction", "rightpageorder", "rightrightarrows", "rightskipadaption", "rightsquigarrow", "rightsubguillemot", "rightthreearrows", "rightthreetimes", "righttoleft", "righttolefthbox", "righttoleftvbox", "righttoleftvtop", "righttopbox", "rightwavearrow", "rightwhitearrow", "ring", "rinterval", "rinvertedbreve", "risingdotseq", "rlap", "rlointerval", "rmoustache", "rneq", "robustaddtocommalist", "robustdoifelseinset", "robustdoifinsetelse", "robustpretocommalist", "rointerval", "rollbutton", "roman", "romanC", "romanD", "romanI", "romanII", "romanIII", "romanIV", "romanIX", "romanL", "romanM", "romanV", "romanVI", "romanVII", "romanVIII", "romanX", "romanXI", "romanXII", "romanc", "romand", "romani", "romanii", "romaniii", "romaniv", "romanix", "romanl", "romanm", "romannumerals", "romanv", "romanvi", "romanvii", "romanviii", "romanx", "romanxi", "romanxii", "rootradical", "rotate", "rparent", "rrangle", "rrbracket", "rrointerval", "rtimes", "rtop", "ruby", "ruledhbox", "ruledhpack", "ruledmbox", "ruledtopv", "ruledtpack", "ruledvbox", "ruledvpack", "ruledvtop", "runMPbuffer", "runninghbox", "rvert", "sacute", "safechar", "samplefile", "sans", "sansbold", "sansnormal", "sansserif", "savebox", "savebtxdataset", "savebuffer", "savecounter", "savecurrentattributes", "savenormalmeaning", "savetaggedtwopassdata", "savetwopassdata", "sbox", "scale", "scaron", "scedilla", "schwa", "schwahook", "scircumflex", "scommaaccent", "screen", "searrow", "secondoffivearguments", "secondoffourarguments", "secondofsixarguments", "secondofthreearguments", "secondofthreeunexpanded", "secondoftwoarguments", "secondoftwounexpanded", "section", "sectionmark", "seeindex", "select", "selectblocks", "serializecommalist", "serializedcommalist", "serif", "serifbold", "serifnormal", "setJSpreamble", "setMPlayer", "setMPpositiongraphic", "setMPpositiongraphicrange", "setMPtext", "setMPvariable", "setMPvariables", "setautopagestaterealpageno", "setbar", "setbigbodyfont", "setboxllx", "setboxlly", "setbreakpoints", "setcapstrut", "setcatcodetable", "setcharacteralign", "setcharacteraligndetail", "setcharactercasing", "setcharactercleaning", "setcharacterkerning", "setcharacterspacing", "setcharacterstripping", "setcharstrut", "setcollector", "setcolormodell", "setcounter", "setcounterown", "setcurrentfontclass", "setdataset", "setdefaultpenalties", "setdigitsmanipulation", "setdirection", "setdocumentargument", "setdocumentargumentdefault", "setdocumentfilename", "setdummyparameter", "setelementexporttag", "setemeasure", "setevalue", "setevariable", "setevariables", "setfirstline", "setfirstpasscharacteralign", "setflag", "setfont", "setfontcolorsheme", "setfontfeature", "setfontsolution", "setfontstrut", "setglobalscript", "setgmeasure", "setgvalue", "setgvariable", "setgvariables", "sethboxregister", "sethyphenatedurlafter", "sethyphenatedurlbefore", "sethyphenatedurlnormal", "sethyphenationfeatures", "setinitial", "setinjector", "setinteraction", "setinterfacecommand", "setinterfaceconstant", "setinterfaceelement", "setinterfacemessage", "setinterfacevariable", "setinternalrendering", "setitaliccorrection", "setlayer", "setlayerframed", "setlayertext", "setlinefiller", "setlocalhsize", "setlocalscript", "setmainbodyfont", "setmainparbuilder", "setmarker", "setmarking", "setmathstyle", "setmeasure", "setmessagetext", "setminus", "setmode", "setnostrut", "setnote", "setnotetext", "setobject", "setoldstyle", "setpagereference", "setpagestate", "setpagestaterealpageno", "setpenalties", "setpercentdimen", "setperiodkerning", "setposition", "setpositionbox", "setpositiondata", "setpositiondataplus", "setpositiononly", "setpositionplus", "setpositionstrut", "setprofile", "setrandomseed", "setreference", "setreferencedobject", "setregisterentry", "setreplacement", "setrigidcolumnbalance", "setrigidcolumnhsize", "setscript", "setsecondpasscharacteralign", "setsectionblock", "setsimplecolumnhsize", "setsmallbodyfont", "setsmallcaps", "setstackbox", "setstructurepageregister", "setstrut", "setsuperiors", "setsystemmode", "settabular", "settaggedmetadata", "settextcontent", "settightobject", "settightreferencedobject", "settightstrut", "settightunreferencedobject", "settokenlist", "settrialtypesetting", "setuevalue", "setugvalue", "setunreferencedobject", "setup", "setupMPgraphics", "setupMPinstance", "setupMPpage", "setupMPvariables", "setupTABLE", "setupTEXpage", "setupalign", "setupalternativestyles", "setuparranging", "setupattachment", "setupattachments", "setupbackend", "setupbackground", "setupbackgrounds", "setupbar", "setupbars", "setupblackrules", "setupblank", "setupbleeding", "setupblock", "setupbodyfont", "setupbookmark", "setupbottom", "setupbottomtexts", "setupbtx", "setupbtxdataset", "setupbtxlabeltext", "setupbtxlist", "setupbtxregister", "setupbtxrendering", "setupbuffer", "setupbutton", "setupcapitals", "setupcaption", "setupcaptions", "setupcharacteralign", "setupcharacterkerning", "setupcharacterspacing", "setupchemical", "setupchemicalframed", "setupclipping", "setupcollector", "setupcolor", "setupcolors", "setupcolumns", "setupcolumnset", "setupcolumnsetarea", "setupcolumnsetareatext", "setupcolumnsetlines", "setupcolumnsetspan", "setupcolumnsetstart", "setupcolumnspan", "setupcombination", "setupcombinedlist", "setupcomment", "setupcontent", "setupcounter", "setupdataset", "setupdelimitedtext", "setupdescription", "setupdirections", "setupdocument", "setupeffect", "setupenumeration", "setupenumerations", "setupenv", "setupexport", "setupexternalfigure", "setupexternalsoundtracks", "setupfacingfloat", "setupfield", "setupfieldbody", "setupfieldcategory", "setupfieldcontentframed", "setupfieldlabelframed", "setupfields", "setupfieldtotalframed", "setupfiller", "setupfillinlines", "setupfillinrules", "setupfirstline", "setupfittingpage", "setupfloat", "setupfloatframed", "setupfloats", "setupfloatsplitting", "setupfontexpansion", "setupfontprotrusion", "setupfonts", "setupfontsolution", "setupfooter", "setupfootertexts", "setupforms", "setupformula", "setupformulae", "setupformulaframed", "setupframed", "setupframedcontent", "setupframedtable", "setupframedtablecolumn", "setupframedtablerow", "setupframedtext", "setupframedtexts", "setupglobalreferenceprefix", "setuphead", "setupheadalternative", "setupheader", "setupheadertexts", "setupheadnumber", "setupheads", "setupheadtext", "setuphelp", "setuphigh", "setuphighlight", "setuphyphenation", "setuphyphenmark", "setupindentedtext", "setupindenting", "setupindex", "setupinitial", "setupinsertion", "setupinteraction", "setupinteractionbar", "setupinteractionmenu", "setupinteractionscreen", "setupinterlinespace", "setupitaliccorrection", "setupitemgroup", "setupitemizations", "setupitemize", "setupitems", "setuplabel", "setuplabeltext", "setuplanguage", "setuplayer", "setuplayeredtext", "setuplayout", "setuplayouttext", "setuplegend", "setuplinefiller", "setuplinefillers", "setuplinenote", "setuplinenumbering", "setuplines", "setuplinetable", "setuplinewidth", "setuplist", "setuplistalternative", "setuplistextra", "setuplocalfloats", "setuplocalinterlinespace", "setuplow", "setuplowhigh", "setuplowmidhigh", "setupmakeup", "setupmarginblock", "setupmargindata", "setupmarginframed", "setupmarginrule", "setupmarginrules", "setupmarking", "setupmathalignment", "setupmathcases", "setupmathematics", "setupmathfence", "setupmathfraction", "setupmathfractions", "setupmathframed", "setupmathlabeltext", "setupmathmatrix", "setupmathornament", "setupmathradical", "setupmathstackers", "setupmathstyle", "setupmixedcolumns", "setupmodule", "setupnarrower", "setupnotation", "setupnotations", "setupnote", "setupnotes", "setupoffset", "setupoffsetbox", "setupoperatortext", "setupoppositeplacing", "setupoutputroutine", "setuppagechecker", "setuppagecolumns", "setuppagecomment", "setuppageinjection", "setuppageinjectionalternative", "setuppagenumber", "setuppagenumbering", "setuppageshift", "setuppagestate", "setuppagetransitions", "setuppairedbox", "setuppalet", "setuppaper", "setuppapersize", "setupparagraph", "setupparagraphintro", "setupparagraphnumbering", "setupparagraphs", "setupparallel", "setupperiodkerning", "setupperiods", "setupplacement", "setuppositionbar", "setuppositioning", "setupprefixtext", "setupprocessor", "setupprofile", "setupprograms", "setupquotation", "setupquote", "setuprealpagenumber", "setupreferenceformat", "setupreferenceprefix", "setupreferencestructureprefix", "setupreferencing", "setupregister", "setupregisters", "setuprenderingwindow", "setuprotate", "setupruby", "setups", "setupscale", "setupscript", "setupscripts", "setupsectionblock", "setupselector", "setupshift", "setupsidebar", "setupsorting", "setupspacing", "setupspellchecking", "setupstartstop", "setupstretched", "setupstruts", "setupstyle", "setupsubformula", "setupsubformulas", "setupsubpagenumber", "setupsuffixtext", "setupsymbolset", "setupsynctex", "setupsynonyms", "setuptables", "setuptabulate", "setuptabulation", "setuptagging", "setuptaglabeltext", "setuptext", "setuptextbackground", "setuptextflow", "setuptextrules", "setuptexttexts", "setupthinrules", "setuptolerance", "setuptooltip", "setuptop", "setuptoptexts", "setuptype", "setuptyping", "setupunit", "setupunittext", "setupurl", "setupuserdata", "setupuserdataalternative", "setupuserpagenumber", "setupversion", "setupviewerlayer", "setupvspacing", "setupwhitespace", "setupwithargument", "setupwithargumentswapped", "setupxml", "setupxtable", "setuvalue", "setuxvalue", "setvalue", "setvariable", "setvariables", "setvboxregister", "setvisualizerfont", "setvtopregister", "setwidthof", "setxmeasure", "setxvalue", "setxvariable", "setxvariables", "seveneighths", "sfrac", "shapedhbox", "sharp", "shiftbox", "shiftdown", "shiftup", "showallmakeup", "showattributes", "showbodyfont", "showbodyfontenvironment", "showboxes", "showbtxdatasetauthors", "showbtxdatasetcompleteness", "showbtxdatasetfields", "showbtxfields", "showbtxhashedauthors", "showbtxtables", "showchardata", "showcharratio", "showcolor", "showcolorbar", "showcolorcomponents", "showcolorgroup", "showcolorset", "showcolorstruts", "showcounter", "showdirectives", "showdirsinmargin", "showedebuginfo", "showexperiments", "showfont", "showfontdata", "showfontexpansion", "showfontitalics", "showfontkerns", "showfontparameters", "showfontstrip", "showfontstyle", "showframe", "showglyphdata", "showglyphs", "showgrid", "showgridsnapping", "showhelp", "showhyphenationtrace", "showhyphens", "showinjector", "showjustification", "showkerning", "showlayout", "showlayoutcomponents", "showligature", "showligatures", "showlogcategories", "showmakeup", "showmargins", "showmessage", "showminimalbaseline", "shownextbox", "showotfcomposition", "showpalet", "showparentchain", "showprint", "showsetups", "showsetupsdefinition", "showstruts", "showsymbolset", "showtimer", "showtokens", "showtrackers", "showvalue", "showvariable", "showwarning", "sigma", "signalrightpage", "sim", "simeq", "simplealignedbox", "simplealignedboxplus", "simplealignedspreadbox", "simplegroupedcommand", "simplereversealignedbox", "simplereversealignedboxplus", "singalcharacteralign", "singlebond", "singleverticalbar", "sixperemspace", "sixthofsixarguments", "slanted", "slantedbold", "slantedface", "slash", "slicepages", "slong", "slovenianNumerals", "sloveniannumerals", "small", "smallbodyfont", "smallbold", "smallbolditalic", "smallboldslanted", "smallcappedcharacters", "smallcappedromannumerals", "smaller", "smallitalicbold", "smallnormal", "smallskip", "smallslanted", "smallslantedbold", "smalltype", "smash", "smashbox", "smashboxed", "smashedhbox", "smashedvbox", "smile", "snaptogrid", "softhyphen", "solidus", "someheadnumber", "somekindoftab", "someline", "somelocalfloat", "somenamedheadnumber", "someplace", "somewhere", "space", "spaceddigits", "spaceddigitsmethod", "spaceddigitsseparator", "spaceddigitssymbol", "spadesuit", "spanishNumerals", "spanishnumerals", "speech", "sphericalangle", "splitatasterisk", "splitatcolon", "splitatcolons", "splitatcomma", "splitatperiod", "splitdfrac", "splitfilename", "splitfloat", "splitfrac", "splitoffbase", "splitofffull", "splitoffkind", "splitoffname", "splitoffpath", "splitoffroot", "splitofftokens", "splitofftype", "splitstring", "spreadhbox", "sqcap", "sqcup", "sqrt", "sqsubset", "sqsubseteq", "sqsubsetneq", "sqsupset", "sqsupseteq", "sqsupsetneq", "square", "squaredots", "ssharp", "stackrel", "star", "stareq", "startJScode", "startJSpreamble", "startLUA", "startMP", "startMPclip", "startMPcode", "startMPdefinitions", "startMPdrawing", "startMPenvironment", "startMPextensions", "startMPinclusions", "startMPinitializations", "startMPpage", "startMPpositiongraphic", "startMPpositionmethod", "startMPrun", "startPARSEDXML", "startTABLE", "startTABLEbody", "startTABLEfoot", "startTABLEhead", "startTABLEnext", "startTC", "startTD", "startTDs", "startTEX", "startTEXpage", "startTH", "startTN", "startTR", "startTRs", "startTX", "startTY", "startXML", "startalign", "startalignment", "startallmodes", "startappendices", "startarrangedpages", "startaside", "startattachment", "startbackground", "startbackmatter", "startbar", "startbbordermatrix", "startbitmapimage", "startblockquote", "startbodymatter", "startbordermatrix", "startboxedcolumns", "startbtxlabeltext", "startbtxrenderingdefinitions", "startbuffer", "startcases", "startcatcodetable", "startcenteraligned", "startchapter", "startcharacteralign", "startcheckedfences", "startchemical", "startchemicaltext", "startcollect", "startcollecting", "startcolor", "startcolorintent", "startcoloronly", "startcolorset", "startcolumns", "startcolumnset", "startcolumnsetspan", "startcolumnspan", "startcombination", "startcomment", "startcomponent", "startcontextcode", "startcontextdefinitioncode", "startctxfunction", "startctxfunctiondefinition", "startcurrentcolor", "startcurrentlistentrywrapper", "startdelimited", "startdelimitedtext", "startdisplaymath", "startdmath", "startdocument", "starteffect", "startelement", "startembeddedxtable", "startendnote", "startendofline", "startenvironment", "startexceptions", "startexpanded", "startexpandedcollect", "startextendedcatcodetable", "startexternalfigurecollection", "startfacingfloat", "startfact", "startfigure", "startfiguretext", "startfittingpage", "startfixed", "startfloatcombination", "startfont", "startfontclass", "startfontsolution", "startfootnote", "startformula", "startformulas", "startframed", "startframedcell", "startframedcontent", "startframedrow", "startframedtable", "startframedtext", "startfrontmatter", "startgoto", "startgraphictext", "startgridsnapping", "starthanging", "starthbox", "starthboxestohbox", "starthboxregister", "starthead", "startheadtext", "starthelptext", "starthiding", "starthighlight", "starthyphenation", "startimath", "startindentation", "startindentedtext", "startinteraction", "startinteractionmenu", "startinterface", "startintermezzotext", "startintertext", "startitem", "startitemgroup", "startitemgroupcolumns", "startitemize", "startknockout", "startlabeltext", "startlanguage", "startlayout", "startleftaligned", "startlegend", "startline", "startlinealignment", "startlinecorrection", "startlinefiller", "startlinenote", "startlinenumbering", "startlines", "startlinetable", "startlinetablebody", "startlinetablecell", "startlinetablehead", "startlocalfootnotes", "startlocalheadsetup", "startlocallinecorrection", "startlocalnotes", "startlocalsetups", "startlua", "startluacode", "startluaparameterset", "startluasetups", "startmakeup", "startmarginblock", "startmarginrule", "startmarkedcontent", "startmarkpages", "startmathalignment", "startmathcases", "startmathlabeltext", "startmathmatrix", "startmathmode", "startmathstyle", "startmatrices", "startmatrix", "startmaxaligned", "startmdformula", "startmidaligned", "startmiddlealigned", "startmiddlemakeup", "startmixedcolumns", "startmode", "startmodeset", "startmodule", "startmoduletestsection", "startmpformula", "startnamedsection", "startnamedsubformulas", "startnarrow", "startnarrower", "startnegative", "startnicelyfilledbox", "startnointerference", "startnotallmodes", "startnotext", "startnotmode", "startoperatortext", "startopposite", "startoutputstream", "startoverlay", "startoverprint", "startpacked", "startpagecolumns", "startpagecomment", "startpagefigure", "startpagelayout", "startpagemakeup", "startpar", "startparagraph", "startparagraphs", "startparagraphscell", "startparbuilder", "startpart", "startpath", "startplacechemical", "startplacefigure", "startplacefloat", "startplaceformula", "startplacegraphic", "startplaceintermezzo", "startplacelegend", "startplacepairedbox", "startplacetable", "startpositioning", "startpositionoverlay", "startpositive", "startpostponing", "startpostponingnotes", "startprefixtext", "startprocessassignmentcommand", "startprocessassignmentlist", "startprocesscommacommand", "startprocesscommalist", "startproduct", "startproject", "startprotect", "startprotectedcolors", "startpublication", "startpunctuation", "startquotation", "startquote", "startrandomized", "startrandomseed", "startrawsetups", "startreadingfile", "startreferenceprefix", "startregime", "startregister", "startreusableMPgraphic", "startrightaligned", "startruby", "startscript", "startsdformula", "startsection", "startsectionblock", "startsectionblockenvironment", "startsectionlevel", "startsetups", "startshapebox", "startshift", "startsidebar", "startsimplecolumns", "startspecialitem", "startspeech", "startspformula", "startsplitformula", "startsplittext", "startspread", "startstandardmakeup", "startstaticMPfigure", "startstaticMPgraphic", "startstrictinspectnextcharacter", "startstructurepageregister", "startstrut", "startstyle", "startsubformulas", "startsubject", "startsubjectlevel", "startsubsection", "startsubsentence", "startsubstack", "startsubsubject", "startsubsubsection", "startsubsubsubject", "startsubsubsubsection", "startsubsubsubsubject", "startsubsubsubsubsection", "startsubsubsubsubsubject", "startsuffixtext", "startsymbolset", "starttable", "starttablehead", "starttables", "starttabletail", "starttabletext", "starttabulate", "starttabulatehead", "starttabulatetail", "starttagged", "starttaglabeltext", "starttexcode", "starttexdefinition", "starttext", "starttextbackground", "starttextbackgroundmanual", "starttextcolor", "starttextcolorintent", "starttextflow", "starttextmakeup", "starttextrule", "starttitle", "starttokenlist", "starttokens", "starttransparent", "starttypescript", "starttypescriptcollection", "starttyping", "startuniqueMPgraphic", "startuniqueMPpagegraphic", "startunittext", "startunpacked", "startusableMPgraphic", "startuseMPgraphic", "startusemathstyleparameter", "startuserdata", "startusingbtxspecification", "startvbox", "startvboxregister", "startvboxtohbox", "startvboxtohboxseparator", "startviewerlayer", "startvtop", "startvtopregister", "startxcell", "startxcellgroup", "startxcolumn", "startxgroup", "startxmldisplayverbatim", "startxmlinlineverbatim", "startxmlraw", "startxmlsetups", "startxrow", "startxrowgroup", "startxtable", "startxtablebody", "startxtablefoot", "startxtablehead", "startxtablenext", "stligature", "stopJScode", "stopJSpreamble", "stopLUA", "stopMP", "stopMPclip", "stopMPcode", "stopMPdefinitions", "stopMPdrawing", "stopMPenvironment", "stopMPextensions", "stopMPinclusions", "stopMPinitializations", "stopMPpage", "stopMPpositiongraphic", "stopMPpositionmethod", "stopMPrun", "stopPARSEDXML", "stopTABLE", "stopTABLEbody", "stopTABLEfoot", "stopTABLEhead", "stopTABLEnext", "stopTC", "stopTD", "stopTDs", "stopTEX", "stopTEXpage", "stopTH", "stopTN", "stopTR", "stopTRs", "stopTX", "stopTY", "stopXML", "stopalign", "stopalignment", "stopallmodes", "stopappendices", "stoparrangedpages", "stopaside", "stopattachment", "stopbackground", "stopbackmatter", "stopbar", "stopbbordermatrix", "stopbitmapimage", "stopblockquote", "stopbodymatter", "stopbordermatrix", "stopboxedcolumns", "stopbtxlabeltext", "stopbtxrenderingdefinitions", "stopbuffer", "stopcases", "stopcatcodetable", "stopcenteraligned", "stopchapter", "stopcharacteralign", "stopcheckedfences", "stopchemical", "stopchemicaltext", "stopcollect", "stopcollecting", "stopcolor", "stopcolorintent", "stopcoloronly", "stopcolorset", "stopcolumns", "stopcolumnset", "stopcolumnsetspan", "stopcolumnspan", "stopcombination", "stopcomment", "stopcomponent", "stopcontextcode", "stopcontextdefinitioncode", "stopctxfunction", "stopctxfunctiondefinition", "stopcurrentcolor", "stopcurrentlistentrywrapper", "stopdelimited", "stopdelimitedtext", "stopdisplaymath", "stopdmath", "stopdocument", "stopeffect", "stopelement", "stopembeddedxtable", "stopendnote", "stopendofline", "stopenvironment", "stopexceptions", "stopexpanded", "stopexpandedcollect", "stopextendedcatcodetable", "stopexternalfigurecollection", "stopfacingfloat", "stopfact", "stopfigure", "stopfiguretext", "stopfittingpage", "stopfixed", "stopfloatcombination", "stopfont", "stopfontclass", "stopfontsolution", "stopfootnote", "stopformula", "stopformulas", "stopframed", "stopframedcell", "stopframedcontent", "stopframedrow", "stopframedtable", "stopframedtext", "stopfrontmatter", "stopgoto", "stopgraphictext", "stopgridsnapping", "stophanging", "stophbox", "stophboxestohbox", "stophboxregister", "stophead", "stopheadtext", "stophelptext", "stophiding", "stophighlight", "stophyphenation", "stopimath", "stopindentation", "stopindentedtext", "stopinteraction", "stopinteractionmenu", "stopinterface", "stopintermezzotext", "stopintertext", "stopitem", "stopitemgroup", "stopitemgroupcolumns", "stopitemize", "stopknockout", "stoplabeltext", "stoplanguage", "stoplayout", "stopleftaligned", "stoplegend", "stopline", "stoplinealignment", "stoplinecorrection", "stoplinefiller", "stoplinenote", "stoplinenumbering", "stoplines", "stoplinetable", "stoplinetablebody", "stoplinetablecell", "stoplinetablehead", "stoplocalfootnotes", "stoplocalheadsetup", "stoplocallinecorrection", "stoplocalnotes", "stoplocalsetups", "stoplua", "stopluacode", "stopluaparameterset", "stopluasetups", "stopmakeup", "stopmarginblock", "stopmarginrule", "stopmarkedcontent", "stopmarkpages", "stopmathalignment", "stopmathcases", "stopmathlabeltext", "stopmathmatrix", "stopmathmode", "stopmathstyle", "stopmatrices", "stopmatrix", "stopmaxaligned", "stopmdformula", "stopmidaligned", "stopmiddlealigned", "stopmiddlemakeup", "stopmixedcolumns", "stopmode", "stopmodeset", "stopmodule", "stopmoduletestsection", "stopmpformula", "stopnamedsection", "stopnamedsubformulas", "stopnarrow", "stopnarrower", "stopnegative", "stopnicelyfilledbox", "stopnointerference", "stopnotallmodes", "stopnotext", "stopnotmode", "stopoperatortext", "stopopposite", "stopoutputstream", "stopoverlay", "stopoverprint", "stoppacked", "stoppagecolumns", "stoppagecomment", "stoppagefigure", "stoppagelayout", "stoppagemakeup", "stoppar", "stopparagraph", "stopparagraphs", "stopparagraphscell", "stopparbuilder", "stoppart", "stoppath", "stopplacechemical", "stopplacefigure", "stopplacefloat", "stopplaceformula", "stopplacegraphic", "stopplaceintermezzo", "stopplacelegend", "stopplacepairedbox", "stopplacetable", "stoppositioning", "stoppositionoverlay", "stoppositive", "stoppostponing", "stoppostponingnotes", "stopprefixtext", "stopprocessassignmentcommand", "stopprocessassignmentlist", "stopprocesscommacommand", "stopprocesscommalist", "stopproduct", "stopproject", "stopprotect", "stopprotectedcolors", "stoppublication", "stoppunctuation", "stopquotation", "stopquote", "stoprandomized", "stoprandomseed", "stoprawsetups", "stopreadingfile", "stopreferenceprefix", "stopregime", "stopregister", "stopreusableMPgraphic", "stoprightaligned", "stopruby", "stopscript", "stopsdformula", "stopsection", "stopsectionblock", "stopsectionblockenvironment", "stopsectionlevel", "stopsetups", "stopshapebox", "stopshift", "stopsidebar", "stopsimplecolumns", "stopspecialitem", "stopspeech", "stopspformula", "stopsplitformula", "stopsplittext", "stopspread", "stopstandardmakeup", "stopstaticMPfigure", "stopstaticMPgraphic", "stopstrictinspectnextcharacter", "stopstructurepageregister", "stopstrut", "stopstyle", "stopsubformulas", "stopsubject", "stopsubjectlevel", "stopsubsection", "stopsubsentence", "stopsubstack", "stopsubsubject", "stopsubsubsection", "stopsubsubsubject", "stopsubsubsubsection", "stopsubsubsubsubject", "stopsubsubsubsubsection", "stopsubsubsubsubsubject", "stopsuffixtext", "stopsymbolset", "stoptable", "stoptablehead", "stoptables", "stoptabletail", "stoptabletext", "stoptabulate", "stoptabulatehead", "stoptabulatetail", "stoptagged", "stoptaglabeltext", "stoptexcode", "stoptexdefinition", "stoptext", "stoptextbackground", "stoptextbackgroundmanual", "stoptextcolor", "stoptextcolorintent", "stoptextflow", "stoptextmakeup", "stoptextrule", "stoptitle", "stoptokenlist", "stoptokens", "stoptransparent", "stoptypescript", "stoptypescriptcollection", "stoptyping", "stopuniqueMPgraphic", "stopuniqueMPpagegraphic", "stopunittext", "stopunpacked", "stopusableMPgraphic", "stopuseMPgraphic", "stopusemathstyleparameter", "stopuserdata", "stopusingbtxspecification", "stopvbox", "stopvboxregister", "stopvboxtohbox", "stopvboxtohboxseparator", "stopviewerlayer", "stopvtop", "stopvtopregister", "stopxcell", "stopxcellgroup", "stopxcolumn", "stopxgroup", "stopxmldisplayverbatim", "stopxmlinlineverbatim", "stopxmlraw", "stopxmlsetups", "stopxrow", "stopxrowgroup", "stopxtable", "stopxtablebody", "stopxtablefoot", "stopxtablehead", "stopxtablenext", "stretched", "strictdoifelsenextoptional", "strictdoifnextoptionalelse", "stripcharacter", "strippedcsname", "stripspaces", "structurelistuservariable", "structurenumber", "structuretitle", "structureuservariable", "structurevariable", "strut", "strutdp", "strutgap", "strutht", "struthtdp", "struttedbox", "strutwd", "style", "styleinstance", "subject", "subpagenumber", "subsection", "subsentence", "subset", "subseteq", "subseteqq", "subsetneq", "subsetneqq", "substituteincommalist", "subsubject", "subsubsection", "subsubsubject", "subsubsubsection", "subsubsubsubject", "subsubsubsubsection", "subsubsubsubsubject", "subtractfeature", "succ", "succapprox", "succcurlyeq", "succeq", "succeqq", "succnapprox", "succneq", "succneqq", "succnsim", "succsim", "suffixlanguage", "suffixtext", "sum", "supset", "supseteq", "supseteqq", "supsetneq", "supsetneqq", "surd", "surdradical", "swapcounts", "swapdimens", "swapface", "swapmacros", "swaptypeface", "swarrow", "switchstyleonly", "switchtobodyfont", "switchtocolor", "switchtointerlinespace", "symbol", "symbolreference", "synchronizeblank", "synchronizeindenting", "synchronizemarking", "synchronizeoutputstreams", "synchronizestrut", "synchronizewhitespace", "synctexblockfilename", "synctexresetfilename", "synctexsetfilename", "systemlog", "systemlogfirst", "systemloglast", "systemsetups", "tLeftarrow", "tLeftrightarrow", "tRightarrow", "tabulateautoline", "tabulateautorule", "tabulateline", "tabulaterule", "taggedctxcommand", "taggedlabeltexts", "taglabellanguage", "taglabeltext", "tau", "tbinom", "tbox", "tcaron", "tcedilla", "tcommaaccent", "tcurl", "tequal", "test", "testandsplitstring", "testcolumn", "testfeature", "testfeatureonce", "testpage", "testpageonly", "testpagesync", "testtokens", "tex", "texdefinition", "texsetup", "textAngstrom", "textacute", "textampersand", "textasciicircum", "textasciitilde", "textat", "textbackslash", "textbar", "textbottomcomma", "textbottomdot", "textbraceleft", "textbraceright", "textbreve", "textbrokenbar", "textbullet", "textcaron", "textcedilla", "textcelsius", "textcent", "textcircledP", "textcircumflex", "textcitation", "textcite", "textcomma", "textcontrolspace", "textcurrency", "textdag", "textddag", "textdegree", "textdiaeresis", "textdiv", "textdollar", "textdong", "textdotaccent", "textellipsis", "texteuro", "textflowcollector", "textfraction", "textgrave", "texthash", "texthorizontalbar", "texthungarumlaut", "texthyphen", "textkelvin", "textlognot", "textmacron", "textmath", "textmho", "textminus", "textmu", "textmultiply", "textnumero", "textogonek", "textohm", "textormathchar", "textormathchars", "textounce", "textpercent", "textperiod", "textplus", "textpm", "textreference", "textring", "textrule", "textslash", "textsterling", "texttilde", "textunderscore", "textvisiblespace", "textyen", "thai", "thainumerals", "thefirstcharacter", "thenormalizedbodyfontsize", "therefore", "theremainingcharacters", "theta", "thickspace", "thinrule", "thinrules", "thinspace", "thirdoffivearguments", "thirdoffourarguments", "thirdofsixarguments", "thirdofthreearguments", "thirdofthreeunexpanded", "thook", "thookleftarrow", "thookrightarrow", "thorn", "threedigitrounding", "threeeighths", "threefifths", "threeperemspace", "threequarter", "threesuperior", "tibetannumerals", "tightlayer", "tilde", "times", "tinyfont", "title", "tlap", "tleftarrow", "tleftharpoondown", "tleftharpoonup", "tleftrightarrow", "tleftrightharpoons", "tmapsto", "to", "tochar", "tolinenote", "tooltip", "top", "topbox", "topleftbox", "toplinebox", "toprightbox", "topskippedbox", "tracecatcodetables", "tracedfontname", "traceoutputroutines", "tracepositions", "trademark", "translate", "transparencycomponents", "transparent", "trel", "triangle", "triangledown", "triangleleft", "triangleq", "triangleright", "trightarrow", "trightharpoondown", "trightharpoonup", "trightleftharpoons", "trightoverleftarrow", "triplebond", "tripleprime", "tripleverticalbar", "truefilename", "truefontname", "tstroke", "ttraggedright", "ttriplerel", "ttwoheadleftarrow", "ttwoheadrightarrow", "turnediota", "twodigitrounding", "twofifths", "twoheaddownarrow", "twoheadleftarrow", "twoheadrightarrow", "twoheadrightarrowtail", "twoheaduparrow", "twosuperior", "twothirds", "tx", "txx", "typ", "type", "typebuffer", "typedefinedbuffer", "typeface", "typefile", "typeinlinebuffer", "typescriptone", "typescriptprefix", "typescriptthree", "typescripttwo", "typesetbuffer", "typesetfile", "uacute", "ubreve", "ucaron", "ucircumflex", "uconvertnumber", "udiaeresis", "udiaeresisacute", "udiaeresiscaron", "udiaeresisgrave", "udiaeresismacron", "udotbelow", "udots", "udoublegrave", "uedcatcodecommand", "ugrave", "uhook", "uhorn", "uhornacute", "uhorndotbelow", "uhorngrave", "uhornhook", "uhorntilde", "uhungarumlaut", "uinvertedbreve", "ulcorner", "umacron", "undefinevalue", "undepthed", "underbar", "underbars", "underbrace", "underbracket", "underdash", "underdashes", "underdot", "underdots", "underleftarrow", "underparent", "underrandom", "underrandoms", "underrightarrow", "underset", "understrike", "understrikes", "undoassign", "unexpandeddocumentvariable", "unframed", "unhhbox", "unihex", "uniqueMPgraphic", "uniqueMPpagegraphic", "unit", "unitlanguage", "unitshigh", "unitslow", "unittext", "unknown", "unprotected", "unregisterhyphenationpattern", "unspaceafter", "unspaceargument", "unspaced", "unspacestring", "untexargument", "untexcommand", "uogonek", "upand", "uparrow", "updasharrow", "updownarrow", "updownarrowbar", "updownarrows", "upharpoonleft", "upharpoonright", "uplus", "uppercased", "uppercasestring", "upperleftdoubleninequote", "upperleftdoublesixquote", "upperleftsingleninequote", "upperleftsinglesixquote", "upperrightdoubleninequote", "upperrightdoublesixquote", "upperrightsingleninequote", "upperrightsinglesixquote", "upsilon", "upuparrows", "upwhitearrow", "urcorner", "uring", "url", "useJSscripts", "useMPenvironmentbuffer", "useMPgraphic", "useMPlibrary", "useMPrun", "useMPvariables", "useURL", "usealignparameter", "useblankparameter", "useblocks", "usebodyfont", "usebodyfontparameter", "usebtxdataset", "usebtxdefinitions", "usecitation", "usecolors", "usecomponent", "usedirectory", "usedummycolorparameter", "usedummystyleandcolor", "usedummystyleparameter", "useenvironment", "useexternaldocument", "useexternalfigure", "useexternalrendering", "useexternalsoundtrack", "usefigurebase", "usefile", "usegridparameter", "useindentingparameter", "useindentnextparameter", "useinterlinespaceparameter", "uselanguageparameter", "useluamodule", "usemathstyleparameter", "usemodule", "useproduct", "useprofileparameter", "useproject", "usereferenceparameter", "userpagenumber", "usesetupsparameter", "usestaticMPfigure", "usesubpath", "usesymbols", "usetexmodule", "usetypescript", "usetypescriptfile", "useurl", "usezipfile", "utfchar", "utflower", "utfupper", "utilde", "utilityregisterlength", "vDash", "varTheta", "varepsilon", "varkappa", "varnothing", "varphi", "varpi", "varrho", "varsigma", "vartheta", "vboxreference", "vdash", "vdots", "vec", "vee", "veebar", "veeeq", "verbatim", "verbatimstring", "verbosenumber", "version", "vert", "verticalgrowingbar", "verticalpositionbar", "veryraggedcenter", "veryraggedleft", "veryraggedright", "vglue", "viewerlayer", "vl", "vphantom", "vpos", "vsmash", "vsmashbox", "vsmashed", "vspace", "vspacing", "wcircumflex", "wdofstring", "wedge", "wedgeeq", "weekday", "whitearrowupfrombar", "widehat", "widetilde", "widthofstring", "widthspanningtext", "withoutpt", "word", "wordright", "words", "wordtonumber", "wp", "wr", "writebetweenlist", "writedatatolist", "writestatus", "writetolist", "xLeftarrow", "xLeftrightarrow", "xRightarrow", "xdefconvertedargument", "xequal", "xfrac", "xhookleftarrow", "xhookrightarrow", "xi", "xleftarrow", "xleftharpoondown", "xleftharpoonup", "xleftrightarrow", "xleftrightharpoons", "xmapsto", "xmladdindex", "xmlafterdocumentsetup", "xmlaftersetup", "xmlall", "xmlappenddocumentsetup", "xmlappendsetup", "xmlapplyselectors", "xmlatt", "xmlattdef", "xmlattribute", "xmlattributedef", "xmlbadinclusions", "xmlbeforedocumentsetup", "xmlbeforesetup", "xmlchainatt", "xmlchainattdef", "xmlchecknamespace", "xmlcommand", "xmlconcat", "xmlconcatrange", "xmlcontext", "xmlcount", "xmldefaulttotext", "xmldirectives", "xmldirectivesafter", "xmldirectivesbefore", "xmldisplayverbatim", "xmldoif", "xmldoifatt", "xmldoifelse", "xmldoifelseatt", "xmldoifelseempty", "xmldoifelseselfempty", "xmldoifelsetext", "xmldoifelsevalue", "xmldoifnot", "xmldoifnotatt", "xmldoifnotselfempty", "xmldoifnottext", "xmldoifselfempty", "xmldoiftext", "xmlelement", "xmlfilter", "xmlfirst", "xmlflush", "xmlflushcontext", "xmlflushdocumentsetups", "xmlflushlinewise", "xmlflushpure", "xmlflushspacewise", "xmlflushtext", "xmlinclude", "xmlinclusion", "xmlinclusions", "xmlinfo", "xmlinjector", "xmlinlineprettyprint", "xmlinlineprettyprinttext", "xmlinlineverbatim", "xmlinstalldirective", "xmllast", "xmllastatt", "xmllastmatch", "xmllastpar", "xmlloadbuffer", "xmlloaddata", "xmlloaddirectives", "xmlloadfile", "xmlloadonly", "xmlmain", "xmlmapvalue", "xmlname", "xmlnamespace", "xmlnonspace", "xmlpar", "xmlparam", "xmlpath", "xmlpos", "xmlposition", "xmlprependdocumentsetup", "xmlprependsetup", "xmlprettyprint", "xmlprettyprinttext", "xmlprocessbuffer", "xmlprocessdata", "xmlprocessfile", "xmlpure", "xmlraw", "xmlrefatt", "xmlregistereddocumentsetups", "xmlregisteredsetups", "xmlregisterns", "xmlremapname", "xmlremapnamespace", "xmlremovedocumentsetup", "xmlremovesetup", "xmlresetdocumentsetups", "xmlresetinjectors", "xmlresetsetups", "xmlsave", "xmlsetatt", "xmlsetattribute", "xmlsetentity", "xmlsetfunction", "xmlsetinjectors", "xmlsetpar", "xmlsetparam", "xmlsetsetup", "xmlsetup", "xmlshow", "xmlsnippet", "xmlstrip", "xmlstripnolines", "xmlstripped", "xmlstrippednolines", "xmltag", "xmltexentity", "xmltext", "xmltobuffer", "xmltobufferverbose", "xmltofile", "xmlvalue", "xmlverbatim", "xrel", "xrightarrow", "xrightharpoondown", "xrightharpoonup", "xrightleftharpoons", "xrightoverleftarrow", "xsplitstring", "xtriplerel", "xtwoheadleftarrow", "xtwoheadrightarrow", "xxfrac", "xypos", "yacute", "ycircumflex", "ydiaeresis", "ydotbelow", "yen", "ygrave", "yhook", "ymacron", "ytilde", "zacute", "zcaron", "zdotaccent", "zerowidthnobreakspace", "zerowidthspace", "zeta", "zhook", "zstroke", "zwj", "zwnj" },
+ ["cs"]={ "Cisla", "Kap", "MESIC", "Rimskecislice", "SLOVA", "SLOVO", "Slova", "Slovo", "VSEDNIDEN", "Znak", "Znaky", "aktualnicislonadpisu", "aktualnidatum", "barevnalista", "barva", "cernalinka", "cernelinky", "cisla", "cislonadpisu", "cislorovnice", "cislostrany", "datum", "definuj", "definujakcent", "definujbarvu", "definujblok", "definujbloksekce", "definujbuffer", "definujfont", "definujformatodkazu", "definujhbox", "definujinterakcnimenu", "definujkombinovanyseznam", "definujkonverzi", "definujnadpis", "definujobrazeksymbol", "definujodkaz", "definujodstavce", "definujopis", "definujoramovani", "definujoramovanytext", "definujpaletu", "definujplvouciobjekt", "definujpodpole", "definujpole", "definujpopis", "definujpopisek", "definujprekryv", "definujprikaz", "definujprofil", "definujprogram", "definujprostredizakladnihofontu", "definujrejstrik", "definujsablonutabulky", "definujsekci", "definujseznam", "definujskupinubarev", "definujstartstop", "definujstyl", "definujstylfontu", "definujsymbol", "definujsynonumumfontu", "definujsynonyma", "definujtabelaci", "definujtext", "definujtrideni", "definujupravu", "definujvelikostpapiru", "definujvycet", "definujzakladnifont", "definujzasobnikpoli", "definujznaceni", "definujznak", "delkaseznamu", "externiobraz", "hlavnijazyk", "hodnotabarvy", "instalacejazyka", "interakcnilista", "interakcnitlacitka", "interaktivnimenu", "jazyk", "jdidolu", "jdina", "jdinabox", "jdinastranu", "klonujpole", "komponenta", "konvertujcislo", "kopirujpole", "korekcebilehomista", "matematika", "meritko", "mesic", "mezera", "mrizka", "nastavbarvu", "nastavbarvy", "nastavbilamista", "nastavblok", "nastavbloksekce", "nastavbuffer", "nastavcernelinky", "nastavcislonadpisu", "nastavcislostrany", "nastavcislovaniodstavcu", "nastavcislovaniradku", "nastavcislovanistran", "nastavcitaci", "nastavdeleniplvoucichobjektu", "nastavdelitko", "nastavdolnitexty", "nastavhorejsek", "nastavhornitexty", "nastavinterakci", "nastavinterakcnilistu", "nastavinterakcnimenu", "nastavinterakcniobrazovku", "nastavjazyk", "nastavkapitalky", "nastavkombinovanyseznam", "nastavkomentar", "nastavkomentarstrany", "nastavmarginalnilinky", "nastavmeziradkovoumezeru", "nastavnadpis", "nastavnadpisy", "nastavodkazovani", "nastavodsazovani", "nastavodstavce", "nastavopis", "nastavoramovanetexty", "nastavoramovani", "nastavorez", "nastavotoceni", "nastavpaletu", "nastavplvouciobjekt", "nastavplvouciobjekty", "nastavpodcislostrany", "nastavpole", "nastavpolozky", "nastavpopisek", "nastavpopisky", "nastavpozadi", "nastavprechodstrany", "nastavpreskok", "nastavprogramy", "nastavradkovani", "nastavradky", "nastavrejstrik", "nastavrovnice", "nastavsadusymbolu", "nastavseznam", "nastavsirkucary", "nastavsloupce", "nastavspodek", "nastavsynonyma", "nastavtabelaci", "nastavtabulky", "nastavtenkelinky", "nastavtext", "nastavtextovelinky", "nastavtexttexty", "nastavtextyupati", "nastavtextyzahlavi", "nastavtoleranci", "nastavtrideni", "nastavtype", "nastavumisteniprotejsku", "nastavumistovani", "nastavupati", "nastavupravu", "nastavurl", "nastavusporadani", "nastavvelikostpapiru", "nastavvsechnapole", "nastavvycty", "nastavvyplnovelinky", "nastavvyplnoveradky", "nastavvzhled", "nastavzahlavi", "nastavzakladnifont", "nastavzarovnani", "nastavznaceni", "nastavzuzeni", "nastrane", "nejakyradek", "nekde", "neznamo", "nivy", "nizky", "nokap", "obrazovka", "odkaz", "odkaznastranu", "odkaznatext", "odkazujici", "opis", "opissoubor", "oramovani", "oref", "orez", "otocit", "oznaceni", "pis", "plnezneni", "pole", "polozka", "polozky", "porovnejpaletu", "porovnejskupinubarev", "pozadi", "pozice", "poznamka", "pref", "prelozit", "prepninazakladnifont", "preskoc", "prizpusobivepole", "prizpusobvzhled", "produkt", "projekt", "prostredi", "resetznaceni", "rimskecislice", "rozdelplvouciobjekt", "roztazene", "schovejbloky", "sedabarva", "sloupec", "slovovpravo", "stanovcharakteristickuseznamu", "stanovcislonadpisu", "startbarva", "startinteraktivnimenu", "startjazyk", "startjdina", "startkomponenta", "startmarginalnilinka", "startnadpis", "startoramovani", "startpolozka", "startpozadi", "startprodukt", "startprojekt", "startprostredi", "startpublikace", "startradek", "starttextovalinka", "startumistirovnici", "startzarovnanonastred", "startzarovnanovlevo", "startzarovnanovpravo", "startzhustene", "stopbarva", "stopinteraktivnimenu", "stopjazyk", "stopjdina", "stopkomponenta", "stopmarginalnilinka", "stopnadpis", "stoporamovani", "stoppolozka", "stoppozadi", "stopprodukt", "stopprojekt", "stopprostredi", "stoppublikace", "stopradek", "stoptextovalinka", "stopumistirovnici", "stopzarovnanonastred", "stopzarovnanovlevo", "stopzarovnanovpravo", "stopzhustene", "strana", "tecky", "tenkalinka", "tenkelinky", "textovalinka", "tlacitko", "tlacitkomenu", "tloustkacary", "tref", "tvrdamezera", "tvrdemezery", "ukazbarvu", "ukazmrizku", "ukaznastaveni", "ukazpaletu", "ukazpodpery", "ukazpostredizakladnihofontu", "ukazramecek", "ukazsadusymbolu", "ukazskupinubarev", "ukazupravu", "ukazvytisk", "ukazvzhled", "ukazzakladnifont", "umistikombinovanyseznam", "umistilokalnipoznamkypodcarou", "umistinadsebe", "umistinamrizku", "umistipodrovnici", "umistipoznamkypodcarou", "umistirejstrik", "umistirovnici", "umistiseznam", "umistivedlesebe", "umistizalozky", "urcicharakteristikurejstriku", "uzijJSscripts", "uzijURL", "uzijadresar", "uzijbloky", "uzijexternidokument", "uzijexterniobraz", "uzijexternizvuk", "uzijmodul", "uzijsymbol", "uzijurl", "verze", "vlasovalinka", "vradku", "vsedniden", "vyberbloky", "vyplnenytext", "vyplnovelinky", "vyplnovyradek", "vysoky", "zachovejbloky", "zadnamezera", "zadnehorniadolniradky", "zadnezahlaviaupati", "zalozka", "zapisdoseznamu", "zapismeziseznam", "zaramovani", "zarovnanonastred", "zarovnanovlevo", "zarovnanovpravo", "zasobnikpoli", "ziskejbuffer", "ziskejznaceni", "znaceni", "znak", "znaky", "zpracujbloky", "zrcadlit", "zref" },
+ ["de"]={ "Buchstabe", "Buchstaben", "Kap", "MONAT", "Roemischezahlen", "WOCHENTAG", "WOERTER", "WORT", "Woerter", "Wort", "Ziffern", "amgitterausrichten", "aufseite", "ausfuelltext", "ausschnitt", "bearbeitebloecke", "behaltebloecke", "bei", "bemerkung", "benutzeverzeichnis", "beschriftung", "bestimmekopfnummer", "bestimmelistencharakeristika", "bestimmeregistercharakteristika", "bildschirm", "blanko", "buchstabe", "buchstaben", "datum", "defineschriftsynonym", "definiereabbsymbol", "definiereabsaetze", "definiereabschnitt", "definiereabschnittsblock", "definiereakzent", "definierebefehl", "definierebeschreibung", "definierebeschriftung", "definiereblock", "definierefarbe", "definierefarbengruppe", "definierefeld", "definierefeldstapel", "definierefliesstext", "definierefliesstextumgebung", "definieregleitobjekt", "definierehbox", "definiereinteraktionsmenue", "definierekonversion", "definierelabel", "definiereliste", "definieren", "definierenummerierung", "definiereoverlay", "definierepalette", "definierepapierformat", "definiereprofil", "definiereprogramme", "definierepuffer", "definierereferenz", "definierereferenzformat", "definiereregister", "definiereschrift", "definiereschriftstil", "definieresortieren", "definierestartstop", "definierestil", "definieresubfeld", "definieresymbol", "definieresynonyme", "definieretabellenvorlage", "definieretabulator", "definieretext", "definieretippen", "definiereueberschrift", "definiereumbruch", "definiereumrahmt", "definiereumrahmtertext", "definierezeichen", "definierezusammengestellteliste", "drehen", "duennelinie", "duennerumriss", "einezeile", "externeabbildung", "farbbalken", "farbe", "farbewert", "feld", "feldstapel", "festesspatium", "format", "formelnummer", "gefuelltesrechteck", "gefuelltezeile", "gestreckt", "gitter", "graufarbe", "haarlinie", "hauptsprache", "heutigesdatum", "heutigeskopfnummer", "hintergrund", "hoch", "holebeschriftung", "holepuffer", "imumriss", "installieresprache", "interaktionsbalken", "interaktionsknopfe", "interaktionsmenue", "inzeile", "irgendwo", "keinekopfundfusszeilen", "keinspatium", "keinzeilenobenundunten", "klonierefeld", "knopf", "komponente", "konvertierezahl", "kopfnummer", "kopierefeld", "korrigierezwischenraum", "liniendicke", "linksbuendig", "listenlaenge", "mathematik", "menueknopf", "monat", "nachunten", "nokap", "notiz", "passelayoutan", "passendfeld", "platzierebookmarks", "platziereformel", "platzierefussnoten", "platziereliste", "platzierelokalefussnoten", "platzierenebeneinander", "platziereregister", "platziereuntereinander", "platziereunterformel", "platzierezusammengestellteliste", "pos", "posten", "produkt", "programm", "projekt", "punkt", "rechteck", "rechtecke", "rechtsbuendig", "referenz", "referieren", "roemischezahlen", "ruecksetztenbeschriftung", "schreibezurliste", "schreibezwischenliste", "seite", "seitenreferenz", "seitenummer", "settext", "spalte", "spatium", "spiegeln", "sprache", "startfarbe", "starthintergrund", "startinteraktionsmenue", "startkleinerdurchschuss", "startkomponente", "startkopf", "startlinksbuendig", "startmarginallinie", "startplatziereformel", "startpos", "startprodukt", "startprojekt", "startpublikation", "startrechtsbuendig", "startsprache", "starttextlinie", "startumgebung", "startumrahmt", "startzeile", "startzentriert", "startzu", "stelleabsaetzeein", "stelleabsatznummerierungein", "stelleabschnittsblockein", "stelleanordnenein", "stelleaufzaehlungenein", "stelleausrichtungein", "stelleausschnittein", "stellebeschreibungein", "stellebeschriftungein", "stellebilderunterschriftein", "stellebildunterschriftein", "stellebindestrichein", "stelleblankoein", "stelleblockein", "stelledrehenein", "stelleduennerumrissein", "stelleeinziehenein", "stelleengerein", "stellefarbeein", "stellefarbenein", "stellefeldein", "stellefelderin", "stellefliesstextein", "stelleformelnein", "stellefusszeileein", "stellefusszeilentextein", "stellegefuelltesrechteckein", "stellegefuelltezeileein", "stellegegenueberplatzierenein", "stellegleitobjekteein", "stellegleitobjektein", "stellehintergruendeein", "stellehintergrundein", "stelleinteraktionein", "stelleinteraktionsbalkenein", "stelleinteraktionsbildschirmein", "stelleinteraktionsmenueein", "stellekommentarein", "stellekopfzahlein", "stellekopfzeileein", "stellekopfzeilentextein", "stellelayoutein", "stellelinienbreiteein", "stellelisteein", "stellemarginallinieein", "stellenobenein", "stellepaletteein", "stellepapierformatein", "stelleplatziegeteiltegleitobjekt", "stellepositionierenein", "stellepostenein", "stelleprogrammein", "stellepufferein", "stellerechteckein", "stellereferenzierenein", "stelleregisterein", "stelleseitenkommentarein", "stelleseitennummerein", "stelleseitennummeriernungein", "stelleseitenuebergangein", "stellesortierenein", "stellespaltenein", "stellespatiumein", "stellespracheein", "stellesymbolsetein", "stellesynonymein", "stelletabellenein", "stelletabulatorein", "stelletextein", "stelletextobenein", "stelletexttexteein", "stelletextumrissein", "stelletextuntenein", "stelletipein", "stelletippenein", "stelletoleranzein", "stelleueberschriftein", "stelleueberschriftenein", "stelleumbruchein", "stelleumrahmtein", "stelleumrahmtetexteein", "stelleuntenein", "stelleunterseitennummerein", "stelleurlein", "stelleversalienein", "stellezeilenabstandein", "stellezeilenein", "stellezeilennumerierungein", "stellezitierenein", "stellezusammengestelltelisteein", "stellezwischenraumein", "stopfarbe", "stophintergrund", "stopinteraktionsmenue", "stopkleinerdurchschuss", "stopkomponente", "stopkopf", "stoplinksbuendig", "stopmarginallinie", "stopplatziereformel", "stoppos", "stopprodukt", "stopprojekt", "stoppublikation", "stoprechtsbuendig", "stopsprache", "stoptextlinie", "stopumgebung", "stopumrahmt", "stopzeile", "stopzentriert", "stopzu", "teilegleitobjekt", "textlinie", "textreferenz", "tief", "tiho", "tip", "tippedatei", "tippen", "tippepuffer", "ueber", "uebersetzten", "umgebung", "umrahmt", "unbekant", "verbergebloecke", "vergleichefarbengruppe", "vergleichepalette", "verwendeJSscript", "verwendeURL", "verwendebloecke", "verwendeexteresdokument", "verwendeexterneabbildung", "verwendeexternestonstueck", "verwendemodul", "verwendesymbole", "verwendeurl", "volleswort", "von", "waehlebloeckeaus", "wechselezumfliesstext", "wochentag", "wortrechts", "zeigedruck", "zeigeeinstellungen", "zeigefarbe", "zeigefarbengruppe", "zeigefliesstext", "zeigefliesstextumgebung", "zeigegitter", "zeigelayout", "zeigepalette", "zeigerahmen", "zeigestruts", "zeigeumbruch", "zentriert", "ziffern", "zu", "zurbox", "zurseite" },
["en"]={},
- ["fr"]={ "Caractere", "Caracteres", "Chiffresromains", "JOURSEMAINE", "MOIS", "MOT", "MOTS", "Mot", "Mots", "Numeros", "a", "adaptedisposition", "ajustechamp", "alaligne", "alapage", "aligneadroite", "aligneagauche", "aligneaumilieu", "arriereplan", "baha", "barrecouleur", "barreinteraction", "bas", "bouton", "boutonmenu", "boutonsinteraction", "cacheblocs", "caractere", "caracteres", "champ", "changepolicecorps", "chiffresromains", "clonechamp", "colonne", "commentaire", "comparegroupecouleur", "comparepalette", "completenumeropage", "completeregistre", "composant", "concernant", "convertitnumero", "copitchamp", "corrigeespaceblanc", "couleur", "couleurgrise", "dactylographier", "dans", "datecourante", "de", "definicaractere", "definit", "definitaccent", "definitbloc", "definitblocsection", "definitbuffer", "definitcalque", "definitchamp", "definitcommande", "definitconversion", "definitcouleur", "definitdactylo", "definitdemarrestoppe", "definitdescription", "definitdisposition", "definitenumeration", "definitenvironnementpolicecorps", "definitetiquette", "definitflottant", "definitformatreference", "definitgroupecouleur", "definithbox", "definitliste", "definitlisteimbriquee", "definitmakeup", "definitmarquage", "definitmenuinteraction", "definitpalette", "definitparagraphes", "definitpilechamp", "definitpolice", "definitpolicecorps", "definitprofil", "definitprogramme", "definitreference", "definitregistre", "definitrevetement", "definitsautdecolonne", "definitsautdepage", "definitsection", "definitsouschamp", "definitstyle", "definitstylepolice", "definitsymbole", "definitsymbolefigure", "definitsynonymepolice", "definitsynonymes", "definittabulation", "definittaillepapier", "definittete", "definittexte", "definittrametableau", "definittri", "definittype", "definitvide", "demarreJScode", "demarreJSpreamble", "demarreLUA", "demarreMP", "demarreMPclip", "demarreMPcode", "demarreMPdefinitions", "demarreMPdrawing", "demarreMPenvironment", "demarreMPextensions", "demarreMPinclusions", "demarreMPinitializations", "demarreMPpage", "demarreMPpositiongraphic", "demarreMPpositionmethod", "demarreMPrun", "demarrePARSEDXML", "demarreTABLE", "demarreTABLEbody", "demarreTABLEfoot", "demarreTABLEhead", "demarreTABLEnext", "demarreTC", "demarreTD", "demarreTDs", "demarreTEX", "demarreTEXpage", "demarreTH", "demarreTN", "demarreTR", "demarreTRs", "demarreTX", "demarreTY", "demarreXML", "demarrealign", "demarrealigneadroite", "demarrealigneagauche", "demarrealigneaumilieu", "demarrealignment", "demarreallmodes", "demarreappendices", "demarrearrangedpages", "demarrearriereplan", "demarreaside", "demarreattachment", "demarrebackmatter", "demarrebar", "demarrebbordermatrix", "demarrebitmapimage", "demarreblockquote", "demarrebodymatter", "demarrebordermatrix", "demarreboxedcolumns", "demarrebtxlabeltext", "demarrebtxrenderingdefinitions", "demarrebuffer", "demarrecases", "demarrecatcodetable", "demarrecenteraligned", "demarrechapter", "demarrecharacteralign", "demarrecheckedfences", "demarrechemical", "demarrechemicaltext", "demarreciter", "demarrecollect", "demarrecollecting", "demarrecolorintent", "demarrecoloronly", "demarrecolorset", "demarrecolumns", "demarrecolumnspan", "demarrecombination", "demarrecomment", "demarrecomposant", "demarrecontextcode", "demarrecontextdefinitioncode", "demarrecouleur", "demarrectxfunction", "demarrectxfunctiondefinition", "demarrecurrentcolor", "demarrecurrentlistentrywrapper", "demarredelimited", "demarredelimitedtext", "demarredisplaymath", "demarredmath", "demarredocument", "demarreeffect", "demarreelement", "demarreembeddedxtable", "demarreendnote", "demarreendofline", "demarreenvironement", "demarreexceptions", "demarreexpanded", "demarreexpandedcollect", "demarreextendedcatcodetable", "demarreexternalfigurecollection", "demarrefact", "demarrefigure", "demarrefiguretext", "demarrefittingpage", "demarrefixed", "demarrefloatcombination", "demarrefont", "demarrefontclass", "demarrefontsolution", "demarrefootnote", "demarreformula", "demarreformulas", "demarreframed", "demarreframedcell", "demarreframedcontent", "demarreframedrow", "demarreframedtable", "demarreframedtext", "demarrefrontmatter", "demarregraphictext", "demarregridsnapping", "demarregroupe", "demarrehanging", "demarrehbox", "demarrehboxestohbox", "demarrehboxregister", "demarreheadtext", "demarrehelptext", "demarrehiding", "demarrehighlight", "demarrehyphenation", "demarreimath", "demarreindentation", "demarreindentedtext", "demarreinteraction", "demarreinterface", "demarreintermezzotext", "demarreintertext", "demarreitemgroup", "demarreitemgroupcolumns", "demarreitemize", "demarreknockout", "demarrelabeltext", "demarrelayout", "demarrelegend", "demarreligne", "demarreligneregleetexte", "demarrelinealignment", "demarrelinecorrection", "demarrelinefiller", "demarrelinenumbering", "demarrelines", "demarrelinetable", "demarrelinetablebody", "demarrelinetablecell", "demarrelinetablehead", "demarrelocalfootnotes", "demarrelocalheadsetup", "demarrelocallinecorrection", "demarrelocalnotes", "demarrelocalsetups", "demarrelua", "demarreluacode", "demarreluaparameterset", "demarreluasetups", "demarremakeup", "demarremargereglee", "demarremarginblock", "demarremarkedcontent", "demarremathalignment", "demarremathcases", "demarremathlabeltext", "demarremathmatrix", "demarremathmode", "demarremathstyle", "demarrematrices", "demarrematrix", "demarremaxaligned", "demarremdformula", "demarremenuinteraction", "demarremiddlealigned", "demarremiddlemakeup", "demarremixedcolumns", "demarremode", "demarremodeset", "demarremodule", "demarremoduletestsection", "demarrempformula", "demarrenamedsection", "demarrenamedsubformulas", "demarrenarrow", "demarrenarrower", "demarrenegative", "demarrenicelyfilledbox", "demarrenointerference", "demarrenotallmodes", "demarrenotext", "demarrenotmode", "demarreoperatortext", "demarreopposite", "demarreoutputstream", "demarreoverlay", "demarreoverprint", "demarrepagecomment", "demarrepagefigure", "demarrepagegrid", "demarrepagegridspan", "demarrepagelayout", "demarrepagemakeup", "demarrepar", "demarreparagraph", "demarreparagraphs", "demarreparagraphscell", "demarreparbuilder", "demarrepart", "demarrepath", "demarreplacechemical", "demarreplacefigure", "demarreplaceflottant", "demarreplaceformule", "demarreplacegraphic", "demarreplaceintermezzo", "demarreplacelegend", "demarreplacepairedbox", "demarreplacetable", "demarrepositioning", "demarrepositionoverlay", "demarrepositive", "demarrepostponing", "demarreprefixtext", "demarreprocessassignmentcommand", "demarreprocessassignmentlist", "demarreprocesscommacommand", "demarreprocesscommalist", "demarreproduit", "demarreprojet", "demarreprotect", "demarreprotectedcolors", "demarrepublication", "demarrepunctuation", "demarrequotation", "demarrequote", "demarrerandomized", "demarrerandomseed", "demarrerawsetups", "demarrereadingfile", "demarrereferenceprefix", "demarreregime", "demarrereusableMPgraphic", "demarrescript", "demarresdformula", "demarresection", "demarresectionblock", "demarresectionblockenvironment", "demarresectionlevel", "demarresetups", "demarreshapebox", "demarreshift", "demarresidebar", "demarresimplecolumns", "demarrespecialitem", "demarrespeech", "demarrespformula", "demarresplitformula", "demarrespread", "demarrestandardmakeup", "demarrestartstop", "demarrestaticMPfigure", "demarrestaticMPgraphic", "demarrestrictinspectnextcharacter", "demarrestrut", "demarrestyle", "demarresubformulas", "demarresubject", "demarresubjectlevel", "demarresubsection", "demarresubsentence", "demarresubstack", "demarresubsubject", "demarresubsubsection", "demarresubsubsubject", "demarresubsubsubsection", "demarresubsubsubsubject", "demarresubsubsubsubsection", "demarresubsubsubsubsubject", "demarresuffixtext", "demarresymbolset", "demarretable", "demarretablehead", "demarretables", "demarretabletail", "demarretabletext", "demarretabulate", "demarretabulatehead", "demarretabulatetail", "demarretagged", "demarretaglabeltext", "demarretete", "demarretexcode", "demarretexdefinition", "demarretext", "demarretextbackground", "demarretextbackgroundmanual", "demarretextcolor", "demarretextcolorintent", "demarretextflow", "demarretextmakeup", "demarretitle", "demarretokens", "demarretransparent", "demarretypescript", "demarretypescriptcollection", "demarretyping", "demarreuniqueMPgraphic", "demarreuniqueMPpagegraphic", "demarreunittext", "demarreunpacked", "demarreusableMPgraphic", "demarreuseMPgraphic", "demarreusemathstyleparameter", "demarreusingbtxspecification", "demarreva", "demarrevbox", "demarrevboxregister", "demarrevboxtohbox", "demarrevboxtohboxseparator", "demarreviewerlayer", "demarrevtop", "demarrevtopregister", "demarrexcell", "demarrexcellgroup", "demarrexgroup", "demarrexmldisplayverbatim", "demarrexmlinlineverbatim", "demarrexmlraw", "demarrexmlsetups", "demarrexrow", "demarrexrowgroup", "demarrextable", "demarrextablebody", "demarrextablefoot", "demarrextablehead", "demarrextablenext", "determinecaracteristiqueliste", "determinecaracteristiquesregistre", "determinenumerotete", "echelle", "ecran", "ecritdansliste", "ecritentreliste", "element", "elements", "environement", "espace", "espacefixe", "espacesfixes", "etire", "faitreference", "fichierdactylo", "figureexterne", "gardeblocs", "grille", "haut", "inconnu", "installelangue", "joursemaine", "langue", "langueprincipale", "largeurligne", "ligneh", "lignenoire", "ligneregleetexte", "lignesnoires", "llongueurliste", "marquage", "marquepage", "mathematique", "menuinteraction", "mois", "montrecadre", "montrecouleur", "montredisposition", "montreedition", "montreenvironnementpolicecorps", "montregrille", "montregroupecouleur", "montrejeusymboles", "montremakeup", "montrepalette", "montrepolicecorps", "montrereglages", "montrestruts", "motdroit", "numeroformule", "numeropage", "numeros", "numerotete", "numerotetecourant", "obtientmarquage", "oriente", "periodes", "pilechamp", "placecoteacote", "placeflottant", "placeformule", "placelesunsaudessusdesautres", "placeliste", "placelisteinmbriquee", "placemarquespages", "placenotespdp", "placenotespdplocales", "placenumeropage", "placenumerotete", "placeregistre", "placesousformule", "placesurgrille", "placetextetete", "prendbuffer", "produit", "programme", "projet", "qqpart", "razmarquage", "referencepage", "referencetexte", "reflete", "reglealignement", "reglearrangement", "reglearriereplan", "reglearriereplans", "reglebarreinteraction", "reglebloc", "regleblocsection", "reglebuffer", "reglecapitales", "reglechamp", "reglechamps", "regleclipping", "reglecolonnes", "reglecommentaire", "reglecommentairepage", "reglecompoetroite", "reglecomposeenalinea", "reglecouleur", "reglecouleurs", "regledactylo", "regledemarrestoppe", "regledisposition", "regleecraninteraction", "regleelements", "regleencadre", "regleentete", "regleenumerations", "regleepaisseurligne", "regleespaceblanc", "regleespacement", "regleespacementinterligne", "regleflottant", "regleflottants", "regleformulaires", "regleformules", "reglegroupeselements", "regleinf", "regleinteraction", "regleintitule", "regleintitules", "reglejeusymboles", "reglelangue", "reglelignes", "reglelignesnoires", "reglelignesreglestexte", "regleliste", "reglelisteimbriquee", "reglemakeup", "reglemargereglee", "reglemarquage", "reglemarquagehyphenation", "reglemenuinteraction", "reglenumeropage", "reglenumerotationligne", "reglenumerotationpage", "reglenumerotationparagraphe", "reglenumerotete", "regleoriente", "reglepalette", "reglepapier", "regleparagraphes", "reglepdp", "regleplacementopposition", "reglepolicecorps", "reglepositionnement", "regleprogrammes", "reglereferencage", "regleregistre", "regleremplitligne", "regleremplitlignesreglees", "regleseparationflottant", "reglesousnumeropage", "reglesup", "reglesynonymes", "regletableaux", "regletabulation", "regletaillepapier", "regletete", "regletetes", "regletexte", "regletextesentete", "regletextesinf", "regletextespdp", "regletextessup", "regletextestexte", "regletolerance", "regletraitsfins", "regletransitionspage", "regletri", "regletype", "regleurl", "remplitligne", "remplitlignesreglees", "remplittexte", "sansespace", "sanslignesenteteetpdp", "sanslignessupetinf", "selectionneblocs", "separeflottant", "settext", "sousnumeropage", "stoppeJScode", "stoppeJSpreamble", "stoppeLUA", "stoppeMP", "stoppeMPclip", "stoppeMPcode", "stoppeMPdefinitions", "stoppeMPdrawing", "stoppeMPenvironment", "stoppeMPextensions", "stoppeMPinclusions", "stoppeMPinitializations", "stoppeMPpage", "stoppeMPpositiongraphic", "stoppeMPpositionmethod", "stoppeMPrun", "stoppePARSEDXML", "stoppeTABLE", "stoppeTABLEbody", "stoppeTABLEfoot", "stoppeTABLEhead", "stoppeTABLEnext", "stoppeTC", "stoppeTD", "stoppeTDs", "stoppeTEX", "stoppeTEXpage", "stoppeTH", "stoppeTN", "stoppeTR", "stoppeTRs", "stoppeTX", "stoppeTY", "stoppeXML", "stoppealign", "stoppealigneadroite", "stoppealigneagauche", "stoppealigneaumilieu", "stoppealignment", "stoppeallmodes", "stoppeappendices", "stoppearrangedpages", "stoppearriereplan", "stoppeaside", "stoppeattachment", "stoppebackmatter", "stoppebar", "stoppebbordermatrix", "stoppebitmapimage", "stoppeblockquote", "stoppebodymatter", "stoppebordermatrix", "stoppeboxedcolumns", "stoppebtxlabeltext", "stoppebtxrenderingdefinitions", "stoppebuffer", "stoppecases", "stoppecatcodetable", "stoppecenteraligned", "stoppechapter", "stoppecharacteralign", "stoppecheckedfences", "stoppechemical", "stoppechemicaltext", "stoppecollect", "stoppecollecting", "stoppecolorintent", "stoppecoloronly", "stoppecolorset", "stoppecolumns", "stoppecolumnspan", "stoppecombination", "stoppecomment", "stoppecomposant", "stoppecontextcode", "stoppecontextdefinitioncode", "stoppecouleur", "stoppectxfunction", "stoppectxfunctiondefinition", "stoppecurrentcolor", "stoppecurrentlistentrywrapper", "stoppedelimited", "stoppedelimitedtext", "stoppedisplaymath", "stoppedmath", "stoppedocument", "stoppeeffect", "stoppeelement", "stoppeembeddedxtable", "stoppeendnote", "stoppeendofline", "stoppeenvironement", "stoppeexceptions", "stoppeexpanded", "stoppeexpandedcollect", "stoppeextendedcatcodetable", "stoppeexternalfigurecollection", "stoppefact", "stoppefigure", "stoppefiguretext", "stoppefittingpage", "stoppefixed", "stoppefloatcombination", "stoppefont", "stoppefontclass", "stoppefontsolution", "stoppefootnote", "stoppeformula", "stoppeformulas", "stoppeframed", "stoppeframedcell", "stoppeframedcontent", "stoppeframedrow", "stoppeframedtable", "stoppeframedtext", "stoppefrontmatter", "stoppegraphictext", "stoppegridsnapping", "stoppegroupe", "stoppehanging", "stoppehbox", "stoppehboxestohbox", "stoppehboxregister", "stoppeheadtext", "stoppehelptext", "stoppehiding", "stoppehighlight", "stoppehyphenation", "stoppeimath", "stoppeindentation", "stoppeindentedtext", "stoppeinteraction", "stoppeinterface", "stoppeintermezzotext", "stoppeintertext", "stoppeitemgroup", "stoppeitemgroupcolumns", "stoppeitemize", "stoppeknockout", "stoppelabeltext", "stoppelayout", "stoppelegend", "stoppeligne", "stoppeligneregleetexte", "stoppelinealignment", "stoppelinecorrection", "stoppelinefiller", "stoppelinenumbering", "stoppelines", "stoppelinetable", "stoppelinetablebody", "stoppelinetablecell", "stoppelinetablehead", "stoppelocalfootnotes", "stoppelocalheadsetup", "stoppelocallinecorrection", "stoppelocalnotes", "stoppelocalsetups", "stoppelua", "stoppeluacode", "stoppeluaparameterset", "stoppeluasetups", "stoppemakeup", "stoppemargereglee", "stoppemarginblock", "stoppemarkedcontent", "stoppemathalignment", "stoppemathcases", "stoppemathlabeltext", "stoppemathmatrix", "stoppemathmode", "stoppemathstyle", "stoppematrices", "stoppematrix", "stoppemaxaligned", "stoppemdformula", "stoppemenuinteraction", "stoppemiddlealigned", "stoppemiddlemakeup", "stoppemixedcolumns", "stoppemode", "stoppemodeset", "stoppemodule", "stoppemoduletestsection", "stoppempformula", "stoppenamedsection", "stoppenamedsubformulas", "stoppenarrow", "stoppenarrower", "stoppenegative", "stoppenicelyfilledbox", "stoppenointerference", "stoppenotallmodes", "stoppenotext", "stoppenotmode", "stoppeoperatortext", "stoppeopposite", "stoppeoutputstream", "stoppeoverlay", "stoppeoverprint", "stoppepagecomment", "stoppepagefigure", "stoppepagegrid", "stoppepagegridspan", "stoppepagelayout", "stoppepagemakeup", "stoppepar", "stoppeparagraph", "stoppeparagraphs", "stoppeparagraphscell", "stoppeparbuilder", "stoppepart", "stoppepath", "stoppeplacechemical", "stoppeplacefigure", "stoppeplaceflottant", "stoppeplaceformule", "stoppeplacegraphic", "stoppeplaceintermezzo", "stoppeplacelegend", "stoppeplacepairedbox", "stoppeplacetable", "stoppepositioning", "stoppepositionoverlay", "stoppepositive", "stoppepostponing", "stoppeprefixtext", "stoppeprocessassignmentcommand", "stoppeprocessassignmentlist", "stoppeprocesscommacommand", "stoppeprocesscommalist", "stoppeproduit", "stoppeprojet", "stoppeprotect", "stoppeprotectedcolors", "stoppepublication", "stoppepunctuation", "stoppequotation", "stoppequote", "stopperandomized", "stopperandomseed", "stopperawsetups", "stoppereadingfile", "stoppereferenceprefix", "stopperegime", "stoppereusableMPgraphic", "stoppescript", "stoppesdformula", "stoppesection", "stoppesectionblock", "stoppesectionblockenvironment", "stoppesectionlevel", "stoppesetups", "stoppeshapebox", "stoppeshift", "stoppesidebar", "stoppesimplecolumns", "stoppespecialitem", "stoppespeech", "stoppespformula", "stoppesplitformula", "stoppespread", "stoppestandardmakeup", "stoppestartstop", "stoppestaticMPfigure", "stoppestaticMPgraphic", "stoppestrictinspectnextcharacter", "stoppestrut", "stoppestyle", "stoppesubformulas", "stoppesubject", "stoppesubjectlevel", "stoppesubsection", "stoppesubsentence", "stoppesubstack", "stoppesubsubject", "stoppesubsubsection", "stoppesubsubsubject", "stoppesubsubsubsection", "stoppesubsubsubsubject", "stoppesubsubsubsubsection", "stoppesubsubsubsubsubject", "stoppesuffixtext", "stoppesymbolset", "stoppetable", "stoppetablehead", "stoppetables", "stoppetabletail", "stoppetabletext", "stoppetabulate", "stoppetabulatehead", "stoppetabulatetail", "stoppetagged", "stoppetaglabeltext", "stoppetete", "stoppetexcode", "stoppetexdefinition", "stoppetext", "stoppetextbackground", "stoppetextbackgroundmanual", "stoppetextcolor", "stoppetextcolorintent", "stoppetextflow", "stoppetextmakeup", "stoppetitle", "stoppetokens", "stoppetransparent", "stoppetypescript", "stoppetypescriptcollection", "stoppetyping", "stoppeuniqueMPgraphic", "stoppeuniqueMPpagegraphic", "stoppeunittext", "stoppeunpacked", "stoppeusableMPgraphic", "stoppeuseMPgraphic", "stoppeusemathstyleparameter", "stoppeusingbtxspecification", "stoppeva", "stoppevbox", "stoppevboxregister", "stoppevboxtohbox", "stoppevboxtohboxseparator", "stoppeviewerlayer", "stoppevtop", "stoppevtopregister", "stoppexcell", "stoppexcellgroup", "stoppexgroup", "stoppexmldisplayverbatim", "stoppexmlinlineverbatim", "stoppexmlraw", "stoppexmlsetups", "stoppexrow", "stoppexrowgroup", "stoppextable", "stoppextablebody", "stoppextablefoot", "stoppextablehead", "stoppextablenext", "symbole", "tapebuffer", "textenotepdp", "traduire", "traiteblocs", "traitfin", "traitsfins", "uneligne", "utiliseJSscripts", "utiliseURL", "utiliseblocs", "utilisechemin", "utilisedocumentexterne", "utilisefigureexterne", "utilisemodule", "utilisepsiteaudioexterne", "utilisesymboles", "utiliseurl", "va", "vaalaboite", "vaalapage", "vaenbas", "valeurcouleur", "vide" },
- ["it"]={ "GIORNOSETTIMANA", "Lettera", "Lettere", "MESE", "Numeri", "Numeriromani", "PAROLA", "PAROLE", "Parola", "Parole", "adattacampo", "adattalayout", "al", "allineacentro", "allineadestra", "allineasinistra", "ambiente", "ap", "apagina", "barracolori", "barrainterazione", "cambiaafontdeltesto", "campi", "capello", "chim", "circondato", "clonacampo", "colonna", "colore", "coloregrigio", "commento", "componenet", "confrontagruppocolori", "confrontatavolozza", "convertinumero", "copiacampo", "correggispaziobianco", "da", "daqualcheparte", "data", "datadioggi", "definisci", "definisciaccento", "definisciambientefontdeltesto", "definisciblocco", "definiscibloccosezione", "definiscibuffer", "definiscicampo", "definiscicapoversi", "definiscicarattere", "definiscicolore", "definiscicomando", "definisciconversione", "definiscidescrizione", "definiscidimensionicarta", "definiscielenco", "definiscielencocombinato", "definiscienumerazione", "definiscietichetta", "definiscifigurasimbolo", "definiscifont", "definiscifontdeltesto", "definisciformatoriferimento", "definiscigruppocolori", "definiscihbox", "definisciincorniciato", "definisciiniziatermina", "definiscilayout", "definiscimakeup", "definiscimarcatura", "definiscimenuinterazione", "definiscimodellotabella", "definiscioggettomobile", "definisciordinamento", "definisciprofilo", "definisciprogramma", "definisciregistro", "definisciriferimento", "definiscisezione", "definiscisimbolo", "definiscisinonimi", "definiscisinonimofont", "definiscisottocampo", "definiscisovrapposizione", "definiscistackcampi", "definiscistile", "definiscistilefont", "definiscitabulato", "definiscitavolozza", "definiscitesta", "definiscitesto", "definiscitestoincorniciato", "definiscitype", "definiscityping", "determinacaratteristicheregistro", "determinacarattersticheelenco", "determinanumerotesta", "elaborablocchi", "elementi", "elemento", "figuraesterna", "giornosettimana", "griglia", "ignoto", "impostaallineamento", "impostaampiezzariga", "impostabarrainterazione", "impostablocco", "impostabloccosezione", "impostabuffer", "impostacampi", "impostacampo", "impostacapoversi", "impostacaption", "impostacaptions", "impostacima", "impostaclippling", "impostacolonne", "impostacolore", "impostacolori", "impostacommento", "impostacommentopagina", "impostadimensionicarta", "impostaelementi", "impostaelencazioni", "impostaelenco", "impostaelencocombinato", "impostaenumerazioni", "impostafondo", "impostafontdeltesto", "impostaforms", "impostaformule", "impostaincorniciato", "impostainiziatermina", "impostainstestazione", "impostainterazione", "impostainterlinea", "impostalayout", "impostalineemargine", "impostalineenere", "impostalineeriempimento", "impostalineesottili", "impostalineetesto", "impostalingua", "impostamaiuscole", "impostamakeup", "impostamarcatura", "impostamenuinterazione", "impostamenzione", "impostanumerazionecapoversi", "impostanumerazionepagina", "impostanumerazionerighe", "impostanumeropagina", "impostanumerosottopagina", "impostanumerotesta", "impostaoggettimobili", "impostaoggettomobile", "impostaordinamento", "impostaparranging", "impostapdp", "impostapiustretto", "impostaposizionamento", "impostaposizionamentoopposti", "impostaprogrammi", "impostaregistro", "impostarientro", "impostariferimento", "impostarighe", "impostarigheriempimento", "impostarigovuoto", "impostarotazione", "impostaschermointerazione", "impostasegnosillabazione", "impostasetsimboli", "impostasfondi", "impostasfondo", "impostasinonimi", "impostaspaziatura", "impostaspaziobianco", "impostaspezzamentooggettomobile", "impostatabelle", "impostatabulato", "impostatavolozza", "impostatesta", "impostateste", "impostatesticima", "impostatestifondo", "impostatestiincorniciati", "impostatestiintestazioni", "impostatestipdp", "impostatesto", "impostatestotesti", "impostatolleranza", "impostatransizionepagina", "impostatype", "impostatyping", "impostaurl", "incorniciato", "iniziaJScode", "iniziaJSpreamble", "iniziaLUA", "iniziaMP", "iniziaMPclip", "iniziaMPcode", "iniziaMPdefinitions", "iniziaMPdrawing", "iniziaMPenvironment", "iniziaMPextensions", "iniziaMPinclusions", "iniziaMPinitializations", "iniziaMPpage", "iniziaMPpositiongraphic", "iniziaMPpositionmethod", "iniziaMPrun", "iniziaPARSEDXML", "iniziaTABLE", "iniziaTABLEbody", "iniziaTABLEfoot", "iniziaTABLEhead", "iniziaTABLEnext", "iniziaTC", "iniziaTD", "iniziaTDs", "iniziaTEX", "iniziaTEXpage", "iniziaTH", "iniziaTN", "iniziaTR", "iniziaTRs", "iniziaTX", "iniziaTY", "iniziaXML", "iniziaalign", "iniziaalignment", "iniziaallineacentro", "iniziaallineadestra", "iniziaallineasinistra", "iniziaallmodes", "iniziaambiente", "iniziaappendices", "iniziaarrangedpages", "iniziaaside", "iniziaattachment", "iniziabackmatter", "iniziabar", "iniziabbordermatrix", "iniziabitmapimage", "iniziablockquote", "iniziabodymatter", "iniziabordermatrix", "iniziaboxedcolumns", "iniziabtxlabeltext", "iniziabtxrenderingdefinitions", "iniziabuffer", "iniziacases", "iniziacatcodetable", "iniziacenteraligned", "iniziachapter", "iniziacharacteralign", "iniziacheckedfences", "iniziachemical", "iniziachemicaltext", "iniziacollect", "iniziacollecting", "iniziacolore", "iniziacolorintent", "iniziacoloronly", "iniziacolorset", "iniziacolumns", "iniziacolumnspan", "iniziacombination", "iniziacomment", "iniziacomponenet", "iniziacontextcode", "iniziacontextdefinitioncode", "iniziactxfunction", "iniziactxfunctiondefinition", "iniziacurrentcolor", "iniziacurrentlistentrywrapper", "iniziadelimited", "iniziadelimitedtext", "iniziadisplaymath", "iniziadmath", "iniziadocument", "iniziaeffect", "iniziaelement", "iniziaelemento", "iniziaembeddedxtable", "iniziaendnote", "iniziaendofline", "iniziaexceptions", "iniziaexpanded", "iniziaexpandedcollect", "iniziaextendedcatcodetable", "iniziaexternalfigurecollection", "iniziafact", "iniziafigure", "iniziafiguretext", "iniziafittingpage", "iniziafixed", "iniziafloatcombination", "iniziafont", "iniziafontclass", "iniziafontsolution", "iniziafootnote", "iniziaformula", "iniziaformulas", "iniziaframedcell", "iniziaframedcontent", "iniziaframedrow", "iniziaframedtable", "iniziaframedtext", "iniziafrontmatter", "iniziagraphictext", "iniziagridsnapping", "iniziahanging", "iniziahbox", "iniziahboxestohbox", "iniziahboxregister", "iniziaheadtext", "iniziahelptext", "iniziahiding", "iniziahighlight", "iniziahyphenation", "iniziaimath", "iniziaimpaccato", "iniziaincorniciato", "iniziaindentation", "iniziaindentedtext", "iniziainteraction", "iniziainterface", "iniziaintermezzotext", "iniziaintertext", "iniziaitemgroup", "iniziaitemgroupcolumns", "iniziaitemize", "iniziaknockout", "inizialabeltext", "inizialayout", "inizialegend", "inizialinealignment", "inizialineamargine", "inizialineatesto", "inizialinecorrection", "inizialinefiller", "inizialinenumbering", "inizialines", "inizialinetable", "inizialinetablebody", "inizialinetablecell", "inizialinetablehead", "inizialocalfootnotes", "inizialocalheadsetup", "inizialocallinecorrection", "inizialocalnotes", "inizialocalsetups", "inizialua", "inizialuacode", "inizialuaparameterset", "inizialuasetups", "iniziamakeup", "iniziamarginblock", "iniziamarkedcontent", "iniziamathalignment", "iniziamathcases", "iniziamathlabeltext", "iniziamathmatrix", "iniziamathmode", "iniziamathstyle", "iniziamatrices", "iniziamatrix", "iniziamaxaligned", "iniziamdformula", "iniziamenuinterattivo", "iniziamettiformula", "iniziamiddlealigned", "iniziamiddlemakeup", "iniziamixedcolumns", "iniziamode", "iniziamodeset", "iniziamodule", "iniziamoduletestsection", "iniziampformula", "inizianamedsection", "inizianamedsubformulas", "inizianarrow", "inizianarrower", "inizianegative", "inizianicelyfilledbox", "inizianointerference", "inizianotallmodes", "inizianotext", "inizianotmode", "iniziaoperatortext", "iniziaopposite", "iniziaoutputstream", "iniziaoverlay", "iniziaoverprint", "iniziapagecomment", "iniziapagefigure", "iniziapagegrid", "iniziapagegridspan", "iniziapagelayout", "iniziapagemakeup", "iniziapar", "iniziaparagraph", "iniziaparagraphs", "iniziaparagraphscell", "iniziaparbuilder", "iniziapart", "iniziapath", "iniziaplacechemical", "iniziaplacefigure", "iniziaplacefloat", "iniziaplacegraphic", "iniziaplaceintermezzo", "iniziaplacelegend", "iniziaplacepairedbox", "iniziaplacetable", "iniziapositioning", "iniziapositionoverlay", "iniziapositive", "iniziapostponing", "iniziaprefixtext", "iniziaprocessassignmentcommand", "iniziaprocessassignmentlist", "iniziaprocesscommacommand", "iniziaprocesscommalist", "iniziaprodotto", "iniziaprogetto", "iniziaprotect", "iniziaprotectedcolors", "iniziapubblicazione", "iniziapunctuation", "iniziaquotation", "iniziaquote", "iniziarandomized", "iniziarandomseed", "iniziarawsetups", "iniziareadingfile", "iniziareferenceprefix", "iniziaregime", "iniziareusableMPgraphic", "iniziariga", "iniziascript", "iniziasdformula", "iniziasection", "iniziasectionblock", "iniziasectionblockenvironment", "iniziasectionlevel", "iniziasetups", "iniziasfondo", "iniziashapebox", "iniziashift", "iniziasidebar", "iniziasimplecolumns", "iniziaspecialitem", "iniziaspeech", "iniziaspformula", "iniziasplitformula", "iniziaspread", "iniziastandardmakeup", "iniziastartstop", "iniziastaticMPfigure", "iniziastaticMPgraphic", "iniziastrictinspectnextcharacter", "iniziastrut", "iniziastyle", "iniziasubformulas", "iniziasubject", "iniziasubjectlevel", "iniziasubsection", "iniziasubsentence", "iniziasubstack", "iniziasubsubject", "iniziasubsubsection", "iniziasubsubsubject", "iniziasubsubsubsection", "iniziasubsubsubsubject", "iniziasubsubsubsubsection", "iniziasubsubsubsubsubject", "iniziasuffixtext", "iniziasymbolset", "iniziatable", "iniziatablehead", "iniziatables", "iniziatabletail", "iniziatabletext", "iniziatabulate", "iniziatabulatehead", "iniziatabulatetail", "iniziatagged", "iniziataglabeltext", "iniziatesta", "iniziatexcode", "iniziatexdefinition", "iniziatext", "iniziatextbackground", "iniziatextbackgroundmanual", "iniziatextcolor", "iniziatextcolorintent", "iniziatextflow", "iniziatextmakeup", "iniziatitle", "iniziatokens", "iniziatransparent", "iniziatypescript", "iniziatypescriptcollection", "iniziatyping", "iniziauniqueMPgraphic", "iniziauniqueMPpagegraphic", "iniziaunittext", "iniziaunpacked", "iniziausableMPgraphic", "iniziauseMPgraphic", "iniziausemathstyleparameter", "iniziausingbtxspecification", "iniziavaia", "iniziavbox", "iniziavboxregister", "iniziavboxtohbox", "iniziavboxtohboxseparator", "iniziaviewerlayer", "iniziavtop", "iniziavtopregister", "iniziaxcell", "iniziaxcellgroup", "iniziaxgroup", "iniziaxmldisplayverbatim", "iniziaxmlinlineverbatim", "iniziaxmlraw", "iniziaxmlsetups", "iniziaxrow", "iniziaxrowgroup", "iniziaxtable", "iniziaxtablebody", "iniziaxtablefoot", "iniziaxtablehead", "iniziaxtablenext", "inriga", "installalingua", "intorno", "lettera", "lettere", "lineanera", "lineasottile", "lineatesto", "lineenere", "lineeriempimento", "lineesottili", "lingua", "linguaprincipale", "lunghezzaelenco", "marcatura", "matematica", "menuinterattivo", "mese", "mettielenco", "mettielencocombinato", "mettifiancoafianco", "mettiformula", "mettiingriglia", "mettinotepdp", "mettinotepdplocali", "mettinumeropagina", "mettiregistro", "mettisegnalibro", "mettisottoformula", "mettiunosullaltro", "mostraambientefontdeltesto", "mostracolore", "mostracornice", "mostrafontdeltesto", "mostragriglia", "mostragruppocolori", "mostraimpostazioni", "mostralyout", "mostramakeup", "mostrasetsimboli", "mostrastampa", "mostrastruts", "mostratavolozza", "nascondiblocchi", "nientelineecimafondo", "nientelineintestazionepdp", "nientespazio", "nota", "numeri", "numeriromani", "numeroformula", "numeropagina", "numeropaginacompleto", "numerotesta", "numerotestacorrente", "pagina", "paroladestra", "ped", "pedap", "perlungo", "posizionanumerotesta", "posizionatestotesta", "posizione", "prendibuffer", "prendimarcatura", "prodotto", "progetto", "programma", "pulsante", "pulsantemenu", "pulsantinterazione", "punti", "qualcheriga", "reimpostamarcatura", "rif", "riferimento", "riferimentopagina", "riferimentotesto", "riflessione", "rigariempimento", "rigovuoto", "ruota", "scala", "schermo", "scrividentroelenco", "scriviinelenco", "segnalibro", "selezionablocchi", "settext", "sfondo", "simbolo", "spazifissi", "spazio", "spaziofisso", "spessoreriga", "spezzaoggettomobile", "stackcampi", "stirato", "terminaJScode", "terminaJSpreamble", "terminaLUA", "terminaMP", "terminaMPclip", "terminaMPcode", "terminaMPdefinitions", "terminaMPdrawing", "terminaMPenvironment", "terminaMPextensions", "terminaMPinclusions", "terminaMPinitializations", "terminaMPpage", "terminaMPpositiongraphic", "terminaMPpositionmethod", "terminaMPrun", "terminaPARSEDXML", "terminaTABLE", "terminaTABLEbody", "terminaTABLEfoot", "terminaTABLEhead", "terminaTABLEnext", "terminaTC", "terminaTD", "terminaTDs", "terminaTEX", "terminaTEXpage", "terminaTH", "terminaTN", "terminaTR", "terminaTRs", "terminaTX", "terminaTY", "terminaXML", "terminaalign", "terminaalignment", "terminaallineacentro", "terminaallineadestra", "terminaallineasinistra", "terminaallmodes", "terminaambiente", "terminaappendices", "terminaarrangedpages", "terminaaside", "terminaattachment", "terminabackmatter", "terminabar", "terminabbordermatrix", "terminabitmapimage", "terminablockquote", "terminabodymatter", "terminabordermatrix", "terminaboxedcolumns", "terminabtxlabeltext", "terminabtxrenderingdefinitions", "terminabuffer", "terminacases", "terminacatcodetable", "terminacenteraligned", "terminachapter", "terminacharacteralign", "terminacheckedfences", "terminachemical", "terminachemicaltext", "terminacollect", "terminacollecting", "terminacolore", "terminacolorintent", "terminacoloronly", "terminacolorset", "terminacolumns", "terminacolumnspan", "terminacombination", "terminacomment", "terminacomponenet", "terminacontextcode", "terminacontextdefinitioncode", "terminactxfunction", "terminactxfunctiondefinition", "terminacurrentcolor", "terminacurrentlistentrywrapper", "terminadelimited", "terminadelimitedtext", "terminadisplaymath", "terminadmath", "terminadocument", "terminaeffect", "terminaelement", "terminaelemento", "terminaembeddedxtable", "terminaendnote", "terminaendofline", "terminaexceptions", "terminaexpanded", "terminaexpandedcollect", "terminaextendedcatcodetable", "terminaexternalfigurecollection", "terminafact", "terminafigure", "terminafiguretext", "terminafittingpage", "terminafixed", "terminafloatcombination", "terminafont", "terminafontclass", "terminafontsolution", "terminafootnote", "terminaformula", "terminaformulas", "terminaframedcell", "terminaframedcontent", "terminaframedrow", "terminaframedtable", "terminaframedtext", "terminafrontmatter", "terminagraphictext", "terminagridsnapping", "terminahanging", "terminahbox", "terminahboxestohbox", "terminahboxregister", "terminaheadtext", "terminahelptext", "terminahiding", "terminahighlight", "terminahyphenation", "terminaimath", "terminaimpaccato", "terminaincorniciato", "terminaindentation", "terminaindentedtext", "terminainteraction", "terminainterface", "terminaintermezzotext", "terminaintertext", "terminaitemgroup", "terminaitemgroupcolumns", "terminaitemize", "terminaknockout", "terminalabeltext", "terminalayout", "terminalegend", "terminalinealignment", "terminalineamargine", "terminalineatesto", "terminalinecorrection", "terminalinefiller", "terminalinenumbering", "terminalines", "terminalinetable", "terminalinetablebody", "terminalinetablecell", "terminalinetablehead", "terminalocalfootnotes", "terminalocalheadsetup", "terminalocallinecorrection", "terminalocalnotes", "terminalocalsetups", "terminalua", "terminaluacode", "terminaluaparameterset", "terminaluasetups", "terminamakeup", "terminamarginblock", "terminamarkedcontent", "terminamathalignment", "terminamathcases", "terminamathlabeltext", "terminamathmatrix", "terminamathmode", "terminamathstyle", "terminamatrices", "terminamatrix", "terminamaxaligned", "terminamdformula", "terminamenuinterattivo", "terminamettiformula", "terminamiddlealigned", "terminamiddlemakeup", "terminamixedcolumns", "terminamode", "terminamodeset", "terminamodule", "terminamoduletestsection", "terminampformula", "terminanamedsection", "terminanamedsubformulas", "terminanarrow", "terminanarrower", "terminanegative", "terminanicelyfilledbox", "terminanointerference", "terminanotallmodes", "terminanotext", "terminanotmode", "terminaoperatortext", "terminaopposite", "terminaoutputstream", "terminaoverlay", "terminaoverprint", "terminapagecomment", "terminapagefigure", "terminapagegrid", "terminapagegridspan", "terminapagelayout", "terminapagemakeup", "terminapar", "terminaparagraph", "terminaparagraphs", "terminaparagraphscell", "terminaparbuilder", "terminapart", "terminapath", "terminaplacechemical", "terminaplacefigure", "terminaplacefloat", "terminaplacegraphic", "terminaplaceintermezzo", "terminaplacelegend", "terminaplacepairedbox", "terminaplacetable", "terminapositioning", "terminapositionoverlay", "terminapositive", "terminapostponing", "terminaprefixtext", "terminaprocessassignmentcommand", "terminaprocessassignmentlist", "terminaprocesscommacommand", "terminaprocesscommalist", "terminaprodotto", "terminaprogetto", "terminaprotect", "terminaprotectedcolors", "terminapubblicazione", "terminapunctuation", "terminaquotation", "terminaquote", "terminarandomized", "terminarandomseed", "terminarawsetups", "terminareadingfile", "terminareferenceprefix", "terminaregime", "terminareusableMPgraphic", "terminariga", "terminascript", "terminasdformula", "terminasection", "terminasectionblock", "terminasectionblockenvironment", "terminasectionlevel", "terminasetups", "terminasfondo", "terminashapebox", "terminashift", "terminasidebar", "terminasimplecolumns", "terminaspecialitem", "terminaspeech", "terminaspformula", "terminasplitformula", "terminaspread", "terminastandardmakeup", "terminastartstop", "terminastaticMPfigure", "terminastaticMPgraphic", "terminastrictinspectnextcharacter", "terminastrut", "terminastyle", "terminasubformulas", "terminasubject", "terminasubjectlevel", "terminasubsection", "terminasubsentence", "terminasubstack", "terminasubsubject", "terminasubsubsection", "terminasubsubsubject", "terminasubsubsubsection", "terminasubsubsubsubject", "terminasubsubsubsubsection", "terminasubsubsubsubsubject", "terminasuffixtext", "terminasymbolset", "terminatable", "terminatablehead", "terminatables", "terminatabletail", "terminatabletext", "terminatabulate", "terminatabulatehead", "terminatabulatetail", "terminatagged", "terminataglabeltext", "terminatesta", "terminatexcode", "terminatexdefinition", "terminatext", "terminatextbackground", "terminatextbackgroundmanual", "terminatextcolor", "terminatextcolorintent", "terminatextflow", "terminatextmakeup", "terminatitle", "terminatokens", "terminatransparent", "terminatypescript", "terminatypescriptcollection", "terminatyping", "terminauniqueMPgraphic", "terminauniqueMPpagegraphic", "terminaunittext", "terminaunpacked", "terminausableMPgraphic", "terminauseMPgraphic", "terminausemathstyleparameter", "terminausingbtxspecification", "terminavaia", "terminavbox", "terminavboxregister", "terminavboxtohbox", "terminavboxtohboxseparator", "terminaviewerlayer", "terminavtop", "terminavtopregister", "terminaxcell", "terminaxcellgroup", "terminaxgroup", "terminaxmldisplayverbatim", "terminaxmlinlineverbatim", "terminaxmlraw", "terminaxmlsetups", "terminaxrow", "terminaxrowgroup", "terminaxtable", "terminaxtablebody", "terminaxtablefoot", "terminaxtablehead", "terminaxtablenext", "testonotapdp", "testoriempimento", "tieniblocchi", "traduci", "usaJSscripts", "usaURL", "usablocco", "usacartella", "usacolonnasonoraesterna", "usadocumentoesterno", "usafiguraesterna", "usamodulo", "usasimboli", "usaurl", "vaia", "vaiabox", "vaiapagina", "vaigiu", "valorecolore", "versione" },
- ["nl"]={ "Cijfers", "Kap", "Letter", "Letters", "MAAND", "Romeins", "WEEKDAG", "WOORD", "WOORDEN", "Woord", "Woorden", "achtergrond", "bepaalkopnummer", "bepaallijstkenmerken", "bepaalregisterkenmerken", "bewaarbuffer", "blanko", "blokje", "blokjes", "cijfers", "converteernummer", "copieerveld", "corrigeerwitruimte", "datum", "definieer", "definieeraccent", "definieeralineas", "definieerblok", "definieerbuffer", "definieercombinatie", "definieercommando", "definieerconversie", "definieerfiguursymbool", "definieerfont", "definieerfontstijl", "definieerfontsynoniem", "definieerhbox", "definieeringesprongentext", "definieerinteractiemenu", "definieeritemgroep", "definieerkadertekst", "definieerkarakter", "definieerkleur", "definieerkleurgroep", "definieerkolomovergang", "definieerkop", "definieerkorps", "definieerkorpsomgeving", "definieerlayer", "definieerlayout", "definieerletter", "definieerlijst", "definieermarkering", "definieeromlijnd", "definieeropmaak", "definieeroverlay", "definieerpaginaovergang", "definieerpalet", "definieerpapierformaat", "definieerplaats", "definieerplaatsblok", "definieerprofiel", "definieerprogramma", "definieerreferentie", "definieerreferentieformaat", "definieerregister", "definieersamengesteldelijst", "definieersectie", "definieersectieblok", "definieersorteren", "definieerstartstop", "definieersubveld", "definieersymbool", "definieersynoniemen", "definieertabelvorm", "definieertabulatie", "definieertekst", "definieertekstachtergrond", "definieertype", "definieertypen", "definieerveld", "definieerveldstapel", "definieerwiskundeuitlijnen", "doordefinieren", "doorlabelen", "doornummeren", "dunnelijn", "dunnelijnen", "eenregel", "ergens", "externfiguur", "formulenummer", "gebruikJSscripts", "gebruikURL", "gebruikblokken", "gebruikexterndocument", "gebruikexternfiguur", "gebruikexterngeluidsfragment", "gebruikmodule", "gebruikpad", "gebruiksymbolen", "gebruiktypescript", "gebruiktypescriptfile", "gebruikurl", "geenbovenenonderregels", "geenhoofdenvoetregels", "geenspatie", "grijskleur", "haalbuffer", "haalmarkering", "haarlijn", "handhaafblokken", "hoofdtaal", "hoog", "huidigedatum", "huidigekopnummer", "inlijnd", "inregel", "installeertaal", "interactiebalk", "interactiebuttons", "interactiemenu", "invullijnen", "invulregel", "invultekst", "kleur", "kleurenbalk", "kleurwaarde", "kloonveld", "kolom", "kopnummer", "laag", "laho", "legeregels", "letter", "letters", "lijndikte", "lijstlengte", "maand", "markeer", "naar", "naarbox", "naarpagina", "nokap", "noot", "omgeving", "omlaag", "omlijnd", "onbekend", "onderdeel", "op", "oppagina", "pagina", "paginanummer", "paginareferentie", "paslayoutaan", "passendveld", "plaatsbookmarks", "plaatsformule", "plaatskopnummer", "plaatskoptekst", "plaatslijst", "plaatslijstmetsynoniemen", "plaatslokalevoetnoten", "plaatsnaastelkaar", "plaatsonderelkaar", "plaatsopgrid", "plaatspaginanummer", "plaatsplaatsblok", "plaatsregister", "plaatsruwelijst", "plaatssamengesteldelijst", "plaatssubformule", "plaatsvoetnoten", "positioneer", "produkt", "programma", "projekt", "punten", "refereer", "referentie", "regellinks", "regelmidden", "regelrechts", "resetmarkering", "romeins", "rooster", "roteer", "schaal", "scherm", "schrijfnaarlijst", "schrijftussenlijst", "selecteerblokken", "som", "spatie", "spiegel", "splitsplaatsblok", "startachtergrond", "startinteractiemenu", "startkantlijn", "startkleur", "startkop", "startlokalevoetnoten", "startmargeblok", "startnaar", "startomgeving", "startomlijnd", "startonderdeel", "startopelkaar", "startplaatsformule", "startplaatsplaatsblok", "startprodukt", "startprojekt", "startpublicatie", "startregel", "startregelcorrectie", "startregellinks", "startregelmidden", "startregelrechts", "startsom", "starttekstachtergrond", "starttekstlijn", "startuitlijnen", "stelachtergrondenin", "stelachtergrondin", "stelalineasin", "stelarrangerenin", "stelblankoin", "stelblokin", "stelblokjesin", "stelblokkopjein", "stelblokkopjesin", "stelbovenin", "stelboventekstenin", "stelbufferin", "stelciterenin", "stelclipin", "stelcommentaarin", "steldoordefinierenin", "steldoornummerenin", "steldunnelijnenin", "stelformulein", "stelformulesin", "stelformulierenin", "stelhoofdin", "stelhoofdtekstenin", "stelingesprongentextin", "stelinmargein", "stelinspringenin", "stelinteractiebalkin", "stelinteractiein", "stelinteractiemenuin", "stelinteractieschermin", "stelinterliniein", "stelinvullijnenin", "stelinvulregelsin", "stelitemgroepin", "stelitemsin", "stelkadertekstenin", "stelkadertekstin", "stelkantlijnin", "stelkapitalenin", "stelkleurenin", "stelkleurin", "stelkolommenin", "stelkopin", "stelkopnummerin", "stelkoppeltekenin", "stelkoppenin", "stelkorpsin", "stellayoutin", "stellijndiktein", "stellijstin", "stelmargeblokkenin", "stelmarkeringin", "stelnaastplaatsenin", "stelomlijndin", "stelonderin", "stelondertekstenin", "stelopmaakin", "stelopsommingenin", "stelpaginacommentaarin", "stelpaginanummerin", "stelpaginanummeringin", "stelpaginaovergangenin", "stelpaletin", "stelpapierformaatin", "stelpapierin", "stelparagraafnummerenin", "stelplaatsblokin", "stelplaatsblokkenin", "stelplaatsbloksplitsenin", "stelplaatsin", "stelpositionerenin", "stelprogrammasin", "stelrefererenin", "stelregelnummerenin", "stelregelsin", "stelregisterin", "stelroterenin", "stelsamengesteldelijstin", "stelsectieblokin", "stelsmallerin", "stelsorterenin", "stelspatieringin", "stelstartstopin", "stelsubpaginanummerin", "stelsymboolsetin", "stelsynoniemenin", "steltaalin", "steltabellenin", "steltabulatiein", "steltekstachtergrondin", "steltekstin", "steltekstinhoudin", "steltekstlijnenin", "stelteksttekstenin", "steltolerantiein", "steltypein", "steltypenin", "steluitlijnenin", "stelurlin", "stelveldenin", "stelveldin", "stelvoetin", "stelvoettekstenin", "stelwiskundeuitlijnenin", "stelwitruimtein", "stopachtergrond", "stopinteractiemenu", "stopkantlijn", "stopkleur", "stopkop", "stoplokalevoetnoten", "stopmargeblok", "stopnaar", "stopomgeving", "stopomlijnd", "stoponderdeel", "stopopelkaar", "stopplaatsformule", "stopplaatsplaatsblok", "stopprodukt", "stopprojekt", "stoppublicatie", "stopregel", "stopregelcorrectie", "stopregellinks", "stopregelmidden", "stopregelrechts", "stopsom", "stoptekstachtergrond", "stoptekstlijn", "stopuitlijnen", "subpaginanummer", "switchnaarkorps", "symbool", "taal", "tekstlijn", "tekstreferentie", "testkolom", "testpagina", "toelichting", "toongrid", "tooninstellingen", "toonkader", "toonkleur", "toonkleurgroep", "toonkorps", "toonkorpsomgeving", "toonlayout", "toonopmaak", "toonpalet", "toonprint", "toonstruts", "toonsymboolset", "uit", "uitgerekt", "vastespatie", "vastespaties", "veld", "veldstapel", "verbergblokken", "vergelijkkleurgroep", "vergelijkpalet", "versie", "vertaal", "verwerkblokken", "voetnoottekst", "volledigepaginanummer", "volledigregister", "voluit", "weekdag", "wiskunde", "woordrechts" },
- ["pe"]={ "آیتم", "آیتمها", "آینه", "از", "استفاده‌بلوکها", "استفاده‌دستخط‌تایپ", "استفاده‌شکل‌خارجی", "استفاده‌قطعه‌موزیک‌خارجی", "استفاده‌مدول", "استفاده‌مسیر", "استفاده‌نمادها", "استفاده‌نوشتارخارجی", "استفاده‌پرونده‌دستخط‌تایپ", "اعدادلاتین", "افزودن", "انتخاب‌بلوکها", "بارگذاری‌آرایش", "بارگذاری‌آیتمها", "بارگذاری‌ارجاع", "بارگذاری‌اندازه‌برگ", "بارگذاری‌باریکتر", "بارگذاری‌بافر", "بارگذاری‌بالا", "بارگذاری‌بردباری", "بارگذاری‌برنامه‌ها", "بارگذاری‌برگ", "بارگذاری‌بلوک", "بارگذاری‌بلوک‌بخش", "بارگذاری‌تایپ", "بارگذاری‌تایپ‌کردن", "بارگذاری‌ترتیب", "بارگذاری‌تنظیم", "بارگذاری‌تنظیم‌ریاضی", "بارگذاری‌ته‌برگ", "بارگذاری‌تورفتگی", "بارگذاری‌توضیح", "بارگذاری‌توضیح‌صفحه", "بارگذاری‌ثبت", "بارگذاری‌جانشانی", "بارگذاری‌جدولها", "بارگذاری‌جدول‌بندی", "بارگذاری‌خالی", "بارگذاری‌خطها", "بارگذاری‌خطهای‌حاشیه", "بارگذاری‌خطهای‌سیاه", "بارگذاری‌خطهای‌متن", "بارگذاری‌خطها‌ی‌نازک", "بارگذاری‌درج‌درخطها", "بارگذاری‌درج‌مخالف", "بارگذاری‌دوران", "بارگذاری‌رنگ", "بارگذاری‌رنگها", "بارگذاری‌زبان", "بارگذاری‌ستونها", "بارگذاری‌سر", "بارگذاری‌سربرگ", "بارگذاری‌سرها", "بارگذاری‌شرح", "بارگذاری‌شرحها", "بارگذاری‌شروع‌پایان", "بارگذاری‌شماره‌زیرصفحه", "بارگذاری‌شماره‌سر", "بارگذاری‌شماره‌صفحه", "بارگذاری‌شماره‌گذاریها", "بارگذاری‌شماره‌گذاری‌صفحه", "بارگذاری‌شماره‌گذاری‌پاراگراف", "بارگذاری‌شماره‌‌گذاری‌خط", "بارگذاری‌شناور", "بارگذاری‌شناورها", "بارگذاری‌شکافتن‌شناورها", "بارگذاری‌طرح", "بارگذاری‌طرح‌بندی", "بارگذاری‌عرض‌خط", "بارگذاری‌فاصله‌بین‌خط", "بارگذاری‌فرمولها", "بارگذاری‌فضای‌سفید", "بارگذاری‌فضا‌گذاری", "بارگذاری‌قالبی", "بارگذاری‌قلم‌متن", "بارگذاری‌لوح", "بارگذاری‌لیست", "بارگذاری‌لیست‌ترکیبی", "بارگذاری‌مترادفها", "بارگذاری‌متن", "بارگذاری‌متنهای‌بالا", "بارگذاری‌متن‌سربرگ", "بارگذاری‌متن‌قالبی", "بارگذاری‌متن‌متنها", "بارگذاری‌متن‌پانوشت", "بارگذاری‌متن‌پایین", "بارگذاری‌مجموعه‌نماد", "بارگذاری‌منوی‌پانل", "بارگذاری‌مکان‌گذاری", "بارگذاری‌میدان", "بارگذاری‌میدانها", "بارگذاری‌میله‌پانل", "بارگذاری‌نشانه‌شکستن", "بارگذاری‌نشانه‌گذاری", "بارگذاری‌نقل", "بارگذاری‌پاراگرافها", "بارگذاری‌پانل", "بارگذاری‌پایین", "بارگذاری‌پرده‌پانل", "بارگذاری‌پرکردن‌خطها", "بارگذاری‌پس‌زمینه", "بارگذاری‌پس‌زمینه‌ها", "بارگذاری‌چیدن", "بارگذاری‌گذارصفحه", "بارگذاری‌گروههای‌آیتم", "بارگذاری‌گروه‌آیتم", "بازنشانی‌نشانه‌گذاری", "بدون‌خط‌بالاوپایین", "بدون‌خط‌سروته‌برگ", "بدون‌فضا", "برنامه", "بروبه", "بروبه‌جعبه", "بروبه‌صفحه", "بروپایین", "بلند", "بلوکهای‌پردازش", "بلوکها‌پنهان", "بنویس‌بین‌لیست", "بنویس‌در‌لیست", "تاریخ", "تاریخ‌جاری", "تایپ", "تایپ‌بافر", "تایپ‌پرونده", "ترجمه", "تعریف", "تعریف‌آرایش", "تعریف‌الگوی‌جدول", "تعریف‌اندازه‌برگ", "تعریف‌بافر", "تعریف‌بخش", "تعریف‌برنامه", "تعریف‌برچسب", "تعریف‌بلوک", "تعریف‌بلوک‌بخش", "تعریف‌تایپ", "تعریف‌تایپ‌کردن", "تعریف‌تبدیل", "تعریف‌ترتیب", "تعریف‌ترکیب", "تعریف‌تنظیم‌ریاضی", "تعریف‌توده‌میدان", "تعریف‌ثبت", "تعریف‌جانشانی", "تعریف‌جدول‌بندی", "تعریف‌جعبه‌‌افقی", "تعریف‌حرف", "تعریف‌رنگ", "تعریف‌زیرمیدان", "تعریف‌سبک", "تعریف‌سبک‌قلم", "تعریف‌سر", "تعریف‌شرح", "تعریف‌شروع‌پایان", "تعریف‌شماره‌بندی", "تعریف‌شمایل‌مرجع", "تعریف‌شناور", "تعریف‌شکستن‌ستون", "تعریف‌شکست‌صفحه", "تعریف‌طرح‌بندی", "تعریف‌فرمان", "تعریف‌قالبی", "تعریف‌قلم", "تعریف‌قلم‌متن", "تعریف‌لایه", "تعریف‌لهجه", "تعریف‌لوح", "تعریف‌لیست", "تعریف‌لیست‌ترکیبی", "تعریف‌مترادفها", "تعریف‌مترادف‌قلم", "تعریف‌متن", "تعریف‌متن‌قالبی", "تعریف‌محیط‌قلم‌بدنه", "تعریف‌مرجع", "تعریف‌منوی‌پانل", "تعریف‌میدان", "تعریف‌نشانه‌گذاری", "تعریف‌نماد", "تعریف‌نمادشکل", "تعریف‌پاراگرافها", "تعریف‌پروفایل", "تعریف‌پوشش", "تعریف‌گروه‌آیتم", "تعریف‌گروه‌رنگ", "تعیین‌شماره‌سر", "تعیین‌محتوای‌متن", "تعیین‌مشخصات‌ثبت", "تعیین‌مشخصات‌لیست", "تغییربه‌قلم‌بدنه", "تنظیم‌راست", "تنظیم‌طرح‌بندی", "تنظیم‌وسط", "توجه", "توری", "تولید", "تک", "ثبت‌کامل", "حرف", "حرفها", "حفظ‌بلوکها", "خالی", "خطهای‌سیاه", "خطهای‌نازک", "خطها‌خالی", "خط‌سیاه", "خط‌متن", "خط‌مو", "خط‌نازک", "خ‌ا", "خ‌ع", "در", "درج‌ثبت", "درج‌درخط", "درج‌درخطها", "درج‌درمتن", "درج‌در‌بالای‌یکدیگر", "درج‌در‌توری", "درج‌زیرفرمول", "درج‌شماره‌سر", "درج‌شماره‌صفحه", "درج‌شناور", "درج‌فرمول", "درج‌لیست", "درج‌لیست‌خام", "درج‌لیست‌مختلط", "درج‌متن‌سر", "درج‌پانوشتها", "درج‌پانوشتهای‌موضعی", "درج‌چوب‌خط", "درج‌کنار‌به‌کنار", "درخط", "درصفحه", "درقالبی", "درمورد", "درون", "درپر", "دریافت‌بافر", "دریافت‌نشانه", "دوران", "دکمه", "دکمه‌منو", "دکمه‌پانل", "رج", "رنگ", "رنگ‌خاکستری", "روزهفته", "ریاضی", "زبان", "زبان‌اصلی", "ستون", "ستون‌امتحان", "سرپوش‌کوچک‌نه", "شروعJScode", "شروعJSpreamble", "شروعLUA", "شروعMP", "شروعMPclip", "شروعMPcode", "شروعMPdefinitions", "شروعMPdrawing", "شروعMPenvironment", "شروعMPextensions", "شروعMPinclusions", "شروعMPinitializations", "شروعMPpage", "شروعMPpositiongraphic", "شروعMPpositionmethod", "شروعMPrun", "شروعPARSEDXML", "شروعTABLE", "شروعTABLEbody", "شروعTABLEfoot", "شروعTABLEhead", "شروعTABLEnext", "شروعTC", "شروعTD", "شروعTDs", "شروعTEX", "شروعTEXpage", "شروعTH", "شروعTN", "شروعTR", "شروعTRs", "شروعTX", "شروعTY", "شروعXML", "شروعalign", "شروعalignment", "شروعallmodes", "شروعappendices", "شروعarrangedpages", "شروعaside", "شروعattachment", "شروعbackmatter", "شروعbar", "شروعbbordermatrix", "شروعbitmapimage", "شروعblockquote", "شروعbodymatter", "شروعbordermatrix", "شروعboxedcolumns", "شروعbtxlabeltext", "شروعbtxrenderingdefinitions", "شروعbuffer", "شروعcases", "شروعcatcodetable", "شروعcenteraligned", "شروعchapter", "شروعcharacteralign", "شروعcheckedfences", "شروعchemical", "شروعchemicaltext", "شروعcollect", "شروعcollecting", "شروعcolorintent", "شروعcoloronly", "شروعcolorset", "شروعcolumns", "شروعcolumnspan", "شروعcombination", "شروعcomment", "شروعcontextcode", "شروعcontextdefinitioncode", "شروعctxfunction", "شروعctxfunctiondefinition", "شروعcurrentcolor", "شروعcurrentlistentrywrapper", "شروعdelimited", "شروعdelimitedtext", "شروعdisplaymath", "شروعdmath", "شروعdocument", "شروعeffect", "شروعelement", "شروعembeddedxtable", "شروعendnote", "شروعendofline", "شروعexceptions", "شروعexpanded", "شروعexpandedcollect", "شروعextendedcatcodetable", "شروعexternalfigurecollection", "شروعfact", "شروعfigure", "شروعfiguretext", "شروعfittingpage", "شروعfixed", "شروعfloatcombination", "شروعfont", "شروعfontclass", "شروعfontsolution", "شروعfootnote", "شروعformula", "شروعformulas", "شروعframedcell", "شروعframedcontent", "شروعframedrow", "شروعframedtable", "شروعframedtext", "شروعfrontmatter", "شروعgraphictext", "شروعgridsnapping", "شروعhanging", "شروعhbox", "شروعhboxestohbox", "شروعhboxregister", "شروعheadtext", "شروعhelptext", "شروعhiding", "شروعhighlight", "شروعhyphenation", "شروعimath", "شروعindentation", "شروعindentedtext", "شروعinteraction", "شروعinterface", "شروعintermezzotext", "شروعintertext", "شروعitemgroup", "شروعitemgroupcolumns", "شروعitemize", "شروعknockout", "شروعlabeltext", "شروعlayout", "شروعlegend", "شروعlinealignment", "شروعlinecorrection", "شروعlinefiller", "شروعlinenumbering", "شروعlines", "شروعlinetable", "شروعlinetablebody", "شروعlinetablecell", "شروعlinetablehead", "شروعlocalfootnotes", "شروعlocalheadsetup", "شروعlocallinecorrection", "شروعlocalnotes", "شروعlocalsetups", "شروعlua", "شروعluacode", "شروعluaparameterset", "شروعluasetups", "شروعmakeup", "شروعmarginblock", "شروعmarkedcontent", "شروعmathalignment", "شروعmathcases", "شروعmathlabeltext", "شروعmathmatrix", "شروعmathmode", "شروعmathstyle", "شروعmatrices", "شروعmatrix", "شروعmaxaligned", "شروعmdformula", "شروعmiddlealigned", "شروعmiddlemakeup", "شروعmixedcolumns", "شروعmode", "شروعmodeset", "شروعmodule", "شروعmoduletestsection", "شروعmpformula", "شروعnamedsection", "شروعnamedsubformulas", "شروعnarrow", "شروعnarrower", "شروعnegative", "شروعnicelyfilledbox", "شروعnointerference", "شروعnotallmodes", "شروعnotext", "شروعnotmode", "شروعoperatortext", "شروعopposite", "شروعoutputstream", "شروعoverlay", "شروعoverprint", "شروعpagecomment", "شروعpagefigure", "شروعpagegrid", "شروعpagegridspan", "شروعpagelayout", "شروعpagemakeup", "شروعpar", "شروعparagraph", "شروعparagraphs", "شروعparagraphscell", "شروعparbuilder", "شروعpart", "شروعpath", "شروعplacechemical", "شروعplacefigure", "شروعplacegraphic", "شروعplaceintermezzo", "شروعplacelegend", "شروعplacepairedbox", "شروعplacetable", "شروعpositioning", "شروعpositionoverlay", "شروعpositive", "شروعpostponing", "شروعprefixtext", "شروعprocessassignmentcommand", "شروعprocessassignmentlist", "شروعprocesscommacommand", "شروعprocesscommalist", "شروعprotect", "شروعprotectedcolors", "شروعpunctuation", "شروعquotation", "شروعquote", "شروعrandomized", "شروعrandomseed", "شروعrawsetups", "شروعreadingfile", "شروعreferenceprefix", "شروعregime", "شروعreusableMPgraphic", "شروعscript", "شروعsdformula", "شروعsection", "شروعsectionblock", "شروعsectionblockenvironment", "شروعsectionlevel", "شروعsetups", "شروعshapebox", "شروعshift", "شروعsidebar", "شروعsimplecolumns", "شروعspecialitem", "شروعspeech", "شروعspformula", "شروعsplitformula", "شروعspread", "شروعstandardmakeup", "شروعstartstop", "شروعstaticMPfigure", "شروعstaticMPgraphic", "شروعstrictinspectnextcharacter", "شروعstrut", "شروعstyle", "شروعsubformulas", "شروعsubject", "شروعsubjectlevel", "شروعsubsection", "شروعsubsentence", "شروعsubstack", "شروعsubsubject", "شروعsubsubsection", "شروعsubsubsubject", "شروعsubsubsubsection", "شروعsubsubsubsubject", "شروعsubsubsubsubsection", "شروعsubsubsubsubsubject", "شروعsuffixtext", "شروعsymbolset", "شروعtable", "شروعtablehead", "شروعtables", "شروعtabletail", "شروعtabletext", "شروعtabulate", "شروعtabulatehead", "شروعtabulatetail", "شروعtagged", "شروعtaglabeltext", "شروعtexcode", "شروعtexdefinition", "شروعtext", "شروعtextbackground", "شروعtextbackgroundmanual", "شروعtextcolor", "شروعtextcolorintent", "شروعtextflow", "شروعtextmakeup", "شروعtitle", "شروعtokens", "شروعtransparent", "شروعtypescript", "شروعtypescriptcollection", "شروعtyping", "شروعuniqueMPgraphic", "شروعuniqueMPpagegraphic", "شروعunittext", "شروعunpacked", "شروعusableMPgraphic", "شروعuseMPgraphic", "شروعusemathstyleparameter", "شروعusingbtxspecification", "شروعvbox", "شروعvboxregister", "شروعvboxtohbox", "شروعvboxtohboxseparator", "شروعviewerlayer", "شروعvtop", "شروعvtopregister", "شروعxcell", "شروعxcellgroup", "شروعxgroup", "شروعxmldisplayverbatim", "شروعxmlinlineverbatim", "شروعxmlraw", "شروعxmlsetups", "شروعxrow", "شروعxrowgroup", "شروعxtable", "شروعxtablebody", "شروعxtablefoot", "شروعxtablehead", "شروعxtablenext", "شروعآیتم", "شروعبروبه", "شروعتنظیم‌راست", "شروعتنظیم‌وسط", "شروعتولید", "شروعخط‌حاشیه", "شروعخط‌متن", "شروعدرج‌شناور", "شروعدرج‌فرمول", "شروعرنگ", "شروعسر", "شروعفشرده", "شروعقالبی", "شروعمحیط", "شروعمنوی‌پانل", "شروعمولفه", "شروعنشر", "شروعپروژه", "شروعپس‌زمینه", "شروعچپ‌چین", "شروع‌خط", "شماره‌زیرصفحه", "شماره‌سر", "شماره‌سرجاری", "شماره‌صفحه", "شماره‌صفحه‌کامل", "شماره‌فرمول", "شماره‌مبدل", "شماره‌ها", "شکافتن‌شناور", "شکل‌خارجی", "صفحه", "صفحه‌تست", "طول‌لیست", "عرض‌خط", "فضا", "فضاهای‌ثابت", "فضای‌ثابت", "فضای‌سفیدصحیح", "قالبی", "لوح‌مقایسه", "ماه", "متن‌پانوشت", "محیط", "مراجعه", "مرجع", "مرجع‌صفحه", "مرجع‌متن", "مقایسه‌گروه‌رنگ", "مقداررنگ", "مقیاس", "منوی‌پانل", "مولفه", "مکان", "میدان", "میدان‌شبیه‌سازی", "میدان‌پشته", "میدان‌کپی", "میله‌رنگ", "میله‌پانل", "ناشناس", "نسخه", "نشانه‌گذاری", "نصب‌زبان", "نقطه‌ها", "نماد", "نمایش‌آرایش", "نمایش‌بارگذاریها", "نمایش‌بستها", "نمایش‌توری", "نمایش‌رنگ", "نمایش‌طرح‌بندی", "نمایش‌قالب", "نمایش‌قلم‌بدنه", "نمایش‌لوح", "نمایش‌مجموعه‌علامت", "نمایش‌محیط‌قلم‌بدنه", "نمایش‌چاپ", "نمایش‌گروه‌رنگ", "پابا", "پایانJScode", "پایانJSpreamble", "پایانLUA", "پایانMP", "پایانMPclip", "پایانMPcode", "پایانMPdefinitions", "پایانMPdrawing", "پایانMPenvironment", "پایانMPextensions", "پایانMPinclusions", "پایانMPinitializations", "پایانMPpage", "پایانMPpositiongraphic", "پایانMPpositionmethod", "پایانMPrun", "پایانPARSEDXML", "پایانTABLE", "پایانTABLEbody", "پایانTABLEfoot", "پایانTABLEhead", "پایانTABLEnext", "پایانTC", "پایانTD", "پایانTDs", "پایانTEX", "پایانTEXpage", "پایانTH", "پایانTN", "پایانTR", "پایانTRs", "پایانTX", "پایانTY", "پایانXML", "پایانalign", "پایانalignment", "پایانallmodes", "پایانappendices", "پایانarrangedpages", "پایانaside", "پایانattachment", "پایانbackmatter", "پایانbar", "پایانbbordermatrix", "پایانbitmapimage", "پایانblockquote", "پایانbodymatter", "پایانbordermatrix", "پایانboxedcolumns", "پایانbtxlabeltext", "پایانbtxrenderingdefinitions", "پایانbuffer", "پایانcases", "پایانcatcodetable", "پایانcenteraligned", "پایانchapter", "پایانcharacteralign", "پایانcheckedfences", "پایانchemical", "پایانchemicaltext", "پایانcollect", "پایانcollecting", "پایانcolorintent", "پایانcoloronly", "پایانcolorset", "پایانcolumns", "پایانcolumnspan", "پایانcombination", "پایانcomment", "پایانcontextcode", "پایانcontextdefinitioncode", "پایانctxfunction", "پایانctxfunctiondefinition", "پایانcurrentcolor", "پایانcurrentlistentrywrapper", "پایانdelimited", "پایانdelimitedtext", "پایانdisplaymath", "پایانdmath", "پایانdocument", "پایانeffect", "پایانelement", "پایانembeddedxtable", "پایانendnote", "پایانendofline", "پایانexceptions", "پایانexpanded", "پایانexpandedcollect", "پایانextendedcatcodetable", "پایانexternalfigurecollection", "پایانfact", "پایانfigure", "پایانfiguretext", "پایانfittingpage", "پایانfixed", "پایانfloatcombination", "پایانfont", "پایانfontclass", "پایانfontsolution", "پایانfootnote", "پایانformula", "پایانformulas", "پایانframedcell", "پایانframedcontent", "پایانframedrow", "پایانframedtable", "پایانframedtext", "پایانfrontmatter", "پایانgraphictext", "پایانgridsnapping", "پایانhanging", "پایانhbox", "پایانhboxestohbox", "پایانhboxregister", "پایانheadtext", "پایانhelptext", "پایانhiding", "پایانhighlight", "پایانhyphenation", "پایانimath", "پایانindentation", "پایانindentedtext", "پایانinteraction", "پایانinterface", "پایانintermezzotext", "پایانintertext", "پایانitemgroup", "پایانitemgroupcolumns", "پایانitemize", "پایانknockout", "پایانlabeltext", "پایانlayout", "پایانlegend", "پایانlinealignment", "پایانlinecorrection", "پایانlinefiller", "پایانlinenumbering", "پایانlines", "پایانlinetable", "پایانlinetablebody", "پایانlinetablecell", "پایانlinetablehead", "پایانlocalfootnotes", "پایانlocalheadsetup", "پایانlocallinecorrection", "پایانlocalnotes", "پایانlocalsetups", "پایانlua", "پایانluacode", "پایانluaparameterset", "پایانluasetups", "پایانmakeup", "پایانmarginblock", "پایانmarkedcontent", "پایانmathalignment", "پایانmathcases", "پایانmathlabeltext", "پایانmathmatrix", "پایانmathmode", "پایانmathstyle", "پایانmatrices", "پایانmatrix", "پایانmaxaligned", "پایانmdformula", "پایانmiddlealigned", "پایانmiddlemakeup", "پایانmixedcolumns", "پایانmode", "پایانmodeset", "پایانmodule", "پایانmoduletestsection", "پایانmpformula", "پایانnamedsection", "پایانnamedsubformulas", "پایانnarrow", "پایانnarrower", "پایانnegative", "پایانnicelyfilledbox", "پایانnointerference", "پایانnotallmodes", "پایانnotext", "پایانnotmode", "پایانoperatortext", "پایانopposite", "پایانoutputstream", "پایانoverlay", "پایانoverprint", "پایانpagecomment", "پایانpagefigure", "پایانpagegrid", "پایانpagegridspan", "پایانpagelayout", "پایانpagemakeup", "پایانpar", "پایانparagraph", "پایانparagraphs", "پایانparagraphscell", "پایانparbuilder", "پایانpart", "پایانpath", "پایانplacechemical", "پایانplacefigure", "پایانplacegraphic", "پایانplaceintermezzo", "پایانplacelegend", "پایانplacepairedbox", "پایانplacetable", "پایانpositioning", "پایانpositionoverlay", "پایانpositive", "پایانpostponing", "پایانprefixtext", "پایانprocessassignmentcommand", "پایانprocessassignmentlist", "پایانprocesscommacommand", "پایانprocesscommalist", "پایانprotect", "پایانprotectedcolors", "پایانpunctuation", "پایانquotation", "پایانquote", "پایانrandomized", "پایانrandomseed", "پایانrawsetups", "پایانreadingfile", "پایانreferenceprefix", "پایانregime", "پایانreusableMPgraphic", "پایانscript", "پایانsdformula", "پایانsection", "پایانsectionblock", "پایانsectionblockenvironment", "پایانsectionlevel", "پایانsetups", "پایانshapebox", "پایانshift", "پایانsidebar", "پایانsimplecolumns", "پایانspecialitem", "پایانspeech", "پایانspformula", "پایانsplitformula", "پایانspread", "پایانstandardmakeup", "پایانstartstop", "پایانstaticMPfigure", "پایانstaticMPgraphic", "پایانstrictinspectnextcharacter", "پایانstrut", "پایانstyle", "پایانsubformulas", "پایانsubject", "پایانsubjectlevel", "پایانsubsection", "پایانsubsentence", "پایانsubstack", "پایانsubsubject", "پایانsubsubsection", "پایانsubsubsubject", "پایانsubsubsubsection", "پایانsubsubsubsubject", "پایانsubsubsubsubsection", "پایانsubsubsubsubsubject", "پایانsuffixtext", "پایانsymbolset", "پایانtable", "پایانtablehead", "پایانtables", "پایانtabletail", "پایانtabletext", "پایانtabulate", "پایانtabulatehead", "پایانtabulatetail", "پایانtagged", "پایانtaglabeltext", "پایانtexcode", "پایانtexdefinition", "پایانtext", "پایانtextbackground", "پایانtextbackgroundmanual", "پایانtextcolor", "پایانtextcolorintent", "پایانtextflow", "پایانtextmakeup", "پایانtitle", "پایانtokens", "پایانtransparent", "پایانtypescript", "پایانtypescriptcollection", "پایانtyping", "پایانuniqueMPgraphic", "پایانuniqueMPpagegraphic", "پایانunittext", "پایانunpacked", "پایانusableMPgraphic", "پایانuseMPgraphic", "پایانusemathstyleparameter", "پایانusingbtxspecification", "پایانvbox", "پایانvboxregister", "پایانvboxtohbox", "پایانvboxtohboxseparator", "پایانviewerlayer", "پایانvtop", "پایانvtopregister", "پایانxcell", "پایانxcellgroup", "پایانxgroup", "پایانxmldisplayverbatim", "پایانxmlinlineverbatim", "پایانxmlraw", "پایانxmlsetups", "پایانxrow", "پایانxrowgroup", "پایانxtable", "پایانxtablebody", "پایانxtablefoot", "پایانxtablehead", "پایانxtablenext", "پایانآیتم", "پایانبروبه", "پایانتنظیم‌راست", "پایانتنظیم‌وسط", "پایانتولید", "پایانخط‌حاشیه", "پایانخط‌متن", "پایاندرج‌شناور", "پایاندرج‌فرمول", "پایانرنگ", "پایانسر", "پایانفشرده", "پایانقالبی", "پایانمحیط", "پایانمنوی‌پانل", "پایانمولفه", "پایاننشر", "پایانپروژه", "پایانپس‌زمینه", "پایانچپ‌چین", "پایان‌خط", "پایین", "پرده", "پروژه", "پرکردن‌میدان", "پس‌زمینه", "چوبخط", "چپ‌چین", "کشیده", "کلمه‌راست", "گیره", "یادداشت", "یک‌جا", "یک‌خط" },
- ["ro"]={ "CUVANT", "CUVINTE", "Cuvant", "Cuvinte", "Kap", "LUNA", "Litera", "Litere", "Numere", "Numereromane", "ZIDINSAPTAMANA", "adapteazaaspect", "adubuffer", "adumarcaje", "afiseazaaspect", "afiseazaculoare", "afiseazafonttext", "afiseazagrid", "afiseazagrupculoare", "afiseazamakeup", "afiseazamediufonttext", "afiseazapaleta", "afiseazarama", "afiseazasetari", "afiseazasetsimboluri", "afiseazastruts", "afiseazatiparire", "aliniatcentru", "aliniatdreapta", "aliniatstanga", "ascundeblocuri", "baraculoare", "barainteractiune", "blanc", "butoaneinteractiune", "buton", "butonmeniu", "camp", "cloneazacamp", "coloana", "comparagrupculoare", "comparapaleta", "completeazanumarpagina", "componenta", "convertestenumar", "copiazacamp", "corecteazaspatiualb", "culoare", "culoaregri", "cuvantdreapta", "data", "datacurenta", "defineste", "definesteaccent", "definesteantet", "definestebloc", "definesteblocsectiune", "definestebuffer", "definestecamp", "definestecaracter", "definestecomanda", "definesteconversie", "definesteculoare", "definestedescriere", "definestedimensiunehartie", "definesteenumerare", "definesteeticheta", "definestefloat", "definestefont", "definestefonttext", "definesteformatreferinte", "definestegrupculori", "definestehbox", "definesteinconjurare", "definestelista", "definestelistacombinata", "definestemakeup", "definestemarcaje", "definestemediulfonttext", "definestemeniuinteractiune", "definesteoverlay", "definestepaleta", "definesteparagraf", "definesteprofil", "definesteprogram", "definestereferinte", "definesteregistru", "definestesablontabel", "definestesectiune", "definestesimbol", "definestesimbolfigura", "definestesinonim", "definestesinonimfont", "definestesortare", "definestestartstop", "definestestil", "definestestilfont", "definestestivacampuri", "definestesubcamp", "definestetabulatori", "definestetext", "definestetexteinconjurate", "definestetextinconjurat", "definestetyping", "despre", "determinacaracteristicilelistei", "determinacaracteristiciregistru", "determinanumartitlu", "din", "dute", "dutebox", "dutepagina", "ecran", "element", "faraliniiantetsisubsol", "faraliniisussijos", "faraspatiu", "figuraexterna", "firdepar", "folosesteURL", "folosestebloc", "folosestedirector", "folosestedocumentextern", "folosestefiguraexterna", "folosestemodul", "folosestemuzicaexterna", "folosestescriptJS", "folosestesimboluri", "folosesteurl", "fundal", "grosimelinie", "impartefloat", "inalt", "injos", "inlinie", "instalarelimba", "intins", "jos", "jossus", "la", "lapagina", "limba", "limbaprincipala", "linieneagra", "liniesubtire", "linieumplere", "liniinegre", "liniisubtiri", "litera", "litere", "luna", "lungimelista", "marcaje", "matematica", "mediu", "meniuinteractiune", "necunoscut", "nokap", "nota", "numarformula", "numarpagina", "numartitlu", "numartitlucurent", "numere", "numereromane", "olinie", "pagina", "pastreazablocuri", "pelung", "plaseazapegrid", "plaseazasemnecarte", "potrivestecamp", "pozitie", "proceseazabloc", "produs", "proiect", "puncte", "punedeasuprafiecareia", "punefatainfata", "puneformula", "punelista", "punelistacombinata", "punenotesubsol", "punenotesubsollocale", "punenumarpagina", "puneregistru", "punesubformula", "referinta", "referintapagina", "referintatext", "reflexie", "remarca", "reseteazamarcaje", "riglatext", "rigleumplere", "roteste", "scala", "scriebuffer", "scrieinlista", "scrieintreliste", "selecteazablocuri", "semncarte", "setareitemization", "setarelimba", "setarepozitie", "seteazaaliniat", "seteazaalinierea", "seteazaantet", "seteazaaranjareapag", "seteazaaspect", "seteazabarainteractiune", "seteazablanc", "seteazabloc", "seteazablocsectiune", "seteazabuffer", "seteazacamp", "seteazacampuri", "seteazaclipping", "seteazacoloane", "seteazacomentariu", "seteazacomentariupagina", "seteazaculoare", "seteazaculori", "seteazadimensiunihartie", "seteazaecraninteractiune", "seteazaelemente", "seteazaenumerare", "seteazafloat", "seteazafloats", "seteazafonttext", "seteazaformulare", "seteazaformule", "seteazafundal", "seteazafundaluri", "seteazagrosimelinie", "seteazaimpartireafloat", "seteazainconjurat", "seteazaingust", "seteazainteractiunea", "seteazajos", "seteazalegenda", "seteazalegendele", "seteazaliniesilabe", "seteazaliniesubtire", "seteazalinii", "seteazaliniimargine", "seteazaliniinegre", "seteazaliniiumplere", "seteazalista", "seteazalistacombinata", "seteazamajuscule", "seteazamakeup", "seteazamarcaje", "seteazameniuinteractiune", "seteazaminicitat", "seteazanumarpagina", "seteazanumarsubpagina", "seteazanumartitlu", "seteazanumerotarelinii", "seteazanumerotarepagina", "seteazanumerotareparagrafe", "seteazapaleta", "seteazaparagrafe", "seteazaplasareaopozita", "seteazaprograme", "seteazareferinte", "seteazaregistru", "seteazarigletext", "seteazarigleumplere", "seteazarotare", "seteazasimbol", "seteazasinonime", "seteazasortare", "seteazaspatiu", "seteazaspatiualb", "seteazaspatiuinterliniar", "seteazasubsol", "seteazasus", "seteazatabele", "seteazatabulatori", "seteazatext", "seteazatexteantet", "seteazatextejos", "seteazatextesubsol", "seteazatextesus", "seteazatextetext", "seteazatitlu", "seteazatitluri", "seteazatoleranta", "seteazatranzitiepagina", "seteazatype", "seteazatyping", "seteazaurl", "simbol", "spatiifixate", "spatiu", "spatiufixat", "startaliniatcentru", "startaliniatdreapta", "startaliniatstanga", "startcomponenta", "startculoare", "startdute", "startfundal", "startimpachetat", "startlinie", "startliniemargine", "startmediu", "startmeniuinteractiune", "startprodus", "startproiect", "startpublicatie", "startpuneformula", "startriglatext", "starttitlu", "stivacampuri", "stopaliniatcentru", "stopaliniatdreapta", "stopaliniatstanga", "stopcomponenta", "stopculoare", "stopdute", "stopfundal", "stopimpachetat", "stoplinie", "stopliniemargine", "stopmediu", "stopmeniuinteractiune", "stopprodus", "stopproiect", "stoppublicatie", "stoppuneformula", "stopriglatext", "stoptitlu", "textumplere", "traduce", "trecilafonttext", "undeva", "valoareculoare", "versiune", "zidinsaptamana" },
+ ["fr"]={ "Caractere", "Caracteres", "Chiffresromains", "JOURSEMAINE", "MOIS", "MOT", "MOTS", "Mot", "Mots", "Numeros", "a", "adaptedisposition", "ajustechamp", "alaligne", "alapage", "aligneadroite", "aligneagauche", "aligneaumilieu", "arriereplan", "baha", "barrecouleur", "barreinteraction", "bas", "bouton", "boutonmenu", "boutonsinteraction", "cacheblocs", "caractere", "caracteres", "champ", "changepolicecorps", "chiffresromains", "clonechamp", "colonne", "commentaire", "comparegroupecouleur", "comparepalette", "completenumeropage", "completeregistre", "composant", "concernant", "convertitnumero", "copitchamp", "corrigeespaceblanc", "couleur", "couleurgrise", "dactylographier", "dans", "datecourante", "de", "definicaractere", "definit", "definitaccent", "definitbloc", "definitblocsection", "definitbuffer", "definitcalque", "definitchamp", "definitcommande", "definitconversion", "definitcouleur", "definitdactylo", "definitdemarrestoppe", "definitdescription", "definitdisposition", "definitenumeration", "definitenvironnementpolicecorps", "definitetiquette", "definitflottant", "definitformatreference", "definitgroupecouleur", "definithbox", "definitjeucolonne", "definitliste", "definitlisteimbriquee", "definitmakeup", "definitmarquage", "definitmenuinteraction", "definitpalette", "definitparagraphes", "definitpilechamp", "definitpolice", "definitpolicecorps", "definitprofil", "definitprogramme", "definitreference", "definitregistre", "definitrevetement", "definitsautdecolonne", "definitsautdepage", "definitsection", "definitsouschamp", "definitstyle", "definitstylepolice", "definitsymbole", "definitsymbolefigure", "definitsynonymepolice", "definitsynonymes", "definittabulation", "definittaillepapier", "definittete", "definittexte", "definittrametableau", "definittri", "definittype", "definitvide", "demarreJScode", "demarreJSpreamble", "demarreLUA", "demarreMP", "demarreMPclip", "demarreMPcode", "demarreMPdefinitions", "demarreMPdrawing", "demarreMPenvironment", "demarreMPextensions", "demarreMPinclusions", "demarreMPinitializations", "demarreMPpage", "demarreMPpositiongraphic", "demarreMPpositionmethod", "demarreMPrun", "demarrePARSEDXML", "demarreTABLE", "demarreTABLEbody", "demarreTABLEfoot", "demarreTABLEhead", "demarreTABLEnext", "demarreTC", "demarreTD", "demarreTDs", "demarreTEX", "demarreTEXpage", "demarreTH", "demarreTN", "demarreTR", "demarreTRs", "demarreTX", "demarreTY", "demarreXML", "demarrealign", "demarrealigneadroite", "demarrealigneagauche", "demarrealigneaumilieu", "demarrealignment", "demarreallmodes", "demarreappendices", "demarrearrangedpages", "demarrearriereplan", "demarreaside", "demarreattachment", "demarrebackmatter", "demarrebar", "demarrebbordermatrix", "demarrebitmapimage", "demarreblockquote", "demarrebodymatter", "demarrebordermatrix", "demarreboxedcolumns", "demarrebtxlabeltext", "demarrebtxrenderingdefinitions", "demarrebuffer", "demarrecases", "demarrecatcodetable", "demarrecenteraligned", "demarrechapter", "demarrecharacteralign", "demarrecheckedfences", "demarrechemical", "demarrechemicaltext", "demarreciter", "demarrecollect", "demarrecollecting", "demarrecolorintent", "demarrecoloronly", "demarrecolorset", "demarrecolumns", "demarrecolumnset", "demarrecolumnsetspan", "demarrecolumnspan", "demarrecombination", "demarrecomment", "demarrecomposant", "demarrecontextcode", "demarrecontextdefinitioncode", "demarrecouleur", "demarrectxfunction", "demarrectxfunctiondefinition", "demarrecurrentcolor", "demarrecurrentlistentrywrapper", "demarredelimited", "demarredelimitedtext", "demarredisplaymath", "demarredmath", "demarredocument", "demarreeffect", "demarreelement", "demarreembeddedxtable", "demarreendnote", "demarreendofline", "demarreenvironement", "demarreexceptions", "demarreexpanded", "demarreexpandedcollect", "demarreextendedcatcodetable", "demarreexternalfigurecollection", "demarrefacingfloat", "demarrefact", "demarrefigure", "demarrefiguretext", "demarrefittingpage", "demarrefixed", "demarrefloatcombination", "demarrefont", "demarrefontclass", "demarrefontsolution", "demarrefootnote", "demarreformula", "demarreformulas", "demarreframed", "demarreframedcell", "demarreframedcontent", "demarreframedrow", "demarreframedtable", "demarreframedtext", "demarrefrontmatter", "demarregraphictext", "demarregridsnapping", "demarregroupe", "demarrehanging", "demarrehbox", "demarrehboxestohbox", "demarrehboxregister", "demarreheadtext", "demarrehelptext", "demarrehiding", "demarrehighlight", "demarrehyphenation", "demarreimath", "demarreindentation", "demarreindentedtext", "demarreinteraction", "demarreinterface", "demarreintermezzotext", "demarreintertext", "demarreitemgroup", "demarreitemgroupcolumns", "demarreitemize", "demarreknockout", "demarrelabeltext", "demarrelangue", "demarrelayout", "demarrelegend", "demarreligne", "demarreligneregleetexte", "demarrelinealignment", "demarrelinecorrection", "demarrelinefiller", "demarrelinenumbering", "demarrelines", "demarrelinetable", "demarrelinetablebody", "demarrelinetablecell", "demarrelinetablehead", "demarrelocalfootnotes", "demarrelocalheadsetup", "demarrelocallinecorrection", "demarrelocalnotes", "demarrelocalsetups", "demarrelua", "demarreluacode", "demarreluaparameterset", "demarreluasetups", "demarremakeup", "demarremargereglee", "demarremarginblock", "demarremarkedcontent", "demarremarkpages", "demarremathalignment", "demarremathcases", "demarremathlabeltext", "demarremathmatrix", "demarremathmode", "demarremathstyle", "demarrematrices", "demarrematrix", "demarremaxaligned", "demarremdformula", "demarremenuinteraction", "demarremiddlealigned", "demarremiddlemakeup", "demarremixedcolumns", "demarremode", "demarremodeset", "demarremodule", "demarremoduletestsection", "demarrempformula", "demarrenamedsection", "demarrenamedsubformulas", "demarrenarrow", "demarrenarrower", "demarrenegative", "demarrenicelyfilledbox", "demarrenointerference", "demarrenotallmodes", "demarrenotext", "demarrenotmode", "demarreoperatortext", "demarreopposite", "demarreoutputstream", "demarreoverlay", "demarreoverprint", "demarrepagecolumns", "demarrepagecomment", "demarrepagefigure", "demarrepagelayout", "demarrepagemakeup", "demarrepar", "demarreparagraph", "demarreparagraphs", "demarreparagraphscell", "demarreparbuilder", "demarrepart", "demarrepath", "demarreplacechemical", "demarreplacefigure", "demarreplaceflottant", "demarreplaceformule", "demarreplacegraphic", "demarreplaceintermezzo", "demarreplacelegend", "demarreplacepairedbox", "demarreplacetable", "demarrepositioning", "demarrepositionoverlay", "demarrepositive", "demarrepostponing", "demarrepostponingnotes", "demarreprefixtext", "demarreprocessassignmentcommand", "demarreprocessassignmentlist", "demarreprocesscommacommand", "demarreprocesscommalist", "demarreproduit", "demarreprojet", "demarreprotect", "demarreprotectedcolors", "demarrepublication", "demarrepunctuation", "demarrequotation", "demarrequote", "demarrerandomized", "demarrerandomseed", "demarrerawsetups", "demarrereadingfile", "demarrereferenceprefix", "demarreregime", "demarrereusableMPgraphic", "demarreruby", "demarrescript", "demarresdformula", "demarresection", "demarresectionblock", "demarresectionblockenvironment", "demarresectionlevel", "demarresetups", "demarreshapebox", "demarreshift", "demarresidebar", "demarresimplecolumns", "demarrespecialitem", "demarrespeech", "demarrespformula", "demarresplitformula", "demarresplittext", "demarrespread", "demarrestandardmakeup", "demarrestaticMPfigure", "demarrestaticMPgraphic", "demarrestrictinspectnextcharacter", "demarrestrut", "demarrestyle", "demarresubformulas", "demarresubject", "demarresubjectlevel", "demarresubsection", "demarresubsentence", "demarresubstack", "demarresubsubject", "demarresubsubsection", "demarresubsubsubject", "demarresubsubsubsection", "demarresubsubsubsubject", "demarresubsubsubsubsection", "demarresubsubsubsubsubject", "demarresuffixtext", "demarresymbolset", "demarretable", "demarretablehead", "demarretables", "demarretabletail", "demarretabletext", "demarretabulate", "demarretabulatehead", "demarretabulatetail", "demarretagged", "demarretaglabeltext", "demarretete", "demarretexcode", "demarretexdefinition", "demarretext", "demarretextbackground", "demarretextbackgroundmanual", "demarretextcolor", "demarretextcolorintent", "demarretextflow", "demarretextmakeup", "demarretitle", "demarretokenlist", "demarretokens", "demarretransparent", "demarretypescript", "demarretypescriptcollection", "demarretyping", "demarreuniqueMPgraphic", "demarreuniqueMPpagegraphic", "demarreunittext", "demarreunpacked", "demarreusableMPgraphic", "demarreuseMPgraphic", "demarreusemathstyleparameter", "demarreuserdata", "demarreusingbtxspecification", "demarreva", "demarrevbox", "demarrevboxregister", "demarrevboxtohbox", "demarrevboxtohboxseparator", "demarreviewerlayer", "demarrevtop", "demarrevtopregister", "demarrexcell", "demarrexcellgroup", "demarrexcolumn", "demarrexgroup", "demarrexmldisplayverbatim", "demarrexmlinlineverbatim", "demarrexmlraw", "demarrexmlsetups", "demarrexrow", "demarrexrowgroup", "demarrextable", "demarrextablebody", "demarrextablefoot", "demarrextablehead", "demarrextablenext", "determinecaracteristiqueliste", "determinecaracteristiquesregistre", "determinenumerotete", "echelle", "ecran", "ecritdansliste", "ecritentreliste", "element", "elements", "environement", "espace", "espacefixe", "espacesfixes", "etire", "faitreference", "fichierdactylo", "figureexterne", "gardeblocs", "grille", "haut", "inconnu", "installelangue", "joursemaine", "langue", "langueprincipale", "largeurligne", "ligneh", "lignenoire", "ligneregleetexte", "lignesnoires", "llongueurliste", "marquage", "marquepage", "mathematique", "menuinteraction", "mois", "montrecadre", "montrecouleur", "montredisposition", "montreedition", "montreenvironnementpolicecorps", "montregrille", "montregroupecouleur", "montrejeusymboles", "montremakeup", "montrepalette", "montrepolicecorps", "montrereglages", "montrestruts", "motdroit", "numeroformule", "numeropage", "numeros", "numerotete", "numerotetecourant", "obtientmarquage", "oriente", "periodes", "pilechamp", "placecoteacote", "placeflottant", "placeformule", "placelesunsaudessusdesautres", "placeliste", "placelisteinmbriquee", "placemarquespages", "placenotespdp", "placenotespdplocales", "placenumeropage", "placenumerotete", "placeregistre", "placesousformule", "placesurgrille", "placetextetete", "prendbuffer", "produit", "programme", "projet", "qqpart", "razmarquage", "referencepage", "referencetexte", "reflete", "reglealignement", "reglearrangement", "reglearriereplan", "reglearriereplans", "reglebarreinteraction", "reglebloc", "regleblocsection", "reglebuffer", "reglecapitales", "reglechamp", "reglechamps", "regleclipping", "reglecolonnes", "reglecommentaire", "reglecommentairepage", "reglecompoetroite", "reglecomposeenalinea", "reglecouleur", "reglecouleurs", "regledactylo", "regledemarrestoppe", "regledisposition", "regleecraninteraction", "regleelements", "regleencadre", "regleentete", "regleenumerations", "regleepaisseurligne", "regleespaceblanc", "regleespacement", "regleespacementinterligne", "regleflottant", "regleflottants", "regleformulaires", "regleformules", "reglegroupeselements", "regleinf", "regleinteraction", "regleintitule", "regleintitules", "reglejeucolonne", "reglejeusymboles", "reglelangue", "reglelignes", "reglelignesnoires", "reglelignesreglestexte", "regleliste", "reglelisteimbriquee", "reglemakeup", "reglemargereglee", "reglemarquage", "reglemarquagehyphenation", "reglemenuinteraction", "reglenumeropage", "reglenumerotationligne", "reglenumerotationpage", "reglenumerotationparagraphe", "reglenumerotete", "regleoriente", "reglepalette", "reglepapier", "regleparagraphes", "reglepdp", "regleplacementopposition", "reglepolicecorps", "reglepositionnement", "regleprogrammes", "reglereferencage", "regleregistre", "regleremplitligne", "regleremplitlignesreglees", "regleseparationflottant", "reglesousnumeropage", "reglesup", "reglesynonymes", "regletableaux", "regletabulation", "regletaillepapier", "regletete", "regletetes", "regletexte", "regletextesentete", "regletextesinf", "regletextespdp", "regletextessup", "regletextestexte", "regletolerance", "regletraitsfins", "regletransitionspage", "regletri", "regletype", "regleurl", "remplitligne", "remplitlignesreglees", "remplittexte", "sansespace", "sanslignesenteteetpdp", "sanslignessupetinf", "selectionneblocs", "separeflottant", "settext", "sousnumeropage", "stoppeJScode", "stoppeJSpreamble", "stoppeLUA", "stoppeMP", "stoppeMPclip", "stoppeMPcode", "stoppeMPdefinitions", "stoppeMPdrawing", "stoppeMPenvironment", "stoppeMPextensions", "stoppeMPinclusions", "stoppeMPinitializations", "stoppeMPpage", "stoppeMPpositiongraphic", "stoppeMPpositionmethod", "stoppeMPrun", "stoppePARSEDXML", "stoppeTABLE", "stoppeTABLEbody", "stoppeTABLEfoot", "stoppeTABLEhead", "stoppeTABLEnext", "stoppeTC", "stoppeTD", "stoppeTDs", "stoppeTEX", "stoppeTEXpage", "stoppeTH", "stoppeTN", "stoppeTR", "stoppeTRs", "stoppeTX", "stoppeTY", "stoppeXML", "stoppealign", "stoppealigneadroite", "stoppealigneagauche", "stoppealigneaumilieu", "stoppealignment", "stoppeallmodes", "stoppeappendices", "stoppearrangedpages", "stoppearriereplan", "stoppeaside", "stoppeattachment", "stoppebackmatter", "stoppebar", "stoppebbordermatrix", "stoppebitmapimage", "stoppeblockquote", "stoppebodymatter", "stoppebordermatrix", "stoppeboxedcolumns", "stoppebtxlabeltext", "stoppebtxrenderingdefinitions", "stoppebuffer", "stoppecases", "stoppecatcodetable", "stoppecenteraligned", "stoppechapter", "stoppecharacteralign", "stoppecheckedfences", "stoppechemical", "stoppechemicaltext", "stoppecollect", "stoppecollecting", "stoppecolorintent", "stoppecoloronly", "stoppecolorset", "stoppecolumns", "stoppecolumnset", "stoppecolumnsetspan", "stoppecolumnspan", "stoppecombination", "stoppecomment", "stoppecomposant", "stoppecontextcode", "stoppecontextdefinitioncode", "stoppecouleur", "stoppectxfunction", "stoppectxfunctiondefinition", "stoppecurrentcolor", "stoppecurrentlistentrywrapper", "stoppedelimited", "stoppedelimitedtext", "stoppedisplaymath", "stoppedmath", "stoppedocument", "stoppeeffect", "stoppeelement", "stoppeembeddedxtable", "stoppeendnote", "stoppeendofline", "stoppeenvironement", "stoppeexceptions", "stoppeexpanded", "stoppeexpandedcollect", "stoppeextendedcatcodetable", "stoppeexternalfigurecollection", "stoppefacingfloat", "stoppefact", "stoppefigure", "stoppefiguretext", "stoppefittingpage", "stoppefixed", "stoppefloatcombination", "stoppefont", "stoppefontclass", "stoppefontsolution", "stoppefootnote", "stoppeformula", "stoppeformulas", "stoppeframed", "stoppeframedcell", "stoppeframedcontent", "stoppeframedrow", "stoppeframedtable", "stoppeframedtext", "stoppefrontmatter", "stoppegraphictext", "stoppegridsnapping", "stoppegroupe", "stoppehanging", "stoppehbox", "stoppehboxestohbox", "stoppehboxregister", "stoppeheadtext", "stoppehelptext", "stoppehiding", "stoppehighlight", "stoppehyphenation", "stoppeimath", "stoppeindentation", "stoppeindentedtext", "stoppeinteraction", "stoppeinterface", "stoppeintermezzotext", "stoppeintertext", "stoppeitemgroup", "stoppeitemgroupcolumns", "stoppeitemize", "stoppeknockout", "stoppelabeltext", "stoppelangue", "stoppelayout", "stoppelegend", "stoppeligne", "stoppeligneregleetexte", "stoppelinealignment", "stoppelinecorrection", "stoppelinefiller", "stoppelinenumbering", "stoppelines", "stoppelinetable", "stoppelinetablebody", "stoppelinetablecell", "stoppelinetablehead", "stoppelocalfootnotes", "stoppelocalheadsetup", "stoppelocallinecorrection", "stoppelocalnotes", "stoppelocalsetups", "stoppelua", "stoppeluacode", "stoppeluaparameterset", "stoppeluasetups", "stoppemakeup", "stoppemargereglee", "stoppemarginblock", "stoppemarkedcontent", "stoppemarkpages", "stoppemathalignment", "stoppemathcases", "stoppemathlabeltext", "stoppemathmatrix", "stoppemathmode", "stoppemathstyle", "stoppematrices", "stoppematrix", "stoppemaxaligned", "stoppemdformula", "stoppemenuinteraction", "stoppemiddlealigned", "stoppemiddlemakeup", "stoppemixedcolumns", "stoppemode", "stoppemodeset", "stoppemodule", "stoppemoduletestsection", "stoppempformula", "stoppenamedsection", "stoppenamedsubformulas", "stoppenarrow", "stoppenarrower", "stoppenegative", "stoppenicelyfilledbox", "stoppenointerference", "stoppenotallmodes", "stoppenotext", "stoppenotmode", "stoppeoperatortext", "stoppeopposite", "stoppeoutputstream", "stoppeoverlay", "stoppeoverprint", "stoppepagecolumns", "stoppepagecomment", "stoppepagefigure", "stoppepagelayout", "stoppepagemakeup", "stoppepar", "stoppeparagraph", "stoppeparagraphs", "stoppeparagraphscell", "stoppeparbuilder", "stoppepart", "stoppepath", "stoppeplacechemical", "stoppeplacefigure", "stoppeplaceflottant", "stoppeplaceformule", "stoppeplacegraphic", "stoppeplaceintermezzo", "stoppeplacelegend", "stoppeplacepairedbox", "stoppeplacetable", "stoppepositioning", "stoppepositionoverlay", "stoppepositive", "stoppepostponing", "stoppepostponingnotes", "stoppeprefixtext", "stoppeprocessassignmentcommand", "stoppeprocessassignmentlist", "stoppeprocesscommacommand", "stoppeprocesscommalist", "stoppeproduit", "stoppeprojet", "stoppeprotect", "stoppeprotectedcolors", "stoppepublication", "stoppepunctuation", "stoppequotation", "stoppequote", "stopperandomized", "stopperandomseed", "stopperawsetups", "stoppereadingfile", "stoppereferenceprefix", "stopperegime", "stoppereusableMPgraphic", "stopperuby", "stoppescript", "stoppesdformula", "stoppesection", "stoppesectionblock", "stoppesectionblockenvironment", "stoppesectionlevel", "stoppesetups", "stoppeshapebox", "stoppeshift", "stoppesidebar", "stoppesimplecolumns", "stoppespecialitem", "stoppespeech", "stoppespformula", "stoppesplitformula", "stoppesplittext", "stoppespread", "stoppestandardmakeup", "stoppestaticMPfigure", "stoppestaticMPgraphic", "stoppestrictinspectnextcharacter", "stoppestrut", "stoppestyle", "stoppesubformulas", "stoppesubject", "stoppesubjectlevel", "stoppesubsection", "stoppesubsentence", "stoppesubstack", "stoppesubsubject", "stoppesubsubsection", "stoppesubsubsubject", "stoppesubsubsubsection", "stoppesubsubsubsubject", "stoppesubsubsubsubsection", "stoppesubsubsubsubsubject", "stoppesuffixtext", "stoppesymbolset", "stoppetable", "stoppetablehead", "stoppetables", "stoppetabletail", "stoppetabletext", "stoppetabulate", "stoppetabulatehead", "stoppetabulatetail", "stoppetagged", "stoppetaglabeltext", "stoppetete", "stoppetexcode", "stoppetexdefinition", "stoppetext", "stoppetextbackground", "stoppetextbackgroundmanual", "stoppetextcolor", "stoppetextcolorintent", "stoppetextflow", "stoppetextmakeup", "stoppetitle", "stoppetokenlist", "stoppetokens", "stoppetransparent", "stoppetypescript", "stoppetypescriptcollection", "stoppetyping", "stoppeuniqueMPgraphic", "stoppeuniqueMPpagegraphic", "stoppeunittext", "stoppeunpacked", "stoppeusableMPgraphic", "stoppeuseMPgraphic", "stoppeusemathstyleparameter", "stoppeuserdata", "stoppeusingbtxspecification", "stoppeva", "stoppevbox", "stoppevboxregister", "stoppevboxtohbox", "stoppevboxtohboxseparator", "stoppeviewerlayer", "stoppevtop", "stoppevtopregister", "stoppexcell", "stoppexcellgroup", "stoppexcolumn", "stoppexgroup", "stoppexmldisplayverbatim", "stoppexmlinlineverbatim", "stoppexmlraw", "stoppexmlsetups", "stoppexrow", "stoppexrowgroup", "stoppextable", "stoppextablebody", "stoppextablefoot", "stoppextablehead", "stoppextablenext", "symbole", "tapebuffer", "textenotepdp", "traduire", "traiteblocs", "traitfin", "traitsfins", "uneligne", "utiliseJSscripts", "utiliseURL", "utiliseblocs", "utilisechemin", "utilisedocumentexterne", "utilisefigureexterne", "utilisemodule", "utilisepsiteaudioexterne", "utilisesymboles", "utiliseurl", "va", "vaalaboite", "vaalapage", "vaenbas", "valeurcouleur", "vide" },
+ ["it"]={ "GIORNOSETTIMANA", "Lettera", "Lettere", "MESE", "Numeri", "Numeriromani", "PAROLA", "PAROLE", "Parola", "Parole", "adattacampo", "adattalayout", "al", "allineacentro", "allineadestra", "allineasinistra", "ambiente", "ap", "apagina", "barracolori", "barrainterazione", "cambiaafontdeltesto", "campi", "capello", "chim", "circondato", "clonacampo", "colonna", "colore", "coloregrigio", "commento", "componenet", "confrontagruppocolori", "confrontatavolozza", "convertinumero", "copiacampo", "correggispaziobianco", "da", "daqualcheparte", "data", "datadioggi", "definisci", "definisciaccento", "definisciambientefontdeltesto", "definisciblocco", "definiscibloccosezione", "definiscibuffer", "definiscicampo", "definiscicapoversi", "definiscicarattere", "definiscicolore", "definiscicomando", "definisciconversione", "definiscidescrizione", "definiscidimensionicarta", "definiscielenco", "definiscielencocombinato", "definiscienumerazione", "definiscietichetta", "definiscifigurasimbolo", "definiscifont", "definiscifontdeltesto", "definisciformatoriferimento", "definiscigruppocolonne", "definiscigruppocolori", "definiscihbox", "definisciincorniciato", "definisciiniziatermina", "definiscilayout", "definiscimakeup", "definiscimarcatura", "definiscimenuinterazione", "definiscimodellotabella", "definiscioggettomobile", "definisciordinamento", "definisciprofilo", "definisciprogramma", "definisciregistro", "definisciriferimento", "definiscisezione", "definiscisimbolo", "definiscisinonimi", "definiscisinonimofont", "definiscisottocampo", "definiscisovrapposizione", "definiscistackcampi", "definiscistile", "definiscistilefont", "definiscitabulato", "definiscitavolozza", "definiscitesta", "definiscitesto", "definiscitestoincorniciato", "definiscitype", "definiscityping", "determinacaratteristicheregistro", "determinacarattersticheelenco", "determinanumerotesta", "elaborablocchi", "elementi", "elemento", "figuraesterna", "giornosettimana", "griglia", "ignoto", "impostaallineamento", "impostaampiezzariga", "impostabarrainterazione", "impostablocco", "impostabloccosezione", "impostabuffer", "impostacampi", "impostacampo", "impostacapoversi", "impostacaption", "impostacaptions", "impostacima", "impostaclippling", "impostacolonne", "impostacolore", "impostacolori", "impostacommento", "impostacommentopagina", "impostadimensionicarta", "impostaelementi", "impostaelencazioni", "impostaelenco", "impostaelencocombinato", "impostaenumerazioni", "impostafondo", "impostafontdeltesto", "impostaforms", "impostaformule", "impostagruppocolonne", "impostaincorniciato", "impostainiziatermina", "impostainstestazione", "impostainterazione", "impostainterlinea", "impostalayout", "impostalineemargine", "impostalineenere", "impostalineeriempimento", "impostalineesottili", "impostalineetesto", "impostalingua", "impostamaiuscole", "impostamakeup", "impostamarcatura", "impostamenuinterazione", "impostamenzione", "impostanumerazionecapoversi", "impostanumerazionepagina", "impostanumerazionerighe", "impostanumeropagina", "impostanumerosottopagina", "impostanumerotesta", "impostaoggettimobili", "impostaoggettomobile", "impostaordinamento", "impostaparranging", "impostapdp", "impostapiustretto", "impostaposizionamento", "impostaposizionamentoopposti", "impostaprogrammi", "impostaregistro", "impostarientro", "impostariferimento", "impostarighe", "impostarigheriempimento", "impostarigovuoto", "impostarotazione", "impostaschermointerazione", "impostasegnosillabazione", "impostasetsimboli", "impostasfondi", "impostasfondo", "impostasinonimi", "impostaspaziatura", "impostaspaziobianco", "impostaspezzamentooggettomobile", "impostatabelle", "impostatabulato", "impostatavolozza", "impostatesta", "impostateste", "impostatesticima", "impostatestifondo", "impostatestiincorniciati", "impostatestiintestazioni", "impostatestipdp", "impostatesto", "impostatestotesti", "impostatolleranza", "impostatransizionepagina", "impostatype", "impostatyping", "impostaurl", "incorniciato", "iniziaJScode", "iniziaJSpreamble", "iniziaLUA", "iniziaMP", "iniziaMPclip", "iniziaMPcode", "iniziaMPdefinitions", "iniziaMPdrawing", "iniziaMPenvironment", "iniziaMPextensions", "iniziaMPinclusions", "iniziaMPinitializations", "iniziaMPpage", "iniziaMPpositiongraphic", "iniziaMPpositionmethod", "iniziaMPrun", "iniziaPARSEDXML", "iniziaTABLE", "iniziaTABLEbody", "iniziaTABLEfoot", "iniziaTABLEhead", "iniziaTABLEnext", "iniziaTC", "iniziaTD", "iniziaTDs", "iniziaTEX", "iniziaTEXpage", "iniziaTH", "iniziaTN", "iniziaTR", "iniziaTRs", "iniziaTX", "iniziaTY", "iniziaXML", "iniziaalign", "iniziaalignment", "iniziaallineacentro", "iniziaallineadestra", "iniziaallineasinistra", "iniziaallmodes", "iniziaambiente", "iniziaappendices", "iniziaarrangedpages", "iniziaaside", "iniziaattachment", "iniziabackmatter", "iniziabar", "iniziabbordermatrix", "iniziabitmapimage", "iniziablockquote", "iniziabodymatter", "iniziabordermatrix", "iniziaboxedcolumns", "iniziabtxlabeltext", "iniziabtxrenderingdefinitions", "iniziabuffer", "iniziacases", "iniziacatcodetable", "iniziacenteraligned", "iniziachapter", "iniziacharacteralign", "iniziacheckedfences", "iniziachemical", "iniziachemicaltext", "iniziacollect", "iniziacollecting", "iniziacolore", "iniziacolorintent", "iniziacoloronly", "iniziacolorset", "iniziacolumns", "iniziacolumnset", "iniziacolumnsetspan", "iniziacolumnspan", "iniziacombination", "iniziacomment", "iniziacomponenet", "iniziacontextcode", "iniziacontextdefinitioncode", "iniziactxfunction", "iniziactxfunctiondefinition", "iniziacurrentcolor", "iniziacurrentlistentrywrapper", "iniziadelimited", "iniziadelimitedtext", "iniziadisplaymath", "iniziadmath", "iniziadocument", "iniziaeffect", "iniziaelement", "iniziaelemento", "iniziaembeddedxtable", "iniziaendnote", "iniziaendofline", "iniziaexceptions", "iniziaexpanded", "iniziaexpandedcollect", "iniziaextendedcatcodetable", "iniziaexternalfigurecollection", "iniziafacingfloat", "iniziafact", "iniziafigure", "iniziafiguretext", "iniziafittingpage", "iniziafixed", "iniziafloatcombination", "iniziafont", "iniziafontclass", "iniziafontsolution", "iniziafootnote", "iniziaformula", "iniziaformulas", "iniziaframedcell", "iniziaframedcontent", "iniziaframedrow", "iniziaframedtable", "iniziaframedtext", "iniziafrontmatter", "iniziagraphictext", "iniziagridsnapping", "iniziahanging", "iniziahbox", "iniziahboxestohbox", "iniziahboxregister", "iniziaheadtext", "iniziahelptext", "iniziahiding", "iniziahighlight", "iniziahyphenation", "iniziaimath", "iniziaimpaccato", "iniziaincorniciato", "iniziaindentation", "iniziaindentedtext", "iniziainteraction", "iniziainterface", "iniziaintermezzotext", "iniziaintertext", "iniziaitemgroup", "iniziaitemgroupcolumns", "iniziaitemize", "iniziaknockout", "inizialabeltext", "inizialayout", "inizialegend", "inizialinealignment", "inizialineamargine", "inizialineatesto", "inizialinecorrection", "inizialinefiller", "inizialinenumbering", "inizialines", "inizialinetable", "inizialinetablebody", "inizialinetablecell", "inizialinetablehead", "inizialingua", "inizialocalfootnotes", "inizialocalheadsetup", "inizialocallinecorrection", "inizialocalnotes", "inizialocalsetups", "inizialua", "inizialuacode", "inizialuaparameterset", "inizialuasetups", "iniziamakeup", "iniziamarginblock", "iniziamarkedcontent", "iniziamarkpages", "iniziamathalignment", "iniziamathcases", "iniziamathlabeltext", "iniziamathmatrix", "iniziamathmode", "iniziamathstyle", "iniziamatrices", "iniziamatrix", "iniziamaxaligned", "iniziamdformula", "iniziamenuinterattivo", "iniziamettiformula", "iniziamiddlealigned", "iniziamiddlemakeup", "iniziamixedcolumns", "iniziamode", "iniziamodeset", "iniziamodule", "iniziamoduletestsection", "iniziampformula", "inizianamedsection", "inizianamedsubformulas", "inizianarrow", "inizianarrower", "inizianegative", "inizianicelyfilledbox", "inizianointerference", "inizianotallmodes", "inizianotext", "inizianotmode", "iniziaoperatortext", "iniziaopposite", "iniziaoutputstream", "iniziaoverlay", "iniziaoverprint", "iniziapagecolumns", "iniziapagecomment", "iniziapagefigure", "iniziapagelayout", "iniziapagemakeup", "iniziapar", "iniziaparagraph", "iniziaparagraphs", "iniziaparagraphscell", "iniziaparbuilder", "iniziapart", "iniziapath", "iniziaplacechemical", "iniziaplacefigure", "iniziaplacefloat", "iniziaplacegraphic", "iniziaplaceintermezzo", "iniziaplacelegend", "iniziaplacepairedbox", "iniziaplacetable", "iniziapositioning", "iniziapositionoverlay", "iniziapositive", "iniziapostponing", "iniziapostponingnotes", "iniziaprefixtext", "iniziaprocessassignmentcommand", "iniziaprocessassignmentlist", "iniziaprocesscommacommand", "iniziaprocesscommalist", "iniziaprodotto", "iniziaprogetto", "iniziaprotect", "iniziaprotectedcolors", "iniziapubblicazione", "iniziapunctuation", "iniziaquotation", "iniziaquote", "iniziarandomized", "iniziarandomseed", "iniziarawsetups", "iniziareadingfile", "iniziareferenceprefix", "iniziaregime", "iniziareusableMPgraphic", "iniziariga", "iniziaruby", "iniziascript", "iniziasdformula", "iniziasection", "iniziasectionblock", "iniziasectionblockenvironment", "iniziasectionlevel", "iniziasetups", "iniziasfondo", "iniziashapebox", "iniziashift", "iniziasidebar", "iniziasimplecolumns", "iniziaspecialitem", "iniziaspeech", "iniziaspformula", "iniziasplitformula", "iniziasplittext", "iniziaspread", "iniziastandardmakeup", "iniziastaticMPfigure", "iniziastaticMPgraphic", "iniziastrictinspectnextcharacter", "iniziastrut", "iniziastyle", "iniziasubformulas", "iniziasubject", "iniziasubjectlevel", "iniziasubsection", "iniziasubsentence", "iniziasubstack", "iniziasubsubject", "iniziasubsubsection", "iniziasubsubsubject", "iniziasubsubsubsection", "iniziasubsubsubsubject", "iniziasubsubsubsubsection", "iniziasubsubsubsubsubject", "iniziasuffixtext", "iniziasymbolset", "iniziatable", "iniziatablehead", "iniziatables", "iniziatabletail", "iniziatabletext", "iniziatabulate", "iniziatabulatehead", "iniziatabulatetail", "iniziatagged", "iniziataglabeltext", "iniziatesta", "iniziatexcode", "iniziatexdefinition", "iniziatext", "iniziatextbackground", "iniziatextbackgroundmanual", "iniziatextcolor", "iniziatextcolorintent", "iniziatextflow", "iniziatextmakeup", "iniziatitle", "iniziatokenlist", "iniziatokens", "iniziatransparent", "iniziatypescript", "iniziatypescriptcollection", "iniziatyping", "iniziauniqueMPgraphic", "iniziauniqueMPpagegraphic", "iniziaunittext", "iniziaunpacked", "iniziausableMPgraphic", "iniziauseMPgraphic", "iniziausemathstyleparameter", "iniziauserdata", "iniziausingbtxspecification", "iniziavaia", "iniziavbox", "iniziavboxregister", "iniziavboxtohbox", "iniziavboxtohboxseparator", "iniziaviewerlayer", "iniziavtop", "iniziavtopregister", "iniziaxcell", "iniziaxcellgroup", "iniziaxcolumn", "iniziaxgroup", "iniziaxmldisplayverbatim", "iniziaxmlinlineverbatim", "iniziaxmlraw", "iniziaxmlsetups", "iniziaxrow", "iniziaxrowgroup", "iniziaxtable", "iniziaxtablebody", "iniziaxtablefoot", "iniziaxtablehead", "iniziaxtablenext", "inriga", "installalingua", "intorno", "lettera", "lettere", "lineanera", "lineasottile", "lineatesto", "lineenere", "lineeriempimento", "lineesottili", "lingua", "linguaprincipale", "lunghezzaelenco", "marcatura", "matematica", "menuinterattivo", "mese", "mettielenco", "mettielencocombinato", "mettifiancoafianco", "mettiformula", "mettiingriglia", "mettinotepdp", "mettinotepdplocali", "mettinumeropagina", "mettiregistro", "mettisegnalibro", "mettisottoformula", "mettiunosullaltro", "mostraambientefontdeltesto", "mostracolore", "mostracornice", "mostrafontdeltesto", "mostragriglia", "mostragruppocolori", "mostraimpostazioni", "mostralyout", "mostramakeup", "mostrasetsimboli", "mostrastampa", "mostrastruts", "mostratavolozza", "nascondiblocchi", "nientelineecimafondo", "nientelineintestazionepdp", "nientespazio", "nota", "numeri", "numeriromani", "numeroformula", "numeropagina", "numeropaginacompleto", "numerotesta", "numerotestacorrente", "pagina", "paroladestra", "ped", "pedap", "perlungo", "posizionanumerotesta", "posizionatestotesta", "posizione", "prendibuffer", "prendimarcatura", "prodotto", "progetto", "programma", "pulsante", "pulsantemenu", "pulsantinterazione", "punti", "qualcheriga", "reimpostamarcatura", "rif", "riferimento", "riferimentopagina", "riferimentotesto", "riflessione", "rigariempimento", "rigovuoto", "ruota", "scala", "schermo", "scrividentroelenco", "scriviinelenco", "segnalibro", "selezionablocchi", "settext", "sfondo", "simbolo", "spazifissi", "spazio", "spaziofisso", "spessoreriga", "spezzaoggettomobile", "stackcampi", "stirato", "terminaJScode", "terminaJSpreamble", "terminaLUA", "terminaMP", "terminaMPclip", "terminaMPcode", "terminaMPdefinitions", "terminaMPdrawing", "terminaMPenvironment", "terminaMPextensions", "terminaMPinclusions", "terminaMPinitializations", "terminaMPpage", "terminaMPpositiongraphic", "terminaMPpositionmethod", "terminaMPrun", "terminaPARSEDXML", "terminaTABLE", "terminaTABLEbody", "terminaTABLEfoot", "terminaTABLEhead", "terminaTABLEnext", "terminaTC", "terminaTD", "terminaTDs", "terminaTEX", "terminaTEXpage", "terminaTH", "terminaTN", "terminaTR", "terminaTRs", "terminaTX", "terminaTY", "terminaXML", "terminaalign", "terminaalignment", "terminaallineacentro", "terminaallineadestra", "terminaallineasinistra", "terminaallmodes", "terminaambiente", "terminaappendices", "terminaarrangedpages", "terminaaside", "terminaattachment", "terminabackmatter", "terminabar", "terminabbordermatrix", "terminabitmapimage", "terminablockquote", "terminabodymatter", "terminabordermatrix", "terminaboxedcolumns", "terminabtxlabeltext", "terminabtxrenderingdefinitions", "terminabuffer", "terminacases", "terminacatcodetable", "terminacenteraligned", "terminachapter", "terminacharacteralign", "terminacheckedfences", "terminachemical", "terminachemicaltext", "terminacollect", "terminacollecting", "terminacolore", "terminacolorintent", "terminacoloronly", "terminacolorset", "terminacolumns", "terminacolumnset", "terminacolumnsetspan", "terminacolumnspan", "terminacombination", "terminacomment", "terminacomponenet", "terminacontextcode", "terminacontextdefinitioncode", "terminactxfunction", "terminactxfunctiondefinition", "terminacurrentcolor", "terminacurrentlistentrywrapper", "terminadelimited", "terminadelimitedtext", "terminadisplaymath", "terminadmath", "terminadocument", "terminaeffect", "terminaelement", "terminaelemento", "terminaembeddedxtable", "terminaendnote", "terminaendofline", "terminaexceptions", "terminaexpanded", "terminaexpandedcollect", "terminaextendedcatcodetable", "terminaexternalfigurecollection", "terminafacingfloat", "terminafact", "terminafigure", "terminafiguretext", "terminafittingpage", "terminafixed", "terminafloatcombination", "terminafont", "terminafontclass", "terminafontsolution", "terminafootnote", "terminaformula", "terminaformulas", "terminaframedcell", "terminaframedcontent", "terminaframedrow", "terminaframedtable", "terminaframedtext", "terminafrontmatter", "terminagraphictext", "terminagridsnapping", "terminahanging", "terminahbox", "terminahboxestohbox", "terminahboxregister", "terminaheadtext", "terminahelptext", "terminahiding", "terminahighlight", "terminahyphenation", "terminaimath", "terminaimpaccato", "terminaincorniciato", "terminaindentation", "terminaindentedtext", "terminainteraction", "terminainterface", "terminaintermezzotext", "terminaintertext", "terminaitemgroup", "terminaitemgroupcolumns", "terminaitemize", "terminaknockout", "terminalabeltext", "terminalayout", "terminalegend", "terminalinealignment", "terminalineamargine", "terminalineatesto", "terminalinecorrection", "terminalinefiller", "terminalinenumbering", "terminalines", "terminalinetable", "terminalinetablebody", "terminalinetablecell", "terminalinetablehead", "terminalingua", "terminalocalfootnotes", "terminalocalheadsetup", "terminalocallinecorrection", "terminalocalnotes", "terminalocalsetups", "terminalua", "terminaluacode", "terminaluaparameterset", "terminaluasetups", "terminamakeup", "terminamarginblock", "terminamarkedcontent", "terminamarkpages", "terminamathalignment", "terminamathcases", "terminamathlabeltext", "terminamathmatrix", "terminamathmode", "terminamathstyle", "terminamatrices", "terminamatrix", "terminamaxaligned", "terminamdformula", "terminamenuinterattivo", "terminamettiformula", "terminamiddlealigned", "terminamiddlemakeup", "terminamixedcolumns", "terminamode", "terminamodeset", "terminamodule", "terminamoduletestsection", "terminampformula", "terminanamedsection", "terminanamedsubformulas", "terminanarrow", "terminanarrower", "terminanegative", "terminanicelyfilledbox", "terminanointerference", "terminanotallmodes", "terminanotext", "terminanotmode", "terminaoperatortext", "terminaopposite", "terminaoutputstream", "terminaoverlay", "terminaoverprint", "terminapagecolumns", "terminapagecomment", "terminapagefigure", "terminapagelayout", "terminapagemakeup", "terminapar", "terminaparagraph", "terminaparagraphs", "terminaparagraphscell", "terminaparbuilder", "terminapart", "terminapath", "terminaplacechemical", "terminaplacefigure", "terminaplacefloat", "terminaplacegraphic", "terminaplaceintermezzo", "terminaplacelegend", "terminaplacepairedbox", "terminaplacetable", "terminapositioning", "terminapositionoverlay", "terminapositive", "terminapostponing", "terminapostponingnotes", "terminaprefixtext", "terminaprocessassignmentcommand", "terminaprocessassignmentlist", "terminaprocesscommacommand", "terminaprocesscommalist", "terminaprodotto", "terminaprogetto", "terminaprotect", "terminaprotectedcolors", "terminapubblicazione", "terminapunctuation", "terminaquotation", "terminaquote", "terminarandomized", "terminarandomseed", "terminarawsetups", "terminareadingfile", "terminareferenceprefix", "terminaregime", "terminareusableMPgraphic", "terminariga", "terminaruby", "terminascript", "terminasdformula", "terminasection", "terminasectionblock", "terminasectionblockenvironment", "terminasectionlevel", "terminasetups", "terminasfondo", "terminashapebox", "terminashift", "terminasidebar", "terminasimplecolumns", "terminaspecialitem", "terminaspeech", "terminaspformula", "terminasplitformula", "terminasplittext", "terminaspread", "terminastandardmakeup", "terminastaticMPfigure", "terminastaticMPgraphic", "terminastrictinspectnextcharacter", "terminastrut", "terminastyle", "terminasubformulas", "terminasubject", "terminasubjectlevel", "terminasubsection", "terminasubsentence", "terminasubstack", "terminasubsubject", "terminasubsubsection", "terminasubsubsubject", "terminasubsubsubsection", "terminasubsubsubsubject", "terminasubsubsubsubsection", "terminasubsubsubsubsubject", "terminasuffixtext", "terminasymbolset", "terminatable", "terminatablehead", "terminatables", "terminatabletail", "terminatabletext", "terminatabulate", "terminatabulatehead", "terminatabulatetail", "terminatagged", "terminataglabeltext", "terminatesta", "terminatexcode", "terminatexdefinition", "terminatext", "terminatextbackground", "terminatextbackgroundmanual", "terminatextcolor", "terminatextcolorintent", "terminatextflow", "terminatextmakeup", "terminatitle", "terminatokenlist", "terminatokens", "terminatransparent", "terminatypescript", "terminatypescriptcollection", "terminatyping", "terminauniqueMPgraphic", "terminauniqueMPpagegraphic", "terminaunittext", "terminaunpacked", "terminausableMPgraphic", "terminauseMPgraphic", "terminausemathstyleparameter", "terminauserdata", "terminausingbtxspecification", "terminavaia", "terminavbox", "terminavboxregister", "terminavboxtohbox", "terminavboxtohboxseparator", "terminaviewerlayer", "terminavtop", "terminavtopregister", "terminaxcell", "terminaxcellgroup", "terminaxcolumn", "terminaxgroup", "terminaxmldisplayverbatim", "terminaxmlinlineverbatim", "terminaxmlraw", "terminaxmlsetups", "terminaxrow", "terminaxrowgroup", "terminaxtable", "terminaxtablebody", "terminaxtablefoot", "terminaxtablehead", "terminaxtablenext", "testonotapdp", "testoriempimento", "tieniblocchi", "traduci", "usaJSscripts", "usaURL", "usablocco", "usacartella", "usacolonnasonoraesterna", "usadocumentoesterno", "usafiguraesterna", "usamodulo", "usasimboli", "usaurl", "vaia", "vaiabox", "vaiapagina", "vaigiu", "valorecolore", "versione" },
+ ["nl"]={ "Cijfers", "Kap", "Letter", "Letters", "MAAND", "Romeins", "WEEKDAG", "WOORD", "WOORDEN", "Woord", "Woorden", "achtergrond", "bepaalkopnummer", "bepaallijstkenmerken", "bepaalregisterkenmerken", "bewaarbuffer", "blanko", "blokje", "blokjes", "cijfers", "converteernummer", "copieerveld", "corrigeerwitruimte", "datum", "definieer", "definieeraccent", "definieeralineas", "definieerblok", "definieerbuffer", "definieercombinatie", "definieercommando", "definieerconversie", "definieerfiguursymbool", "definieerfont", "definieerfontstijl", "definieerfontsynoniem", "definieerhbox", "definieeringesprongentext", "definieerinteractiemenu", "definieeritemgroep", "definieerkadertekst", "definieerkarakter", "definieerkleur", "definieerkleurgroep", "definieerkolomgroep", "definieerkolomovergang", "definieerkop", "definieerkorps", "definieerkorpsomgeving", "definieerlayer", "definieerlayout", "definieerletter", "definieerlijst", "definieermarkering", "definieeromlijnd", "definieeropmaak", "definieeroverlay", "definieerpaginaovergang", "definieerpalet", "definieerpapierformaat", "definieerplaats", "definieerplaatsblok", "definieerprofiel", "definieerprogramma", "definieerreferentie", "definieerreferentieformaat", "definieerregister", "definieersamengesteldelijst", "definieersectie", "definieersectieblok", "definieersorteren", "definieerstartstop", "definieersubveld", "definieersymbool", "definieersynoniemen", "definieertabelvorm", "definieertabulatie", "definieertekst", "definieertekstachtergrond", "definieertype", "definieertypen", "definieerveld", "definieerveldstapel", "definieerwiskundeuitlijnen", "doordefinieren", "doorlabelen", "doornummeren", "dunnelijn", "dunnelijnen", "eenregel", "ergens", "externfiguur", "formulenummer", "gebruikJSscripts", "gebruikURL", "gebruikblokken", "gebruikexterndocument", "gebruikexternfiguur", "gebruikexterngeluidsfragment", "gebruikmodule", "gebruikpad", "gebruiksymbolen", "gebruiktypescript", "gebruiktypescriptfile", "gebruikurl", "geenbovenenonderregels", "geenhoofdenvoetregels", "geenspatie", "grijskleur", "haalbuffer", "haalmarkering", "haarlijn", "handhaafblokken", "hoofdtaal", "hoog", "huidigedatum", "huidigekopnummer", "inlijnd", "inregel", "installeertaal", "interactiebalk", "interactiebuttons", "interactiemenu", "invullijnen", "invulregel", "invultekst", "kleur", "kleurenbalk", "kleurwaarde", "kloonveld", "kolom", "kopnummer", "laag", "laho", "legeregels", "letter", "letters", "lijndikte", "lijstlengte", "maand", "markeer", "naar", "naarbox", "naarpagina", "nokap", "noot", "omgeving", "omlaag", "omlijnd", "onbekend", "onderdeel", "op", "oppagina", "pagina", "paginanummer", "paginareferentie", "paslayoutaan", "passendveld", "plaatsbookmarks", "plaatsformule", "plaatskopnummer", "plaatskoptekst", "plaatslijst", "plaatslijstmetsynoniemen", "plaatslokalevoetnoten", "plaatsnaastelkaar", "plaatsonderelkaar", "plaatsopgrid", "plaatspaginanummer", "plaatsplaatsblok", "plaatsregister", "plaatsruwelijst", "plaatssamengesteldelijst", "plaatssubformule", "plaatsvoetnoten", "positioneer", "produkt", "programma", "projekt", "punten", "refereer", "referentie", "regellinks", "regelmidden", "regelrechts", "resetmarkering", "romeins", "rooster", "roteer", "schaal", "scherm", "schrijfnaarlijst", "schrijftussenlijst", "selecteerblokken", "som", "spatie", "spiegel", "splitsplaatsblok", "startachtergrond", "startinteractiemenu", "startkantlijn", "startkleur", "startkop", "startlokalevoetnoten", "startmargeblok", "startnaar", "startomgeving", "startomlijnd", "startonderdeel", "startopelkaar", "startplaatsformule", "startplaatsplaatsblok", "startprodukt", "startprojekt", "startpublicatie", "startregel", "startregelcorrectie", "startregellinks", "startregelmidden", "startregelrechts", "startsom", "starttaal", "starttekstachtergrond", "starttekstlijn", "startuitlijnen", "stelachtergrondenin", "stelachtergrondin", "stelalineasin", "stelarrangerenin", "stelblankoin", "stelblokin", "stelblokjesin", "stelblokkopjein", "stelblokkopjesin", "stelbovenin", "stelboventekstenin", "stelbufferin", "stelciterenin", "stelclipin", "stelcommentaarin", "steldoordefinierenin", "steldoornummerenin", "steldunnelijnenin", "stelformulein", "stelformulesin", "stelformulierenin", "stelhoofdin", "stelhoofdtekstenin", "stelingesprongentextin", "stelinmargein", "stelinspringenin", "stelinteractiebalkin", "stelinteractiein", "stelinteractiemenuin", "stelinteractieschermin", "stelinterliniein", "stelinvullijnenin", "stelinvulregelsin", "stelitemgroepin", "stelitemsin", "stelkadertekstenin", "stelkadertekstin", "stelkantlijnin", "stelkapitalenin", "stelkleurenin", "stelkleurin", "stelkolomgroepin", "stelkolomgroepregelsin", "stelkolomgroepstartin", "stelkolommenin", "stelkopin", "stelkopnummerin", "stelkoppeltekenin", "stelkoppenin", "stelkorpsin", "stellayoutin", "stellijndiktein", "stellijstin", "stelmargeblokkenin", "stelmarkeringin", "stelnaastplaatsenin", "stelomlijndin", "stelonderin", "stelondertekstenin", "stelopmaakin", "stelopsommingenin", "stelpaginacommentaarin", "stelpaginanummerin", "stelpaginanummeringin", "stelpaginaovergangenin", "stelpaletin", "stelpapierformaatin", "stelpapierin", "stelparagraafnummerenin", "stelplaatsblokin", "stelplaatsblokkenin", "stelplaatsbloksplitsenin", "stelplaatsin", "stelpositionerenin", "stelprogrammasin", "stelrefererenin", "stelregelnummerenin", "stelregelsin", "stelregisterin", "stelroterenin", "stelsamengesteldelijstin", "stelsectieblokin", "stelsmallerin", "stelsorterenin", "stelspatieringin", "stelstartstopin", "stelsubpaginanummerin", "stelsymboolsetin", "stelsynoniemenin", "steltaalin", "steltabellenin", "steltabulatiein", "steltekstachtergrondin", "steltekstin", "steltekstinhoudin", "steltekstlijnenin", "stelteksttekstenin", "steltolerantiein", "steltypein", "steltypenin", "steluitlijnenin", "stelurlin", "stelveldenin", "stelveldin", "stelvoetin", "stelvoettekstenin", "stelwiskundeuitlijnenin", "stelwitruimtein", "stopachtergrond", "stopinteractiemenu", "stopkantlijn", "stopkleur", "stopkop", "stoplokalevoetnoten", "stopmargeblok", "stopnaar", "stopomgeving", "stopomlijnd", "stoponderdeel", "stopopelkaar", "stopplaatsformule", "stopplaatsplaatsblok", "stopprodukt", "stopprojekt", "stoppublicatie", "stopregel", "stopregelcorrectie", "stopregellinks", "stopregelmidden", "stopregelrechts", "stopsom", "stoptaal", "stoptekstachtergrond", "stoptekstlijn", "stopuitlijnen", "subpaginanummer", "switchnaarkorps", "symbool", "taal", "tekstlijn", "tekstreferentie", "testkolom", "testpagina", "toelichting", "toongrid", "tooninstellingen", "toonkader", "toonkleur", "toonkleurgroep", "toonkorps", "toonkorpsomgeving", "toonlayout", "toonopmaak", "toonpalet", "toonprint", "toonstruts", "toonsymboolset", "uit", "uitgerekt", "vastespatie", "vastespaties", "veld", "veldstapel", "verbergblokken", "vergelijkkleurgroep", "vergelijkpalet", "versie", "vertaal", "verwerkblokken", "voetnoottekst", "volledigepaginanummer", "volledigregister", "voluit", "weekdag", "wiskunde", "woordrechts" },
+ ["pe"]={ "آیتم", "آیتمها", "آینه", "از", "استفاده‌بلوکها", "استفاده‌دستخط‌تایپ", "استفاده‌شکل‌خارجی", "استفاده‌قطعه‌موزیک‌خارجی", "استفاده‌مدول", "استفاده‌مسیر", "استفاده‌نمادها", "استفاده‌نوشتارخارجی", "استفاده‌پرونده‌دستخط‌تایپ", "اعدادلاتین", "افزودن", "انتخاب‌بلوکها", "بارگذاری‌آرایش", "بارگذاری‌آیتمها", "بارگذاری‌ارجاع", "بارگذاری‌اندازه‌برگ", "بارگذاری‌باریکتر", "بارگذاری‌بافر", "بارگذاری‌بالا", "بارگذاری‌بردباری", "بارگذاری‌برنامه‌ها", "بارگذاری‌برگ", "بارگذاری‌بلوک", "بارگذاری‌بلوک‌بخش", "بارگذاری‌تایپ", "بارگذاری‌تایپ‌کردن", "بارگذاری‌ترتیب", "بارگذاری‌تنظیم", "بارگذاری‌تنظیم‌ریاضی", "بارگذاری‌ته‌برگ", "بارگذاری‌تورفتگی", "بارگذاری‌توضیح", "بارگذاری‌توضیح‌صفحه", "بارگذاری‌ثبت", "بارگذاری‌جانشانی", "بارگذاری‌جدولها", "بارگذاری‌جدول‌بندی", "بارگذاری‌خالی", "بارگذاری‌خطها", "بارگذاری‌خطهای‌حاشیه", "بارگذاری‌خطهای‌سیاه", "بارگذاری‌خطهای‌متن", "بارگذاری‌خطهای‌مجموعه‌ستون", "بارگذاری‌خطها‌ی‌نازک", "بارگذاری‌درج‌درخطها", "بارگذاری‌درج‌مخالف", "بارگذاری‌دوران", "بارگذاری‌رنگ", "بارگذاری‌رنگها", "بارگذاری‌زبان", "بارگذاری‌ستونها", "بارگذاری‌سر", "بارگذاری‌سربرگ", "بارگذاری‌سرها", "بارگذاری‌شرح", "بارگذاری‌شرحها", "بارگذاری‌شروع‌مجموعه‌ستون", "بارگذاری‌شروع‌پایان", "بارگذاری‌شماره‌زیرصفحه", "بارگذاری‌شماره‌سر", "بارگذاری‌شماره‌صفحه", "بارگذاری‌شماره‌گذاریها", "بارگذاری‌شماره‌گذاری‌صفحه", "بارگذاری‌شماره‌گذاری‌پاراگراف", "بارگذاری‌شماره‌‌گذاری‌خط", "بارگذاری‌شناور", "بارگذاری‌شناورها", "بارگذاری‌شکافتن‌شناورها", "بارگذاری‌طرح", "بارگذاری‌طرح‌بندی", "بارگذاری‌عرض‌خط", "بارگذاری‌فاصله‌بین‌خط", "بارگذاری‌فرمولها", "بارگذاری‌فضای‌سفید", "بارگذاری‌فضا‌گذاری", "بارگذاری‌قالبی", "بارگذاری‌قلم‌متن", "بارگذاری‌لوح", "بارگذاری‌لیست", "بارگذاری‌لیست‌ترکیبی", "بارگذاری‌مترادفها", "بارگذاری‌متن", "بارگذاری‌متنهای‌بالا", "بارگذاری‌متن‌سربرگ", "بارگذاری‌متن‌قالبی", "بارگذاری‌متن‌متنها", "بارگذاری‌متن‌پانوشت", "بارگذاری‌متن‌پایین", "بارگذاری‌مجموعه‌ستون", "بارگذاری‌مجموعه‌نماد", "بارگذاری‌منوی‌پانل", "بارگذاری‌مکان‌گذاری", "بارگذاری‌میدان", "بارگذاری‌میدانها", "بارگذاری‌میله‌پانل", "بارگذاری‌نشانه‌شکستن", "بارگذاری‌نشانه‌گذاری", "بارگذاری‌نقل", "بارگذاری‌پاراگرافها", "بارگذاری‌پانل", "بارگذاری‌پایین", "بارگذاری‌پرده‌پانل", "بارگذاری‌پرکردن‌خطها", "بارگذاری‌پس‌زمینه", "بارگذاری‌پس‌زمینه‌ها", "بارگذاری‌چیدن", "بارگذاری‌گذارصفحه", "بارگذاری‌گروههای‌آیتم", "بارگذاری‌گروه‌آیتم", "بازنشانی‌نشانه‌گذاری", "بدون‌خط‌بالاوپایین", "بدون‌خط‌سروته‌برگ", "بدون‌فضا", "برنامه", "بروبه", "بروبه‌جعبه", "بروبه‌صفحه", "بروپایین", "بلند", "بلوکهای‌پردازش", "بلوکها‌پنهان", "بنویس‌بین‌لیست", "بنویس‌در‌لیست", "تاریخ", "تاریخ‌جاری", "تایپ", "تایپ‌بافر", "تایپ‌پرونده", "ترجمه", "تعریف", "تعریف‌آرایش", "تعریف‌الگوی‌جدول", "تعریف‌اندازه‌برگ", "تعریف‌بافر", "تعریف‌بخش", "تعریف‌برنامه", "تعریف‌برچسب", "تعریف‌بلوک", "تعریف‌بلوک‌بخش", "تعریف‌تایپ", "تعریف‌تایپ‌کردن", "تعریف‌تبدیل", "تعریف‌ترتیب", "تعریف‌ترکیب", "تعریف‌تنظیم‌ریاضی", "تعریف‌توده‌میدان", "تعریف‌ثبت", "تعریف‌جانشانی", "تعریف‌جدول‌بندی", "تعریف‌جعبه‌‌افقی", "تعریف‌حرف", "تعریف‌رنگ", "تعریف‌زیرمیدان", "تعریف‌سبک", "تعریف‌سبک‌قلم", "تعریف‌سر", "تعریف‌شرح", "تعریف‌شروع‌پایان", "تعریف‌شماره‌بندی", "تعریف‌شمایل‌مرجع", "تعریف‌شناور", "تعریف‌شکستن‌ستون", "تعریف‌شکست‌صفحه", "تعریف‌طرح‌بندی", "تعریف‌فرمان", "تعریف‌قالبی", "تعریف‌قلم", "تعریف‌قلم‌متن", "تعریف‌لایه", "تعریف‌لهجه", "تعریف‌لوح", "تعریف‌لیست", "تعریف‌لیست‌ترکیبی", "تعریف‌مترادفها", "تعریف‌مترادف‌قلم", "تعریف‌متن", "تعریف‌متن‌قالبی", "تعریف‌مجموعه‌ستون", "تعریف‌محیط‌قلم‌بدنه", "تعریف‌مرجع", "تعریف‌منوی‌پانل", "تعریف‌میدان", "تعریف‌نشانه‌گذاری", "تعریف‌نماد", "تعریف‌نمادشکل", "تعریف‌پاراگرافها", "تعریف‌پروفایل", "تعریف‌پوشش", "تعریف‌گروه‌آیتم", "تعریف‌گروه‌رنگ", "تعیین‌شماره‌سر", "تعیین‌محتوای‌متن", "تعیین‌مشخصات‌ثبت", "تعیین‌مشخصات‌لیست", "تغییربه‌قلم‌بدنه", "تنظیم‌راست", "تنظیم‌طرح‌بندی", "تنظیم‌وسط", "توجه", "توری", "تولید", "تک", "ثبت‌کامل", "حرف", "حرفها", "حفظ‌بلوکها", "خالی", "خطهای‌سیاه", "خطهای‌نازک", "خطها‌خالی", "خط‌سیاه", "خط‌متن", "خط‌مو", "خط‌نازک", "خ‌ا", "خ‌ع", "در", "درج‌ثبت", "درج‌درخط", "درج‌درخطها", "درج‌درمتن", "درج‌در‌بالای‌یکدیگر", "درج‌در‌توری", "درج‌زیرفرمول", "درج‌شماره‌سر", "درج‌شماره‌صفحه", "درج‌شناور", "درج‌فرمول", "درج‌لیست", "درج‌لیست‌خام", "درج‌لیست‌مختلط", "درج‌متن‌سر", "درج‌پانوشتها", "درج‌پانوشتهای‌موضعی", "درج‌چوب‌خط", "درج‌کنار‌به‌کنار", "درخط", "درصفحه", "درقالبی", "درمورد", "درون", "درپر", "دریافت‌بافر", "دریافت‌نشانه", "دوران", "دکمه", "دکمه‌منو", "دکمه‌پانل", "رج", "رنگ", "رنگ‌خاکستری", "روزهفته", "ریاضی", "زبان", "زبان‌اصلی", "ستون", "ستون‌امتحان", "سرپوش‌کوچک‌نه", "شروعJScode", "شروعJSpreamble", "شروعLUA", "شروعMP", "شروعMPclip", "شروعMPcode", "شروعMPdefinitions", "شروعMPdrawing", "شروعMPenvironment", "شروعMPextensions", "شروعMPinclusions", "شروعMPinitializations", "شروعMPpage", "شروعMPpositiongraphic", "شروعMPpositionmethod", "شروعMPrun", "شروعPARSEDXML", "شروعTABLE", "شروعTABLEbody", "شروعTABLEfoot", "شروعTABLEhead", "شروعTABLEnext", "شروعTC", "شروعTD", "شروعTDs", "شروعTEX", "شروعTEXpage", "شروعTH", "شروعTN", "شروعTR", "شروعTRs", "شروعTX", "شروعTY", "شروعXML", "شروعalign", "شروعalignment", "شروعallmodes", "شروعappendices", "شروعarrangedpages", "شروعaside", "شروعattachment", "شروعbackmatter", "شروعbar", "شروعbbordermatrix", "شروعbitmapimage", "شروعblockquote", "شروعbodymatter", "شروعbordermatrix", "شروعboxedcolumns", "شروعbtxlabeltext", "شروعbtxrenderingdefinitions", "شروعbuffer", "شروعcases", "شروعcatcodetable", "شروعcenteraligned", "شروعchapter", "شروعcharacteralign", "شروعcheckedfences", "شروعchemical", "شروعchemicaltext", "شروعcollect", "شروعcollecting", "شروعcolorintent", "شروعcoloronly", "شروعcolorset", "شروعcolumns", "شروعcolumnset", "شروعcolumnsetspan", "شروعcolumnspan", "شروعcombination", "شروعcomment", "شروعcontextcode", "شروعcontextdefinitioncode", "شروعctxfunction", "شروعctxfunctiondefinition", "شروعcurrentcolor", "شروعcurrentlistentrywrapper", "شروعdelimited", "شروعdelimitedtext", "شروعdisplaymath", "شروعdmath", "شروعdocument", "شروعeffect", "شروعelement", "شروعembeddedxtable", "شروعendnote", "شروعendofline", "شروعexceptions", "شروعexpanded", "شروعexpandedcollect", "شروعextendedcatcodetable", "شروعexternalfigurecollection", "شروعfacingfloat", "شروعfact", "شروعfigure", "شروعfiguretext", "شروعfittingpage", "شروعfixed", "شروعfloatcombination", "شروعfont", "شروعfontclass", "شروعfontsolution", "شروعfootnote", "شروعformula", "شروعformulas", "شروعframedcell", "شروعframedcontent", "شروعframedrow", "شروعframedtable", "شروعframedtext", "شروعfrontmatter", "شروعgraphictext", "شروعgridsnapping", "شروعhanging", "شروعhbox", "شروعhboxestohbox", "شروعhboxregister", "شروعheadtext", "شروعhelptext", "شروعhiding", "شروعhighlight", "شروعhyphenation", "شروعimath", "شروعindentation", "شروعindentedtext", "شروعinteraction", "شروعinterface", "شروعintermezzotext", "شروعintertext", "شروعitemgroup", "شروعitemgroupcolumns", "شروعitemize", "شروعknockout", "شروعlabeltext", "شروعlayout", "شروعlegend", "شروعlinealignment", "شروعlinecorrection", "شروعlinefiller", "شروعlinenumbering", "شروعlines", "شروعlinetable", "شروعlinetablebody", "شروعlinetablecell", "شروعlinetablehead", "شروعlocalfootnotes", "شروعlocalheadsetup", "شروعlocallinecorrection", "شروعlocalnotes", "شروعlocalsetups", "شروعlua", "شروعluacode", "شروعluaparameterset", "شروعluasetups", "شروعmakeup", "شروعmarginblock", "شروعmarkedcontent", "شروعmarkpages", "شروعmathalignment", "شروعmathcases", "شروعmathlabeltext", "شروعmathmatrix", "شروعmathmode", "شروعmathstyle", "شروعmatrices", "شروعmatrix", "شروعmaxaligned", "شروعmdformula", "شروعmiddlealigned", "شروعmiddlemakeup", "شروعmixedcolumns", "شروعmode", "شروعmodeset", "شروعmodule", "شروعmoduletestsection", "شروعmpformula", "شروعnamedsection", "شروعnamedsubformulas", "شروعnarrow", "شروعnarrower", "شروعnegative", "شروعnicelyfilledbox", "شروعnointerference", "شروعnotallmodes", "شروعnotext", "شروعnotmode", "شروعoperatortext", "شروعopposite", "شروعoutputstream", "شروعoverlay", "شروعoverprint", "شروعpagecolumns", "شروعpagecomment", "شروعpagefigure", "شروعpagelayout", "شروعpagemakeup", "شروعpar", "شروعparagraph", "شروعparagraphs", "شروعparagraphscell", "شروعparbuilder", "شروعpart", "شروعpath", "شروعplacechemical", "شروعplacefigure", "شروعplacegraphic", "شروعplaceintermezzo", "شروعplacelegend", "شروعplacepairedbox", "شروعplacetable", "شروعpositioning", "شروعpositionoverlay", "شروعpositive", "شروعpostponing", "شروعpostponingnotes", "شروعprefixtext", "شروعprocessassignmentcommand", "شروعprocessassignmentlist", "شروعprocesscommacommand", "شروعprocesscommalist", "شروعprotect", "شروعprotectedcolors", "شروعpunctuation", "شروعquotation", "شروعquote", "شروعrandomized", "شروعrandomseed", "شروعrawsetups", "شروعreadingfile", "شروعreferenceprefix", "شروعregime", "شروعreusableMPgraphic", "شروعruby", "شروعscript", "شروعsdformula", "شروعsection", "شروعsectionblock", "شروعsectionblockenvironment", "شروعsectionlevel", "شروعsetups", "شروعshapebox", "شروعshift", "شروعsidebar", "شروعsimplecolumns", "شروعspecialitem", "شروعspeech", "شروعspformula", "شروعsplitformula", "شروعsplittext", "شروعspread", "شروعstandardmakeup", "شروعstaticMPfigure", "شروعstaticMPgraphic", "شروعstrictinspectnextcharacter", "شروعstrut", "شروعstyle", "شروعsubformulas", "شروعsubject", "شروعsubjectlevel", "شروعsubsection", "شروعsubsentence", "شروعsubstack", "شروعsubsubject", "شروعsubsubsection", "شروعsubsubsubject", "شروعsubsubsubsection", "شروعsubsubsubsubject", "شروعsubsubsubsubsection", "شروعsubsubsubsubsubject", "شروعsuffixtext", "شروعsymbolset", "شروعtable", "شروعtablehead", "شروعtables", "شروعtabletail", "شروعtabletext", "شروعtabulate", "شروعtabulatehead", "شروعtabulatetail", "شروعtagged", "شروعtaglabeltext", "شروعtexcode", "شروعtexdefinition", "شروعtext", "شروعtextbackground", "شروعtextbackgroundmanual", "شروعtextcolor", "شروعtextcolorintent", "شروعtextflow", "شروعtextmakeup", "شروعtitle", "شروعtokenlist", "شروعtokens", "شروعtransparent", "شروعtypescript", "شروعtypescriptcollection", "شروعtyping", "شروعuniqueMPgraphic", "شروعuniqueMPpagegraphic", "شروعunittext", "شروعunpacked", "شروعusableMPgraphic", "شروعuseMPgraphic", "شروعusemathstyleparameter", "شروعuserdata", "شروعusingbtxspecification", "شروعvbox", "شروعvboxregister", "شروعvboxtohbox", "شروعvboxtohboxseparator", "شروعviewerlayer", "شروعvtop", "شروعvtopregister", "شروعxcell", "شروعxcellgroup", "شروعxcolumn", "شروعxgroup", "شروعxmldisplayverbatim", "شروعxmlinlineverbatim", "شروعxmlraw", "شروعxmlsetups", "شروعxrow", "شروعxrowgroup", "شروعxtable", "شروعxtablebody", "شروعxtablefoot", "شروعxtablehead", "شروعxtablenext", "شروعآیتم", "شروعبروبه", "شروعتنظیم‌راست", "شروعتنظیم‌وسط", "شروعتولید", "شروعخط‌حاشیه", "شروعخط‌متن", "شروعدرج‌شناور", "شروعدرج‌فرمول", "شروعرنگ", "شروعزبان", "شروعسر", "شروعفشرده", "شروعقالبی", "شروعمحیط", "شروعمنوی‌پانل", "شروعمولفه", "شروعنشر", "شروعپروژه", "شروعپس‌زمینه", "شروعچپ‌چین", "شروع‌خط", "شماره‌زیرصفحه", "شماره‌سر", "شماره‌سرجاری", "شماره‌صفحه", "شماره‌صفحه‌کامل", "شماره‌فرمول", "شماره‌مبدل", "شماره‌ها", "شکافتن‌شناور", "شکل‌خارجی", "صفحه", "صفحه‌تست", "طول‌لیست", "عرض‌خط", "فضا", "فضاهای‌ثابت", "فضای‌ثابت", "فضای‌سفیدصحیح", "قالبی", "لوح‌مقایسه", "ماه", "متن‌پانوشت", "محیط", "مراجعه", "مرجع", "مرجع‌صفحه", "مرجع‌متن", "مقایسه‌گروه‌رنگ", "مقداررنگ", "مقیاس", "منوی‌پانل", "مولفه", "مکان", "میدان", "میدان‌شبیه‌سازی", "میدان‌پشته", "میدان‌کپی", "میله‌رنگ", "میله‌پانل", "ناشناس", "نسخه", "نشانه‌گذاری", "نصب‌زبان", "نقطه‌ها", "نماد", "نمایش‌آرایش", "نمایش‌بارگذاریها", "نمایش‌بستها", "نمایش‌توری", "نمایش‌رنگ", "نمایش‌طرح‌بندی", "نمایش‌قالب", "نمایش‌قلم‌بدنه", "نمایش‌لوح", "نمایش‌مجموعه‌علامت", "نمایش‌محیط‌قلم‌بدنه", "نمایش‌چاپ", "نمایش‌گروه‌رنگ", "پابا", "پایانJScode", "پایانJSpreamble", "پایانLUA", "پایانMP", "پایانMPclip", "پایانMPcode", "پایانMPdefinitions", "پایانMPdrawing", "پایانMPenvironment", "پایانMPextensions", "پایانMPinclusions", "پایانMPinitializations", "پایانMPpage", "پایانMPpositiongraphic", "پایانMPpositionmethod", "پایانMPrun", "پایانPARSEDXML", "پایانTABLE", "پایانTABLEbody", "پایانTABLEfoot", "پایانTABLEhead", "پایانTABLEnext", "پایانTC", "پایانTD", "پایانTDs", "پایانTEX", "پایانTEXpage", "پایانTH", "پایانTN", "پایانTR", "پایانTRs", "پایانTX", "پایانTY", "پایانXML", "پایانalign", "پایانalignment", "پایانallmodes", "پایانappendices", "پایانarrangedpages", "پایانaside", "پایانattachment", "پایانbackmatter", "پایانbar", "پایانbbordermatrix", "پایانbitmapimage", "پایانblockquote", "پایانbodymatter", "پایانbordermatrix", "پایانboxedcolumns", "پایانbtxlabeltext", "پایانbtxrenderingdefinitions", "پایانbuffer", "پایانcases", "پایانcatcodetable", "پایانcenteraligned", "پایانchapter", "پایانcharacteralign", "پایانcheckedfences", "پایانchemical", "پایانchemicaltext", "پایانcollect", "پایانcollecting", "پایانcolorintent", "پایانcoloronly", "پایانcolorset", "پایانcolumns", "پایانcolumnset", "پایانcolumnsetspan", "پایانcolumnspan", "پایانcombination", "پایانcomment", "پایانcontextcode", "پایانcontextdefinitioncode", "پایانctxfunction", "پایانctxfunctiondefinition", "پایانcurrentcolor", "پایانcurrentlistentrywrapper", "پایانdelimited", "پایانdelimitedtext", "پایانdisplaymath", "پایانdmath", "پایانdocument", "پایانeffect", "پایانelement", "پایانembeddedxtable", "پایانendnote", "پایانendofline", "پایانexceptions", "پایانexpanded", "پایانexpandedcollect", "پایانextendedcatcodetable", "پایانexternalfigurecollection", "پایانfacingfloat", "پایانfact", "پایانfigure", "پایانfiguretext", "پایانfittingpage", "پایانfixed", "پایانfloatcombination", "پایانfont", "پایانfontclass", "پایانfontsolution", "پایانfootnote", "پایانformula", "پایانformulas", "پایانframedcell", "پایانframedcontent", "پایانframedrow", "پایانframedtable", "پایانframedtext", "پایانfrontmatter", "پایانgraphictext", "پایانgridsnapping", "پایانhanging", "پایانhbox", "پایانhboxestohbox", "پایانhboxregister", "پایانheadtext", "پایانhelptext", "پایانhiding", "پایانhighlight", "پایانhyphenation", "پایانimath", "پایانindentation", "پایانindentedtext", "پایانinteraction", "پایانinterface", "پایانintermezzotext", "پایانintertext", "پایانitemgroup", "پایانitemgroupcolumns", "پایانitemize", "پایانknockout", "پایانlabeltext", "پایانlayout", "پایانlegend", "پایانlinealignment", "پایانlinecorrection", "پایانlinefiller", "پایانlinenumbering", "پایانlines", "پایانlinetable", "پایانlinetablebody", "پایانlinetablecell", "پایانlinetablehead", "پایانlocalfootnotes", "پایانlocalheadsetup", "پایانlocallinecorrection", "پایانlocalnotes", "پایانlocalsetups", "پایانlua", "پایانluacode", "پایانluaparameterset", "پایانluasetups", "پایانmakeup", "پایانmarginblock", "پایانmarkedcontent", "پایانmarkpages", "پایانmathalignment", "پایانmathcases", "پایانmathlabeltext", "پایانmathmatrix", "پایانmathmode", "پایانmathstyle", "پایانmatrices", "پایانmatrix", "پایانmaxaligned", "پایانmdformula", "پایانmiddlealigned", "پایانmiddlemakeup", "پایانmixedcolumns", "پایانmode", "پایانmodeset", "پایانmodule", "پایانmoduletestsection", "پایانmpformula", "پایانnamedsection", "پایانnamedsubformulas", "پایانnarrow", "پایانnarrower", "پایانnegative", "پایانnicelyfilledbox", "پایانnointerference", "پایانnotallmodes", "پایانnotext", "پایانnotmode", "پایانoperatortext", "پایانopposite", "پایانoutputstream", "پایانoverlay", "پایانoverprint", "پایانpagecolumns", "پایانpagecomment", "پایانpagefigure", "پایانpagelayout", "پایانpagemakeup", "پایانpar", "پایانparagraph", "پایانparagraphs", "پایانparagraphscell", "پایانparbuilder", "پایانpart", "پایانpath", "پایانplacechemical", "پایانplacefigure", "پایانplacegraphic", "پایانplaceintermezzo", "پایانplacelegend", "پایانplacepairedbox", "پایانplacetable", "پایانpositioning", "پایانpositionoverlay", "پایانpositive", "پایانpostponing", "پایانpostponingnotes", "پایانprefixtext", "پایانprocessassignmentcommand", "پایانprocessassignmentlist", "پایانprocesscommacommand", "پایانprocesscommalist", "پایانprotect", "پایانprotectedcolors", "پایانpunctuation", "پایانquotation", "پایانquote", "پایانrandomized", "پایانrandomseed", "پایانrawsetups", "پایانreadingfile", "پایانreferenceprefix", "پایانregime", "پایانreusableMPgraphic", "پایانruby", "پایانscript", "پایانsdformula", "پایانsection", "پایانsectionblock", "پایانsectionblockenvironment", "پایانsectionlevel", "پایانsetups", "پایانshapebox", "پایانshift", "پایانsidebar", "پایانsimplecolumns", "پایانspecialitem", "پایانspeech", "پایانspformula", "پایانsplitformula", "پایانsplittext", "پایانspread", "پایانstandardmakeup", "پایانstaticMPfigure", "پایانstaticMPgraphic", "پایانstrictinspectnextcharacter", "پایانstrut", "پایانstyle", "پایانsubformulas", "پایانsubject", "پایانsubjectlevel", "پایانsubsection", "پایانsubsentence", "پایانsubstack", "پایانsubsubject", "پایانsubsubsection", "پایانsubsubsubject", "پایانsubsubsubsection", "پایانsubsubsubsubject", "پایانsubsubsubsubsection", "پایانsubsubsubsubsubject", "پایانsuffixtext", "پایانsymbolset", "پایانtable", "پایانtablehead", "پایانtables", "پایانtabletail", "پایانtabletext", "پایانtabulate", "پایانtabulatehead", "پایانtabulatetail", "پایانtagged", "پایانtaglabeltext", "پایانtexcode", "پایانtexdefinition", "پایانtext", "پایانtextbackground", "پایانtextbackgroundmanual", "پایانtextcolor", "پایانtextcolorintent", "پایانtextflow", "پایانtextmakeup", "پایانtitle", "پایانtokenlist", "پایانtokens", "پایانtransparent", "پایانtypescript", "پایانtypescriptcollection", "پایانtyping", "پایانuniqueMPgraphic", "پایانuniqueMPpagegraphic", "پایانunittext", "پایانunpacked", "پایانusableMPgraphic", "پایانuseMPgraphic", "پایانusemathstyleparameter", "پایانuserdata", "پایانusingbtxspecification", "پایانvbox", "پایانvboxregister", "پایانvboxtohbox", "پایانvboxtohboxseparator", "پایانviewerlayer", "پایانvtop", "پایانvtopregister", "پایانxcell", "پایانxcellgroup", "پایانxcolumn", "پایانxgroup", "پایانxmldisplayverbatim", "پایانxmlinlineverbatim", "پایانxmlraw", "پایانxmlsetups", "پایانxrow", "پایانxrowgroup", "پایانxtable", "پایانxtablebody", "پایانxtablefoot", "پایانxtablehead", "پایانxtablenext", "پایانآیتم", "پایانبروبه", "پایانتنظیم‌راست", "پایانتنظیم‌وسط", "پایانتولید", "پایانخط‌حاشیه", "پایانخط‌متن", "پایاندرج‌شناور", "پایاندرج‌فرمول", "پایانرنگ", "پایانزبان", "پایانسر", "پایانفشرده", "پایانقالبی", "پایانمحیط", "پایانمنوی‌پانل", "پایانمولفه", "پایاننشر", "پایانپروژه", "پایانپس‌زمینه", "پایانچپ‌چین", "پایان‌خط", "پایین", "پرده", "پروژه", "پرکردن‌میدان", "پس‌زمینه", "چوبخط", "چپ‌چین", "کشیده", "کلمه‌راست", "گیره", "یادداشت", "یک‌جا", "یک‌خط" },
+ ["ro"]={ "CUVANT", "CUVINTE", "Cuvant", "Cuvinte", "Kap", "LUNA", "Litera", "Litere", "Numere", "Numereromane", "ZIDINSAPTAMANA", "adapteazaaspect", "adubuffer", "adumarcaje", "afiseazaaspect", "afiseazaculoare", "afiseazafonttext", "afiseazagrid", "afiseazagrupculoare", "afiseazamakeup", "afiseazamediufonttext", "afiseazapaleta", "afiseazarama", "afiseazasetari", "afiseazasetsimboluri", "afiseazastruts", "afiseazatiparire", "aliniatcentru", "aliniatdreapta", "aliniatstanga", "ascundeblocuri", "baraculoare", "barainteractiune", "blanc", "butoaneinteractiune", "buton", "butonmeniu", "camp", "cloneazacamp", "coloana", "comparagrupculoare", "comparapaleta", "completeazanumarpagina", "componenta", "convertestenumar", "copiazacamp", "corecteazaspatiualb", "culoare", "culoaregri", "cuvantdreapta", "data", "datacurenta", "defineste", "definesteaccent", "definesteantet", "definestebloc", "definesteblocsectiune", "definestebuffer", "definestecamp", "definestecaracter", "definestecomanda", "definesteconversie", "definesteculoare", "definestedescriere", "definestedimensiunehartie", "definesteenumerare", "definesteeticheta", "definestefloat", "definestefont", "definestefonttext", "definesteformatreferinte", "definestegrupculori", "definestehbox", "definesteinconjurare", "definestelista", "definestelistacombinata", "definestemakeup", "definestemarcaje", "definestemediulfonttext", "definestemeniuinteractiune", "definesteoverlay", "definestepaleta", "definesteparagraf", "definesteprofil", "definesteprogram", "definestereferinte", "definesteregistru", "definestesablontabel", "definestesectiune", "definestesimbol", "definestesimbolfigura", "definestesinonim", "definestesinonimfont", "definestesortare", "definestestartstop", "definestestil", "definestestilfont", "definestestivacampuri", "definestesubcamp", "definestetabulatori", "definestetext", "definestetexteinconjurate", "definestetextinconjurat", "definestetyping", "despre", "determinacaracteristicilelistei", "determinacaracteristiciregistru", "determinanumartitlu", "din", "dute", "dutebox", "dutepagina", "ecran", "element", "faraliniiantetsisubsol", "faraliniisussijos", "faraspatiu", "figuraexterna", "firdepar", "folosesteURL", "folosestebloc", "folosestedirector", "folosestedocumentextern", "folosestefiguraexterna", "folosestemodul", "folosestemuzicaexterna", "folosestescriptJS", "folosestesimboluri", "folosesteurl", "fundal", "grosimelinie", "impartefloat", "inalt", "injos", "inlinie", "instalarelimba", "intins", "jos", "jossus", "la", "lapagina", "limba", "limbaprincipala", "linieneagra", "liniesubtire", "linieumplere", "liniinegre", "liniisubtiri", "litera", "litere", "luna", "lungimelista", "marcaje", "matematica", "mediu", "meniuinteractiune", "necunoscut", "nokap", "nota", "numarformula", "numarpagina", "numartitlu", "numartitlucurent", "numere", "numereromane", "olinie", "pagina", "pastreazablocuri", "pelung", "plaseazapegrid", "plaseazasemnecarte", "potrivestecamp", "pozitie", "proceseazabloc", "produs", "proiect", "puncte", "punedeasuprafiecareia", "punefatainfata", "puneformula", "punelista", "punelistacombinata", "punenotesubsol", "punenotesubsollocale", "punenumarpagina", "puneregistru", "punesubformula", "referinta", "referintapagina", "referintatext", "reflexie", "remarca", "reseteazamarcaje", "riglatext", "rigleumplere", "roteste", "scala", "scriebuffer", "scrieinlista", "scrieintreliste", "selecteazablocuri", "semncarte", "setareitemization", "setarelimba", "setarepozitie", "seteazaaliniat", "seteazaalinierea", "seteazaantet", "seteazaaranjareapag", "seteazaaspect", "seteazabarainteractiune", "seteazablanc", "seteazabloc", "seteazablocsectiune", "seteazabuffer", "seteazacamp", "seteazacampuri", "seteazaclipping", "seteazacoloane", "seteazacomentariu", "seteazacomentariupagina", "seteazaculoare", "seteazaculori", "seteazadimensiunihartie", "seteazaecraninteractiune", "seteazaelemente", "seteazaenumerare", "seteazafloat", "seteazafloats", "seteazafonttext", "seteazaformulare", "seteazaformule", "seteazafundal", "seteazafundaluri", "seteazagrosimelinie", "seteazaimpartireafloat", "seteazainconjurat", "seteazaingust", "seteazainteractiunea", "seteazajos", "seteazalegenda", "seteazalegendele", "seteazaliniesilabe", "seteazaliniesubtire", "seteazalinii", "seteazaliniimargine", "seteazaliniinegre", "seteazaliniiumplere", "seteazalista", "seteazalistacombinata", "seteazamajuscule", "seteazamakeup", "seteazamarcaje", "seteazameniuinteractiune", "seteazaminicitat", "seteazanumarpagina", "seteazanumarsubpagina", "seteazanumartitlu", "seteazanumerotarelinii", "seteazanumerotarepagina", "seteazanumerotareparagrafe", "seteazapaleta", "seteazaparagrafe", "seteazaplasareaopozita", "seteazaprograme", "seteazareferinte", "seteazaregistru", "seteazarigletext", "seteazarigleumplere", "seteazarotare", "seteazasimbol", "seteazasinonime", "seteazasortare", "seteazaspatiu", "seteazaspatiualb", "seteazaspatiuinterliniar", "seteazasubsol", "seteazasus", "seteazatabele", "seteazatabulatori", "seteazatext", "seteazatexteantet", "seteazatextejos", "seteazatextesubsol", "seteazatextesus", "seteazatextetext", "seteazatitlu", "seteazatitluri", "seteazatoleranta", "seteazatranzitiepagina", "seteazatype", "seteazatyping", "seteazaurl", "simbol", "spatiifixate", "spatiu", "spatiufixat", "startaliniatcentru", "startaliniatdreapta", "startaliniatstanga", "startcomponenta", "startculoare", "startdute", "startfundal", "startimpachetat", "startlimba", "startlinie", "startliniemargine", "startmediu", "startmeniuinteractiune", "startprodus", "startproiect", "startpublicatie", "startpuneformula", "startriglatext", "starttitlu", "stivacampuri", "stopaliniatcentru", "stopaliniatdreapta", "stopaliniatstanga", "stopcomponenta", "stopculoare", "stopdute", "stopfundal", "stopimpachetat", "stoplimba", "stoplinie", "stopliniemargine", "stopmediu", "stopmeniuinteractiune", "stopprodus", "stopproiect", "stoppublicatie", "stoppuneformula", "stopriglatext", "stoptitlu", "textumplere", "traduce", "trecilafonttext", "undeva", "valoareculoare", "versiune", "zidinsaptamana" },
} \ No newline at end of file
diff --git a/context/data/textadept/context/data/scite-context-data-metafun.lua b/context/data/textadept/context/data/scite-context-data-metafun.lua
index b577c8aee..4d18d3081 100644
--- a/context/data/textadept/context/data/scite-context-data-metafun.lua
+++ b/context/data/textadept/context/data/scite-context-data-metafun.lua
@@ -1,4 +1,4 @@
return {
- ["commands"]={ "loadfile", "loadimage", "loadmodule", "dispose", "nothing", "transparency", "tolist", "topath", "tocycle", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "tanh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "perpendicular", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "drawdoublearrows", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "boundingradius", "boundingcircle", "boundingpoint", "crossingunder", "insideof", "outsideof", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", "withshadestep", "withshadefraction", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "colordecimalslist", "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "istextext", "verbatim", "thelabel", "label", "autoalign", "transparent", "withtransparency", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "colorlike", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "resetarrows", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "pencilled", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "topair", "format", "formatted", "quotation", "quote", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "fillup", "eofillup", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright", "sortlist", "copylist", "shapedlist", "listtocurves", "listtolines", "listsize", "listlast", "uniquelist", "circularpath", "squarepath", "linearpath" },
- ["internals"]={ "nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel", "shadefactor", "textextoffset", "normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent", "softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent", "darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent", "huetransparent", "saturationtransparent", "colortransparent", "luminositytransparent", "ahvariant", "ahdimple", "ahfactor", "ahscale", "metapostversion", "maxdimensions", "drawoptionsfactor", "dq", "sq", "crossingscale", "crossingoption" },
+ ["commands"]={ "loadfile", "loadimage", "loadmodule", "dispose", "nothing", "transparency", "tolist", "topath", "tocycle", "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "invtan", "acosh", "asinh", "sinh", "cosh", "tanh", "zmod", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "unittriangle", "fulltriangle", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "uptriangle", "downtriangle", "lefttriangle", "righttriangle", "triangle", "smoothed", "cornered", "superellipsed", "randomized", "randomizedcontrols", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "perpendicular", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "drawdoublearrows", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "boundingradius", "boundingcircle", "boundingpoint", "crossingunder", "insideof", "outsideof", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withcircularshade", "withlinearshade", "defineshade", "shaded", "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", "withshadestep", "withshadefraction", "withshadeorigin", "shownshadevector", "shownshadeorigin", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "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", "transparent", "withtransparency", "property", "properties", "withproperties", "asgroup", "infont", "space", "crlf", "dquote", "percent", "SPACE", "CRLF", "DQUOTE", "PERCENT", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "colorlike", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedfunction", "constructedpath", "constructedpairs", "straightfunction", "straightpath", "straightpairs", "curvedfunction", "curvedpath", "curvedpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "resetarrows", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "basiccolors", "complementary", "complemented", "resolvedcolor", "normalfill", "normaldraw", "visualizepaths", "detailpaths", "naturalizepaths", "drawboundary", "drawwholepath", "drawpathonly", "visualizeddraw", "visualizedfill", "detaileddraw", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions", "undashed", "pencilled", "decorated", "redecorated", "undecorated", "passvariable", "passarrayvariable", "tostring", "topair", "format", "formatted", "quotation", "quote", "startpassingvariable", "stoppassingvariable", "eofill", "eoclip", "nofill", "fillup", "eofillup", "area", "addbackground", "shadedup", "shadeddown", "shadedleft", "shadedright", "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" },
+ ["internals"]={ "nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel", "shadefactor", "textextoffset", "textextanchor", "normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent", "softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent", "darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent", "huetransparent", "saturationtransparent", "colortransparent", "luminositytransparent", "ahvariant", "ahdimple", "ahfactor", "ahscale", "metapostversion", "maxdimensions", "drawoptionsfactor", "dq", "sq", "crossingscale", "crossingoption" },
} \ No newline at end of file
diff --git a/context/data/textadept/context/data/scite-context-data-tex.lua b/context/data/textadept/context/data/scite-context-data-tex.lua
index 31cb6e4fb..473c64499 100644
--- a/context/data/textadept/context/data/scite-context-data-tex.lua
+++ b/context/data/textadept/context/data/scite-context-data-tex.lua
@@ -1,9 +1,9 @@
return {
["aleph"]={ "Alephminorversion", "Alephrevision", "Alephversion" },
["etex"]={ "botmarks", "clubpenalties", "currentgrouplevel", "currentgrouptype", "currentifbranch", "currentiflevel", "currentiftype", "detokenize", "dimexpr", "displaywidowpenalties", "eTeXVersion", "eTeXminorversion", "eTeXrevision", "eTeXversion", "everyeof", "firstmarks", "fontchardp", "fontcharht", "fontcharic", "fontcharwd", "glueexpr", "glueshrink", "glueshrinkorder", "gluestretch", "gluestretchorder", "gluetomu", "ifcsname", "ifdefined", "iffontchar", "interactionmode", "interlinepenalties", "lastlinefit", "lastnodetype", "marks", "muexpr", "mutoglue", "numexpr", "pagediscards", "parshapedimen", "parshapeindent", "parshapelength", "predisplaydirection", "protected", "readline", "savinghyphcodes", "savingvdiscards", "scantokens", "showgroups", "showifs", "showtokens", "splitbotmarks", "splitdiscards", "splitfirstmarks", "topmarks", "tracingassigns", "tracinggroups", "tracingifs", "tracingnesting", "tracingscantokens", "unexpanded", "unless", "widowpenalties" },
- ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Unosubscript", "Unosuperscript", "Uoverdelimiter", "Uradical", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "alignmark", "aligntab", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenmode", "automatichyphenpenalty", "begincsname", "bodydir", "bodydirection", "boxdir", "boxdirection", "breakafterdirmode", "catcodetable", "clearmarks", "copyfont", "compoundhyphenmode", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "draftmode", "dviextension", "dvifeedback", "dvivariable", "efcode", "etoksapp", "etokspre", "expanded", "expandglyphsinfont", "explicitdiscretionary", "explicithyphenpenalty", "fontid", "formatname", "gleaders", "hjcode", "hyphenationbounds", "hyphenationmin", "hyphenpenaltymode", "ifabsdim", "ifabsnum", "ifincsname", "ifprimitive", "ignoreligaturesinfont", "initcatcodetable", "insertht", "lastnamedcs", "lastsavedboxresourceindex", "lastsavedimageresourceindex", "lastsavedimageresourcepages", "lastxpos", "lastypos", "latelua", "leftghost", "leftmarginkern", "letcharcode", "letterspacefont", "linedir", "linedirection", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "lpcode", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathdelimitersmode", "mathdir", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathitalicsmode", "mathnolimitsmode", "mathoption", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathscriptsmode", "mathscriptboxmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "nohrule", "nokerns", "noligs", "normaldeviate", "nospaces", "novrule", "outputbox", "outputmode", "pagebottomoffset", "pagedir", "pagedirection", "pageheight", "pageleftoffset", "pagerightoffset", "pagetopoffset", "pagewidth", "pardir", "pardirection", "pdfextension", "pdffeedback", "pdfvariable", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "primitive", "protrudechars", "pxdimen", "quitvmode", "randomseed", "rightghost", "rightmarginkern", "rpcode", "saveboxresource", "savecatcodetable", "saveimageresource", "savepos", "scantextokens", "setfontid", "setrandomseed", "shapemode", "suppressfontnotfounderror", "suppressifcsnameerror", "suppresslongerror", "suppressmathparerror", "suppressoutererror", "suppressprimitiveerror", "synctex", "tagcode", "textdir", "textdirection", "toksapp", "tokspre", "tracingfonts", "uniformdeviate", "useboxresource", "useimageresource" },
+ ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Uhextensible", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathcharclass", "Umathchardef", "Umathcharfam", "Umathcharnum", "Umathcharnumdef", "Umathcharslot", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathnolimitsubfactor", "Umathnolimitsupfactor", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathskewedfractionhgap", "Umathskewedfractionvgap", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Unosubscript", "Unosuperscript", "Uoverdelimiter", "Uradical", "Uroot", "Uskewed", "Uskewedwithdelims", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "Uvextensible", "adjustspacing", "alignmark", "aligntab", "attribute", "attributedef", "automaticdiscretionary", "automatichyphenmode", "automatichyphenpenalty", "begincsname", "bodydir", "bodydirection", "boxdir", "boxdirection", "breakafterdirmode", "catcodetable", "clearmarks", "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", "lastsavedboxresourceindex", "lastsavedimageresourceindex", "lastsavedimageresourcepages", "lastxpos", "lastypos", "latelua", "lateluafunction", "leftghost", "leftmarginkern", "letcharcode", "letterspacefont", "linedir", "linedirection", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "lpcode", "luabytecode", "luabytecodecall", "luacopyinputnodes", "luadef", "luaescapestring", "luafunction", "luafunctioncall", "luatexbanner", "luatexrevision", "luatexversion", "mathdelimitersmode", "mathdir", "mathdirection", "mathdisplayskipmode", "matheqnogapstep", "mathflattenmode", "mathitalicsmode", "mathnolimitsmode", "mathoption", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", "mathrulethicknessmode", "mathscriptboxmode", "mathscriptcharmode", "mathscriptsmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", "nohrule", "nokerns", "noligs", "normaldeviate", "nospaces", "novrule", "outputbox", "outputmode", "pagebottomoffset", "pagedir", "pagedirection", "pageheight", "pageleftoffset", "pagerightoffset", "pagetopoffset", "pagewidth", "pardir", "pardirection", "pdfextension", "pdffeedback", "pdfvariable", "postexhyphenchar", "posthyphenchar", "prebinoppenalty", "predisplaygapfactor", "preexhyphenchar", "prehyphenchar", "prerelpenalty", "primitive", "protrudechars", "pxdimen", "quitvmode", "randomseed", "rightghost", "rightmarginkern", "rpcode", "saveboxresource", "savecatcodetable", "saveimageresource", "savepos", "scantextokens", "setfontid", "setrandomseed", "shapemode", "suppressfontnotfounderror", "suppressifcsnameerror", "suppresslongerror", "suppressmathparerror", "suppressoutererror", "suppressprimitiveerror", "synctex", "tagcode", "textdir", "textdirection", "toksapp", "tokspre", "tracingfonts", "uniformdeviate", "useboxresource", "useimageresource", "xtoksapp", "xtokspre" },
["omega"]={ "Omegaminorversion", "Omegarevision", "Omegaversion" },
- ["pdftex"]={ "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfignoreunknownimages", "pdfimageaddfilename", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinfoomitdate", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmapfile", "pdfmapline", "pdfmajorversion", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdfsuppressoptionalinfo", "pdfsuppressptexinfo", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage" },
- ["tex"]={ " ", "-", "/", "Uleft", "Umiddle", "Uright", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "botmark", "boundary", "box", "boxmaxdepth", "brokenpenalty", "catcode", "char", "chardef", "cleaders", "closein", "closeout", "clubpenalty", "copy", "count", "countdef", "cr", "crcr", "csname", "csstring", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "dimen", "dimendef", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "firstvalidlanguage", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hpack", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifcase", "ifcat", "ifdim", "ifeof", "iffalse", "ifhbox", "ifhmode", "ifinner", "ifmmode", "ifnum", "ifodd", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "immediate", "indent", "input", "inputlineno", "insert", "insertpenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastpenalty", "lastskip", "lccode", "leaders", "left", "lefthyphenmin", "leftskip", "leqno", "let", "limits", "linepenalty", "lineskip", "lineskiplimit", "long", "looseness", "lower", "lowercase", "mag", "mark", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "muskip", "muskipdef", "newlinechar", "noalign", "noboundary", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "openin", "openout", "or", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillskip", "parindent", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "protrusionboundary", "radical", "raise", "read", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "special", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tpack", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vpack", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "wordboundary", "write", "xdef", "xleaders", "xspaceskip", "year" },
+ ["pdftex"]={ "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfignoreunknownimages", "pdfimageaddfilename", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinfoomitdate", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmajorversion", "pdfmapfile", "pdfmapline", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfomitcharset", "pdfomitcidset", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrecompress", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdfsuppressoptionalinfo", "pdfsuppressptexinfo", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage" },
+ ["tex"]={ " ", "-", "/", "Uleft", "Umiddle", "Uright", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "atop", "atopwithdelims", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "botmark", "boundary", "box", "boxmaxdepth", "brokenpenalty", "catcode", "char", "chardef", "cleaders", "closein", "closeout", "clubpenalty", "copy", "count", "countdef", "cr", "crcr", "csname", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "dimen", "dimendef", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "edef", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "fam", "fi", "finalhyphendemerits", "firstmark", "firstvalidlanguage", "floatingpenalty", "font", "fontdimen", "fontname", "futurelet", "gdef", "glet", "global", "globaldefs", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hpack", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifcase", "ifcat", "ifdim", "ifeof", "iffalse", "ifhbox", "ifhmode", "ifinner", "ifmmode", "ifnum", "ifodd", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "immediate", "indent", "input", "inputlineno", "insert", "insertpenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastpenalty", "lastskip", "lccode", "leaders", "left", "lefthyphenmin", "leftskip", "leqno", "let", "limits", "linepenalty", "lineskip", "lineskiplimit", "long", "looseness", "lower", "lowercase", "mag", "mark", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "multiply", "muskip", "muskipdef", "newlinechar", "noalign", "noboundary", "noexpand", "noindent", "nolimits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "omit", "openin", "openout", "or", "outer", "output", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagedepth", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageshrink", "pagestretch", "pagetotal", "par", "parfillskip", "parindent", "parshape", "parskip", "patterns", "pausing", "penalty", "postdisplaypenalty", "predisplaypenalty", "predisplaysize", "pretolerance", "prevdepth", "prevgraf", "protrusionboundary", "radical", "raise", "read", "relax", "relpenalty", "right", "righthyphenmin", "rightskip", "romannumeral", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showlists", "showthe", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "special", "splitbotmark", "splitfirstmark", "splitmaxdepth", "splittopskip", "string", "tabskip", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topskip", "tpack", "tracingcommands", "tracinglostchars", "tracingmacros", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingstats", "uccode", "uchyph", "underline", "unhbox", "unhcopy", "unkern", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vpack", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalty", "wordboundary", "write", "xdef", "xleaders", "xspaceskip", "year" },
["xetex"]={ "XeTeXversion" },
} \ No newline at end of file
diff --git a/context/data/textadept/context/init.lua b/context/data/textadept/context/init.lua
index 2aefb970f..9d89d2c0a 100644
--- a/context/data/textadept/context/init.lua
+++ b/context/data/textadept/context/init.lua
@@ -66,4 +66,78 @@ require("textadept-context-types")
-- This prevents other themes to spoil our settings.
-ui.set_theme("scite-context-theme")
+-- ui.set_theme("scite-context-theme")
+buffer:set_theme("scite-context-theme")
+
+-- Since version 10 there is some settings stuff in the main init file but that
+-- crashes on load_settings. It has to do with the replacement of properties
+-- but we already had that replaced for a while. There is some blob made that
+-- gets loaded but it's not robust (should be done different I think). Anyway,
+-- intercepting the two event handlers is easiest. Maybe some day I will
+-- replace that init anyway (if these fundamentals keep changing between
+-- versions.)
+--
+-- I admit that it's not a beautiful solution but it works ok and I already
+-- spent too much time figuring things out anyway.
+
+local events_connect = events.connect
+
+local function events_newbuffer()
+ local buffer = _G.buffer
+ local SETDIRECTFUNCTION = _SCINTILLA.properties.direct_function[1]
+ local SETDIRECTPOINTER = _SCINTILLA.properties.doc_pointer[2]
+ local SETLUASTATE = _SCINTILLA.functions.change_lexer_state[1]
+ local SETLEXERLANGUAGE = _SCINTILLA.properties.lexer_language[2]
+ buffer.lexer_language = 'lpeg'
+ buffer:private_lexer_call(SETDIRECTFUNCTION, buffer.direct_function)
+ buffer:private_lexer_call(SETDIRECTPOINTER, buffer.direct_pointer)
+ buffer:private_lexer_call(SETLUASTATE, _LUA)
+ buffer.property['lexer.lpeg.home'] = _USERHOME..'/lexers/?.lua;'.. _HOME..'/lexers'
+ -- load_settings()
+ buffer:private_lexer_call(SETLEXERLANGUAGE, 'text')
+ if buffer == ui.command_entry then
+ buffer.caret_line_visible = false
+ end
+end
+
+-- Why these resets:
+
+local ctrl_keys = {
+ '[', ']', '/', '\\', 'Z', 'Y', 'X', 'C', 'V', 'A', 'L', 'T', 'D', 'U'
+}
+
+local ctrl_shift_keys = {
+ 'L', 'T', 'U', 'Z'
+}
+
+local function events_newview()
+ local buffer = _G.buffer
+ for i=1, #ctrl_keys do
+ buffer:clear_cmd_key(string.byte(ctrl_keys[i]) | buffer.MOD_CTRL << 16)
+ end
+ for i=1, #ctrl_shift_keys do
+ buffer:clear_cmd_key(string.byte(ctrl_shift_keys[i]) | (buffer.MOD_CTRL | buffer.MOD_SHIFT) << 16)
+ end
+ if #_VIEWS > 1 then
+ -- load_settings()
+ local SETLEXERLANGUAGE = _SCINTILLA.properties.lexer_language[2]
+ buffer:private_lexer_call(SETLEXERLANGUAGE, buffer._lexer or 'text')
+ end
+end
+
+events.connect = function(where,what,location)
+ if location == 1 then
+ if where == events.BUFFER_NEW then
+ return events_connect(where,events_newbuffer,location)
+ elseif where == events.VIEW_NEW then
+ return events_connect(where,events_newview,location)
+ end
+ end
+ return events_connect(where,what,location)
+end
+
+local savedrequire = require
+
+require = function(name,...)
+ return savedrequire(name == "lexer" and "scite-context-lexer" or name,...)
+end
diff --git a/context/data/textadept/context/lexers/lexer.lua b/context/data/textadept/context/lexers/lexer.lua
new file mode 100644
index 000000000..234b03c05
--- /dev/null
+++ b/context/data/textadept/context/lexers/lexer.lua
@@ -0,0 +1,2664 @@
+local info = {
+ version = 1.400,
+ comment = "basics for scintilla lpeg lexer for context/metafun",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+ comment = "contains copyrighted code from mitchell.att.foicica.com",
+
+}
+
+-- We need a copy of this file to lexer.lua in the same path. This was not needed
+-- before version 10 but I can't figure out what else to do. It looks like there
+-- is some loading of lexer.lua but I can't see where.
+
+if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
+
+local log = false
+local trace = false
+local detail = false
+local show = false -- nice for tracing (also for later)
+local collapse = false -- can save some 15% (maybe easier on scintilla)
+local inspect = false -- can save some 15% (maybe easier on scintilla)
+
+-- local log = true
+-- local trace = true
+
+-- GET GOING
+--
+-- You need to copy this file over lexer.lua. In principle other lexers could work
+-- too but not now. Maybe some day. All patterns will move into the patterns name
+-- space. I might do the same with styles. If you run an older version of SciTE you
+-- can take one of the archives. Pre 3.41 versions can just be copied to the right
+-- path, as there we still use part of the normal lexer. Below we mention some
+-- issues with different versions of SciTE. We try to keep up with changes but best
+-- check careful if the version that yuou install works as expected because SciTE
+-- and the scintillua dll need to be in sync.
+--
+-- REMARK
+--
+-- We started using lpeg lexing as soon as it came available. Because we had rather
+-- demanding files and also wanted to use nested lexers, we ended up with our own
+-- variant. At least at that time this was more robust and also much faster (as we
+-- have some pretty large Lua data files and also work with large xml files). As a
+-- consequence successive versions had to be adapted to changes in the (at that time
+-- still unstable) api. In addition to lexing we also have spell checking and such.
+-- Around version 3.60 things became more stable so I don't expect to change much.
+--
+-- LEXING
+--
+-- When pc's showed up we wrote our own editor (texedit) in MODULA 2. It was fast,
+-- had multiple overlapping (text) windows, could run in the at most 1M memory at
+-- that time, etc. The realtime file browsing with lexing that we had at that time
+-- is still on my current wish list. The color scheme and logic that we used related
+-- to the logic behind the ConTeXt user interface that evolved.
+--
+-- Later I rewrote the editor in perl/tk. I don't like the perl syntax but tk
+-- widgets are very powerful and hard to beat. In fact, TextAdept reminds me of
+-- that: wrap your own interface around a framework (tk had an edit control that one
+-- could control completely not that different from scintilla). Last time I checked
+-- it still ran fine so I might try to implement something like its file handling in
+-- TextAdept.
+--
+-- In the end I settled for SciTE for which I wrote TeX and MetaPost lexers that
+-- could handle keyword sets. With respect to lexing (syntax highlighting) ConTeXt
+-- has a long history, if only because we need it for manuals. Anyway, in the end we
+-- arrived at lpeg based lexing (which is quite natural as we have lots of lpeg
+-- usage in ConTeXt). The basic color schemes haven't changed much. The most
+-- prominent differences are the nested lexers.
+--
+-- In the meantime I made the lexer suitable for typesetting sources which was no
+-- big deal as we already had that in place (ConTeXt used lpeg from the day it
+-- showed up so we have several lexing options there too).
+--
+-- Keep in mind that in ConTeXt (typesetting) lexing can follow several approached:
+-- line based (which is handy for verbatim mode), syntax mode (which is nice for
+-- tutorials), and tolerant mode (so that one can also show bad examples or errors).
+-- These demands can clash.
+--
+-- HISTORY
+--
+-- The remarks below are more for myself so that I keep track of changes in the
+-- way we adapt to the changes in the scintillua and scite.
+--
+-- The fold and lex functions are copied and patched from original code by Mitchell
+-- (see lexer.lua) in the scintillua distribution. So whatever I say below, assume
+-- that all errors are mine. The ability to use lpeg in scintilla is a real nice
+-- addition and a brilliant move. The code is a byproduct of the (mainly Lua based)
+-- TextAdept which at the time I ran into it was a rapidly moving target so I
+-- decided to stick ot SciTE. When I played with it, it had no realtime output pane
+-- although that seems to be dealt with now (2017). I need to have a look at it in
+-- more detail but a first test again made the output hang and it was a bit slow too
+-- (and I also want the log pane as SciTE has it, on the right, in view). So, for
+-- now I stick to SciTE even when it's somewhat crippled by the fact that we cannot
+-- hook our own (language dependent) lexer into the output pane (somehow the
+-- errorlist lexer is hard coded into the editor). Hopefully that will change some
+-- day. The ConTeXt distribution has cmd runner for textdept that will plug in the
+-- lexers discussed here as well as a dedicated runner. Considere it an experiment.
+--
+-- The basic code hasn't changed much but we had to adapt a few times to changes in
+-- the api and/or work around bugs. Starting with SciTE version 3.20 there was an
+-- issue with coloring. We still lacked a connection with SciTE itself (properties
+-- as well as printing to the log pane) and we could not trace this (on windows).
+-- However on unix we can see messages! As far as I can see, there are no
+-- fundamental changes in lexer.lua or LexLPeg.cxx so it must be/have been in
+-- Scintilla itself. So we went back to 3.10. Indicators of issues are: no lexing of
+-- 'next' and 'goto <label>' in the Lua lexer and no brace highlighting either.
+-- Interesting is that it does work ok in the cld lexer (so the Lua code is okay).
+-- All seems to be ok again in later versions, so, when you update best check first
+-- and just switch back to an older version as normally a SciTE update is not
+-- critital. When char-def.lua lexes real fast this is a signal that the lexer quits
+-- somewhere halfway. Maybe there are some hard coded limitations on the amount of
+-- styles and/or length of names.
+--
+-- Anyway, after checking 3.24 and adapting to the new lexer tables things are okay
+-- again. So, this version assumes 3.24 or higher. In 3.24 we have a different token
+-- result, i.e. no longer a { tag, pattern } but just two return values. I didn't
+-- check other changes but will do that when I run into issues. I had already
+-- optimized these small tables by hashing which was much more efficient (and maybe
+-- even more efficient than the current approach) but this is no longer needed. For
+-- the moment we keep some of that code around as I don't know what happens in
+-- future versions. I'm anyway still happy with this kind of lexing.
+--
+-- In 3.31 another major change took place: some helper constants (maybe they're no
+-- longer constants) and functions were moved into the lexer modules namespace but
+-- the functions are assigned to the Lua module afterward so we cannot alias them
+-- beforehand. We're probably getting close to a stable interface now. At that time
+-- for the first time I considered making a whole copy and patch the other functions
+-- too as we need an extra nesting model. However, I don't want to maintain too
+-- much. An unfortunate change in 3.03 is that no longer a script can be specified.
+-- This means that instead of loading the extensions via the properties file, we now
+-- need to load them in our own lexers, unless of course we replace lexer.lua
+-- completely (which adds another installation issue).
+--
+-- Another change has been that _LEXERHOME is no longer available. It looks like
+-- more and more functionality gets dropped so maybe at some point we need to ship
+-- our own dll/so files. For instance, I'd like to have access to the current
+-- filename and other SciTE properties. We could then cache some info with each
+-- file, if only we had knowledge of what file we're dealing with. This all makes a
+-- nice installation more complex and (worse) makes it hard to share files between
+-- different editors usign s similar directory structure.
+--
+-- For huge files folding can be pretty slow and I do have some large ones that I
+-- keep open all the time. Loading is normally no ussue, unless one has remembered
+-- the status and the cursor is at the last line of a 200K line file. Optimizing the
+-- fold function brought down loading of char-def.lua from 14 sec => 8 sec.
+-- Replacing the word_match function and optimizing the lex function gained another
+-- 2+ seconds. A 6 second load is quite ok for me. The changed lexer table structure
+-- (no subtables) brings loading down to a few seconds.
+--
+-- When the lexer path is copied to the TextAdept lexer path, and the theme
+-- definition to theme path (as lexer.lua), the lexer works there as well. Although
+-- ... when I decided to check the state of TextAdept I had to adapt some loader
+-- code. The solution is not pretty but works and also permits overloading. When I
+-- have time and motive I will make a proper setup file to tune the look and feel a
+-- bit more than we do now. The TextAdept editor nwo has tabs and a console so it
+-- has become more useable for me (it's still somewhat slower than SciTE).
+-- Interesting is that the jit version of TextAdept crashes on lexing large files
+-- (and does not feel faster either; maybe a side effect of known limitations as we
+-- know that Luajit is more limited than stock Lua).
+--
+-- Function load(lexer_name) starts with _lexers.WHITESPACE = lexer_name ..
+-- '_whitespace' which means that we need to have it frozen at the moment we load
+-- another lexer. Because spacing is used to revert to a parent lexer we need to
+-- make sure that we load children as late as possible in order not to get the wrong
+-- whitespace trigger. This took me quite a while to figure out (not being that
+-- familiar with the internals). The lex and fold functions have been optimized. It
+-- is a pitty that there is no proper print available. Another thing needed is a
+-- default style in our own theme style definition, as otherwise we get wrong nested
+-- lexers, especially if they are larger than a view. This is the hardest part of
+-- getting things right.
+--
+-- It's a pitty that there is no scintillua library for the OSX version of SciTE.
+-- Even better would be to have the scintillua library as integral part of SciTE as
+-- that way I could use OSX alongside windows and linux (depending on needs). Also
+-- nice would be to have a proper interface to SciTE then because currently the
+-- lexer is rather isolated and the Lua version does not provide all standard
+-- libraries. It would also be good to have lpeg support in the regular SciTE Lua
+-- extension (currently you need to pick it up from someplace else). I keep hoping.
+--
+-- With 3.41 the interface changed again so it became time to look into the C++ code
+-- and consider compiling and patching myself, something that I like to avoid.
+-- Loading is more complicated now as the lexer gets loaded automatically so we have
+-- little control over extending the code now. After a few days trying all kind of
+-- solutions I decided to follow a different approach: drop in a complete
+-- replacement. This of course means that I need to keep track of even more changes
+-- (which for sure will happen) but at least I get rid of interferences. Till 3.60
+-- the api (lexing and configuration) was simply too unstable across versions which
+-- is a pitty because we expect authors to install SciTE without hassle. Maybe in a
+-- few years things will have stabelized. Maybe it's also not really expected that
+-- one writes lexers at all. A side effect is that I now no longer will use shipped
+-- lexers for languages that I made no lexer for, but just the built-in ones in
+-- addition to the ConTeXt lpeg lexers. Not that it matters much as the ConTeXt
+-- lexers cover what I need (and I can always write more). For editing TeX files one
+-- only needs a limited set of lexers (TeX, MetaPost, Lua, BibTeX, C/W, PDF, SQL,
+-- etc). I can add more when I want.
+--
+-- In fact, the transition to 3.41 was triggered by an unfateful update of Ubuntu
+-- which left me with an incompatible SciTE and lexer library and updating was not
+-- possible due to the lack of 64 bit libraries. We'll see what the future brings.
+-- For now I can use SciTE under wine on linux. The fact that scintillua ships
+-- independently is a showstopper.
+--
+-- Promissing is that the library now can use another Lua instance so maybe some day
+-- it will get properly in SciTE and we can use more clever scripting.
+--
+-- In some lexers we use embedded ones even if we could do it directly, The reason
+-- is that when the end token is edited (e.g. -->), backtracking to the space before
+-- the begin token (e.g. <!--) results in applying the surrounding whitespace which
+-- in turn means that when the end token is edited right, backtracking doesn't go
+-- back. One solution (in the dll) would be to backtrack several space categories.
+-- After all, lexing is quite fast (applying the result is much slower).
+--
+-- For some reason the first blob of text tends to go wrong (pdf and web). It would
+-- be nice to have 'whole doc' initial lexing. Quite fishy as it makes it impossible
+-- to lex the first part well (for already opened documents) because only a partial
+-- text is passed.
+--
+-- So, maybe I should just write this from scratch (assuming more generic usage)
+-- because after all, the dll expects just tables, based on a string. I can then
+-- also do some more aggressive resource sharing (needed when used generic).
+--
+-- I think that nested lexers are still bugged (esp over longer ranges). It never
+-- was robust or maybe it's simply not meant for too complex cases (well, it
+-- probably *is* tricky material). The 3.24 version was probably the best so far.
+-- The fact that styles bleed between lexers even if their states are isolated is an
+-- issue. Another issus is that zero characters in the text passed to the lexer can
+-- mess things up (pdf files have them in streams).
+--
+-- For more complex 'languages', like web or xml, we need to make sure that we use
+-- e.g. 'default' for spacing that makes up some construct. Ok, we then still have a
+-- backtracking issue but less.
+--
+-- Good news for some ConTeXt users: there is now a scintillua plugin for notepad++
+-- and we ship an ini file for that editor with some installation instructions
+-- embedded. Also, TextAdept has a console so that we can run realtime. The spawner
+-- is still not perfect (sometimes hangs) but it was enough reason to spend time on
+-- making our lexer work with TextAdept and create a setup.
+--
+-- Some bad news. The interface changed (again) in textadept 10, some for the better
+-- (but a bit different from what happens here) and some for the worse, especially
+-- moving some code to the init file so we now need some bad hacks. I decided to
+-- stay with the old method of defining lexers and because the lexer cannot be run
+-- in parallel any more (some change in the binary?) I will probably also cleanup
+-- code below as we no longer need to be compatible. Unfortunately textadept is too
+-- much a moving target to simply kick in some (tex related) production flow (apart
+-- from the fact that it doesn't yet have the scite like realtime console). I'll
+-- keep an eye on it. Because we don't need many added features I might as well decide
+-- to make a lean and mean instance (after all the license permits forking).
+
+-- TRACING
+--
+-- The advantage is that we now can check more easily with regular Lua(TeX). We can
+-- also use wine and print to the console (somehow stdout is intercepted there.) So,
+-- I've added a bit of tracing. Interesting is to notice that each document gets its
+-- own instance which has advantages but also means that when we are spellchecking
+-- we reload the word lists each time. (In the past I assumed a shared instance and
+-- took some precautions. But I can fix this.)
+--
+-- TODO
+--
+-- It would be nice if we could load some ConTeXt Lua modules (the basic set) and
+-- then use resolvers and such. But it might not work well with scite.
+--
+-- The current lexer basics are still a mix between old and new. Maybe I should redo
+-- some more. This is probably easier in TextAdept than in SciTE.
+--
+-- We have to make sure we don't overload ConTeXt definitions when this code is used
+-- in ConTeXt. I still have to add some of the goodies that we have there in lexers
+-- into these.
+--
+-- Maybe I should use a special stripped on the one hand and extended version of the
+-- dll (stable api) and at least add a bit more interfacing to scintilla.
+--
+-- I need to investigate if we can use the already built in Lua instance so that we
+-- can combine the power of lexing with extensions.
+--
+-- I need to play with hotspot and other properties like indicators (whatever they
+-- are).
+--
+-- I want to get rid of these lexers.STYLE_XX and lexers.XX things. This is possible
+-- when we give up compatibility. Generalize the helpers that I wrote for SciTE so
+-- that they also can be used TextAdept.
+--
+-- I can make an export to ConTeXt, but first I'll redo the code that makes the
+-- grammar, as we only seem to need
+--
+-- lexer._TOKENSTYLES : table
+-- lexer._CHILDREN : flag
+-- lexer._EXTRASTYLES : table
+-- lexer._GRAMMAR : flag
+--
+-- lexers.load : function
+-- lexers.lex : function
+--
+-- So, if we drop compatibility with other lex definitions, we can make things
+-- simpler. However, in the meantime one can just do this:
+--
+-- context --extra=listing --scite [--compact --verycompact] somefile.tex
+--
+-- and get a printable document. So, this todo is a bit obsolete.
+--
+-- Properties is an ugly mess ... due to chages in the interface we're now left
+-- with some hybrid that sort of works ok
+
+-- textadept: buffer:colourise(0,-1)
+
+local lpeg = require("lpeg")
+
+local global = _G
+local find, gmatch, match, lower, upper, gsub, sub, format, byte = string.find, string.gmatch, string.match, string.lower, string.upper, string.gsub, string.sub, string.format, string.byte
+local concat, sort = table.concat, table.sort
+local type, next, setmetatable, rawset, tonumber, tostring = type, next, setmetatable, rawset, tonumber, tostring
+local R, P, S, V, C, Cp, Cs, Ct, Cmt, Cc, Cf, Cg, Carg = lpeg.R, lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Cp, lpeg.Cs, lpeg.Ct, lpeg.Cmt, lpeg.Cc, lpeg.Cf, lpeg.Cg, lpeg.Carg
+local lpegmatch = lpeg.match
+
+local usage = (textadept and "textadept") or (resolvers and "context") or "scite"
+local nesting = 0
+local output = nil
+
+----- print = textadept and ui and ui.print or print -- crashes when ui is not yet defined
+
+local function print(...)
+ if not output then
+ output = io.open("lexer.log","w")
+ end
+ output:write(...,"\n")
+ output:flush()
+end
+
+local function report(fmt,str,...)
+ if log then
+ if str then
+ fmt = format(fmt,str,...)
+ end
+ print(format("scite lpeg lexer > %s > %s",nesting == 0 and "-" or nesting,fmt))
+ end
+end
+
+local function inform(...)
+ if log and trace then
+ report(...)
+ end
+end
+
+inform("loading context lexer module (global table: %s)",tostring(global))
+
+do
+
+ local floor = math and math.floor
+ local format = format
+ local tonumber = tonumber
+
+ if not floor then
+
+ if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then
+ floor = function(n)
+ return tonumber(format("%d",n))
+ end
+ else
+ -- 5.3 has a mixed number system and format %d doesn't work with
+ -- floats any longer ... no fun
+ floor = function(n)
+ return (n - n % 1)
+ end
+ end
+
+ math = math or { }
+
+ math.floor = floor
+
+ end
+
+end
+
+local floor = math.floor
+
+if not package.searchpath then
+
+ -- Unfortunately the io library is only available when we end up
+ -- in this branch of code.
+
+ inform("using adapted function 'package.searchpath' (if used at all)")
+
+ function package.searchpath(name,path)
+ local tried = { }
+ for part in gmatch(path,"[^;]+") do
+ local filename = gsub(part,"%?",name)
+ local f = io.open(filename,"r")
+ if f then
+ inform("file found on path: %s",filename)
+ f:close()
+ return filename
+ end
+ tried[#tried + 1] = format("no file '%s'",filename)
+ end
+ -- added: local path .. for testing
+ local f = io.open(filename,"r")
+ if f then
+ inform("file found on current path: %s",filename)
+ f:close()
+ return filename
+ end
+ --
+ tried[#tried + 1] = format("no file '%s'",filename)
+ return nil, concat(tried,"\n")
+ end
+
+end
+
+local lexers = { }
+local context = { }
+local helpers = { }
+lexers.context = context
+lexers.helpers = helpers
+
+local patterns = { }
+context.patterns = patterns -- todo: lexers.patterns
+
+context.report = report
+context.inform = inform
+
+lexers.LEXERPATH = package.path -- can be multiple paths separated by ;
+
+if resolvers then
+ -- todo: set LEXERPATH
+ -- todo: set report
+end
+
+local function sortedkeys(hash) -- simple version, good enough for here
+ local t, n = { }, 0
+ for k, v in next, hash do
+ t[#t+1] = k
+ local l = #tostring(k)
+ if l > n then
+ n = l
+ end
+ end
+ sort(t)
+ return t, n
+end
+
+helpers.sortedkeys = sortedkeys
+
+local usedlexers = { }
+local parent_lexer = nil
+
+-- The problem with styles is that there is some nasty interaction with scintilla
+-- and each version of lexer dll/so has a different issue. So, from now on we will
+-- just add them here. There is also a limit on some 30 styles. Maybe I should
+-- hash them in order to reuse.
+
+-- todo: work with proper hashes and analyze what styles are really used by a
+-- lexer
+
+local default = {
+ "nothing", "whitespace", "comment", "string", "number", "keyword",
+ "identifier", "operator", "error", "preprocessor", "constant", "variable",
+ "function", "type", "label", "embedded",
+ "quote", "special", "extra", "reserved", "okay", "warning",
+ "command", "internal", "preamble", "grouping", "primitive", "plain",
+ "user",
+ -- not used (yet) .. we cross the 32 boundary so had to patch the initializer, see (1)
+ "char", "class", "data", "definition", "invisible", "regex",
+ "standout", "tag",
+ "text",
+}
+
+local predefined = {
+ "default", "linenumber", "bracelight", "bracebad", "controlchar",
+ "indentguide", "calltip",
+ -- seems new
+ "folddisplaytext"
+}
+
+-- Bah ... ugly ... nicer would be a proper hash .. we now have properties
+-- as well as STYLE_* and some connection between them ... why .. ok, we
+-- could delay things but who cares. Anyway, at this moment the properties
+-- are still unknown.
+
+local function preparestyles(list)
+ local reverse = { }
+ for i=1,#list do
+ local k = list[i]
+ local K = upper(k)
+ local s = "style." .. k
+ lexers[K] = k -- is this used
+ lexers["STYLE_"..K] = "$(" .. k .. ")"
+ reverse[k] = true
+ end
+ return reverse
+end
+
+local defaultstyles = preparestyles(default)
+local predefinedstyles = preparestyles(predefined)
+
+-- These helpers are set afterwards so we delay their initialization ... there
+-- is no need to alias each time again and this way we can more easily adapt
+-- to updates.
+
+-- These keep changing (values, functions, tables ...) so we nee to check these
+-- with each update. Some of them are set in the loader (the require 'lexer' is
+-- in fact not a real one as the lexer code is loaded in the dll). It's also not
+-- getting more efficient.
+
+-- FOLD_BASE = lexers.FOLD_BASE or SC_FOLDLEVELBASE
+-- FOLD_HEADER = lexers.FOLD_HEADER or SC_FOLDLEVELHEADERFLAG
+-- FOLD_BLANK = lexers.FOLD_BLANK or SC_FOLDLEVELWHITEFLAG
+-- get_style_at = lexers.get_style_at or GetStyleAt
+-- get_indent_amount = lexers.get_indent_amount or GetIndentAmount
+-- get_property = lexers.get_property or GetProperty
+-- get_fold_level = lexers.get_fold_level or GetFoldLevel
+
+-- It needs checking: do we have access to all properties now? I'll clean
+-- this up anyway as I want a simple clean and stable model.
+
+-- This is somewhat messy. The lexer dll provides some virtual fields:
+--
+-- + property
+-- + property_int
+-- + style_at
+-- + fold_level
+-- + indent_amount
+--
+-- but for some reasons not:
+--
+-- + property_expanded
+--
+-- As a consequence we need to define it here because otherwise the
+-- lexer will crash. The fuzzy thing is that we don't have to define
+-- the property and property_int tables but we do have to define the
+-- expanded beforehand. The folding properties are no longer interfaced
+-- so the interface to scite is now rather weak (only a few hard coded
+-- properties).
+
+local FOLD_BASE = 0
+local FOLD_HEADER = 0
+local FOLD_BLANK = 0
+
+local style_at = { }
+local indent_amount = { }
+local fold_level = { }
+
+local function check_main_properties()
+ if not lexers.property then
+ lexers.property = { }
+ end
+ if not lexers.property_int then
+ lexers.property_int = setmetatable({ }, {
+ __index = function(t,k)
+ -- why the tostring .. it relies on lua casting to a number when
+ -- doing a comparison
+ return tonumber(lexers.property[k]) or 0 -- tostring removed
+ end,
+ -- __newindex = function(t,k,v)
+ -- report("properties are read-only, '%s' is not changed",k)
+ -- end,
+ })
+ end
+end
+
+lexers.property_expanded = setmetatable({ }, {
+ __index = function(t,k)
+ -- better be safe for future changes .. what if at some point this is
+ -- made consistent in the dll ... we need to keep an eye on that
+ local property = lexers.property
+ if not property then
+ check_main_properties()
+ end
+ --
+-- return gsub(property[k],"[$%%]%b()", function(k)
+-- return t[sub(k,3,-2)]
+-- end)
+ local v = property[k]
+ if v then
+ v = gsub(v,"[$%%]%b()", function(k)
+ return t[sub(k,3,-2)]
+ end)
+ end
+ return v
+ end,
+ __newindex = function(t,k,v)
+ report("properties are read-only, '%s' is not changed",k)
+ end,
+})
+
+-- A downward compatible feature but obsolete:
+
+-- local function get_property(tag,default)
+-- return lexers.property_int[tag] or lexers.property[tag] or default
+-- end
+
+-- We still want our own properties (as it keeps changing so better play
+-- safe from now on). At some point I can freeze them.
+
+local function check_properties(lexer)
+ if lexer.properties then
+ return lexer
+ end
+ check_main_properties()
+ -- we use a proxy
+ local mainproperties = lexers.property
+ local properties = { }
+ local expanded = setmetatable({ }, {
+ __index = function(t,k)
+ return gsub(properties[k] or mainproperties[k],"[$%%]%b()", function(k)
+ return t[sub(k,3,-2)]
+ end)
+ end,
+ })
+ lexer.properties = setmetatable(properties, {
+ __index = mainproperties,
+ __call = function(t,k,default) -- expands
+ local v = expanded[k]
+ local t = type(default)
+ if t == "number" then
+ return tonumber(v) or default
+ elseif t == "boolean" then
+ return v == nil and default or v
+ else
+ return v or default
+ end
+ end,
+ })
+ return lexer
+end
+
+-- do
+-- lexers.property = { foo = 123, red = "R" }
+-- local a = check_properties({}) print("a.foo",a.properties.foo)
+-- a.properties.foo = "bar" print("a.foo",a.properties.foo)
+-- a.properties.foo = "bar:$(red)" print("a.foo",a.properties.foo) print("a.foo",a.properties("foo"))
+-- end
+
+local function set(value,default)
+ if value == 0 or value == false or value == "0" then
+ return false
+ elseif value == 1 or value == true or value == "1" then
+ return true
+ else
+ return default
+ end
+end
+
+local function check_context_properties()
+ local property = lexers.property -- let's hope that this stays
+ log = set(property["lexer.context.log"], log)
+ trace = set(property["lexer.context.trace"], trace)
+ detail = set(property["lexer.context.detail"], detail)
+ show = set(property["lexer.context.show"], show)
+ collapse = set(property["lexer.context.collapse"],collapse)
+ inspect = set(property["lexer.context.inspect"], inspect)
+end
+
+function context.registerproperties(p) -- global
+ check_main_properties()
+ local property = lexers.property -- let's hope that this stays
+ for k, v in next, p do
+ property[k] = v
+ end
+ check_context_properties()
+end
+
+context.properties = setmetatable({ }, {
+ __index = lexers.property,
+ __newindex = function(t,k,v)
+ check_main_properties()
+ lexers.property[k] = v
+ check_context_properties()
+ end,
+})
+
+-- We want locals to we set them delayed. Once.
+
+local function initialize()
+ FOLD_BASE = lexers.FOLD_BASE
+ FOLD_HEADER = lexers.FOLD_HEADER
+ FOLD_BLANK = lexers.FOLD_BLANK
+ --
+ style_at = lexers.style_at -- table
+ indent_amount = lexers.indent_amount -- table
+ fold_level = lexers.fold_level -- table
+ --
+ check_main_properties()
+ --
+ initialize = nil
+end
+
+-- Style handler.
+--
+-- The property table will be set later (after loading) by the library. The
+-- styleset is not needed any more as we predefine all styles as defaults
+-- anyway (too bug sensitive otherwise).
+
+local function tocolors(colors)
+ local colorset = { }
+ local property_int = lexers.property_int or { }
+ for k, v in next, colors do
+ if type(v) == "table" then
+ local r, g, b = v[1], v[2], v[3]
+ if r and g and b then
+ v = tonumber(format("%02X%02X%02X",b,g,r),16) or 0 -- hm
+ elseif r then
+ v = tonumber(format("%02X%02X%02X",r,r,r),16) or 0
+ else
+ v = 0
+ end
+ end
+ colorset[k] = v
+ property_int["color."..k] = v
+ end
+ return colorset
+end
+
+local function toproperty(specification)
+ local serialized = { }
+ for key, value in next, specification do
+ if value == true then
+ serialized[#serialized+1] = key
+ elseif type(value) == "table" then
+ local r, g, b = value[1], value[2], value[3]
+ if r and g and b then
+ value = format("#%02X%02X%02X",r,g,b) or "#000000"
+ elseif r then
+ value = format("#%02X%02X%02X",r,r,r) or "#000000"
+ else
+ value = "#000000"
+ end
+ serialized[#serialized+1] = key .. ":" .. value
+ else
+ serialized[#serialized+1] = key .. ":" .. tostring(value)
+ end
+ end
+ return concat(serialized,",")
+end
+
+local function tostyles(styles)
+ local styleset = { }
+ local property = lexers.property or { }
+ for k, v in next, styles do
+ v = toproperty(v)
+ styleset[k] = v
+ property["style."..k] = v
+ end
+ return styleset
+end
+
+context.toproperty = toproperty
+context.tostyles = tostyles
+context.tocolors = tocolors
+
+-- If we had one instance/state of Lua as well as all regular libraries
+-- preloaded we could use the context base libraries. So, let's go poor-
+-- mans solution now.
+
+function context.registerstyles(styles)
+ local styleset = tostyles(styles)
+ context.styles = styles
+ context.styleset = styleset
+ if detail then
+ local t, n = sortedkeys(styleset)
+ local template = " %-" .. n .. "s : %s"
+ report("initializing styleset:")
+ for i=1,#t do
+ local k = t[i]
+ report(template,k,styleset[k])
+ end
+ elseif trace then
+ report("initializing styleset")
+ end
+end
+
+function context.registercolors(colors) -- needed for textadept
+ local colorset = tocolors(colors)
+ context.colors = colors
+ context.colorset = colorset
+ if detail then
+ local t, n = sortedkeys(colorset)
+ local template = " %-" .. n .. "s : %i"
+ report("initializing colorset:")
+ for i=1,#t do
+ local k = t[i]
+ report(template,k,colorset[k])
+ end
+ elseif trace then
+ report("initializing colorset")
+ end
+end
+
+-- Some spell checking related stuff. Unfortunately we cannot use a path set
+-- by property. This will get a hook for resolvers.
+
+local locations = {
+ "context/lexers", -- context lexers
+ "context/lexers/data", -- context lexers
+ "../lexers", -- original lexers
+ "../lexers/data", -- original lexers
+ ".", -- whatever
+ "./data", -- whatever
+}
+
+-- local function collect(name)
+-- local root = gsub(lexers.LEXERPATH or ".","/.-lua$","") .. "/" -- this is a horrible hack
+-- -- report("module '%s' locating '%s'",tostring(lexers),name)
+-- for i=1,#locations do
+-- local fullname = root .. locations[i] .. "/" .. name .. ".lua" -- so we can also check for .luc
+-- if trace then
+-- report("attempt to locate '%s'",fullname)
+-- end
+-- local okay, result = pcall(function () return dofile(fullname) end)
+-- if okay then
+-- return result, fullname
+-- end
+-- end
+-- end
+
+local collect
+
+if usage == "context" then
+
+ collect = function(name)
+ return require(name), name
+ end
+
+else
+
+ collect = function(name)
+ local rootlist = lexers.LEXERPATH or "."
+ for root in gmatch(rootlist,"[^;]+") do
+ local root = gsub(root,"/[^/]-lua$","")
+ for i=1,#locations do
+ local fullname = root .. "/" .. locations[i] .. "/" .. name .. ".lua" -- so we can also check for .luc
+ if trace then
+ report("attempt to locate '%s'",fullname)
+ end
+ local okay, result = pcall(function () return dofile(fullname) end)
+ if okay then
+ return result, fullname
+ end
+ end
+ end
+ -- return require(name), name
+ end
+
+end
+
+function context.loadluafile(name)
+ local data, fullname = collect(name)
+ if data then
+ if trace then
+ report("lua file '%s' has been loaded",fullname)
+ end
+ return data, fullname
+ end
+ if not textadept then
+ report("unable to load lua file '%s'",name)
+ end
+end
+
+-- in fact we could share more as we probably process the data but then we need
+-- to have a more advanced helper
+
+local cache = { }
+
+function context.loaddefinitions(name)
+ local data = cache[name]
+ if data then
+ if trace then
+ report("reusing definitions '%s'",name)
+ end
+ return data
+ elseif trace and data == false then
+ report("definitions '%s' were not found",name)
+ end
+ local data, fullname = collect(name)
+ if not data then
+ if not textadept then
+ report("unable to load definition file '%s'",name)
+ end
+ data = false
+ elseif trace then
+ report("definition file '%s' has been loaded",fullname)
+ if detail then
+ local t, n = sortedkeys(data)
+ local template = " %-" .. n .. "s : %s"
+ for i=1,#t do
+ local k = t[i]
+ local v = data[k]
+ if type(v) ~= "table" then
+ report(template,k,tostring(v))
+ elseif #v > 0 then
+ report(template,k,#v)
+ else
+ -- no need to show hash
+ end
+ end
+ end
+ end
+ cache[name] = data
+ return type(data) == "table" and data
+end
+
+-- A bit of regression in textadept > 10 so updated ... done a bit different.
+-- We don't use this in the context lexers anyway.
+
+function context.word_match(words,word_chars,case_insensitive)
+ -- used to be proper tables ...
+ if type(words) == "string" then
+ local clean = gsub(words,"%-%-[^\n]+","")
+ local split = { }
+ for s in gmatch(clean,"%S+") do
+ split[#split+1] = s
+ end
+ words = split
+ end
+ local list = { }
+ for i=1,#words do
+ list[words[i]] = true
+ end
+ if case_insensitive then
+ for i=1,#words do
+ list[lower(words[i])] = true
+ end
+ end
+ local chars = S(word_chars or "")
+ for i=1,#words do
+ chars = chars + S(words[i])
+ end
+ local match = case_insensitive and
+ function(input,index,word)
+ -- We can speed mixed case if needed.
+ return (list[word] or list[lower(word)]) and index or nil
+ end
+ or
+ function(input,index,word)
+ return list[word] and index or nil
+ end
+ return Cmt(chars^1,match)
+end
+
+-- Patterns are grouped in a separate namespace but the regular lexers expect
+-- shortcuts to be present in the lexers library. Maybe I'll incorporate some
+-- of l-lpeg later.
+
+do
+
+ local anything = P(1)
+ local idtoken = R("az","AZ","\127\255","__")
+ local digit = R("09")
+ local sign = S("+-")
+ local period = P(".")
+ local octdigit = R("07")
+ local hexdigit = R("09","AF","af")
+ local lower = R("az")
+ local upper = R("AZ")
+ local alpha = upper + lower
+ local space = S(" \n\r\t\f\v")
+ local eol = S("\r\n")
+ local backslash = P("\\")
+ local decimal = digit^1
+ local octal = P("0")
+ * octdigit^1
+ local hexadecimal = P("0") * S("xX")
+ * (hexdigit^0 * period * hexdigit^1 + hexdigit^1 * period * hexdigit^0 + hexdigit^1)
+ * (S("pP") * sign^-1 * hexdigit^1)^-1 -- *
+ local integer = sign^-1
+ * (hexadecimal + octal + decimal)
+ local float = sign^-1
+ * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1)
+ * S("eE") * sign^-1 * digit^1 -- *
+
+ patterns.idtoken = idtoken
+ patterns.digit = digit
+ patterns.sign = sign
+ patterns.period = period
+ patterns.octdigit = octdigit
+ patterns.hexdigit = hexdigit
+ patterns.ascii = R("\000\127") -- useless
+ patterns.extend = R("\000\255") -- useless
+ patterns.control = R("\000\031")
+ patterns.lower = lower
+ patterns.upper = upper
+ patterns.alpha = alpha
+ patterns.decimal = decimal
+ patterns.octal = octal
+ patterns.hexadecimal = hexadecimal
+ patterns.float = float
+ patterns.cardinal = decimal
+
+ patterns.signeddecimal = sign^-1 * decimal
+ patterns.signedoctal = sign^-1 * octal
+ patterns.signedhexadecimal = sign^-1 * hexadecimal
+ patterns.integer = integer
+ patterns.real =
+ sign^-1 * ( -- at most one
+ digit^1 * period * digit^0 -- 10.0 10.
+ + digit^0 * period * digit^1 -- 0.10 .10
+ + digit^1 -- 10
+ )
+
+ patterns.anything = anything
+ patterns.any = anything
+ patterns.restofline = (1-eol)^1
+ patterns.space = space
+ patterns.spacing = space^1
+ patterns.nospacing = (1-space)^1
+ patterns.eol = eol
+ patterns.newline = P("\r\n") + eol
+ patterns.backslash = backslash
+
+ local endof = S("\n\r\f")
+
+ patterns.startofline = P(function(input,index)
+ return (index == 1 or lpegmatch(endof,input,index-1)) and index
+ end)
+
+ -- These are the expected ones for other lexers. Maybe all in own namespace
+ -- and provide compatibility layer. or should I just remove them?
+
+ lexers.any = anything
+ lexers.ascii = ascii
+ lexers.extend = extend
+ lexers.alpha = alpha
+ lexers.digit = digit
+ lexers.alnum = alpha + digit
+ lexers.lower = lower
+ lexers.upper = upper
+ lexers.xdigit = hexdigit
+ lexers.cntrl = control
+ lexers.graph = R("!~")
+ lexers.print = R(" ~")
+ lexers.punct = R("!/", ":@", "[\'", "{~")
+ lexers.space = space
+ lexers.newline = S("\r\n\f")^1
+ lexers.nonnewline = 1 - lexers.newline
+ lexers.nonnewline_esc = 1 - (lexers.newline + '\\') + backslash * anything
+ lexers.dec_num = decimal
+ lexers.oct_num = octal
+ lexers.hex_num = hexadecimal
+ lexers.integer = integer
+ lexers.float = float
+ lexers.word = (alpha + "_") * (alpha + digit + "_")^0 -- weird, why digits
+
+end
+
+-- end of patterns
+
+function context.exact_match(words,word_chars,case_insensitive)
+ local characters = concat(words)
+ local pattern -- the concat catches _ etc
+ if word_chars == true or word_chars == false or word_chars == nil then
+ word_chars = ""
+ end
+ if type(word_chars) == "string" then
+ pattern = S(characters) + patterns.idtoken
+ if case_insensitive then
+ pattern = pattern + S(upper(characters)) + S(lower(characters))
+ end
+ if word_chars ~= "" then
+ pattern = pattern + S(word_chars)
+ end
+ elseif word_chars then
+ pattern = word_chars
+ end
+ if case_insensitive then
+ local list = { }
+ if #words == 0 then
+ for k, v in next, words do
+ list[lower(k)] = v
+ end
+ else
+ for i=1,#words do
+ list[lower(words[i])] = true
+ end
+ end
+ return Cmt(pattern^1, function(_,i,s)
+ return list[lower(s)] -- and i or nil
+ end)
+ else
+ local list = { }
+ if #words == 0 then
+ for k, v in next, words do
+ list[k] = v
+ end
+ else
+ for i=1,#words do
+ list[words[i]] = true
+ end
+ end
+ return Cmt(pattern^1, function(_,i,s)
+ return list[s] -- and i or nil
+ end)
+ end
+end
+
+function context.just_match(words)
+ local p = P(words[1])
+ for i=2,#words do
+ p = p + P(words[i])
+ end
+ return p
+end
+
+-- spell checking (we can only load lua files)
+--
+-- return {
+-- min = 3,
+-- max = 40,
+-- n = 12345,
+-- words = {
+-- ["someword"] = "someword",
+-- ["anotherword"] = "Anotherword",
+-- },
+-- }
+
+local lists = { }
+local disabled = false
+
+function context.disablewordcheck()
+ disabled = true
+end
+
+function context.setwordlist(tag,limit) -- returns hash (lowercase keys and original values)
+ if not tag or tag == "" then
+ return false, 3
+ end
+ local list = lists[tag]
+ if not list then
+ list = context.loaddefinitions("spell-" .. tag)
+ if not list or type(list) ~= "table" then
+ if not textadept then
+ report("invalid spell checking list for '%s'",tag)
+ end
+ list = { words = false, min = 3 }
+ else
+ list.words = list.words or false
+ list.min = list.min or 3
+ end
+ lists[tag] = list
+ end
+ if trace then
+ report("enabling spell checking for '%s' with minimum '%s'",tag,list.min)
+ end
+ return list.words, list.min
+end
+
+patterns.wordtoken = R("az","AZ","\127\255")
+patterns.wordpattern = patterns.wordtoken^3 -- todo: if limit and #s < limit then
+
+function context.checkedword(validwords,validminimum,s,i) -- ,limit
+ if not validwords then -- or #s < validminimum then
+ return true, "text", i -- true, "default", i
+ else
+ -- keys are lower
+ local word = validwords[s]
+ if word == s then
+ return true, "okay", i -- exact match
+ elseif word then
+ return true, "warning", i -- case issue
+ else
+ local word = validwords[lower(s)]
+ if word == s then
+ return true, "okay", i -- exact match
+ elseif word then
+ return true, "warning", i -- case issue
+ elseif upper(s) == s then
+ return true, "warning", i -- probably a logo or acronym
+ else
+ return true, "error", i
+ end
+ end
+ end
+end
+
+function context.styleofword(validwords,validminimum,s) -- ,limit
+ if not validwords or #s < validminimum then
+ return "text"
+ else
+ -- keys are lower
+ local word = validwords[s]
+ if word == s then
+ return "okay" -- exact match
+ elseif word then
+ return "warning" -- case issue
+ else
+ local word = validwords[lower(s)]
+ if word == s then
+ return "okay" -- exact match
+ elseif word then
+ return "warning" -- case issue
+ elseif upper(s) == s then
+ return "warning" -- probably a logo or acronym
+ else
+ return "error"
+ end
+ end
+ end
+end
+
+-- overloaded functions
+
+local h_table, b_table, n_table = { }, { }, { } -- from the time small tables were used (optimization)
+
+setmetatable(h_table, { __index = function(t,level) local v = { level, FOLD_HEADER } t[level] = v return v end })
+setmetatable(b_table, { __index = function(t,level) local v = { level, FOLD_BLANK } t[level] = v return v end })
+setmetatable(n_table, { __index = function(t,level) local v = { level } t[level] = v return v end })
+
+local newline = patterns.newline
+local p_yes = Cp() * Cs((1-newline)^1) * newline^-1
+local p_nop = newline
+
+local folders = { }
+
+-- Snippets from the > 10 code .. but we do things different so ...
+
+local function fold_by_parsing(text,start_pos,start_line,start_level,lexer)
+ local folder = folders[lexer]
+ if not folder then
+ --
+ local pattern, folds, text, start_pos, line_num, prev_level, current_level
+ --
+ local fold_symbols = lexer._foldsymbols
+ local fold_pattern = lexer._foldpattern -- use lpeg instead (context extension)
+ --
+ -- textadept >= 10
+ --
+ -- local zerosumlines = lexer.property_int["fold.on.zero.sum.lines"] > 0 -- not done
+ -- local compact = lexer.property_int['fold.compact'] > 0 -- not done
+ -- local lowercase = lexer._CASEINSENSITIVEFOLDPOINTS -- useless (utf will distort)
+ --
+ if fold_pattern then
+ -- if no functions are found then we could have a faster one
+ fold_pattern = Cp() * C(fold_pattern) / function(s,match)
+ local symbols = fold_symbols[style_at[start_pos + s]]
+ if symbols then
+ local l = symbols[match]
+ if l then
+ current_level = current_level + l
+ end
+ end
+ end
+ local action_y = function()
+ folds[line_num] = prev_level
+ if current_level > prev_level then
+ folds[line_num] = prev_level + FOLD_HEADER
+ end
+ if current_level < FOLD_BASE then
+ current_level = FOLD_BASE
+ end
+ prev_level = current_level
+ line_num = line_num + 1
+ end
+ local action_n = function()
+ folds[line_num] = prev_level + FOLD_BLANK
+ line_num = line_num + 1
+ end
+ pattern = ((fold_pattern + (1-newline))^1 * newline / action_y + newline/action_n)^0
+
+ else
+ -- the traditional one but a bit optimized
+ local fold_symbols_patterns = fold_symbols._patterns
+ local action_y = function(pos,line)
+ for j=1, #fold_symbols_patterns do
+ for s, match in gmatch(line,fold_symbols_patterns[j]) do -- "()(" .. patterns[i] .. ")"
+ local symbols = fold_symbols[style_at[start_pos + pos + s - 1]]
+ local l = symbols and symbols[match]
+ local t = type(l)
+ if t == "number" then
+ current_level = current_level + l
+ elseif t == "function" then
+ current_level = current_level + l(text, pos, line, s, match)
+ end
+ end
+ end
+ folds[line_num] = prev_level
+ if current_level > prev_level then
+ folds[line_num] = prev_level + FOLD_HEADER
+ end
+ if current_level < FOLD_BASE then
+ current_level = FOLD_BASE
+ end
+ prev_level = current_level
+ line_num = line_num + 1
+ end
+ local action_n = function()
+ folds[line_num] = prev_level + FOLD_BLANK
+ line_num = line_num + 1
+ end
+ pattern = (p_yes/action_y + p_nop/action_n)^0
+ end
+ --
+ local reset_parser = lexer._reset_parser
+ --
+ folder = function(_text_,_start_pos_,_start_line_,_start_level_)
+ if reset_parser then
+ reset_parser()
+ end
+ folds = { }
+ text = _text_
+ start_pos = _start_pos_
+ line_num = _start_line_
+ prev_level = _start_level_
+ current_level = prev_level
+ lpegmatch(pattern,text)
+ -- make folds collectable
+ local t = folds
+ folds = nil
+ return t
+ end
+ folders[lexer] = folder
+ end
+ return folder(text,start_pos,start_line,start_level,lexer)
+end
+
+local folds, current_line, prev_level
+
+local function action_y()
+ local current_level = FOLD_BASE + indent_amount[current_line]
+ if current_level > prev_level then -- next level
+ local i = current_line - 1
+ local f
+ while true do
+ f = folds[i]
+ if not f then
+ break
+ elseif f[2] == FOLD_BLANK then
+ i = i - 1
+ else
+ f[2] = FOLD_HEADER -- low indent
+ break
+ end
+ end
+ folds[current_line] = { current_level } -- high indent
+ elseif current_level < prev_level then -- prev level
+ local f = folds[current_line - 1]
+ if f then
+ f[1] = prev_level -- high indent
+ end
+ folds[current_line] = { current_level } -- low indent
+ else -- same level
+ folds[current_line] = { prev_level }
+ end
+ prev_level = current_level
+ current_line = current_line + 1
+end
+
+local function action_n()
+ folds[current_line] = { prev_level, FOLD_BLANK }
+ current_line = current_line + 1
+end
+
+local pattern = ( S("\t ")^0 * ( (1-patterns.eol)^1 / action_y + P(true) / action_n) * newline )^0
+
+local function fold_by_indentation(text,start_pos,start_line,start_level)
+ -- initialize
+ folds = { }
+ current_line = start_line
+ prev_level = start_level
+ -- define
+ -- -- not here .. pattern binds and local functions are not frozen
+ -- analyze
+ lpegmatch(pattern,text)
+ -- flatten
+ for line, level in next, folds do
+ folds[line] = level[1] + (level[2] or 0)
+ end
+ -- done, make folds collectable
+ local t = folds
+ folds = nil
+ return t
+end
+
+local function fold_by_line(text,start_pos,start_line,start_level)
+ local folds = { }
+ -- can also be lpeg'd
+ for _ in gmatch(text,".-\r?\n") do
+ folds[start_line] = n_table[start_level] -- { start_level } -- stile tables ? needs checking
+ start_line = start_line + 1
+ end
+ return folds
+end
+
+local threshold_by_lexer = 512 * 1024 -- we don't know the filesize yet
+local threshold_by_parsing = 512 * 1024 -- we don't know the filesize yet
+local threshold_by_indentation = 512 * 1024 -- we don't know the filesize yet
+local threshold_by_line = 512 * 1024 -- we don't know the filesize yet
+
+function context.fold(lexer,text,start_pos,start_line,start_level) -- hm, we had size thresholds .. where did they go
+ if text == "" then
+ return { }
+ end
+ if initialize then
+ initialize()
+ end
+ local fold_by_lexer = lexer._fold
+ local fold_by_symbols = lexer._foldsymbols
+ local filesize = 0 -- we don't know that
+ if fold_by_lexer then
+ if filesize <= threshold_by_lexer then
+ return fold_by_lexer(text,start_pos,start_line,start_level,lexer)
+ end
+ elseif fold_by_symbols then -- and lexer.properties("fold.by.parsing",1) > 0 then
+ if filesize <= threshold_by_parsing then
+ return fold_by_parsing(text,start_pos,start_line,start_level,lexer)
+ end
+ elseif lexer._FOLDBYINDENTATION or lexer.properties("fold.by.indentation",1) > 0 then
+ if filesize <= threshold_by_indentation then
+ return fold_by_indentation(text,start_pos,start_line,start_level,lexer)
+ end
+ elseif lexer._FOLDBYLINE or lexer.properties("fold.by.line",1) > 0 then
+ if filesize <= threshold_by_line then
+ return fold_by_line(text,start_pos,start_line,start_level,lexer)
+ end
+ end
+ return { }
+end
+
+-- The following code is mostly unchanged:
+
+local function add_rule(lexer,id,rule) -- unchanged
+ if not lexer._RULES then
+ lexer._RULES = { }
+ lexer._RULEORDER = { }
+ end
+ lexer._RULES[id] = rule
+ lexer._RULEORDER[#lexer._RULEORDER + 1] = id
+end
+
+local function modify_rule(lexer,id,rule) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ lexer._RULES[id] = rule
+end
+
+local function get_rule(lexer,id) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ return lexer._RULES[id]
+end
+
+-- I finally figured out that adding more styles was an issue because of several
+-- reasons:
+--
+-- + in old versions there was a limit in the amount, so we overran the built-in
+-- hard coded scintilla range
+-- + then, the add_style function didn't check for already known ones, so again
+-- we had an overrun (with some magic that could be avoided)
+-- + then, when I messed with a new default set I realized that there is no check
+-- in initializing _TOKENSTYLES (here the inspect function helps)
+-- + of course it was mostly a side effect of passing all the used styles to the
+-- _tokenstyles instead of only the not-default ones but such a thing should not
+-- matter (read: intercepted)
+--
+-- This finally removed a head-ache and was revealed by lots of tracing, which I
+-- should have built in way earlier.
+
+local function add_style(lexer,token_name,style) -- changed a bit around 3.41
+ -- We don't add styles that are already defined as this can overflow the
+ -- amount possible (in old versions of scintilla).
+ if defaultstyles[token_name] then
+ if trace and detail then
+ report("default style '%s' is ignored as extra style",token_name)
+ end
+ if textadept then
+ -- go on, stored per buffer
+ else
+ return
+ end
+ elseif predefinedstyles[token_name] then
+ if trace and detail then
+ report("predefined style '%s' is ignored as extra style",token_name)
+ end
+ if textadept then
+ -- go on, stored per buffer
+ else
+ return
+ end
+ else
+ if trace and detail then
+ report("adding extra style '%s' as '%s'",token_name,style)
+ end
+ end
+ -- This is unchanged. We skip the dangerous zone.
+ local num_styles = lexer._numstyles
+ if num_styles == 32 then
+ num_styles = num_styles + 8
+ end
+ if num_styles >= 255 then
+ report("there can't be more than %s styles",255)
+ end
+ lexer._TOKENSTYLES[token_name] = num_styles
+ lexer._EXTRASTYLES[token_name] = style
+ lexer._numstyles = num_styles + 1
+ -- hm, the original (now) also copies to the parent ._lexer
+end
+
+local function check_styles(lexer)
+ -- Here we also use a check for the dangerous zone. That way we can have a
+ -- larger default set. The original code just assumes that #default is less
+ -- than the dangerous zone's start.
+ local numstyles = 0
+ local tokenstyles = { }
+ for i=1, #default do
+ if numstyles == 32 then
+ numstyles = numstyles + 8
+ end
+ tokenstyles[default[i]] = numstyles
+ numstyles = numstyles + 1
+ end
+ -- Unchanged.
+ for i=1, #predefined do
+ tokenstyles[predefined[i]] = i + 31
+ end
+ lexer._TOKENSTYLES = tokenstyles
+ lexer._numstyles = numstyles
+ lexer._EXTRASTYLES = { }
+ return lexer
+end
+
+-- At some point an 'any' append showed up in the original code ...
+-- but I see no need to catch that case ... beter fix the specification.
+--
+-- hm, why are many joined twice
+
+local function join_tokens(lexer) -- slightly different from the original (no 'any' append)
+ local patterns = lexer._RULES
+ local order = lexer._RULEORDER
+ -- report("lexer: %s, tokens: %s",lexer._NAME,table.concat(order," + "))
+ if patterns and order then
+ local token_rule = patterns[order[1]] -- normally whitespace
+ for i=2,#order do
+ token_rule = token_rule + patterns[order[i]]
+ end
+ if lexer._TYPE ~= "context" then
+ token_rule = token_rule + lexers.token(lexers.DEFAULT, patterns.any)
+ end
+ lexer._TOKENRULE = token_rule
+ return token_rule
+ else
+ return P(1)
+ end
+end
+
+-- hm, maybe instead of a grammer just a flat one
+
+local function add_lexer(grammar, lexer) -- mostly the same as the original
+ local token_rule = join_tokens(lexer)
+ local lexer_name = lexer._NAME
+ local children = lexer._CHILDREN
+ for i=1,#children do
+ local child = children[i]
+ if child._CHILDREN then
+ add_lexer(grammar, child)
+ end
+ local child_name = child._NAME
+ local rules = child._EMBEDDEDRULES[lexer_name]
+ local rules_token_rule = grammar["__" .. child_name] or rules.token_rule
+ local pattern = (-rules.end_rule * rules_token_rule)^0 * rules.end_rule^-1
+ grammar[child_name] = pattern * V(lexer_name)
+ local embedded_child = "_" .. child_name
+ grammar[embedded_child] = rules.start_rule * pattern
+ token_rule = V(embedded_child) + token_rule
+ end
+ if trace then
+ report("adding lexer '%s' with %s children",lexer_name,#children)
+ end
+ grammar["__" .. lexer_name] = token_rule
+ grammar[lexer_name] = token_rule^0
+end
+
+local function build_grammar(lexer,initial_rule) -- same as the original
+ local children = lexer._CHILDREN
+ local lexer_name = lexer._NAME
+ local preamble = lexer._preamble
+ local grammar = lexer._grammar
+ -- if grammar then
+ -- -- experiment
+ -- elseif children then
+ if children then
+ if not initial_rule then
+ initial_rule = lexer_name
+ end
+ grammar = { initial_rule }
+ add_lexer(grammar, lexer)
+ lexer._INITIALRULE = initial_rule
+ grammar = Ct(P(grammar))
+ if trace then
+ report("building grammar for '%s' with whitespace '%s'and %s children",lexer_name,lexer.whitespace or "?",#children)
+ end
+ else
+ grammar = Ct(join_tokens(lexer)^0)
+ if trace then
+ report("building grammar for '%s' with whitespace '%s'",lexer_name,lexer.whitespace or "?")
+ end
+ end
+ if preamble then
+ grammar = preamble^-1 * grammar
+ end
+ lexer._GRAMMAR = grammar
+end
+
+-- So far. We need these local functions in the next one.
+
+local lineparsers = { }
+
+local maxmatched = 100
+
+local function collapsed(t)
+ local lasttoken = nil
+ local lastindex = nil
+ for i=1,#t,2 do
+ local token = t[i]
+ local position = t[i+1]
+ if token == lasttoken then
+ t[lastindex] = position
+ elseif lastindex then
+ lastindex = lastindex + 1
+ t[lastindex] = token
+ lastindex = lastindex + 1
+ t[lastindex] = position
+ lasttoken = token
+ else
+ lastindex = i+1
+ lasttoken = token
+ end
+ end
+ for i=#t,lastindex+1,-1 do
+ t[i] = nil
+ end
+ return t
+end
+
+local function matched(lexer,grammar,text)
+ -- text = string.gsub(text,"\z","!")
+ local t = lpegmatch(grammar,text)
+ if trace then
+ if show then
+ report("output of lexer: %s (max %s entries)",lexer._NAME,maxmatched)
+ local s = lexer._TOKENSTYLES
+ local p = 1
+ for i=1,2*maxmatched,2 do
+ local n = i + 1
+ local ti = t[i]
+ local tn = t[n]
+ if ti then
+ local txt = sub(text,p,tn-1)
+ if txt then
+ txt = gsub(txt,"[%s]"," ")
+ else
+ txt = "!no text!"
+ end
+ report("%4i : %s > %s (%s) (%s)",floor(n/2),ti,tn,s[ti] or "!unset!",txt)
+ p = tn
+ else
+ break
+ end
+ end
+ end
+ report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2))
+ if collapse then
+ t = collapsed(t)
+ report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2))
+ end
+ elseif collapse then
+ t = collapsed(t)
+ end
+ return t
+end
+
+-- Todo: make nice generic lexer (extra argument with start/stop commands) for
+-- context itself.
+--
+-- In textadept >= 10 grammar building seem to have changed a bit. So, in retrospect
+-- I could better have just dropped compatibility and stick to ctx lexers only.
+
+function context.lex(lexer,text,init_style)
+ -- local lexer = global._LEXER
+ local grammar = lexer._GRAMMAR
+ if initialize then
+ initialize()
+ end
+ if not grammar then
+ return { }
+ elseif lexer._LEXBYLINE then -- we could keep token
+ local tokens = { }
+ local offset = 0
+ local noftokens = 0
+ local lineparser = lineparsers[lexer]
+ if not lineparser then -- probably a cmt is more efficient
+ lineparser = C((1-newline)^0 * newline) / function(line)
+ local length = #line
+ local line_tokens = length > 0 and lpegmatch(grammar,line)
+ if line_tokens then
+ for i=1,#line_tokens,2 do
+ noftokens = noftokens + 1
+ tokens[noftokens] = line_tokens[i]
+ noftokens = noftokens + 1
+ tokens[noftokens] = line_tokens[i + 1] + offset
+ end
+ end
+ offset = offset + length
+ if noftokens > 0 and tokens[noftokens] ~= offset then
+ noftokens = noftokens + 1
+ tokens[noftokens] = "default"
+ noftokens = noftokens + 1
+ tokens[noftokens] = offset + 1
+ end
+ end
+ lineparser = lineparser^0
+ lineparsers[lexer] = lineparser
+ end
+ lpegmatch(lineparser,text)
+ return tokens
+ elseif lexer._CHILDREN then
+ local hash = lexer._HASH -- hm, was _hash
+ if not hash then
+ hash = { }
+ lexer._HASH = hash
+ end
+ grammar = hash[init_style]
+ if grammar then
+ lexer._GRAMMAR = grammar
+ -- lexer._GRAMMAR = lexer._GRAMMAR or grammar
+ else
+ for style, style_num in next, lexer._TOKENSTYLES do
+ if style_num == init_style then
+ -- the name of the lexers is filtered from the whitespace
+ -- specification .. weird code, should be a reverse hash
+ local lexer_name = match(style,"^(.+)_whitespace") or lexer._NAME
+ if lexer._INITIALRULE ~= lexer_name then
+ grammar = hash[lexer_name]
+ if not grammar then
+ build_grammar(lexer,lexer_name)
+ grammar = lexer._GRAMMAR
+ hash[lexer_name] = grammar
+ end
+ end
+ break
+ end
+ end
+ grammar = grammar or lexer._GRAMMAR
+ hash[init_style] = grammar
+ end
+ if trace then
+ report("lexing '%s' with initial style '%s' and %s children", lexer._NAME,init_style,#lexer._CHILDREN or 0)
+ end
+ return matched(lexer,grammar,text)
+ else
+ if trace then
+ report("lexing '%s' with initial style '%s'",lexer._NAME,init_style)
+ end
+ return matched(lexer,grammar,text)
+ end
+end
+
+-- hm, changed in 3.24 .. no longer small table but one table (so we could remove our
+-- agressive optimization which worked quite well)
+
+function context.token(name, patt)
+ return patt * Cc(name) * Cp()
+end
+
+-- The next ones were mostly unchanged (till now), we moved it here when 3.41
+-- became close to impossible to combine with cq. overload and a merge was
+-- the only solution. It makes later updates more painful but the update to
+-- 3.41 was already a bit of a nightmare anyway.
+
+-- Loading lexers is rather interwoven with what the dll/so sets and
+-- it changes over time. So, we need to keep an eye on changes. One
+-- problem that we always faced were the limitations in length of
+-- lexer names (as they get app/prepended occasionally to strings with
+-- a hard coded limit). So, we always used alternative names and now need
+-- to make sure this doesn't clash. As I no longer intend to use shipped
+-- lexers I could strip away some of the code in the future, but keeping
+-- it as reference makes sense.
+
+-- I spend quite some time figuring out why 3.41 didn't work or crashed which
+-- is hard when no stdout is available and when the io library is absent. In
+-- the end of of the problems was in the _NAME setting. We set _NAME
+-- to e.g. 'tex' but load from a file with a longer name, which we do
+-- as we don't want to clash with existing files, we end up in
+-- lexers not being found.
+
+local whitespaces = { }
+
+local function push_whitespace(name)
+ table.insert(whitespaces,lexers.WHITESPACE or "whitespace")
+ lexers.WHITESPACE = name .. "_whitespace"
+end
+
+local function pop_whitespace()
+ lexers.WHITESPACE = table.remove(whitespaces) or "whitespace"
+end
+
+local function check_whitespace(lexer,name)
+ if lexer then
+ lexer.whitespace = (name or lexer.name or lexer._NAME) .. "_whitespace"
+ end
+end
+
+function context.new(name,filename)
+ local lexer = {
+ _TYPE = "context",
+ --
+ _NAME = name, -- used for token building
+ _FILENAME = filename, -- for diagnostic purposed
+ --
+ name = name,
+ filename = filename,
+ }
+ if trace then
+ report("initializing lexer tagged '%s' from file '%s'",name,filename or name)
+ end
+ check_whitespace(lexer)
+ check_styles(lexer)
+ check_properties(lexer)
+ lexer._tokenstyles = context.styleset
+ return lexer
+end
+
+local function nolexer(name)
+ local lexer = {
+ _TYPE = "unset",
+ _NAME = name,
+ -- _rules = { },
+ }
+ check_styles(lexer)
+ check_whitespace(lexer)
+ check_properties(lexer)
+ return lexer
+end
+
+local function load_lexer(name,namespace)
+ if trace then
+ report("loading lexer file '%s'",name)
+ end
+ push_whitespace(namespace or name) -- for traditional lexers .. no alt_name yet
+ local lexer, fullname = context.loadluafile(name)
+ pop_whitespace()
+ if not lexer then
+ report("invalid lexer file '%s'",name)
+ elseif trace then
+ report("lexer file '%s' has been loaded",fullname)
+ end
+ if type(lexer) ~= "table" then
+ if trace then
+ report("lexer file '%s' gets a dummy lexer",name)
+ end
+ return nolexer(name)
+ end
+ if lexer._TYPE ~= "context" then
+ lexer._TYPE = "native"
+ check_styles(lexer)
+ check_whitespace(lexer,namespace or name)
+ check_properties(lexer)
+ end
+ if not lexer._NAME then
+ lexer._NAME = name -- so: filename
+ end
+ if name ~= namespace then
+ lexer._NAME = namespace
+ end
+ return lexer
+end
+
+-- tracing ...
+
+local function inspect_lexer(lexer,level)
+ -- If we had the regular libs available I could use the usual
+ -- helpers.
+ local parent = lexer._lexer
+ lexer._lexer = nil -- prevent endless recursion
+ local name = lexer._NAME
+ local function showstyles_1(tag,styles)
+ local numbers = { }
+ for k, v in next, styles do
+ numbers[v] = k
+ end
+ -- sort by number and make number hash too
+ local keys = sortedkeys(numbers)
+ for i=1,#keys do
+ local k = keys[i]
+ local v = numbers[k]
+ report("[%s %s] %s %s = %s",level,name,tag,k,v)
+ end
+ end
+ local function showstyles_2(tag,styles)
+ local keys = sortedkeys(styles)
+ for i=1,#keys do
+ local k = keys[i]
+ local v = styles[k]
+ report("[%s %s] %s %s = %s",level,name,tag,k,v)
+ end
+ end
+ local keys = sortedkeys(lexer)
+ for i=1,#keys do
+ local k = keys[i]
+ local v = lexer[k]
+ report("[%s %s] root key : %s = %s",level,name,k,tostring(v))
+ end
+ showstyles_1("token style",lexer._TOKENSTYLES)
+ showstyles_2("extra style",lexer._EXTRASTYLES)
+ local children = lexer._CHILDREN
+ if children then
+ for i=1,#children do
+ inspect_lexer(children[i],level+1)
+ end
+ end
+ lexer._lexer = parent
+end
+
+function context.inspect(lexer)
+ inspect_lexer(lexer,0)
+end
+
+-- An optional second argument has been introduced so that one can embed a lexer
+-- more than once ... maybe something to look into (as not it's done by remembering
+-- the start sequence ... quite okay but maybe suboptimal ... anyway, never change
+-- a working solution).
+
+-- namespace can be automatic: if parent then use name of parent (chain)
+
+-- The original lexer framework had a rather messy user uinterface (e.g. moving
+-- stuff from _rules to _RULES at some point but I could live with that. Now it uses
+-- add_ helpers. But the subsystem is still not clean and pretty. Now, I can move to
+-- the add_ but there is no gain in it so we support a mix which gives somewhat ugly
+-- code. In fact, there should be proper subtables for this. I might actually do
+-- this because we now always overload the normal lexer (parallel usage seems no
+-- longer possible). For SciTE we can actually do a conceptual upgrade (more the
+-- context way) because there is no further development there. That way we could
+-- make even more advanced lexers.
+
+local savedrequire = require
+
+local escapes = {
+ ["%"] = "%%",
+ ["."] = "%.",
+ ["+"] = "%+", ["-"] = "%-", ["*"] = "%*",
+ ["["] = "%[", ["]"] = "%]",
+ ["("] = "%(", [")"] = "%)",
+ -- ["{"] = "%{", ["}"] = "%}"
+ -- ["^"] = "%^", ["$"] = "%$",
+}
+
+function context.loadlexer(filename,namespace)
+
+ if textadept then
+ require = function(name)
+ return savedrequire(name == "lexer" and "scite-context-lexer" or name)
+ end
+ end
+
+ nesting = nesting + 1
+ if not namespace then
+ namespace = filename
+ end
+ local lexer = usedlexers[namespace] -- we load by filename but the internal name can be short
+ if lexer then
+ if trace then
+ report("reusing lexer '%s'",namespace)
+ end
+ nesting = nesting - 1
+ return lexer
+ elseif trace then
+ report("loading lexer '%s'",namespace)
+ end
+ --
+ if initialize then
+ initialize()
+ end
+ --
+ parent_lexer = nil
+ --
+ lexer = load_lexer(filename,namespace) or nolexer(filename,namespace)
+ usedlexers[filename] = lexer
+ --
+ if not lexer._rules and not lexer._lexer and not lexer_grammar then -- hmm should be lexer._grammar
+ lexer._lexer = parent_lexer
+ end
+ --
+ if lexer._lexer then
+ local _l = lexer._lexer
+ local _r = lexer._rules
+ local _s = lexer._tokenstyles
+ if not _l._tokenstyles then
+ _l._tokenstyles = { }
+ end
+ if _r then
+ local rules = _l._rules
+ local name = lexer.name
+ for i=1,#_r do
+ local rule = _r[i]
+ rules[#rules + 1] = {
+ name .. "_" .. rule[1],
+ rule[2],
+ }
+ end
+ end
+ if _s then
+ local tokenstyles = _l._tokenstyles
+ for token, style in next, _s do
+ tokenstyles[token] = style
+ end
+ end
+ lexer = _l
+ end
+ --
+ local _r = lexer._rules
+ local _g = lexer._grammar
+ -- if _r or _g then
+ if _r then
+ local _s = lexer._tokenstyles
+ if _s then
+ for token, style in next, _s do
+ add_style(lexer, token, style)
+ end
+ end
+ if _r then
+ for i=1,#_r do
+ local rule = _r[i]
+ add_rule(lexer, rule[1], rule[2])
+ end
+ end
+ build_grammar(lexer)
+ else
+ -- other lexers
+ build_grammar(lexer)
+ end
+ --
+ add_style(lexer, lexer.whitespace, lexers.STYLE_WHITESPACE)
+ --
+ local foldsymbols = lexer._foldsymbols
+ if foldsymbols then
+ local patterns = foldsymbols._patterns
+ if patterns then
+ for i = 1, #patterns do
+ patterns[i] = "()(" .. gsub(patterns[i],".",escapes) .. ")"
+ end
+ end
+ end
+ --
+ lexer.lex = lexers.lex
+ lexer.fold = lexers.fold
+ --
+ nesting = nesting - 1
+ --
+ if inspect then
+ context.inspect(lexer)
+ end
+ --
+ if textadept then
+ require = savedrequire
+ end
+ --
+ return lexer
+end
+
+-- I probably need to check this occasionally with the original as I've messed around a bit
+-- in the past to get nesting working well as one can hit the max number of styles, get
+-- clashes due to fuzzy inheritance etc. so there is some interplay with the other patched
+-- code.
+
+function context.embed_lexer(parent, child, start_rule, end_rule) -- mostly the same as the original
+ local embeddedrules = child._EMBEDDEDRULES
+ if not embeddedrules then
+ embeddedrules = { }
+ child._EMBEDDEDRULES = embeddedrules
+ end
+ if not child._RULES then
+ local rules = child._rules
+ if not rules then
+ report("child lexer '%s' has no rules",child._NAME or "unknown")
+ rules = { }
+ child._rules = rules
+ end
+ for i=1,#rules do
+ local rule = rules[i]
+ add_rule(child, rule[1], rule[2])
+ end
+ end
+ embeddedrules[parent._NAME] = {
+ ["start_rule"] = start_rule,
+ ["token_rule"] = join_tokens(child),
+ ["end_rule"] = end_rule
+ }
+ local children = parent._CHILDREN
+ if not children then
+ children = { }
+ parent._CHILDREN = children
+ end
+ children[#children + 1] = child
+ local tokenstyles = parent._tokenstyles
+ if not tokenstyles then
+ tokenstyles = { }
+ parent._tokenstyles = tokenstyles
+ end
+ local childname = child._NAME
+ local whitespace = childname .. "_whitespace"
+ tokenstyles[whitespace] = lexers.STYLE_WHITESPACE -- all these STYLE_THINGS will go .. just a proper hash
+ if trace then
+ report("using whitespace '%s' as trigger for '%s' with property '%s'",whitespace,childname,lexers.STYLE_WHITESPACE)
+ end
+ local childstyles = child._tokenstyles
+ if childstyles then
+ for token, style in next, childstyles do
+ tokenstyles[token] = style
+ end
+ end
+ -- new, a bit redone, untested, no clue yet what it is for
+ local parentsymbols = parent._foldsymbols
+ local childsymbols = child ._foldsymbols
+ if not parentsymbols then
+ parentsymbols = { }
+ parent._foldsymbols = parentsymbols
+ end
+ if childsymbols then
+ for token, symbols in next, childsymbols do
+ local tokensymbols = parentsymbols[token]
+ if not tokensymbols then
+ tokensymbols = { }
+ parentsymbols[token] = tokensymbols
+ end
+ for k, v in next, symbols do
+ if type(k) == 'number' then
+ tokensymbols[#tokensymbols + 1] = v
+ elseif not tokensymbols[k] then
+ tokensymbols[k] = v
+ end
+ end
+ end
+ end
+ --
+ child._lexer = parent
+ parent_lexer = parent
+end
+
+-- we now move the adapted code to the lexers namespace
+
+lexers.new = context.new
+lexers.load = context.loadlexer
+------.loadlexer = context.loadlexer
+lexers.loadluafile = context.loadluafile
+lexers.embed_lexer = context.embed_lexer
+lexers.fold = context.fold
+lexers.lex = context.lex
+lexers.token = context.token
+lexers.word_match = context.word_match
+lexers.exact_match = context.exact_match
+lexers.just_match = context.just_match
+lexers.inspect = context.inspect
+lexers.report = context.report
+lexers.inform = context.inform
+
+-- helper .. alas ... in scite the lexer's lua instance is rather crippled .. not
+-- even math is part of it
+
+do
+
+ local floor = math and math.floor
+ local char = string.char
+ local format = format
+ local tonumber = tonumber
+
+ local function utfchar(n)
+ if n < 0x80 then
+ return char(n)
+ elseif n < 0x800 then
+ return char(
+ 0xC0 + floor(n/0x40),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x10000 then
+ return char(
+ 0xE0 + floor(n/0x1000),
+ 0x80 + (floor(n/0x40) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ elseif n < 0x40000 then
+ return char(
+ 0xF0 + floor(n/0x40000),
+ 0x80 + floor(n/0x1000),
+ 0x80 + (floor(n/0x40) % 0x40),
+ 0x80 + (n % 0x40)
+ )
+ else
+ -- return char(
+ -- 0xF1 + floor(n/0x1000000),
+ -- 0x80 + floor(n/0x40000),
+ -- 0x80 + floor(n/0x1000),
+ -- 0x80 + (floor(n/0x40) % 0x40),
+ -- 0x80 + (n % 0x40)
+ -- )
+ return "?"
+ end
+ end
+
+ context.utfchar = utfchar
+
+ -- -- the next one is good enough for use here but not perfect (see context for a
+ -- -- better one)
+ --
+ -- local function make(t)
+ -- local p
+ -- for k, v in next, t do
+ -- if not p then
+ -- if next(v) then
+ -- p = P(k) * make(v)
+ -- else
+ -- p = P(k)
+ -- end
+ -- else
+ -- if next(v) then
+ -- p = p + P(k) * make(v)
+ -- else
+ -- p = p + P(k)
+ -- end
+ -- end
+ -- end
+ -- return p
+ -- end
+ --
+ -- function lpeg.utfchartabletopattern(list)
+ -- local tree = { }
+ -- for i=1,#list do
+ -- local t = tree
+ -- for c in gmatch(list[i],".") do
+ -- if not t[c] then
+ -- t[c] = { }
+ -- end
+ -- t = t[c]
+ -- end
+ -- end
+ -- return make(tree)
+ -- end
+
+ local utf8next = R("\128\191")
+ local utf8one = R("\000\127")
+ local utf8two = R("\194\223") * utf8next
+ local utf8three = R("\224\239") * utf8next * utf8next
+ local utf8four = R("\240\244") * utf8next * utf8next * utf8next
+
+ helpers.utfcharpattern = P(1) * utf8next^0 -- unchecked but fast
+ helpers.utfbytepattern = utf8one / byte
+ + utf8two / function(s) local c1, c2 = byte(s,1,2) return c1 * 64 + c2 - 12416 end
+ + utf8three / function(s) local c1, c2, c3 = byte(s,1,3) return (c1 * 64 + c2) * 64 + c3 - 925824 end
+ + utf8four / function(s) local c1, c2, c3, c4 = byte(s,1,4) return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168 end
+
+ local p_false = P(false)
+ local p_true = P(true)
+
+ local function make(t)
+ local function making(t)
+ 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
+ -- can't happen
+ else
+ p = p + P(k) * making(v)
+ end
+ end
+ end
+ if t[""] then
+ p = p + p_true
+ end
+ return p
+ end
+ 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
+ -- can't happen
+ else
+ p = p + P(k) * making(v)
+ end
+ end
+ end
+ return p
+ end
+
+ local function collapse(t,x)
+ if type(t) ~= "table" then
+ return t, x
+ else
+ local n = next(t)
+ if n == nil then
+ return t, x
+ elseif next(t,n) == nil then
+ -- one entry
+ local k = n
+ local v = t[k]
+ if type(v) == "table" then
+ return collapse(v,x..k)
+ else
+ return v, x .. k
+ end
+ else
+ local tt = { }
+ for k, v in next, t do
+ local vv, kk = collapse(v,k)
+ tt[kk] = vv
+ end
+ return tt, x
+ end
+ end
+ end
+
+ function helpers.utfchartabletopattern(list)
+ 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
+ -- okay
+ 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
+ -- okay
+ else
+ t[""] = true
+ end
+ end
+ end
+ collapse(tree,"")
+ -- inspect(tree)
+ return make(tree)
+ end
+
+ patterns.invisibles = helpers.utfchartabletopattern {
+ utfchar(0x00A0), -- nbsp
+ utfchar(0x2000), -- enquad
+ utfchar(0x2001), -- emquad
+ utfchar(0x2002), -- enspace
+ utfchar(0x2003), -- emspace
+ utfchar(0x2004), -- threeperemspace
+ utfchar(0x2005), -- fourperemspace
+ utfchar(0x2006), -- sixperemspace
+ utfchar(0x2007), -- figurespace
+ utfchar(0x2008), -- punctuationspace
+ utfchar(0x2009), -- breakablethinspace
+ utfchar(0x200A), -- hairspace
+ utfchar(0x200B), -- zerowidthspace
+ utfchar(0x202F), -- narrownobreakspace
+ utfchar(0x205F), -- math thinspace
+ }
+
+ -- now we can make:
+
+ patterns.iwordtoken = patterns.wordtoken - patterns.invisibles
+ patterns.iwordpattern = patterns.iwordtoken^3
+
+end
+
+-- The following helpers are not used, partially replaced by other mechanisms and
+-- when needed I'll first optimize them. I only made them somewhat more readable.
+
+function lexers.delimited_range(chars, single_line, no_escape, balanced) -- unchanged
+ local s = sub(chars,1,1)
+ local e = #chars == 2 and sub(chars,2,2) or s
+ local range
+ local b = balanced and s or ""
+ local n = single_line and "\n" or ""
+ if no_escape then
+ local invalid = S(e .. n .. b)
+ range = patterns.any - invalid
+ else
+ local invalid = S(e .. n .. b) + patterns.backslash
+ range = patterns.any - invalid + patterns.backslash * patterns.any
+ end
+ if balanced and s ~= e then
+ return P {
+ s * (range + V(1))^0 * e
+ }
+ else
+ return s * range^0 * P(e)^-1
+ end
+end
+
+function lexers.starts_line(patt) -- unchanged
+ return P ( function(input, index)
+ if index == 1 then
+ return index
+ end
+ local char = sub(input,index - 1,index - 1)
+ if char == "\n" or char == "\r" or char == "\f" then
+ return index
+ end
+ end ) * patt
+end
+
+function lexers.last_char_includes(s) -- unchanged
+ s = "[" .. gsub(s,"[-%%%[]", "%%%1") .. "]"
+ return P ( function(input, index)
+ if index == 1 then
+ return index
+ end
+ local i = index
+ while match(sub(input,i - 1,i - 1),"[ \t\r\n\f]") do
+ i = i - 1
+ end
+ if match(sub(input,i - 1,i - 1),s) then
+ return index
+ end
+ end)
+end
+
+function lexers.nested_pair(start_chars, end_chars) -- unchanged
+ local s = start_chars
+ local e = P(end_chars)^-1
+ return P {
+ s * (patterns.any - s - end_chars + V(1))^0 * e
+ }
+end
+
+local function prev_line_is_comment(prefix, text, pos, line, s) -- unchanged
+ local start = find(line,"%S")
+ if start < s and not find(line,prefix,start,true) then
+ return false
+ end
+ local p = pos - 1
+ if sub(text,p,p) == "\n" then
+ p = p - 1
+ if sub(text,p,p) == "\r" then
+ p = p - 1
+ end
+ if sub(text,p,p) ~= "\n" then
+ while p > 1 and sub(text,p - 1,p - 1) ~= "\n"
+ do p = p - 1
+ end
+ while find(sub(text,p,p),"^[\t ]$") do
+ p = p + 1
+ end
+ return sub(text,p,p + #prefix - 1) == prefix
+ end
+ end
+ return false
+end
+
+local function next_line_is_comment(prefix, text, pos, line, s)
+ local p = find(text,"\n",pos + s)
+ if p then
+ p = p + 1
+ while find(sub(text,p,p),"^[\t ]$") do
+ p = p + 1
+ end
+ return sub(text,p,p + #prefix - 1) == prefix
+ end
+ return false
+end
+
+function lexers.fold_line_comments(prefix)
+ local property_int = lexers.property_int
+ return function(text, pos, line, s)
+ if property_int["fold.line.comments"] == 0 then
+ return 0
+ end
+ if s > 1 and match(line,"^%s*()") < s then
+ return 0
+ end
+ local prev_line_comment = prev_line_is_comment(prefix, text, pos, line, s)
+ local next_line_comment = next_line_is_comment(prefix, text, pos, line, s)
+ if not prev_line_comment and next_line_comment then
+ return 1
+ end
+ if prev_line_comment and not next_line_comment then
+ return -1
+ end
+ return 0
+ end
+end
+
+-- There are some fundamental changes in textadept version 10 and I don't want to
+-- adapt again so we go the reverse route: map new to old. This is needed because
+-- we need to load other lexers which is teh result of not being able to load the
+-- lexer framework in parallel. Something happened in 10 that makes the main lexer
+-- always enforced so now we need to really replace that one (and even then it loads
+-- twice (i can probably sort that out). Maybe there's now some hard coded magic
+-- in the binary.
+
+if textadept then
+
+ -- Folds are still somewhat weak because of the end condition not being
+ -- bound to a start .. probably to complex and it seems to work anyhow. As
+ -- we have extended thinsg we just remap.
+
+ local function add_fold_point(lexer,token_name,start_symbol,end_symbol)
+ if type(start_symbol) == "string" then
+ local foldsymbols = lexer._foldsymbols
+ if not foldsymbols then
+ foldsymbols = { }
+ lexer._foldsymbols = foldsymbols
+ end
+ local patterns = foldsymbols._patterns
+ if not patterns then
+ patterns = { }
+ usedpatt = { } -- > 10 uses a mixed index/hash (we don't use patterns)
+ foldsymbols._patterns = patterns
+ foldsymbols._usedpatt = usedpatt
+ end
+ local foldsymbol = foldsymbols[token_name]
+ if not foldsymbol then
+ foldsymbol = { }
+ foldsymbols[token_name] = foldsymbol
+ end
+ if not usedpatt[start_symbol] then
+ patterns[#patterns+1] = start_symbol
+ usedpatt[start_symbol] = true
+ end
+ if type(end_symbol) == "string" then
+ foldsymbol[start_symbol] = 1
+ foldsymbol[end_symbol] = -1
+ if not usedpatt[end_symbol] then
+ patterns[#patterns+1] = end_symbol
+ usedpatt[end_symbol] = true
+ end
+ else
+ foldsymbol[start_symbol] = end_symbol
+ end
+ end
+ end
+
+ local function add_style(lexer,name,style)
+ local tokenstyles = lexer._tokenstyles
+ if not tokenstyles then
+ tokenstyles = { }
+ lexer._tokenstyles = tokenstyles
+ end
+ tokenstyles[name] = style
+ end
+
+ local function add_rule(lexer,id,rule)
+ local rules = lexer._rules
+ if not rules then
+ rules = { }
+ lexer._rules = rules
+ end
+ rules[#rules+1] = { id, rule }
+ end
+
+ local function modify_rule(lexer,id,rule) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ local RULES = lexer._RULES
+ if RULES then
+ RULES[id] = rule
+ end
+ end
+
+ local function get_rule(lexer,id) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ local RULES = lexer._RULES
+ if RULES then
+ return RULES[id]
+ end
+ end
+
+ local new = context.new
+ local lmt = {
+ __index = {
+
+ add_rule = add_rule,
+ modify_rule = modify_rule,
+ get_rule = get_rule,
+ add_style = add_style,
+ add_fold_point = add_fold_point,
+
+ join_tokens = join_tokens,
+ build_grammar = build_grammar,
+
+ embed = lexers.embed,
+ lex = lexers.lex,
+ fold = lexers.fold
+
+ }
+ }
+
+ function lexers.new(name,options)
+ local lexer = new(name)
+ if options then
+ lexer._LEXBYLINE = options['lex_by_line']
+ lexer._FOLDBYINDENTATION = options['fold_by_indentation']
+ lexer._CASEINSENSITIVEFOLDPOINTS = options['case_insensitive_fold_points']
+ lexer._lexer = options['inherit']
+ end
+ setmetatable(lexer,lmt)
+ return lexer
+ end
+
+end
+
+-- done
+
+return lexers
diff --git a/context/data/textadept/context/lexers/scite-context-lexer-bnf.lua b/context/data/textadept/context/lexers/scite-context-lexer-bnf.lua
new file mode 100644
index 000000000..ce57642ba
--- /dev/null
+++ b/context/data/textadept/context/lexers/scite-context-lexer-bnf.lua
@@ -0,0 +1,99 @@
+local info = {
+ version = 1.001,
+ comment = "scintilla lpeg lexer for bnf",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+-- will replace the one in metafun
+
+local global, lpeg = _G, lpeg
+local P, R, S = lpeg.P, lpeg.R, lpeg.S
+
+local lexer = require("scite-context-lexer")
+local context = lexer.context
+local patterns = context.patterns
+
+local token = lexer.token
+local exact_match = lexer.exact_match
+
+local bnflexer = lexer.new("bnf","scite-context-lexer-bnf")
+local whitespace = bnflexer.whitespace
+
+-- from wikipedia:
+--
+-- <syntax> ::= <rule> | <rule> <syntax>
+-- <rule> ::= <opt-whitespace> "<" <rule-name> ">" <opt-whitespace> "::=" <opt-whitespace> <expression> <line-end>
+-- <opt-whitespace> ::= " " <opt-whitespace> | ""
+-- <expression> ::= <list> | <list> <opt-whitespace> "|" <opt-whitespace> <expression>
+-- <line-end> ::= <opt-whitespace> <EOL> | <line-end> <line-end>
+-- <list> ::= <term> | <term> <opt-whitespace> <list>
+-- <term> ::= <literal> | "<" <rule-name> ">"
+-- <literal> ::= '"' <text1> '"' | "'" <text2> "'"
+-- <text1> ::= "" | <character1> <text1>
+-- <text2> ::= "" | <character2> <text2>
+-- <character> ::= <letter> | <digit> | <symbol>
+-- <letter> ::= "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" | "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"
+-- <digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
+-- <symbol> ::= "|" | " " | "-" | "!" | "#" | "$" | "%" | "&" | "(" | ")" | "*" | "+" | "," | "-" | "." | "/" | ":" | ";" | ">" | "=" | "<" | "?" | "@" | "[" | "\" | "]" | "^" | "_" | "`" | "{" | "}" | "~"
+-- <character1> ::= <character> | "'"
+-- <character2> ::= <character> | '"'
+-- <rule-name> ::= <letter> | <rule-name> <rule-char>
+-- <rule-char> ::= <letter> | <digit> | "-"
+
+local anything = patterns.anything
+local separator = P("|")
+local left = P("<")
+local right = P(">")
+local space = S(" \t\n\r\f")
+local spaces = space^1
+local letter = R("AZ","az")
+local digit = R("09")
+local symbol = S([[| -!#$%&()*+,-./:;>=<?@[\]^_`{}~]])
+local text = (letter + digit + symbol^0)
+local name = letter * (letter + digit + P("-"))^0
+local becomes = P("::=")
+local extra = P("|")
+local single = P("'")
+local double = P('"')
+
+local t_spacing = token(whitespace,space^1)
+local t_term = token("command",left)
+ * token("text",name)
+ * token("command",right)
+local t_text = token("quote",single)
+ * token("text",text)
+ * token("quote",single)
+ + token("quote",double)
+ * token("text",text)
+ * token("quote",double)
+local t_becomes = token("operator",becomes)
+local t_extra = token("extra",extra)
+local t_rest = token("default",anything)
+
+bnflexer._rules = {
+ { "whitespace", t_spacing },
+ { "term", t_term },
+ { "text", t_text },
+ { "becomes", t_becomes },
+ { "extra", t_extra },
+ { "rest", t_rest },
+}
+
+bnflexer._tokenstyles = context.styleset
+
+bnflexer._foldpattern = left + right
+
+bnflexer._foldsymbols = {
+ _patterns = {
+ "<",
+ ">",
+ },
+ ["grouping"] = {
+ ["<"] = 1,
+ [">"] = -1,
+ },
+}
+
+return bnflexer
diff --git a/context/data/textadept/context/lexers/scite-context-lexer-json.lua b/context/data/textadept/context/lexers/scite-context-lexer-json.lua
new file mode 100644
index 000000000..20a2d1d12
--- /dev/null
+++ b/context/data/textadept/context/lexers/scite-context-lexer-json.lua
@@ -0,0 +1,100 @@
+local info = {
+ version = 1.002,
+ comment = "scintilla lpeg lexer for json",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+local global, string, table, lpeg = _G, string, table, lpeg
+local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V
+local type = type
+
+local lexer = require("scite-context-lexer")
+local context = lexer.context
+local patterns = context.patterns
+
+local token = lexer.token
+local exact_match = lexer.exact_match
+
+local jsonlexer = lexer.new("json","scite-context-lexer-json")
+local whitespace = jsonlexer.whitespace
+
+local anything = patterns.anything
+local comma = P(",")
+local colon = P(":")
+local escape = P("\\")
+----- single = P("'")
+local double = P('"')
+local openarray = P('[')
+local closearray = P(']')
+local openhash = P('{')
+local closehash = P('}')
+----- lineending = S("\n\r")
+local space = S(" \t\n\r\f")
+local spaces = space^1
+local operator = S(':,{}[]')
+local fence = openarray + closearray + openhash + closehash
+
+local escape_un = P("\\u") / "0x" * S("09","AF","af")
+local escape_bs = P([[\]]) * P(1)
+local content = (escape_un + escape_bs + (1-double))^0
+
+local reserved = P("true")
+ + P("false")
+ + P("null")
+
+local integer = P("-")^-1 * (patterns.hexadecimal + patterns.decimal)
+local float = patterns.float
+
+local t_number = token("number", float + integer)
+ * (token("error",R("AZ","az","__")^1))^0
+
+local t_spacing = token(whitespace, space^1)
+local t_optionalws = token("default", space^1)^0
+
+local t_operator = token("special", operator)
+
+local t_string = token("operator",double)
+ * token("string",content)
+ * token("operator",double)
+
+local t_key = token("operator",double)
+ * token("text",content)
+ * token("operator",double)
+ * t_optionalws
+ * token("operator",colon)
+
+local t_fences = token("operator",fence) -- grouping
+
+local t_reserved = token("primitive",reserved)
+
+local t_rest = token("default",anything)
+
+jsonlexer._rules = {
+ { "whitespace", t_spacing },
+ { "reserved", t_reserved },
+ { "key", t_key },
+ { "number", t_number },
+ { "string", t_string },
+ { "fences", t_fences },
+ { "operator", t_operator },
+ { "rest", t_rest },
+}
+
+jsonlexer._tokenstyles = context.styleset
+
+jsonlexer._foldpattern = fence
+
+jsonlexer._foldsymbols = {
+ _patterns = {
+ "{", "}",
+ "[", "]",
+ },
+ ["grouping"] = {
+ ["{"] = 1, ["}"] = -1,
+ ["["] = 1, ["]"] = -1,
+ },
+}
+
+return jsonlexer
diff --git a/context/data/textadept/context/lexers/scite-context-lexer-mps.lua b/context/data/textadept/context/lexers/scite-context-lexer-mps.lua
index 1c87ea6d0..4bbfae03c 100644
--- a/context/data/textadept/context/lexers/scite-context-lexer-mps.lua
+++ b/context/data/textadept/context/lexers/scite-context-lexer-mps.lua
@@ -91,9 +91,12 @@ local plain = token("plain", exact_match(metapostcommands))
local quoted = token("quote", dquote)
* token("string", P(1-dquote)^0)
* token("quote", dquote)
-local texstuff = token("quote", P("btex ") + P("verbatimtex "))
- * token("string", P(1-P(" etex"))^0)
- * token("quote", P(" etex"))
+local separator = P(" ") + S("\n\r")^1
+local btex = (P("btex") + P("verbatimtex")) * separator
+local etex = separator * P("etex")
+local texstuff = token("quote", btex)
+ * token("string", (1-etex)^0)
+ * token("quote", etex)
local primitive = token("primitive", exact_match(metapostprimitives))
local identifier = token("default", cstoken^1)
local number = token("number", number)
@@ -130,10 +133,10 @@ metafunlexer._rules = {
{ "comment", comment },
{ "internal", internal },
{ "shortcut", shortcut },
+ { "luacall", luacall },
{ "helper", helper },
{ "plain", plain },
{ "primitive", primitive },
- { "luacall", luacall },
{ "texstuff", texstuff },
{ "suffix", suffix },
{ "identifier", identifier },
diff --git a/context/data/textadept/context/lexers/scite-context-lexer-pdf.lua b/context/data/textadept/context/lexers/scite-context-lexer-pdf.lua
index 0fd238d63..1956071b7 100644
--- a/context/data/textadept/context/lexers/scite-context-lexer-pdf.lua
+++ b/context/data/textadept/context/lexers/scite-context-lexer-pdf.lua
@@ -90,7 +90,7 @@ local t_number = token("number", real)
-- t_reference = token("number", cardinal)
-- * t_spacing
-- * token("number", cardinal)
-local t_reserved = token("number", P("true") + P("false") + P("NULL"))
+local t_reserved = token("number", P("true") + P("false") + P("null"))
-- t_reference = token("warning", cardinal * spacing * cardinal * spacing)
-- * token("keyword", p_reference)
local t_reference = token("warning", cardinal)
@@ -121,17 +121,31 @@ local t_stream = token("keyword", p_stream)
* token("text", (1 - p_endstream)^1)
* token("keyword", p_endstream)
+local t_other = t_constant + t_reference + t_string + t_unicode + t_number + t_reserved + t_whatsit
+
local t_dictionary = { "dictionary",
- dictionary = t_opendictionary * (t_spaces * t_keyword * t_spaces * V("whatever"))^0 * t_spaces * t_closedictionary,
- array = t_openarray * (t_spaces * V("whatever"))^0 * t_spaces * t_closearray,
- whatever = V("dictionary") + V("array") + t_constant + t_reference + t_string + t_unicode + t_number + t_reserved + t_whatsit,
+ dictionary = t_opendictionary
+ * (t_spaces * t_keyword * t_spaces * V("whatever"))^0
+ * t_spaces
+ * t_closedictionary,
+ array = t_openarray
+ * (t_spaces * V("whatever"))^0
+ * t_spaces
+ * t_closearray,
+ whatever = V("dictionary")
+ + V("array")
+ + t_other,
}
local t_object = { "object", -- weird that we need to catch the end here (probably otherwise an invalid lpeg)
dictionary = t_dictionary.dictionary,
array = t_dictionary.array,
whatever = t_dictionary.whatever,
- object = t_openobject * t_spaces * (V("dictionary")^-1 * t_spaces * t_stream^-1 + V("array") + V("number") + t_spaces) * t_spaces * t_closeobject,
+ object = t_openobject
+ * t_spaces
+ * (V("dictionary") * t_spaces * t_stream^-1 + V("array") + t_other)
+ * t_spaces
+ * t_closeobject,
number = t_number,
}
diff --git a/context/data/textadept/context/lexers/scite-context-lexer-tex.lua b/context/data/textadept/context/lexers/scite-context-lexer-tex.lua
index 1f1246fc0..d4e28f99b 100644
--- a/context/data/textadept/context/lexers/scite-context-lexer-tex.lua
+++ b/context/data/textadept/context/lexers/scite-context-lexer-tex.lua
@@ -57,24 +57,36 @@ do -- todo: only once, store in global
local definitions = context.loaddefinitions("scite-context-data-interfaces")
if definitions then
- local list = { }
+ local used = { }
for interface, list in next, definitions do
- list[#list+1] = interface
- local c = { }
- for i=1,#list do
- c[list[i]] = true
- end
- if interface ~= "en" then
+ if interface ~= "common" then
+ used[#used+1] = interface
+ local c = { }
+ -- these are shared
+ local list = definitions.common
+ if list then
+ for i=1,#list do
+ c[list[i]] = true
+ end
+ end
+ -- normally this one is empty
list = definitions.en
if list then
for i=1,#list do
c[list[i]] = true
end
end
+ -- these are interface specific
+ if interface ~= "en" then
+ for i=1,#list do
+ c[list[i]] = true
+ end
+ end
+ commands[interface] = c
end
- commands[interface] = c
end
- inform("context user interfaces '%s' supported",table.concat(list," "))
+ table.sort(used)
+ inform("context user interfaces '%s' supported",table.concat(used," "))
end
local definitions = context.loaddefinitions("scite-context-data-context")
@@ -399,13 +411,13 @@ contextlexer._reset_parser = function()
lualevel = 0
end
-local luaenvironment = P("lua") * (P("setups") + P("code") + P(true))
+local luaenvironment = P("lua") * (P("setups") + P("code") + P("parameterset") + P(true))
+ P("ctxfunction") * (P("definition") + P(true))
local inlinelua = P("\\") * (
P("ctx") * (P("lua") + P("command") + P("late") * (P("lua") + P("command")) + P("function"))
+ P("cld") * (P("command") + P("context"))
- + P("luaexpr")
+ + P("lua") * (P("expr") + P("script") + P("thread"))
+ (P("direct") + P("late")) * P("lua")
)
diff --git a/context/data/textadept/context/lexers/scite-context-lexer.lua b/context/data/textadept/context/lexers/scite-context-lexer.lua
index 37f236a89..234b03c05 100644
--- a/context/data/textadept/context/lexers/scite-context-lexer.lua
+++ b/context/data/textadept/context/lexers/scite-context-lexer.lua
@@ -8,6 +8,10 @@ local info = {
}
+-- We need a copy of this file to lexer.lua in the same path. This was not needed
+-- before version 10 but I can't figure out what else to do. It looks like there
+-- is some loading of lexer.lua but I can't see where.
+
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
local log = false
@@ -232,6 +236,17 @@ local inspect = false -- can save some 15% (maybe easier on scintilla)
-- is still not perfect (sometimes hangs) but it was enough reason to spend time on
-- making our lexer work with TextAdept and create a setup.
--
+-- Some bad news. The interface changed (again) in textadept 10, some for the better
+-- (but a bit different from what happens here) and some for the worse, especially
+-- moving some code to the init file so we now need some bad hacks. I decided to
+-- stay with the old method of defining lexers and because the lexer cannot be run
+-- in parallel any more (some change in the binary?) I will probably also cleanup
+-- code below as we no longer need to be compatible. Unfortunately textadept is too
+-- much a moving target to simply kick in some (tex related) production flow (apart
+-- from the fact that it doesn't yet have the scite like realtime console). I'll
+-- keep an eye on it. Because we don't need many added features I might as well decide
+-- to make a lean and mean instance (after all the license permits forking).
+
-- TRACING
--
-- The advantage is that we now can check more easily with regular Lua(TeX). We can
@@ -243,8 +258,8 @@ local inspect = false -- can save some 15% (maybe easier on scintilla)
--
-- TODO
--
--- It would be nice if we could lods some ConTeXt Lua modules (the basic set) and
--- then use resolvers and such.
+-- It would be nice if we could load some ConTeXt Lua modules (the basic set) and
+-- then use resolvers and such. But it might not work well with scite.
--
-- The current lexer basics are still a mix between old and new. Maybe I should redo
-- some more. This is probably easier in TextAdept than in SciTE.
@@ -300,7 +315,17 @@ local lpegmatch = lpeg.match
local usage = (textadept and "textadept") or (resolvers and "context") or "scite"
local nesting = 0
-local print = textadept and ui and ui.print or print
+local output = nil
+
+----- print = textadept and ui and ui.print or print -- crashes when ui is not yet defined
+
+local function print(...)
+ if not output then
+ output = io.open("lexer.log","w")
+ end
+ output:write(...,"\n")
+ output:flush()
+end
local function report(fmt,str,...)
if log then
@@ -319,6 +344,36 @@ end
inform("loading context lexer module (global table: %s)",tostring(global))
+do
+
+ local floor = math and math.floor
+ local format = format
+ local tonumber = tonumber
+
+ if not floor then
+
+ if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then
+ floor = function(n)
+ return tonumber(format("%d",n))
+ end
+ else
+ -- 5.3 has a mixed number system and format %d doesn't work with
+ -- floats any longer ... no fun
+ floor = function(n)
+ return (n - n % 1)
+ end
+ end
+
+ math = math or { }
+
+ math.floor = floor
+
+ end
+
+end
+
+local floor = math.floor
+
if not package.searchpath then
-- Unfortunately the io library is only available when we end up
@@ -412,7 +467,9 @@ local default = {
local predefined = {
"default", "linenumber", "bracelight", "bracebad", "controlchar",
- "indentguide", "calltip"
+ "indentguide", "calltip",
+ -- seems new
+ "folddisplaytext"
}
-- Bah ... ugly ... nicer would be a proper hash .. we now have properties
@@ -510,9 +567,16 @@ lexers.property_expanded = setmetatable({ }, {
check_main_properties()
end
--
- return gsub(property[k],"[$%%]%b()", function(k)
- return t[sub(k,3,-2)]
- end)
+-- return gsub(property[k],"[$%%]%b()", function(k)
+-- return t[sub(k,3,-2)]
+-- end)
+ local v = property[k]
+ if v then
+ v = gsub(v,"[$%%]%b()", function(k)
+ return t[sub(k,3,-2)]
+ end)
+ end
+ return v
end,
__newindex = function(t,k,v)
report("properties are read-only, '%s' is not changed",k)
@@ -835,32 +899,42 @@ function context.loaddefinitions(name)
return type(data) == "table" and data
end
+-- A bit of regression in textadept > 10 so updated ... done a bit different.
+-- We don't use this in the context lexers anyway.
+
function context.word_match(words,word_chars,case_insensitive)
- local chars = "%w_" -- maybe just "" when word_chars
- if word_chars then
- chars = "^([" .. chars .. gsub(word_chars,"([%^%]%-])", "%%%1") .."]+)"
- else
- chars = "^([" .. chars .."]+)"
+ -- used to be proper tables ...
+ if type(words) == "string" then
+ local clean = gsub(words,"%-%-[^\n]+","")
+ local split = { }
+ for s in gmatch(clean,"%S+") do
+ split[#split+1] = s
+ end
+ words = split
+ end
+ local list = { }
+ for i=1,#words do
+ list[words[i]] = true
end
if case_insensitive then
- local word_list = { }
- for i=1,#words do
- word_list[lower(words[i])] = true
- end
- return P(function(input, index)
- local s, e, word = find(input,chars,index)
- return word and word_list[lower(word)] and e + 1 or nil
- end)
- else
- local word_list = { }
for i=1,#words do
- word_list[words[i]] = true
+ list[lower(words[i])] = true
end
- return P(function(input, index)
- local s, e, word = find(input,chars,index)
- return word and word_list[word] and e + 1 or nil
- end)
end
+ local chars = S(word_chars or "")
+ for i=1,#words do
+ chars = chars + S(words[i])
+ end
+ local match = case_insensitive and
+ function(input,index,word)
+ -- We can speed mixed case if needed.
+ return (list[word] or list[lower(word)]) and index or nil
+ end
+ or
+ function(input,index,word)
+ return list[word] and index or nil
+ end
+ return Cmt(chars^1,match)
end
-- Patterns are grouped in a separate namespace but the regular lexers expect
@@ -888,6 +962,11 @@ do
local hexadecimal = P("0") * S("xX")
* (hexdigit^0 * period * hexdigit^1 + hexdigit^1 * period * hexdigit^0 + hexdigit^1)
* (S("pP") * sign^-1 * hexdigit^1)^-1 -- *
+ local integer = sign^-1
+ * (hexadecimal + octal + decimal)
+ local float = sign^-1
+ * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1)
+ * S("eE") * sign^-1 * digit^1 -- *
patterns.idtoken = idtoken
patterns.digit = digit
@@ -904,15 +983,13 @@ do
patterns.decimal = decimal
patterns.octal = octal
patterns.hexadecimal = hexadecimal
- patterns.float = sign^-1
- * (digit^0 * period * digit^1 + digit^1 * period * digit^0 + digit^1)
- * S("eE") * sign^-1 * digit^1 -- *
+ patterns.float = float
patterns.cardinal = decimal
patterns.signeddecimal = sign^-1 * decimal
patterns.signedoctal = sign^-1 * octal
patterns.signedhexadecimal = sign^-1 * hexadecimal
- patterns.integer = sign^-1 * (hexadecimal + octal + decimal)
+ patterns.integer = integer
patterns.real =
sign^-1 * ( -- at most one
digit^1 * period * digit^0 -- 10.0 10.
@@ -928,6 +1005,7 @@ do
patterns.nospacing = (1-space)^1
patterns.eol = eol
patterns.newline = P("\r\n") + eol
+ patterns.backslash = backslash
local endof = S("\n\r\f")
@@ -943,7 +1021,7 @@ do
lexers.extend = extend
lexers.alpha = alpha
lexers.digit = digit
- lexers.alnum = alnum
+ lexers.alnum = alpha + digit
lexers.lower = lower
lexers.upper = upper
lexers.xdigit = hexdigit
@@ -1034,7 +1112,12 @@ end
-- },
-- }
-local lists = { }
+local lists = { }
+local disabled = false
+
+function context.disablewordcheck()
+ disabled = true
+end
function context.setwordlist(tag,limit) -- returns hash (lowercase keys and original values)
if not tag or tag == "" then
@@ -1127,6 +1210,8 @@ local p_nop = newline
local folders = { }
+-- Snippets from the > 10 code .. but we do things different so ...
+
local function fold_by_parsing(text,start_pos,start_line,start_level,lexer)
local folder = folders[lexer]
if not folder then
@@ -1136,6 +1221,12 @@ local function fold_by_parsing(text,start_pos,start_line,start_level,lexer)
local fold_symbols = lexer._foldsymbols
local fold_pattern = lexer._foldpattern -- use lpeg instead (context extension)
--
+ -- textadept >= 10
+ --
+ -- local zerosumlines = lexer.property_int["fold.on.zero.sum.lines"] > 0 -- not done
+ -- local compact = lexer.property_int['fold.compact'] > 0 -- not done
+ -- local lowercase = lexer._CASEINSENSITIVEFOLDPOINTS -- useless (utf will distort)
+ --
if fold_pattern then
-- if no functions are found then we could have a faster one
fold_pattern = Cp() * C(fold_pattern) / function(s,match)
@@ -1168,7 +1259,7 @@ local function fold_by_parsing(text,start_pos,start_line,start_level,lexer)
-- the traditional one but a bit optimized
local fold_symbols_patterns = fold_symbols._patterns
local action_y = function(pos,line)
- for j = 1, #fold_symbols_patterns do
+ for j=1, #fold_symbols_patterns do
for s, match in gmatch(line,fold_symbols_patterns[j]) do -- "()(" .. patterns[i] .. ")"
local symbols = fold_symbols[style_at[start_pos + pos + s - 1]]
local l = symbols and symbols[match]
@@ -1311,11 +1402,11 @@ function context.fold(lexer,text,start_pos,start_line,start_level) -- hm, we had
if filesize <= threshold_by_parsing then
return fold_by_parsing(text,start_pos,start_line,start_level,lexer)
end
- elseif lexer.properties("fold.by.indentation",1) > 0 then
+ elseif lexer._FOLDBYINDENTATION or lexer.properties("fold.by.indentation",1) > 0 then
if filesize <= threshold_by_indentation then
return fold_by_indentation(text,start_pos,start_line,start_level,lexer)
end
- elseif lexer.properties("fold.by.line",1) > 0 then
+ elseif lexer._FOLDBYLINE or lexer.properties("fold.by.line",1) > 0 then
if filesize <= threshold_by_line then
return fold_by_line(text,start_pos,start_line,start_level,lexer)
end
@@ -1334,6 +1425,20 @@ local function add_rule(lexer,id,rule) -- unchanged
lexer._RULEORDER[#lexer._RULEORDER + 1] = id
end
+local function modify_rule(lexer,id,rule) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ lexer._RULES[id] = rule
+end
+
+local function get_rule(lexer,id) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ return lexer._RULES[id]
+end
+
-- I finally figured out that adding more styles was an issue because of several
-- reasons:
--
@@ -1357,12 +1462,20 @@ local function add_style(lexer,token_name,style) -- changed a bit around 3.41
if trace and detail then
report("default style '%s' is ignored as extra style",token_name)
end
- return
+ if textadept then
+ -- go on, stored per buffer
+ else
+ return
+ end
elseif predefinedstyles[token_name] then
if trace and detail then
report("predefined style '%s' is ignored as extra style",token_name)
end
- return
+ if textadept then
+ -- go on, stored per buffer
+ else
+ return
+ end
else
if trace and detail then
report("adding extra style '%s' as '%s'",token_name,style)
@@ -1379,6 +1492,7 @@ local function add_style(lexer,token_name,style) -- changed a bit around 3.41
lexer._TOKENSTYLES[token_name] = num_styles
lexer._EXTRASTYLES[token_name] = style
lexer._numstyles = num_styles + 1
+ -- hm, the original (now) also copies to the parent ._lexer
end
local function check_styles(lexer)
@@ -1428,6 +1542,8 @@ local function join_tokens(lexer) -- slightly different from the original (no 'a
end
end
+-- hm, maybe instead of a grammer just a flat one
+
local function add_lexer(grammar, lexer) -- mostly the same as the original
local token_rule = join_tokens(lexer)
local lexer_name = lexer._NAME
@@ -1458,9 +1574,10 @@ local function build_grammar(lexer,initial_rule) -- same as the original
local lexer_name = lexer._NAME
local preamble = lexer._preamble
local grammar = lexer._grammar
- if grammar then
- -- experiment
- elseif children then
+ -- if grammar then
+ -- -- experiment
+ -- elseif children then
+ if children then
if not initial_rule then
initial_rule = lexer_name
end
@@ -1533,17 +1650,17 @@ local function matched(lexer,grammar,text)
else
txt = "!no text!"
end
- report("%4i : %s > %s (%s) (%s)",n/2,ti,tn,s[ti] or "!unset!",txt)
+ report("%4i : %s > %s (%s) (%s)",floor(n/2),ti,tn,s[ti] or "!unset!",txt)
p = tn
else
break
end
end
end
- report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,#t/2)
+ report("lexer results: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2))
if collapse then
t = collapsed(t)
- report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,#t/2)
+ report("lexer collapsed: %s, length: %s, ranges: %s",lexer._NAME,#text,floor(#t/2))
end
elseif collapse then
t = collapsed(t)
@@ -1553,6 +1670,9 @@ end
-- Todo: make nice generic lexer (extra argument with start/stop commands) for
-- context itself.
+--
+-- In textadept >= 10 grammar building seem to have changed a bit. So, in retrospect
+-- I could better have just dropped compatibility and stick to ctx lexers only.
function context.lex(lexer,text,init_style)
-- local lexer = global._LEXER
@@ -1623,9 +1743,9 @@ function context.lex(lexer,text,init_style)
hash[init_style] = grammar
end
if trace then
- report("lexing '%s' with initial style '%s' and %s children",lexer._NAME,#lexer._CHILDREN or 0,init_style)
+ report("lexing '%s' with initial style '%s' and %s children", lexer._NAME,init_style,#lexer._CHILDREN or 0)
end
- return result
+ return matched(lexer,grammar,text)
else
if trace then
report("lexing '%s' with initial style '%s'",lexer._NAME,init_style)
@@ -1634,7 +1754,8 @@ function context.lex(lexer,text,init_style)
end
end
--- hm, changed in 3.24 .. no longer small table but one table:
+-- hm, changed in 3.24 .. no longer small table but one table (so we could remove our
+-- agressive optimization which worked quite well)
function context.token(name, patt)
return patt * Cc(name) * Cp()
@@ -1694,6 +1815,7 @@ function context.new(name,filename)
check_whitespace(lexer)
check_styles(lexer)
check_properties(lexer)
+ lexer._tokenstyles = context.styleset
return lexer
end
@@ -1799,7 +1921,36 @@ end
-- namespace can be automatic: if parent then use name of parent (chain)
+-- The original lexer framework had a rather messy user uinterface (e.g. moving
+-- stuff from _rules to _RULES at some point but I could live with that. Now it uses
+-- add_ helpers. But the subsystem is still not clean and pretty. Now, I can move to
+-- the add_ but there is no gain in it so we support a mix which gives somewhat ugly
+-- code. In fact, there should be proper subtables for this. I might actually do
+-- this because we now always overload the normal lexer (parallel usage seems no
+-- longer possible). For SciTE we can actually do a conceptual upgrade (more the
+-- context way) because there is no further development there. That way we could
+-- make even more advanced lexers.
+
+local savedrequire = require
+
+local escapes = {
+ ["%"] = "%%",
+ ["."] = "%.",
+ ["+"] = "%+", ["-"] = "%-", ["*"] = "%*",
+ ["["] = "%[", ["]"] = "%]",
+ ["("] = "%(", [")"] = "%)",
+ -- ["{"] = "%{", ["}"] = "%}"
+ -- ["^"] = "%^", ["$"] = "%$",
+}
+
function context.loadlexer(filename,namespace)
+
+ if textadept then
+ require = function(name)
+ return savedrequire(name == "lexer" and "scite-context-lexer" or name)
+ end
+ end
+
nesting = nesting + 1
if not namespace then
namespace = filename
@@ -1824,7 +1975,7 @@ function context.loadlexer(filename,namespace)
lexer = load_lexer(filename,namespace) or nolexer(filename,namespace)
usedlexers[filename] = lexer
--
- if not lexer._rules and not lexer._lexer and not lexer_grammar then
+ if not lexer._rules and not lexer._lexer and not lexer_grammar then -- hmm should be lexer._grammar
lexer._lexer = parent_lexer
end
--
@@ -1857,7 +2008,8 @@ function context.loadlexer(filename,namespace)
--
local _r = lexer._rules
local _g = lexer._grammar
- if _r or _g then
+ -- if _r or _g then
+ if _r then
local _s = lexer._tokenstyles
if _s then
for token, style in next, _s do
@@ -1871,6 +2023,9 @@ function context.loadlexer(filename,namespace)
end
end
build_grammar(lexer)
+ else
+ -- other lexers
+ build_grammar(lexer)
end
--
add_style(lexer, lexer.whitespace, lexers.STYLE_WHITESPACE)
@@ -1880,7 +2035,7 @@ function context.loadlexer(filename,namespace)
local patterns = foldsymbols._patterns
if patterns then
for i = 1, #patterns do
- patterns[i] = "()(" .. patterns[i] .. ")"
+ patterns[i] = "()(" .. gsub(patterns[i],".",escapes) .. ")"
end
end
end
@@ -1894,6 +2049,10 @@ function context.loadlexer(filename,namespace)
context.inspect(lexer)
end
--
+ if textadept then
+ require = savedrequire
+ end
+ --
return lexer
end
@@ -1993,8 +2152,8 @@ lexers.inspect = context.inspect
lexers.report = context.report
lexers.inform = context.inform
--- helper .. alas ... the lexer's lua instance is rather crippled .. not even
--- math is part of it
+-- helper .. alas ... in scite the lexer's lua instance is rather crippled .. not
+-- even math is part of it
do
@@ -2003,26 +2162,6 @@ do
local format = format
local tonumber = tonumber
- if not floor then
-
- if tonumber(string.match(_VERSION,"%d%.%d")) < 5.3 then
- floor = function(n)
- return tonumber(format("%d",n))
- end
- else
- -- 5.3 has a mixed number system and format %d doesn't work with
- -- floats any longer ... no fun
- floor = function(n)
- return (n - n % 1)
- end
- end
-
- math = math or { }
-
- math.floor = floor
-
- end
-
local function utfchar(n)
if n < 0x80 then
return char(n)
@@ -2398,6 +2537,128 @@ function lexers.fold_line_comments(prefix)
end
end
+-- There are some fundamental changes in textadept version 10 and I don't want to
+-- adapt again so we go the reverse route: map new to old. This is needed because
+-- we need to load other lexers which is teh result of not being able to load the
+-- lexer framework in parallel. Something happened in 10 that makes the main lexer
+-- always enforced so now we need to really replace that one (and even then it loads
+-- twice (i can probably sort that out). Maybe there's now some hard coded magic
+-- in the binary.
+
+if textadept then
+
+ -- Folds are still somewhat weak because of the end condition not being
+ -- bound to a start .. probably to complex and it seems to work anyhow. As
+ -- we have extended thinsg we just remap.
+
+ local function add_fold_point(lexer,token_name,start_symbol,end_symbol)
+ if type(start_symbol) == "string" then
+ local foldsymbols = lexer._foldsymbols
+ if not foldsymbols then
+ foldsymbols = { }
+ lexer._foldsymbols = foldsymbols
+ end
+ local patterns = foldsymbols._patterns
+ if not patterns then
+ patterns = { }
+ usedpatt = { } -- > 10 uses a mixed index/hash (we don't use patterns)
+ foldsymbols._patterns = patterns
+ foldsymbols._usedpatt = usedpatt
+ end
+ local foldsymbol = foldsymbols[token_name]
+ if not foldsymbol then
+ foldsymbol = { }
+ foldsymbols[token_name] = foldsymbol
+ end
+ if not usedpatt[start_symbol] then
+ patterns[#patterns+1] = start_symbol
+ usedpatt[start_symbol] = true
+ end
+ if type(end_symbol) == "string" then
+ foldsymbol[start_symbol] = 1
+ foldsymbol[end_symbol] = -1
+ if not usedpatt[end_symbol] then
+ patterns[#patterns+1] = end_symbol
+ usedpatt[end_symbol] = true
+ end
+ else
+ foldsymbol[start_symbol] = end_symbol
+ end
+ end
+ end
+
+ local function add_style(lexer,name,style)
+ local tokenstyles = lexer._tokenstyles
+ if not tokenstyles then
+ tokenstyles = { }
+ lexer._tokenstyles = tokenstyles
+ end
+ tokenstyles[name] = style
+ end
+
+ local function add_rule(lexer,id,rule)
+ local rules = lexer._rules
+ if not rules then
+ rules = { }
+ lexer._rules = rules
+ end
+ rules[#rules+1] = { id, rule }
+ end
+
+ local function modify_rule(lexer,id,rule) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ local RULES = lexer._RULES
+ if RULES then
+ RULES[id] = rule
+ end
+ end
+
+ local function get_rule(lexer,id) -- needed for textadept > 10
+ if lexer._lexer then
+ lexer = lexer._lexer
+ end
+ local RULES = lexer._RULES
+ if RULES then
+ return RULES[id]
+ end
+ end
+
+ local new = context.new
+ local lmt = {
+ __index = {
+
+ add_rule = add_rule,
+ modify_rule = modify_rule,
+ get_rule = get_rule,
+ add_style = add_style,
+ add_fold_point = add_fold_point,
+
+ join_tokens = join_tokens,
+ build_grammar = build_grammar,
+
+ embed = lexers.embed,
+ lex = lexers.lex,
+ fold = lexers.fold
+
+ }
+ }
+
+ function lexers.new(name,options)
+ local lexer = new(name)
+ if options then
+ lexer._LEXBYLINE = options['lex_by_line']
+ lexer._FOLDBYINDENTATION = options['fold_by_indentation']
+ lexer._CASEINSENSITIVEFOLDPOINTS = options['case_insensitive_fold_points']
+ lexer._lexer = options['inherit']
+ end
+ setmetatable(lexer,lmt)
+ return lexer
+ end
+
+end
+
-- done
return lexers
diff --git a/context/data/textadept/context/lexers/text.lua b/context/data/textadept/context/lexers/text.lua
new file mode 100644
index 000000000..5d3096b7d
--- /dev/null
+++ b/context/data/textadept/context/lexers/text.lua
@@ -0,0 +1,35 @@
+local info = {
+ version = 1.002,
+ comment = "scintilla lpeg lexer that triggers whitespace backtracking",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+}
+
+-- the lexer dll doesn't backtrack when there is no embedded lexer so
+-- we need to trigger that, for instance in the bibtex lexer, but still
+-- we get failed lexing
+
+local lexer = require("scite-context-lexer")
+local context = lexer.context
+local patterns = context.patterns
+
+local token = lexer.token
+
+local dummylexer = lexer.new("dummy","scite-context-lexer-dummy")
+local whitespace = dummylexer.whitespace
+
+local space = patterns.space
+local nospace = (1-space)
+
+local t_spacing = token(whitespace, space ^1)
+local t_rest = token("default", nospace^1)
+
+dummylexer._rules = {
+ { "whitespace", t_spacing },
+ { "rest", t_rest },
+}
+
+dummylexer._tokenstyles = context.styleset
+
+return dummylexer
diff --git a/context/data/textadept/context/modules/textadept-context-files.lua b/context/data/textadept/context/modules/textadept-context-files.lua
index d3412edc1..28cc794cb 100644
--- a/context/data/textadept/context/modules/textadept-context-files.lua
+++ b/context/data/textadept/context/modules/textadept-context-files.lua
@@ -366,7 +366,7 @@ do
}
- newkeys[OSX and 'mc' or 'cc'] = runner.check
+ -- newkeys[OSX and 'mc' or 'cc'] = runner.check
newkeys[OSX and 'mr' or 'cr'] = runner.process
newkeys[OSX and 'mp' or 'cp'] = runner.preview
-- newkeys[OSX and 'mx' or 'cx'] = runner.quit -- makes no sense
@@ -529,7 +529,7 @@ end
do
- -- It's a pity that we can't have a proper monospaced font here so we try to make the best of it:
+ -- It's a pitt y that we can't have a proper monospaced font here so we try to make the best of it:
local template = "\n\trelease info: %s\t\n\n\tcopyright: %s\t\n\n\tvariant: ConTeXt related editing\t\n\n\tadapted by: Hans Hagen\t"
@@ -697,7 +697,7 @@ local function synchronize(lexer)
end
events.connect(events.FILE_OPENED,function(filename)
- synchronize(buffer.get_lexer(buffer))
+ synchronize(buffer:get_lexer())
end)
events.connect(events.LEXER_LOADED,function(lexer)
@@ -707,23 +707,23 @@ end)
-- obsolete
-- events.connect(events.BUFFER_AFTER_SWITCH,function()
--- synchronize(buffer.get_lexer(buffer))
+-- synchronize(buffer:get_lexer())
-- end)
-- events.connect(events.VIEW_AFTER_SWITCH,function()
--- synchronize(buffer.get_lexer(buffer))
+-- synchronize(buffer:get_lexer())
-- end)
-- events.connect(events.BUFFER_NEW,function()
--- synchronize(buffer.get_lexer(buffer))
+-- synchronize(buffer:get_lexer())
-- end)
-- events.connect(events.VIEW_NEW,function()
--- synchronize(buffer.get_lexer(buffer))
+-- synchronize(buffer:get_lexer())
-- end)
-- events.connect(events.RESET_AFTER,function()
--- synchronize(buffer.get_lexer(buffer))
+-- synchronize(buffer:get_lexer())
-- end)
-- local oldtools = { }
diff --git a/context/data/textadept/context/modules/textadept-context-settings.lua b/context/data/textadept/context/modules/textadept-context-settings.lua
index 53b5c896f..4a5be38da 100644
--- a/context/data/textadept/context/modules/textadept-context-settings.lua
+++ b/context/data/textadept/context/modules/textadept-context-settings.lua
@@ -95,21 +95,41 @@ if context then
buffer.annotation_visible = buffer.ANNOTATION_BOXED
- -- local NUMBER_MARGIN = 0
- -- local MARKER_MARGIN = 1
- -- local FOLD_MARGIN = 2 -- there are more
- --
- -- buffer.margin_type_n [NUMBER_MARGIN] = buffer.MARGIN_NUMBER
- -- buffer.margin_width_n[NUMBER_MARGIN] = (CURSES and 0 or 4)
- -- + 4 * buffer:text_width(buffer.STYLE_LINENUMBER,'9') -- magic
- -- buffer.margin_width_n[MARKER_MARGIN] = CURSES and 1 or 4
- -- buffer.margin_width_n[FOLD_MARGIN] = CURSES and 1 or 12
- --
- -- buffer.margin_mask_n[FOLD_MARGIN] = buffer.MASK_FOLDERS
+ local NUMBER_MARGIN = 0
+ local MARKER_MARGIN = 1
+ local FOLD_MARGIN = 2 -- there are more
+
+ buffer.margin_type_n [NUMBER_MARGIN] = buffer.MARGIN_NUMBER
+ buffer.margin_width_n[NUMBER_MARGIN] = (CURSES and 0 or 6) + 4 * buffer:text_width(buffer.STYLE_LINENUMBER,'9') -- magic
+ buffer.margin_width_n[MARKER_MARGIN] = CURSES and 1 or 18
+ buffer.margin_width_n[FOLD_MARGIN] = CURSES and 1 or 18
+
+ buffer.margin_mask_n[FOLD_MARGIN] = buffer.MASK_FOLDERS -- does something weird: bullets
+
+ buffer:marker_define(buffer.MARKNUM_FOLDEROPEN, buffer.MARK_BOXMINUS)
+ buffer:marker_define(buffer.MARKNUM_FOLDER, buffer.MARK_BOXPLUS)
+ buffer:marker_define(buffer.MARKNUM_FOLDERSUB, buffer.MARK_VLINE)
+ buffer:marker_define(buffer.MARKNUM_FOLDERTAIL, buffer.MARK_LCORNER)
+ buffer:marker_define(buffer.MARKNUM_FOLDEREND, buffer.MARK_BOXPLUSCONNECTED)
+ buffer:marker_define(buffer.MARKNUM_FOLDEROPENMID, buffer.MARK_BOXMINUSCONNECTED)
+ buffer:marker_define(buffer.MARKNUM_FOLDERMIDTAIL, buffer.MARK_TCORNER)
+
+ -- buffer.fold_all = buffer.FOLDACTION_CONTRACT + buffer.FOLDACTION_EXPAND + buffer.FOLDACTION_TOGGLE
+
+ -- somehow the foldeing sumbol sin th emargin cannot be clicked on ... there seems to be some
+ -- interface .. if this needs to be implemented via events i'll then probably make a copy and
+ -- start doing all
+
+ -- buffer.margin_sensitive_n[2] = true
+
+ -- buffer.property['fold'] = "1"
+ -- buffer.automatic_fold = buffer.AUTOMATICFOLD_SHOW + buffer.AUTOMATICFOLD_CLICK + buffer.AUTOMATICFOLD_CHANGE
+ -- buffer.fold_flags = not CURSES and buffer.FOLDFLAG_LINEAFTER_CONTRACTED or 0
+ -- buffer.fold_display_text_style = buffer.FOLDDISPLAYTEXT_BOXED
buffer.wrap_mode = buffer.WRAP_NONE
- buffer.margin_back_n[0] = property_int["color.linenumber"] -- doesn't work
+ buffer.margin_back_n[NUMBER_MARGIN] = property_int["color.linenumber"] -- doesn't work
buffer.property = {
-- ["style.linenumber"] = property["style.linenumber"], -- somehow it fails
diff --git a/doc/context/documents/general/manuals/bidi.pdf b/doc/context/documents/general/manuals/bidi.pdf
index 0d88c7de7..feec5913e 100644
--- a/doc/context/documents/general/manuals/bidi.pdf
+++ b/doc/context/documents/general/manuals/bidi.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/graphics.pdf b/doc/context/documents/general/manuals/graphics.pdf
new file mode 100644
index 000000000..db4d4d4f7
--- /dev/null
+++ b/doc/context/documents/general/manuals/graphics.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/interaction.pdf b/doc/context/documents/general/manuals/interaction.pdf
new file mode 100644
index 000000000..6bfcc99cc
--- /dev/null
+++ b/doc/context/documents/general/manuals/interaction.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/luatex.pdf b/doc/context/documents/general/manuals/luatex.pdf
index 0d7adafbe..d932219bc 100644
--- a/doc/context/documents/general/manuals/luatex.pdf
+++ b/doc/context/documents/general/manuals/luatex.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/musings.pdf b/doc/context/documents/general/manuals/musings.pdf
new file mode 100644
index 000000000..9d83dd555
--- /dev/null
+++ b/doc/context/documents/general/manuals/musings.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/nodes.pdf b/doc/context/documents/general/manuals/nodes.pdf
index 8f0ec1b73..c1e94b14d 100644
--- a/doc/context/documents/general/manuals/nodes.pdf
+++ b/doc/context/documents/general/manuals/nodes.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/onandon.pdf b/doc/context/documents/general/manuals/onandon.pdf
index fe291acf0..add044367 100644
--- a/doc/context/documents/general/manuals/onandon.pdf
+++ b/doc/context/documents/general/manuals/onandon.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/rules-mkiv.pdf b/doc/context/documents/general/manuals/rules-mkiv.pdf
index 9861f76ef..dee2a4607 100644
--- a/doc/context/documents/general/manuals/rules-mkiv.pdf
+++ b/doc/context/documents/general/manuals/rules-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/texit.pdf b/doc/context/documents/general/manuals/texit.pdf
new file mode 100644
index 000000000..e89fa1caf
--- /dev/null
+++ b/doc/context/documents/general/manuals/texit.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/tiptrick.pdf b/doc/context/documents/general/manuals/tiptrick.pdf
index 55d65029a..ea55ab7d8 100644
--- a/doc/context/documents/general/manuals/tiptrick.pdf
+++ b/doc/context/documents/general/manuals/tiptrick.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/tools-mkiv.pdf b/doc/context/documents/general/manuals/tools-mkiv.pdf
index 1da11dcb0..6cde31552 100644
--- a/doc/context/documents/general/manuals/tools-mkiv.pdf
+++ b/doc/context/documents/general/manuals/tools-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/xml-mkiv.pdf b/doc/context/documents/general/manuals/xml-mkiv.pdf
index 78f6ffa1c..6508f2ecc 100644
--- a/doc/context/documents/general/manuals/xml-mkiv.pdf
+++ b/doc/context/documents/general/manuals/xml-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/manuals/xtables-mkiv.pdf b/doc/context/documents/general/manuals/xtables-mkiv.pdf
index d1b1a3ed0..255a730b8 100644
--- a/doc/context/documents/general/manuals/xtables-mkiv.pdf
+++ b/doc/context/documents/general/manuals/xtables-mkiv.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf
index dc3b916a8..eed68e1db 100644
--- a/doc/context/documents/general/qrcs/setup-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf
index 9c7678654..14a74ddf6 100644
--- a/doc/context/documents/general/qrcs/setup-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf
index 39538aa7b..7f468c416 100644
--- a/doc/context/documents/general/qrcs/setup-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf
index 99c12ebd6..4bd083e65 100644
--- a/doc/context/documents/general/qrcs/setup-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf
index c687c7e39..22059b647 100644
--- a/doc/context/documents/general/qrcs/setup-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
index f5bd52a9f..71d7ea47b 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-de.pdf b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
index 274daaf89..8b96f1b12 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-en.pdf b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
index 3aab7cf71..fa1909a0c 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
index b32744159..5b682a879 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-it.pdf b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
index 309929f72..20876ded0 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
index c6bb58d3c..618fbaefd 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
index a43f56921..41cbfaebe 100644
--- a/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-mapping-ro.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf
index ce5340b15..e3e352a62 100644
--- a/doc/context/documents/general/qrcs/setup-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf
index 63b27bf7a..410607bc7 100644
--- a/doc/context/documents/general/qrcs/setup-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-ro.pdf
Binary files differ
diff --git a/doc/context/examples/calculator/calculator.pdf b/doc/context/examples/calculator/calculator.pdf
new file mode 100644
index 000000000..3c7a4b8e8
--- /dev/null
+++ b/doc/context/examples/calculator/calculator.pdf
Binary files differ
diff --git a/doc/context/examples/calculator/calculator.tex b/doc/context/examples/calculator/calculator.tex
new file mode 100644
index 000000000..7ff3235a6
--- /dev/null
+++ b/doc/context/examples/calculator/calculator.tex
@@ -0,0 +1,1871 @@
+%D The calculator
+%D
+%D This document was made in 1998 as demonstration of widgets in \CONTEXT in \MKII.
+%D It has been adapted to run in \MKIV. Not many changes were needed. The macro
+%D definitions are layout a bit more readable and we use official scratch variables.
+%D
+%D The \JAVASCRIPT\ interpeter has changes and also became more strict. So, I
+%D reformatted the code bit and added some more semicolons and vars.
+%D
+%D We changed to font from a Helvetica lookalike to Dejavu but kept the colors as
+%D in the original. We also kept the \JAVASCRIPT\ and \METAPOST\ code (although
+%D we had to add some initalizations for \METAPOST\ due to the runtime graphic
+%D generation. I didn't check the functionality.
+%D
+%D Should I do it different nowaways? For sure. I might use layers of make nicer
+%D \METAPOST\ code but it's also a demonstration of how thinsg were done in 1998.
+
+% acrobat 3->4 : different field initialization
+% acrobat 4->5 : typecasting fails [switch"2" vs 2]
+% acrobat 6-> : more strict interpreter
+
+\starttext
+
+\dontcomplain
+
+\setuppapersize
+ [S6][S6]
+
+\setupwhitespace
+ [medium]
+
+\setupbodyfont
+ [dejavu,9pt]
+
+\setuptyping
+ [margin=standard]
+
+\setuplayout
+ [backspace=1cm,
+ topspace=1cm,
+ header=0pt,
+ footer=0pt,
+ width=middle,
+ height=middle]
+
+\setupinteraction
+ [page=yes,
+ state=start,
+ author=Hans Hagen,
+ title=The Calculator,
+ color=keyboard]
+
+\setupinteractionscreen
+ [option=max]
+
+\definecolor [action] [r= 1, g=.9, b=.5]
+\definecolor [keyboard] [r= 0, g=.7, b=.7]
+\definecolor [stack] [r=.7, g=.6, b=.8]
+
+\useURL[pragma-mail][mailto:pragma@xs4all.nl][][pragma@xs4all.nl]
+
+%D We have to use \type {String(...)=""} otherwise zero is regarded
+%D as non|-|entry (empty). This is a bit fuzzy.
+
+\def\MinLevel{50}
+\def\MaxLevel {8}
+
+\startJSpreamble {variables} used now
+
+ var Growing = false ;
+ var MinLevel = -50 ;
+ var MaxLevel = 8 ;
+ var Level = 1 ;
+ var NoErrorFound = ">ok" ;
+ var NoValueError = ">invalid" ;
+ var WhateverError = ">error" ;
+ var OverflowError = ">overflow" ;
+ var ExhaustedError = ">exhausted" ;
+
+ var Stack = new Array() ;
+ var Stats = new Array() ;
+
+ // console.clear() ;
+
+ // console.println("preamble loaded: variables") ;
+
+\stopJSpreamble
+
+\startJSpreamble {housekeeping} used now
+
+ function do_reset_all () {
+ if (Growing) {
+ Level = 1 ;
+ } else {
+ Level = MaxLevel ;
+ }
+ for (var i=MinLevel ; i<=MaxLevel ; i++) {
+ Stack[i] = "" ;
+ }
+ do_mark (NoErrorFound) ;
+ }
+
+ function do_refresh (i) {
+ var vv = this.getField("Stack." + String(i)) ;
+ if (vv) {
+ vv.value = Stack[i] ;
+ vv.readonly = (i != Level) ;
+ this.dirty = false ;
+ }
+ }
+
+ function do_refresh_all () {
+ for (var i=1 ; i<=MaxLevel ; i++) {
+ do_refresh(i) ;
+ }
+ }
+
+ function do_update_A () {
+ if (Stack[1] == "") {
+ for (var i=1 ; i<=MaxLevel ; i++) {
+ vv = this.getField("Stack." + String(i)) ;
+ if (vv) {
+ Level = i ;
+ if (valid_number(vv.value)) {
+ Stack[Level] = String(vv.value)
+ } else {
+ vv.value = "" ;
+ this.dirty = false ;
+ return ;
+ }
+ }
+ }
+ }
+ }
+
+ function do_update_B () {
+ if (String(Stack[MaxLevel-1]) == "") {
+ for (var i=1 ; i<=MaxLevel ; i++) {
+ vv = this.getField("Stack." + String(i)) ;
+ if (vv) {
+ if (valid_number(vv.value)) {
+ Stack[Level] = String(vv.value) ;
+ } else {
+ vv.value = "" ;
+ this.dirty = false ;
+ return ;
+ }
+ }
+ }
+ }
+ }
+
+ function do_update () {
+ if (Growing) {
+ do_update_A() ;
+ } else {
+ do_update_B() ;
+ }
+ }
+
+ function do_mark (s) {
+ var vv = this.getField("Stack." + String(Level)) ;
+ if (vv) {
+ vv.value = s ;
+ this.dirty = false ;
+ }
+ }
+
+ // console.println("preamble loaded: housekeeping") ;
+\stopJSpreamble
+
+\startJSpreamble {handling} used now
+
+ function do_enter () {
+ do_update() ;
+ var vv = this.getField("Stack." + String(Level)) ;
+ if ((vv.value!=Stack[Level]) && (String(vv.value).search(/>/)==-1)) {
+ do_push (vv.value) ;
+ } else {
+ do_push (Stack[Level]) ;
+ }
+ }
+
+ function do_push_A (Value) {
+ do_update() ;
+ Stack[Level] = String(Value) ;
+ do_parse(Level) ;
+ if (String(Stack[Level])!="") {
+ if (Level<MaxLevel) {
+ ++Level ;
+ do_mark (ErrorString) ;
+ } else {
+ for (var i=MinLevel ; i<MaxLevel ; i++) {
+ Stack[i] = Stack[i+1] ;
+ }
+ Stack[MaxLevel] = "" ;
+ do_refresh_all() ;
+ if (String(Stack[MinLevel])!="") {
+ ErrorString = ExhaustedError ;
+ }
+ do_mark (ErrorString) ;
+ }
+ }
+ }
+
+ function do_push_B (Value) {
+ do_update() ;
+ Stack[MaxLevel] = String(Value) ;
+ do_parse(MaxLevel) ;
+ if (String(Stack[MaxLevel])!="") {
+ for (var i=MinLevel ; i<MaxLevel ; i++) {
+ Stack[i] = Stack[i+1] ;
+ }
+ Stack[MaxLevel] = "" ;
+ do_refresh_all() ;
+ if (Stack[MinLevel]!="") {
+ ErrorString = ExhaustedError ;
+ }
+ do_mark (ErrorString) ;
+ }
+ }
+
+ function do_push (Value) {
+ if (Growing) {
+ do_push_A (Value) ;
+ } else {
+ do_push_B (Value) ;
+ }
+ }
+
+ function do_pop_A () {
+ do_update() ;
+ if (String(Stack[0])!="") {
+ for (var i=MaxLevel ; i>MinLevel ; i--) {
+ Stack[i] = Stack[i-1] ;
+ }
+ Stack[MinLevel] = "" ;
+ do_refresh_all() ;
+ Level = MaxLevel ;
+ } else {
+ while ((Level>1) && (String(Stack[Level])=="")) {
+ do_refresh(Level) ;
+ --Level ;
+ }
+ }
+ if (String(Stack[Level])=="") {
+ return("") ;
+ } else {
+ Value = Number(Stack[Level]) ;
+ Stack[Level] = "" ;
+ do_refresh(Level) ;
+ return(Value) ;
+ }
+ }
+
+ function do_pop_B () {
+ do_update() ;
+ if (String(Stack[MaxLevel])=="") {
+ for (var i=MaxLevel ; i>MinLevel ; i--) {
+ Stack[i] = Stack[i-1] ;
+ }
+ Stack[MinLevel] = "" ;
+ do_refresh_all() ;
+ }
+ if (String(Stack[MaxLevel])=="") {
+ return("") ;
+ } else {
+ Value = Number(Stack[MaxLevel]) ;
+ Stack[MaxLevel] = "" ;
+ return(Value) ;
+ }
+ }
+
+ function do_pop () {
+ if (Growing) {
+ return(do_pop_A()) ;
+ } else {
+ return(do_pop_B()) ;
+ }
+ }
+
+ function do_dup () {
+ var X = do_pop() ;
+ if (valid_number(X)) {
+ do_push(X) ;
+ do_push(X) ;
+ } else {
+ do_mark (ErrorString) ;
+ }
+ }
+
+ function do_parse ( i ) {
+ if (valid_number(Stack[i])) {
+ Stack[i] = parseFloat(Stack[i]) ;
+ do_refresh(i) ;
+ } else {
+ Stack[i] = "" ;
+ do_refresh(i) ;
+ do_mark (ErrorString) ;
+ }
+ }
+
+ function do_digit ( d ) {
+ Stack[Level] += String(d) ;
+ do_refresh(Level) ;
+ }
+
+ function valid_number ( x ) {
+ if (String(x) == "") {
+ ErrorString = NoValueError ;
+ return(false) ;
+ } else if (isNaN(x)) {
+ ErrorString = NoValueError ;
+ return(false) ;
+ } else if (isFinite(x)) {
+ ErrorString = NoErrorFound ;
+ return(true) ;
+ } else {
+ ErrorString = OverflowError ;
+ return(false) ;
+ }
+ }
+
+ // console.println("preamble loaded: handling") ;
+
+\stopJSpreamble
+
+\startJSpreamble {operations} used now
+
+ function do_calculate (Operator) {
+ do_enter() ;
+ var Y = do_pop() ;
+ var X = 0 ;
+ if (valid_number(Y)) {
+ X = do_pop() ;
+ if (valid_number(X)) {
+ switch (Number(Operator)) {
+ case 1 :
+ if (Y) {
+ X /= Y ;
+ }
+ break ;
+ case 2 :
+ X *= Y ;
+ break ;
+ case 3 :
+ X -= Y ;
+ break ;
+ case 4 :
+ X += Y ;
+ break ;
+ case 5 :
+ X = Math.max(X,Y) ;
+ break ;
+ case 6 :
+ X = Math.min(X,Y) ;
+ break ;
+ case 7 :
+ X = Math.pow(X,Y) ;
+ break
+ }
+ do_push(X) ;
+ } else {
+ do_push(Y) ;
+ ErrorString = NoValueError ;
+ }
+ }
+ do_mark(ErrorString) ;
+ }
+
+ // console.println("preamble loaded: operations") ;
+\stopJSpreamble
+
+\startJSpreamble {functions} used now
+
+ function do_facultate (Value) {
+ var n = Math.min(Math.round(Value),500) ;
+ if (n <= 1) {
+ return(1) ;
+ } else {
+ var m = 1 ;
+ for (m=1, i=1 ; i<=n ; i++) {
+ m = m * i ;
+ }
+ return(m) ;
+ }
+ }
+
+ function do_constant (Operation) {
+ do_update() ;
+ switch (Number(Operation)) {
+ case 1 :
+ do_push(Math.PI) ;
+ break ;
+ case 2 :
+ do_push(Math.E) ;
+ break ;
+ case 3 :
+ do_push(Math.random(1)) ;
+ break ;
+ case 4 :
+ do_dup() ;
+ break ;
+ }
+ }
+
+ function do_do_memory (mv, Sign) {
+ var X = do_pop() ;
+ if (valid_number(X)) {
+ mv.value += Sign*X ;
+ if (!valid_number(mv.value)) {
+ mv.value = "" ;
+ }
+ this.dirty = false ;
+ }
+ do_mark(ErrorString) ;
+ }
+
+ function do_memory (Operation) {
+ var mv = this.getField("Stats.mem") ;
+ if (mv) {
+ switch (Number(Operation)) {
+ case 1 :
+ mv.value = "" ;
+ break ;
+ case 2 :
+ do_do_memory(mv, 1) ;
+ break ;
+ case 3 :
+ do_do_memory(mv, -1) ;
+ break ;
+ case 4 :
+ if (mv.value == "") {
+ ErrorString = NoValueError ;
+ do_mark(ErrorString) ;
+ } else {
+ do_push(mv.value) ;
+ }
+ break ;
+ }
+ this.dirty = false ;
+ }
+ }
+
+ function do_operation (Operator) {
+ do_enter() ;
+ var X = do_pop() ;
+ if (valid_number(X)) {
+ switch (Number(Operator)) {
+ case 1 :
+ do_push(Math.sin(X)) ;
+ break ;
+ case 2 :
+ do_push(Math.cos(X)) ;
+ break ;
+ case 3 :
+ do_push(Math.tan(X)) ;
+ break ;
+ case 4 :
+ do_push(Math.exp(X)) ;
+ break ;
+ case 5 :
+ do_push(Math.ceil(X)) ;
+ break ;
+ case 6 :
+ do_push(Math.pow(X,2)) ;
+ break ;
+ case 7 :
+ do_push(do_facultate(X)) ;
+ break ;
+ case 8 :
+ do_push(Math.asin(X)) ;
+ break ;
+ case 9 :
+ do_push(Math.acos(X)) ;
+ break ;
+ case 10 :
+ do_push(Math.atan(X)) ;
+ break ;
+ case 11 :
+ do_push(Math.log(X)) ;
+ break ;
+ case 12 :
+ do_push(Math.floor(X)) ;
+ break ;
+ case 13 :
+ do_push(Math.sqrt(X)) ;
+ break ;
+ case 14 :
+ do_push(Math.round(X)) ;
+ break ;
+ case 15 :
+ do_push(Math.pow(X,-1)) ;
+ break ;
+ case 16 :
+ do_push(X*(2*Math.PI/360)) ;
+ break ;
+ case 17 :
+ do_push(X/(2*Math.PI/360)) ;
+ break ;
+ case 18 :
+ do_push(-X) ;
+ break ;
+ }
+ }
+ do_mark(ErrorString) ;
+ }
+
+ // console.println("preamble loaded: functions") ;
+\stopJSpreamble
+
+\startJSpreamble {statistics} used now
+
+ var s_min_max = 1 ;
+ var s_sqrt = 0 ;
+
+ function do_statcalcs (Sign, X) {
+ s_n.value += Sign ;
+ s_sqrt += Sign*X*X ;
+ s_total.value += Sign*X ;
+ s_mean.value = s_total.value / s_n.value ;
+ s_temp = Math.max(s_sqrt - 2*s_total.value*s_mean.value +
+ s_n.value*s_mean.value*s_mean.value, 0) ;
+ s_sdev.value = Math.sqrt(s_temp/s_n.value) ;
+ if (!(valid_number(X) && valid_number(s_sqrt) &&
+ valid_number(s_sdev.value) && valid_number(s_total.value) &&
+ valid_number(s_mean.value))) {
+ do_statistics(1) ;
+ }
+ this.dirty = false ;
+ }
+
+ function do_statistics(Operator) {
+ var s_n = this.getField("Stats.n") ;
+ var s_min = this.getField("Stats.min") ;
+ var s_max = this.getField("Stats.max") ;
+ var s_total = this.getField("Stats.total") ;
+ var s_mean = this.getField("Stats.mean") ;
+ var s_sdev = this.getField("Stats.sdev") ;
+ if ((s_sqrt==0) && (s_n.value!="") && (s_n.value>0)) {
+ s_min_max = 1 ;
+ s_sqrt = s_n.value*s_sdev.value*s_sdev.value +
+ 2*s_total.value*s_mean.value -
+ s_n.value*s_mean.value*s_mean.value ;
+ }
+ switch (Number(Operator)) {
+ case 1 :
+ s_min_max = 1 ;
+ s_n.value = "" ;
+ s_min.value = "" ;
+ s_max.value = "" ;
+ s_total.value = "" ;
+ s_mean.value = "" ;
+ s_sdev.value = "" ;
+ s_sqrt = 0 ;
+ break ;
+ case 2 :
+ do_enter() ;
+ var X = do_pop() ;
+ if (valid_number(X)) {
+ if (s_n.value=="") {
+ s_n.value = 0 ;
+ s_total.value = 0 ;
+ s_mean.value = 0 ;
+ if (s_min_max) {
+ s_min.value = X ;
+ s_max.value = X ;
+ }
+ } else {
+ if ((s_min_max) && (X<s_min.value)) {
+ s_min.value = X ;
+ }
+ if ((s_min_max) && (X>s_max.value)) {
+ s_max.value = X ;
+ }
+ }
+ do_statcalcs(1,X) ;
+ }
+ break ;
+ case 3 :
+ do_enter() ;
+ var X = do_pop() ;
+ if (valid_number(X)) {
+ s_min.value = "" ;
+ s_max.value = "" ;
+ s_min_max = 0 ;
+ if (s_n.value>0) {
+ do_statcalcs(-1,X) ;
+ } else {
+ do_statistics(1) ;
+ }
+ }
+ break ;
+ }
+ do_mark(ErrorString) ;
+ this.dirty = false ;
+ }
+
+ function do_copystat (Field) {
+ var sv = this.getField("Stats.".concat(Field)) ;
+ do_push(sv.value) ;
+ }
+
+ // console.println("preamble loaded: statistics") ;
+\stopJSpreamble
+
+\startJSpreamble {initialization} used now
+ do_reset_all() ;
+ do_update() ;
+ do_refresh_all() ;
+ do_mark (NoErrorFound) ;
+
+ // console.println("preamble loaded: initialization") ;
+\stopJSpreamble
+
+%D We could use functions instead but this demonstrates inline
+%D code. We also could use predefined references.
+
+\startJScode{period}
+ if (Stack[Level].search(/[.|e]/)==-1) {
+ do_digit(".") ;
+ }
+\stopJScode
+
+\startJScode{sign}
+ L = Stack[Level].length ;
+ if ((L==0) || (Stack[Level].charAt(L-1)=="e")) {
+ do_digit("-") ;
+ }
+\stopJScode
+
+\startJScode{exponent}
+ L = Stack[Level].length ;
+ if ((L>0) && valid_number(Stack[Level]) && (Stack[Level].search(/[e]/)==-1)) {
+ do_digit("e") ;
+ }
+\stopJScode
+
+\startJScode{reset}
+ do_reset_all() ;
+ do_refresh_all() ;
+ do_mark (NoErrorFound) ;
+\stopJScode
+
+\startJScode{clear}
+ do_update() ;
+ Stack[Level] = String(Stack[Level]).substring(0,String(Stack[Level]).length-1) ;
+ do_refresh(Level) ;
+\stopJScode
+
+\startJScode{pop}
+ X = do_pop() ;
+ do_mark(NoErrorFound) ;
+\stopJScode
+
+\startJScode{push}
+ do_enter() ;
+\stopJScode
+
+\startJScode{grow}
+ Growing = !Growing ;
+ do_reset_all() ;
+ do_refresh_all() ;
+ do_mark (NoErrorFound) ;
+\stopJScode
+
+% graphics
+
+\startuniqueMPgraphic{page}
+ fill OverlayBox
+ withcolor .4white ;
+ draw OverlayBox enlarged -10pt
+ withpen pencircle scaled 5pt
+ withcolor .8white ;
+\stopuniqueMPgraphic
+
+\startuniqueMPgraphic{shape}
+ path p ; color c ;
+ p := OverlayBox ;
+ c := \overlaycolor ;
+ fill p withcolor c ;
+ draw p withpen pencircle scaled 1.5pt withcolor .8c ;
+\stopuniqueMPgraphic
+
+\defineoverlay [page] [\uniqueMPgraphic{page}]
+\defineoverlay [shape] [\uniqueMPgraphic{shape}]
+
+\setupbackgrounds
+ [page]
+ [background=page]
+
+\definemeasure[ButtonWidth][\makeupwidth/15]
+
+\setupbuttons
+ [width=\measured{ButtonWidth},
+ height=\measured{ButtonWidth},
+ background=shape,
+ backgroundcolor=\MPcolor{keyboard},
+ frame=off,
+ style=,
+ color=]
+
+\setupfield
+ [Results]
+ [horizontal,frame]
+ [width=fit,
+ align={lohi},
+ height=.5\measured{ButtonWidth},
+ background=shape,
+ backgroundcolor=\MPcolor{stack},
+ frame=off]
+ [width=3.5\measured{ButtonWidth},
+ frame=off]
+ [width=3.5\measured{ButtonWidth},
+ height=.45\measured{ButtonWidth},
+ option=readonly,
+ frame=off]
+
+\starttexdefinition unexpanded Star
+ \lower.65ex\hbox {
+ *
+ }
+\stoptexdefinition
+
+\starttexdefinition unexpanded InfoButton #1
+ \setbox\scratchbox\hbox {
+ \lower .5cm \hbox {
+ \button [
+ width=\dimexpr\overlaywidth + .5cm\relax,
+ height=\dimexpr\overlayheight + .5cm\relax,
+ strut=no,
+ frame=off,
+ background=
+ ] {
+ } [
+ info:#1
+ ]
+ }
+ }
+ \wd\scratchbox\overlaywidth
+ \ht\scratchbox\overlayheight
+ \box\scratchbox
+\stoptexdefinition
+
+\starttexdefinition unexpanded SomeKey #1#2#3
+
+ \bgroup
+
+ \doifelsenothing {#2} {
+ \button[background=]{#2}[#3]
+ } {
+ \defineoverlay
+ [infobutton]
+ [\InfoButton{#1}]
+ % \button
+ % [background={infobutton,shape}]
+ % {#2}
+ % [#3]
+ \framed
+ [offset=overlay,
+ frame=off,
+ background=infobutton,
+ backgroundcolor=red]
+ {\button{#2}[#3]}
+ }
+
+ \egroup
+
+ \ignorespaces
+
+\stoptexdefinition
+
+\starttexdefinition unexpanded StatField #1
+ \hbox \bgroup
+ \doifelsenothing {#1} {
+ \framed [
+ height=.5\measured{ButtonWidth},
+ width=3.5\measured{ButtonWidth},
+ frame=off
+ ] {
+ }
+ } {
+ \definefield[Stats.#1][line][Results]
+ \field[Stats.#1][option=readonly]
+ }
+ \egroup
+ \ignorespaces
+\stoptexdefinition
+
+\setbox\scratchboxone=\hbox to .4\makeupwidth \bgroup
+ \ss
+ \SomeKey {7} {\ssb 7} {JS(do_digit{7})} \hss
+ \SomeKey {8} {\ssb 8} {JS(do_digit{8})} \hss
+ \SomeKey {9} {\ssb 9} {JS(do_digit{9})} \hss
+ \SomeKey {div} {\ssb /} {JS(do_calculate{1})} \hss
+ \SomeKey {del} {del} {JS(clear)}
+\egroup
+
+\setbox\scratchboxtwo=\hbox to \wd\scratchboxone \bgroup
+ \ss
+ \SomeKey {4} {\ssb 4} {JS(do_digit{4})} \hss
+ \SomeKey {5} {\ssb 5} {JS(do_digit{5})} \hss
+ \SomeKey {6} {\ssb 6} {JS(do_digit{6})} \hss
+ \SomeKey {mul} {\ssb \Star} {JS(do_calculate{2})} \hss
+ \SomeKey {E} {E} {JS(exponent)}
+\egroup
+
+\setbox\scratchboxthree=\hbox to \wd\scratchboxone \bgroup
+ \ss
+ \SomeKey {1} {\ssb 1} {JS(do_digit{1})} \hss
+ \SomeKey {2} {\ssb 2} {JS(do_digit{2})} \hss
+ \SomeKey {3} {\ssb 3} {JS(do_digit{3})} \hss
+ \SomeKey {sub} {\ssb --} {JS(do_calculate{3})} \hss
+ \SomeKey {pop} {pop} {JS(pop)}
+\egroup
+
+\setbox\scratchboxfour=\hbox to \wd\scratchboxone \bgroup
+ \ss
+ \SomeKey {0} {\ssb 0} {JS(do_digit{0})} \hss
+ \SomeKey {period} {\ssb .} {JS(period)} \hss
+ \SomeKey {sign} {\ssb -} {JS(sign)} \hss
+ \SomeKey {add} {\ssb +} {JS(do_calculate{4})} \hss
+ \SomeKey {push} {push} {JS(push)}
+\egroup
+
+\setbox\scratchboxone=\vbox to .8\wd\scratchboxone \bgroup
+ \box\scratchboxone \vss
+ \box\scratchboxtwo \vss
+ \box\scratchboxthree\vss
+ \box\scratchboxfour
+\egroup
+
+\setbox\scratchboxtwo=\vbox to \ht\scratchboxone \bgroup
+ \dostepwiserecurse {\MaxLevel} {1} {-1} {
+ \definefield[Stack.\recurselevel][line][Results]
+ \hbox \bgroup
+ \field[Stack.\recurselevel][option=readonly]%
+ \egroup
+ \vfill
+ }
+ \unskip
+\egroup
+
+\setbox\scratchboxthree=\vbox to \ht\scratchboxone \bgroup
+ \StatField {n} \vfill
+ \StatField {min} \vfill
+ \StatField {max} \vfill
+ \StatField {total} \vfill
+ \StatField {mean} \vfill
+ \StatField {sdev} \vfill
+ \StatField {} \vfill
+ \StatField {}
+\egroup
+
+\setbox\scratchboxfour=\vbox to \ht\scratchboxone \bgroup
+ \ss\setstrut
+ \setupbuttons
+ [width=\measured{ButtonWidth},
+ height=.5\measured{ButtonWidth},
+ backgroundcolor=\MPcolor{action}]%
+ \SomeKey {sn} {n} {JS(do_copystat{n})} \vfill
+ \SomeKey {smin} {min} {JS(do_copystat{min})} \vfill
+ \SomeKey {smax} {max} {JS(do_copystat{max})} \vfill
+ \SomeKey {stotal} {total} {JS(do_copystat{total})} \vfill
+ \SomeKey {smean} {mean} {JS(do_copystat{mean})} \vfill
+ \SomeKey {ssdev} {sdev} {JS(do_copystat{sdev})} \vfill
+ \SomeKey {} {} {} \vfill
+ \SomeKey {} {} {}
+\egroup
+
+\setbox\scratchboxone=\hbox to \hsize \bgroup
+ \box\scratchboxone \hss
+ \box\scratchboxtwo \hss
+ \box\scratchboxthree\hss
+ \box\scratchboxfour
+\egroup
+
+\setupbuttons
+ [width=1.5cm,
+ height=1cm,
+ backgroundcolor=\MPcolor{action}]
+
+\setbox\scratchboxtwo=\hbox to \wd\scratchboxone \bgroup
+ \ss\setstrut
+ \SomeKey {sin} {sin} {JS(do_operation{1})} \hss
+ \SomeKey {cos} {cos} {JS(do_operation{2})} \hss
+ \SomeKey {tan} {tan} {JS(do_operation{3})} \hss
+ \SomeKey {max} {max} {JS(do_calculate{5})} \hss
+ \SomeKey {exp} {exp} {JS(do_operation{4})} \hss
+ \SomeKey {ceil} {ceil} {JS(do_operation{5})} \hss
+ \SomeKey {sqr} {x\high{2}} {JS(do_operation{6})} \hss
+ \SomeKey {fac} {x!} {JS(do_operation{7})} \hss
+ \SomeKey {pow} {x\high{y}} {JS(do_calculate{7})} \hss
+ \SomeKey {rad} {rad} {JS(do_operation{16})}
+\egroup
+
+\setbox\scratchboxthree=\hbox to \wd\scratchboxone \bgroup
+ \ss\setstrut
+ \SomeKey {asin} {asin} {JS(do_operation{8})} \hss
+ \SomeKey {acos} {acos} {JS(do_operation{9})} \hss
+ \SomeKey {atan} {atan} {JS(do_operation{10})} \hss
+ \SomeKey {min} {min} {JS(do_calculate{6})} \hss
+ \SomeKey {ln} {ln} {JS(do_operation{11})} \hss
+ \SomeKey {floor}{floor} {JS(do_operation{12})} \hss
+ \SomeKey {sqrt} {sqrt} {JS(do_operation{13})} \hss
+ \SomeKey {round}{round} {JS(do_operation{14})} \hss
+ \SomeKey {inv} {1/x} {JS(do_operation{15})} \hss
+ \SomeKey {deg} {deg} {JS(do_operation{17})}
+\egroup
+
+\setbox\scratchboxfour=\hbox to \wd\scratchboxone \bgroup
+ \ss\setstrut
+ \SomeKey {} {} {} \hss
+ \SomeKey {} {} {} \hss
+ \setupbuttons
+ [backgroundcolor=\MPcolor{keyboard}]%
+ \SomeKey {new} {new} {JS(reset)} \hss
+ \SomeKey {} {} {} \hss
+ \SomeKey {} {} {} \hss
+ \SomeKey {} {} {} \hss
+ \SomeKey {} {} {} \hss
+ \SomeKey {newn} {new} {JS(do_statistics{1})} \hss
+ \SomeKey {addn} {+n} {JS(do_statistics{2})} \hss
+ \SomeKey {subn} {--n} {JS(do_statistics{3})}
+\egroup
+
+\setbox\scratchboxfive=\hbox to \wd\scratchboxone \bgroup
+ \ss\setstrut
+ \SomeKey {neg} {--x} {JS(do_operation{18})} \hss
+ \SomeKey {random}{random} {JS(do_constant{3})} \hss
+ \SomeKey {pi} {pi} {JS(do_constant{1})} \hss
+ \SomeKey {e} {e} {JS(do_constant{2})} \hss
+ \SomeKey {dup} {dup} {JS(do_constant{4})} \hss
+ \SomeKey {} {} {} \hss
+ \SomeKey {} {} {} \hss
+ \setupbuttons
+ [backgroundcolor=\MPcolor{keyboard}]%
+ \SomeKey {} {} {} \hss
+ \SomeKey {exit} {exit} {CloseDocument} \hss
+ \SomeKey {help} {info} {info:help}
+\egroup
+
+\setbox\scratchboxsix=\hbox to \wd\scratchboxone \bgroup
+ \ss\setstrut
+ \setupbuttons
+ [width=\measured{ButtonWidth},
+ height=.5\measured{ButtonWidth},
+ backgroundcolor=\MPcolor{keyboard}]%
+ \SomeKey {newmem} {new} {JS(do_memory{1})} \hss
+ \SomeKey {addmem} {+m} {JS(do_memory{2})} \hss
+ \SomeKey {submem} {--m} {JS(do_memory{3})} \hss
+ \StatField {mem} \hss
+ \setupbuttons
+ [backgroundcolor=\MPcolor{action}]%
+ \SomeKey {copmem} {mem} {JS(do_memory{4})} \hss
+ \SomeKey {} {} {} \hss
+ \setupbuttons
+ [backgroundcolor=\MPcolor{stack}]%
+ \SomeKey {grow} {grow} {JS(grow)} \hss
+ \StatField {}
+\egroup
+
+\startstandardmakeup
+
+ \pagereference[calculator]
+
+ \vfill
+
+ \hbox to \hsize \bgroup
+ \hss
+ \vbox to \vsize \bgroup
+ \box\scratchboxtwo \vss
+ \box\scratchboxthree\vss
+ \box\scratchboxone \vss
+ \box\scratchboxfour \vss
+ \box\scratchboxfive \vss
+ \box\scratchboxsix
+ \egroup
+ \hss
+ \egroup
+
+ \vfill
+
+\stopstandardmakeup
+
+\starttexdefinition unexpanded BackgroundButton
+ \button [
+ background=screen,
+ backgroundscreen=.8,
+ backgroundoffset=5pt,
+ height=\vsize,
+ width=\hsize
+ ] {
+ } [
+ calculator
+ ]
+\stoptexdefinition
+
+\setuptexttexts
+ [\BackgroundButton]
+ []
+
+\starttexdefinition unexpanded Key #1#2
+ \goto {
+ \ss#1
+ } [
+ info:#2
+ ]
+\stoptexdefinition
+
+\startstandardmakeup[top=,bottom=]
+
+ \switchtobodyfont[8pt]
+
+ \start
+
+ \setupwhitespace[big]
+
+ \midaligned{\ssd The Calculator}
+
+ \blank[2*big]
+
+ \pagereference[info:help]
+ This calculator is stack based, which means that one enters values and
+ invokes an action that acts on the value(s) last entered. Subtracting 10 from
+ 20 using (\Key {--} {sub}) for instance comes down to clicking:
+
+ \startnarrower\ss
+ 10\quad in\quad 20\quad --
+ \stopnarrower
+
+ while calculating a sinus (\Key {sin} {sin}) results from entering:
+
+ \startnarrower\ss
+ .89\quad sin
+ \stopnarrower
+
+ The left column of fields (numbers) shows the Stack. One uses \Key {push}
+ {push} to push a value on the stack and \Key {pop} {pop} to remove a value.
+ Clicking \Key {new} {new} removes them all and the \Key {del} {del} button
+ can be used to undo the last entered digit. When a dyadic operation is
+ applied, the top value is used as~y. The \Key {grow} {grow} key toggles
+ between two different visualizations of the stack.
+
+ The stack is considerably larger than the screen representation suggests. In
+ the rare occasion that one encounters the message {\ss exhausted}, the amount
+ of stack entries already has totaled far beyond \MinLevel\ and one probably
+ already has forgotten what the values first entered represent.
+
+ The right column of fields reports the statistic calculations. By clicking on
+ the tag, one pushes the value on the Stack. The lower buttons are used to
+ reset~(\Key {new} {newn}), enter~(\Key {+} {addn}) and remove~(\Key {--}
+ {subn}) values to be taken into account when calculating those statistics.
+
+ This document is produced by \ConTeXt, a macro package written in \TeX. The
+ graphics are METAPOST graphics. The graphics, the PDF objects and the form
+ fields as well as JavaScript code were generated and inserted at run time.
+ Originally we used PDF\TeX\ and \MKII\ to process this document but this one
+ is done by \LUATEX\ and \MKIV. We kept the design and code original so that
+ it reflects how things were done (for readability we updated some \TEX\
+ definitions).
+
+ \stop
+
+ \vfilll
+
+ \startMPrun
+ logo_type := 302 ; % force single logo type
+ mpgraph := 302 ; % and use this number
+ input mp-prag ; % calculate logo of type
+ \stopMPrun
+
+ \startlinecorrection
+ \midaligned{\externalfigure[mprun.302][height=1.5cm]}
+ \stoplinecorrection
+
+ \midaligned{\strut Hans Hagen, PRAGMA ADE, \ConTeXt\ 18/2/1998--25/9/2018}
+
+ \blank
+
+ \midaligned{\strut\url[pragma-mail]}
+
+\stopstandardmakeup
+
+\starttexdefinition unexpanded BackgroundButton
+ \button [
+ background=screen,
+ backgroundscreen=.8,
+ backgroundoffset=5pt,
+ height=\vsize,
+ width=\hsize
+ ] {
+ } [
+ firstpage
+ ]
+\stoptexdefinition
+
+\starttexdefinition unexpanded ShowInfo #1#2
+ \startstandardmakeup
+ \pagereference[info:#1]
+ \vfill
+ \hbox to \hsize \bgroup
+ \hss
+ \useMPgraphic{#1}
+ \hss
+ \egroup
+ \blank[2*big]
+ \midaligned{#2}
+ \vfill
+ \stopstandardmakeup
+\stoptexdefinition
+
+\startMPinclusions
+
+ path ax, ay, p[] ;
+ color c ; c := \MPcolor{action} ;
+ pmax := 0 ;
+
+ let normalpow = pow ;
+
+ def draw_function (text fun) (expr xmin, xmax, xstep) =
+ pmax := pmax+1 ;
+ p[pmax] := for x=xmin step xstep until xmax:
+ (x,fun(x)) ..
+ endfor (xmax,fun(xmax)) ;
+ enddef ;
+
+ def draw_axis = % should sort of snap, to-do
+ pickup pencircle scaled 0 ;
+ for i=1 upto pmax:
+ draw p[i] ;
+ endfor ;
+ xmin := xpart llcorner currentpicture ;
+ xmax := xpart urcorner currentpicture ;
+ ymin := ypart llcorner currentpicture ;
+ ymax := ypart urcorner currentpicture ;
+ ax := (xmin,0)--(0,0)--(xmax,0) ;
+ ay := (0,ymin)--(0,0)--(0,ymax) ;
+ currentpicture := nullpicture ;
+ sx := 400/(xmax-xmin) ;
+ sy := 250/(ymax-ymin) ;
+ pickup pencircle xscaled (10/sx) yscaled (10/sy) ;
+ draw ax withcolor .4white ;
+ draw ay withcolor .4white ;
+ for i=1 upto pmax:
+ draw p[i] withcolor c ;
+ endfor ;
+ currentpicture := currentpicture xscaled sx yscaled sy ;
+ pmax := 0 ;
+ enddef ;
+
+\stopMPinclusions
+
+\startuseMPgraphic{sin}
+ draw_function(sind)(-360,360,60) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{sin}{Calculate the sine of the topmost stack entry.}
+
+\startuseMPgraphic{cos}
+ draw_function(cosd)(-360,360,60) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{cos}{Calculate the cosine of the topmost stack entry.}
+
+\startuseMPgraphic{tan}
+ draw_function(tand)(-240,-120,30) ;
+ draw_function(tand)( -60, 60,30) ;
+ draw_function(tand)( 120, 240,30) ;
+ draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{tan}{Calculate the tangent of the topmost stack entry.}
+
+\startuseMPgraphic{asin}
+ draw_function(asin)(-1,1,.2) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{asin}{Calculate the arcsine of the topmost stack entry.}
+
+\startuseMPgraphic{acos}
+ draw_function(acos)(-1,1,.2) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{acos}{Calculate the arccosine of the topmost stack entry.}
+
+\startuseMPgraphic{atan}
+ draw_function(atan)(-1,1,.2) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{atan}{Calculate the arctangent of the topmost stack entry.}
+
+\startuseMPgraphic{sqr}
+ draw_function(sqr)(-3,3,1) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{sqr}{Calculate the square of the topmost stack entry.}
+
+\startuseMPgraphic{sqrt}
+ draw_function(sqrt)(0,5,1) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{sqrt}{Calculate the square root of the topmost stack entry.}
+
+\startuseMPgraphic{exp}
+ draw_function(exp)(0,5,1) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{exp}{Calculate the exponential function of the topmost stack entry.}
+
+\startuseMPgraphic{ln}
+ draw_function(ln)(0,50,5) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{ln}{Calculate the natural logaritm of the topmost stack entry.}
+
+\startuseMPgraphic{pow}
+ vardef mypow(expr n) = 3**n enddef ;
+ draw_function(mypow)(-3,3,.5) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{pow}{Calculate x\high{y} where y is the topmost stack entry.}
+
+\startuseMPgraphic{inv}
+ draw_function(inv)(-10,10,1) ; draw_axis ;
+\stopuseMPgraphic
+
+\ShowInfo{inv}{Calculate 1/x using the topmost stack entry.}
+
+\startMPinclusions
+
+ def draw_statistics (expr ShowNew, ShowAdd, ShowSubtract, ShowN, ShowSum, ShowMin, ShowMax, ShowMean, ShowSdev) =
+ color c ; c := \MPcolor{action} ;
+ Delta := 20 ;
+ Total := 100 ;
+ Range := 24 ;
+ Sum := 0 ;
+ Sqr := 0 ;
+ randomseed := .5 ;
+ pickup pencircle scaled .5Delta ;
+ for r := 0 upto Range:
+ Value[r] := 0 ;
+ endfor ;
+ for i=1 upto Total:
+ r := uniformdeviate 1 ;
+ Sum := Sum + r ;
+ Sqr := Sqr + r*r ;
+ r := round(r*Range) ;
+ Value[r] := Value[r]+1 ;
+ endfor ;
+ Mean := Sum/Total ;
+ Sdev := sqrt((Sqr-2*Sum*Mean+Total*Mean*Mean)/Total) ;
+ Mean := Mean*Range ;
+ Sdev := Sdev*Range ;
+ SdevMin := Mean-Sdev ;
+ SdevMax := Mean+Sdev ;
+ for r := 0 upto Range:
+ draw (r*Delta,0)--(r*Delta,Value[r]*Delta)
+ withcolor
+ if (ShowSdev and (r>SdevMin) and (r<SdevMax)) or ShowSum or
+ (ShowMin and (r=0)) or (ShowMax and (r=Range)) or
+ (ShowMean and (r=round(Mean)) or ShowSubtract) :
+ c
+ else :
+ .4white
+ fi ;
+ if ShowN:
+ draw (r*Delta,0) withcolor c
+ fi ;
+ endfor ;
+ if ShowAdd or ShowNew:
+ pushboundingbox currentpicture ;
+ currentpicture := nullpicture ;
+ for r := 0 upto Range:
+ draw (r*Delta,0) withcolor .4white ;
+ endfor ;
+ if ShowAdd:
+ draw (5*Delta,0) withcolor c ;
+ fi ;
+ popboundingbox currentpicture ;
+ elseif ShowSubtract:
+ draw (5*Delta,0) withcolor .4white ;
+ fi ;
+ enddef ;
+
+\stopMPinclusions
+
+\startuseMPgraphic{addn}
+ draw_statistics (false, true, false, false, false, false, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{addn}{Add an observation to the statistics.}
+
+\startuseMPgraphic{subn}
+ draw_statistics (false, false, true, false, false, false, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{subn}{Remove an observation from the statistics.}
+
+\startuseMPgraphic{newn}
+ draw_statistics (true, false, false, false, false, false, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{newn}{Reset the statistics.}
+
+\startuseMPgraphic{sn}
+ draw_statistics (false, false, false, true, false, false, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{sn}{Push the number of observations to the stack.}
+
+\startuseMPgraphic{stotal}
+ draw_statistics (false, false, false, false, true, false, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{stotal}{Push the sum of encountered values to the stack.}
+
+\startuseMPgraphic{smin}
+ draw_statistics (false, false, false, false, false, true, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{smin}{Push the lowest encountered value to the stack.}
+
+\startuseMPgraphic{smax}
+ draw_statistics (false, false, false, false, false, false, true, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{smax}{Push the highest encountered value to the stack.}
+
+\startuseMPgraphic{smean}
+ draw_statistics (false, false, false, false, false, false, false, true, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{smean}{Push the mean value to the stack.}
+
+\startuseMPgraphic{ssdev}
+ draw_statistics (false, false, false, false, false, false, false, false, true) ;
+\stopuseMPgraphic
+
+\ShowInfo{ssdev}{Push the standard deviation to the stack.}
+
+\startMPinclusions
+
+ def draw_ranges (expr ShowNegate, ShowCeiling, ShowFloor, ShowRound, ShowMin, ShowMax, ShowE) =
+
+ color c ; c := \MPcolor{action} ;
+
+ Tics := 5 ;
+ Gap := 5Tics ;
+ Height := .5Gap ;
+ Place := 3 ;
+
+ pickup pencircle scaled 10 ;
+
+ for i=-Tics upto Tics:
+ draw (i*Gap,-Height)--(i*Gap,Height) withcolor .4white ;
+ endfor ;
+
+ draw (-Tics*Gap,0)--(Tics*Gap,0) withcolor .4white ;
+ draw (0,-2Height)--(0,2Height) withcolor .4white ;
+
+ z1 = (Place*Gap,0) ;
+ z2 = ((Place+1)*Gap,0) ;
+
+ if ShowNegate:
+ draw (x1,-Height)--(x1,Height) withcolor c ;
+ draw (-x1,-0)--(-x1,0) withcolor c ;
+ elseif ShowCeiling:
+ draw (x2,-Height)--(x2,Height) withcolor c ;
+ linecap := butt ;
+ draw z1--z2 withcolor c ;
+ elseif ShowFloor:
+ draw (x1,-Height)--(x1,Height) withcolor c ;
+ linecap := butt ;
+ draw z1--z2 withcolor c ;
+ elseif ShowRound:
+ draw (x2,-Height)--(x2,Height) withcolor c ;
+ linecap := butt ;
+ draw .5[z1,z2]--z2 withcolor c ;
+ elseif ShowMin:
+ draw (x1,-Height)--(x1,Height) withcolor c ;
+ draw (x2,0)--(x2,0) withcolor c ;
+ elseif ShowMax:
+ draw (x2,-Height)--(x2,Height) withcolor c ;
+ draw (x1,0)--(x1,0) withcolor c ;
+ elseif ShowE:
+ e := Gap*mexp256 ;
+ draw (e,-3Height)--(e,3Height) withcolor c ;
+ fi ;
+
+enddef ;
+
+\stopMPinclusions
+
+\startuseMPgraphic{neg}
+ draw_ranges (true, false, false, false, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{neg}{Negate the topmost stack entry.}
+
+\startuseMPgraphic{ceil}
+ draw_ranges (false, true, false, false, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{ceil}{Set the topmost stack entry to the next integer.}
+
+\startuseMPgraphic{floor}
+ draw_ranges (false, false, true, false, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{floor}{Set the topmost stack entry to the previous integer.}
+
+\startuseMPgraphic{round}
+ draw_ranges (false, false, false, true, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{round}{Set the topmost stack entry to the nearest integer.}
+
+\startuseMPgraphic{min}
+ draw_ranges (false, false, false, false, true, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{min}{Take the minumum of the two topmost stack entries.}
+
+\startuseMPgraphic{max}
+ draw_ranges (false, false, false, false, false, true, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{max}{Take the maximum of the two topmost stack entries.}
+
+\startuseMPgraphic{e}
+ draw_ranges (false, false, false, false, false, false, true) ;
+\stopuseMPgraphic
+
+\ShowInfo{e}{Push 2.71828182845905 onto the stack.}
+
+\startuseMPgraphic{pi}
+ pickup pencircle scaled 10 ;
+ draw fullcircle scaled 150 withcolor .4white ;
+ linecap := butt ;
+ ahlength := 25 ;
+ drawarrow halfcircle scaled 150 withcolor \MPcolor{action} ;
+\stopuseMPgraphic
+
+\ShowInfo{pi}{Push 3.14159265358979 onto the stack.}
+
+\startMPinclusions
+
+ def draw_degrees(expr DrawInner, DrawOuter) =
+ pickup pencircle scaled .02 ;
+ path p ; p := fullcircle ;
+ path q ; q := subpath(0,1) of fullcircle ;
+ path r ; r := (0,0)--q--(0,0)--cycle ;
+ filldraw p withcolor .4white ;
+ filldraw r withcolor \MPcolor{action} ;
+ ahlength := .04 ;
+ if DrawInner:
+ drawarrow q scaled .30 withcolor .4white ;
+ elseif DrawOuter:
+ drawarrow q scaled .90 withcolor .4white ;
+ fi ;
+ currentpicture := currentpicture scaled 200 ;
+ enddef ;
+
+\stopMPinclusions
+
+\startuseMPgraphic{deg}
+ draw_degrees (true, false)
+\stopuseMPgraphic
+
+\ShowInfo{deg}{Convert radians into degrees.}
+
+\startuseMPgraphic{rad}
+ draw_degrees (false, true)
+\stopuseMPgraphic
+
+\ShowInfo{rad}{Convert degrees into radians.}
+
+\startuseMPgraphic{random}
+
+ pickup pencircle scaled 5 ;
+ color c ; c := \MPcolor{action} ;
+ draw unitsquare scaled 100 withcolor .4white ;
+ for i=1 upto 250:
+ draw (uniformdeviate 90, uniformdeviate 90)
+ shifted (5,5) withcolor (.4+uniformdeviate .6)*c ;
+ endfor ;
+ currentpicture := currentpicture scaled 2 ;
+
+\stopuseMPgraphic
+
+\ShowInfo{random}{Generate a random number in the range 0--1.}
+
+\startMPinclusions
+
+ def do_draw_number (expr n, drift, s, c) =
+ numeric Height, Delta, Drift, x_max, y_max, x_pos, y_pos ;
+ Height := 11 ;
+ Delta := 5 ;
+ Drift := if drift: 1.5 else: 0 fi ;
+ x_max := 8 ;
+ def d = (uniformdeviate Drift) enddef ;
+ if n=0:
+ draw ((-d-4.5Delta,d)--(+d-0.5Delta,Height-d))
+ withpen pencircle scaled 2
+ withcolor c ;
+ else:
+ for i := 1 upto n :
+ x_pos := ((i-1) mod (5*x_max))*Delta ;
+ y_pos := ((i-1) div (5*x_max))*(Height+Delta) ;
+ draw
+ if (i mod 5)=0 :
+ ((-d-4.5Delta,d)--(+d-0.5Delta,Height-d))
+ else :
+ ((-d,+d)--(+d,Height-d))
+ fi
+ shifted (x_pos,-y_pos)
+ withpen pencircle scaled 2
+ withcolor c ;
+ endfor ;
+ fi ;
+ currentpicture := currentpicture scaled s ;
+ enddef ;
+
+ def draw_number (expr n, s) =
+ do_draw_number(n,false,s,\MPcolor{keyboard}) ;
+ push_boundingbox currentpicture ;
+ currentpicture := nullpicture ;
+ do_draw_number(n,true,s,\MPcolor{keyboard}) ;
+ pop_boundingbox currentpicture ;
+ enddef ;
+
+\stopMPinclusions
+
+\dostepwiserecurse {0}{9}{1} {
+ \startuseMPgraphic{\recurselevel}
+ draw_number(\recurselevel,10)
+ \stopuseMPgraphic
+ \expanded {
+ \ShowInfo
+ {\recurselevel}
+ {Add a digit \recurselevel\ to the current stack entry.}%
+ }
+}
+
+\startuseMPgraphic{fac}
+
+ def facultate (expr n) =
+ if n=1: 1 else: n*facultate(n-1) fi
+ enddef ;
+ picture pic[] ;
+ for m := 1 upto 5:
+ do_draw_number(facultate(m),true,1,\MPcolor{action}) ;
+ pic[m] := currentpicture ;
+ currentpicture := nullpicture ;
+ endfor ;
+ xmax := xpart urcorner pic[5] - xpart llcorner pic[5] ;
+ for m = 1 upto 5:
+ xmin := xpart urcorner pic[m] - xpart llcorner pic[m] ;
+ addto currentpicture also pic[m] shifted (.5(xmax-xmin),-m*25) ;
+ endfor ;
+ currentpicture := currentpicture scaled 2 ;
+
+\stopuseMPgraphic
+
+\ShowInfo{fac}{Calculate the recursive multiplication of n, n--1, n--2, etc.}
+
+\startMPinclusions
+
+ def draw_template (expr ShowSign, ShowPeriod, ShowExponent, ShowDel) =
+ pickup pencircle scaled 10 ;
+ color ca ; ca := if (ShowDel): .4white else: \MPcolor{stack} fi ;
+ color cb ; cb := \MPcolor{keyboard} ;
+ Delta := 20 ;
+ Width := 10 ;
+ Position := 6 ;
+ Max := 15 ;
+ path p ; p := (0,0)--(Width,0) ;
+ draw (-2Width,0)--(0,0) withcolor if ShowSign: cb else: ca fi ;
+ for i=1 upto Position-1:
+ draw p shifted (i*Delta,0) withcolor ca ;
+ endfor ;
+ draw (Position*Delta+.5Width,0)
+ withcolor if ShowPeriod: cb else: ca fi ;
+ for i=Position+1 upto Max:
+ if i=Max-3:
+ draw ((Width,0)--(0,0)--(0,2Width)--(Width,2Width))
+ shifted (i*Delta,-2.5)
+ withpen pencircle scaled 5
+ withcolor if ShowExponent: cb else: ca fi ;
+ draw ((0,Width)--(Width,Width))
+ shifted (i*Delta,-2.5)
+ withpen pencircle scaled 5
+ withcolor if ShowExponent: cb else: ca fi ;
+ else:
+ draw p shifted (i*Delta,0) withcolor ca ;
+ fi ;
+ endfor ;
+ enddef ;
+
+\stopMPinclusions
+
+\startuseMPgraphic{sign}
+ draw_template(true, false, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{sign}{Add a sign to the current stack entry.}
+
+\startuseMPgraphic{period}
+ draw_template(false, true, false, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{period}{Add a period to the current stack entry.}
+
+\startuseMPgraphic{E}
+ draw_template(false, false, true, false) ;
+\stopuseMPgraphic
+
+\ShowInfo{E}{Start setting the exponent part of the current stack entry.}
+
+\startuseMPgraphic{del}
+ draw_template(false, false, false, true) ;
+\stopuseMPgraphic
+
+\ShowInfo{del}{Delete the last entered digit of the current stack entry.}
+
+\startMPinclusions
+
+ u := 50 ;
+ logo_type := 0 ;
+ input mp-prag ;
+ set_phead(u) ;
+
+ def draw_memory (expr DrawErase, DrawAdd, DrawSubtract, DrawCopy) =
+ pickup pencircle scaled .1u ;
+ color ca ; ca := \MPcolor{stack} ;
+ color cb ; cb := \MPcolor{keyboard} ;
+ draw phead withcolor .4white ;
+ if DrawErase:
+ stripe_path_n
+ (withcolor .4white)
+ (fill) pbrain scaled .8 shifted (.5u,.5u) withcolor .8cb ;
+ else:
+ fill pbrain scaled .8 shifted (.5u,.5u)
+ if DrawCopy: withcolor .8ca else: withcolor .8cb fi ;
+ fi ;
+ draw pbrain scaled .8 shifted (.5u,.5u) withcolor cb ;
+ push_boundingbox currentpicture ;
+ ahlength:=.2u ;
+ path drain ; drain := (4.5u,2u){dir 120}..(2.25u,2.75u) ;
+ if DrawAdd:
+ drawarrow drain withcolor ca ;
+ elseif DrawSubtract or DrawCopy:
+ drawarrow reverse drain withcolor ca ;
+ fi ;
+ pop_boundingbox currentpicture ;
+ enddef ;
+
+\stopMPinclusions
+
+\startuseMPgraphic{newmem}
+ draw_memory (true,false,false,false) ;
+\stopuseMPgraphic
+
+\ShowInfo{newmem}{Erase the memory buffer.}
+
+\startuseMPgraphic{addmem}
+ draw_memory (false,true,false,false) ;
+\stopuseMPgraphic
+
+\ShowInfo{addmem}{Add to the memory buffer.}
+
+\startuseMPgraphic{submem}
+ draw_memory (false,false,true,false) ;
+\stopuseMPgraphic
+
+\ShowInfo{submem}{Substract from the memory buffer.}
+
+\startuseMPgraphic{copmem}
+ draw_memory (false,false,false,true) ;
+\stopuseMPgraphic
+
+\ShowInfo{copmem}{Copy the memory buffer to the stack.}
+
+\startMPinclusions
+
+ def erase_stack =
+ stripe_path_n
+ (withcolor .4white)
+ (fill) p withcolor .8cb ;
+ enddef ;
+
+ def draw_stack (expr ShowNew, ShowPush, ShowPop, ShowDup) =
+ path p ;
+ color ca ; ca := \MPcolor{stack} ;
+ color cb ; cb := \MPcolor{keyboard} ;
+ for i=8 downto 1:
+ j := i-1 ;
+ pickup pencircle scaled 1.5 ;
+ p := unitsquare
+ shifted(-.5,-.5)
+ xscaled 100 yscaled 40
+ shifted(20*j,j*15)
+ scaled (1-j*.04) ;
+ if i<3:
+ fill p withcolor .4white ;
+ elseif ShowPush:
+ fill p withcolor if i=3: .8cb else : .8ca fi ;
+ elseif ShowPop:
+ if i=3: erase_stack else: fill p withcolor .8ca fi ;
+ elseif ShowNew:
+ erase_stack ;
+ elseif ShowDup:
+ fill p withcolor if i>4: .8ca else: .8cb fi ;
+ else:
+ fill p withcolor .4white ;
+ fi ;
+ draw p withcolor ca ;
+ endfor ;
+ currentpicture := currentpicture scaled 1.5 ;
+ enddef ;
+
+\stopMPinclusions
+
+\startuseMPgraphic{push}
+ draw_stack (false, true, false, false)
+\stopuseMPgraphic
+
+\ShowInfo{push}{Push a new entry to the stack.}
+
+\startuseMPgraphic{pop}
+ draw_stack (false, false, true, false)
+\stopuseMPgraphic
+
+\ShowInfo{pop}{Remove the topmost entry from the stack.}
+
+\startuseMPgraphic{new}
+ draw_stack (true, false, false, false)
+\stopuseMPgraphic
+
+\ShowInfo{new}{Erase the whole stack.}
+
+\startuseMPgraphic{dup}
+ draw_stack (false, false, false, true)
+\stopuseMPgraphic
+
+\ShowInfo{dup}{Duplicate the topmost stack entry.}
+
+\startMPinclusions
+
+ def draw_funcalc (expr p, q, r, action) =
+
+ color b ; b := \MPcolor{keyboard} ;
+ color c ; c := \MPcolor{stack} ;
+
+ draw ((-2.25max(p,q,r))-1,0)--(-1,0) withcolor .4white ;
+
+ pickup pencircle scaled 2 ;
+ for i=1 upto p: draw (-i*2.25, 3.75) withcolor c ; endfor ;
+ for i=1 upto q: draw (-i*2.25, 1.50) withcolor c ; endfor ;
+ for i=1 upto r: draw (-i*2.25,-1.50) withcolor c ; endfor ;
+ pickup pencircle scaled .5 ;
+
+ push_boundingbox currentpicture ;
+
+ pair w ; w := (1.125,0) ;
+ path ww ; ww := -w -- w ;
+
+ if action=1:
+ draw ww shifted w withcolor b ;
+ draw ww rotated 90 shifted w withcolor b ;
+ elseif action=2:
+ draw ww shifted w withcolor b ;
+ elseif action=3:
+ draw ww rotated 45 shifted w withcolor b ;
+ draw ww rotated 135 shifted w withcolor b ;
+ elseif action=4:
+ draw ww rotated 45 shifted w withcolor b ;
+ fi ;
+
+ pop_boundingbox currentpicture ;
+
+ currentpicture := currentpicture scaled 15 ;
+
+ enddef ;
+
+\stopMPinclusions
+
+\startuseMPgraphic{add}
+ draw_funcalc (6, 6, 7, 1)
+\stopuseMPgraphic
+
+\ShowInfo{add}{Add the two topmost stack entries.}
+
+\startuseMPgraphic{sub}
+ draw_funcalc (5, 4, 5, 2)
+\stopuseMPgraphic
+
+\ShowInfo{sub}{Subtract the topmost stack entry from the one below.}
+
+\startuseMPgraphic{mul}
+ draw_funcalc (3, 4, 7, 3)
+\stopuseMPgraphic
+
+\ShowInfo{mul}{Multiply the two topmost stack entries.}
+
+\startuseMPgraphic{div}
+ draw_funcalc (5, 2, 4, 4)
+\stopuseMPgraphic
+
+\ShowInfo{div}{Divide the pre-last stack entry by the topmost one.}
+
+\startuseMPgraphic{grow}
+
+ pickup pencircle scaled 5 ;
+ ahlength := 10 ;
+
+ path p ; p := (0,0)--(60,0) ;
+ path q ; q := (30,2*15)--(30,7*15) ;
+ path r ; r := (30,0)--(30,7*15) ;
+
+ for i=0 upto 7:
+ draw p shifted (0,i*15) withcolor
+ if i<3: \MPcolor{stack} else: .4white fi ;
+ endfor ;
+
+ addto currentpicture also currentpicture
+ rotatedaround (center currentpicture, 180)
+ shifted (90, 0) ;
+
+ drawarrow q withcolor \MPcolor{keyboard} ;
+ drawarrow reverse r shifted (90, 0) withcolor \MPcolor{keyboard} ;
+
+ currentpicture := currentpicture scaled 2 ;
+
+\stopuseMPgraphic
+
+\ShowInfo{grow}{Toggle grow mode, another way of stacking.}
+
+\startuseMPgraphic{exit}
+
+ path p ; p := (100,30)--(100,0)--(0,0)--(0,100)--(100,100)--(100,70) ;
+ pickup pencircle scaled 10 ;
+ linecap := butt ;
+ ahlength := 60 ;
+ ahangle := 75 ;
+ filldraw
+ p--cycle
+ withcolor \MPcolor{action} ;
+ draw
+ p
+ withcolor \MPcolor{stack} ;
+ push_boundingbox currentpicture ;
+ pickup pencircle scaled 30 ;
+ draw
+ center currentpicture --
+ (xpart lrcorner currentpicture+.75ahlength, ypart center currentpicture)
+ withcolor \MPcolor{keyboard} ;
+ pickup pencircle scaled 5 ;
+ drawarrow
+ center currentpicture --
+ (xpart lrcorner currentpicture, ypart center currentpicture)
+ withcolor \MPcolor{keyboard} ;
+ pop_boundingbox currentpicture ;
+ currentpicture := currentpicture scaled 1.75 ;
+
+\stopuseMPgraphic
+
+\ShowInfo{exit}{Close this document.}
+
+\stoptext
diff --git a/doc/context/examples/clock/clock.pdf b/doc/context/examples/clock/clock.pdf
new file mode 100644
index 000000000..9ce83b407
--- /dev/null
+++ b/doc/context/examples/clock/clock.pdf
Binary files differ
diff --git a/doc/context/examples/clock/clock.tex b/doc/context/examples/clock/clock.tex
new file mode 100644
index 000000000..6b70de585
--- /dev/null
+++ b/doc/context/examples/clock/clock.tex
@@ -0,0 +1,156 @@
+%D This example dates from late 2001, and ws probaby made for some \TEX\ related
+%D meeting. It's a relative simple example that uses a few function from a general
+%D \JAVASCRIPT\ preamble. In fact forcing the \type {FieldStack} code into the
+%D is the only adaptation from \MKII\ to \MKIV\ (because we load on demand and here
+%D the code is ude sindirectly).
+%D
+%D Nowadays we could layers instead which is probably a bit more ligthweight than
+%D widgets. Also, we should actually synchronize the time but on the other hand, but
+%D on the other hand, now it's a sort of stopwatch.
+
+% \nopdfcompression
+
+\starttext
+
+\useJSscripts[fld]
+
+\useJSpreamble[FieldStack]
+
+\definepapersize
+ [clock]
+ [width=2.5cm,
+ height=2.5cm]
+
+\setuppapersize
+ [clock][clock]
+
+\setuplayout
+ [header=0pt,
+ footer=0pt,
+ backspace=.25cm,
+ topspace=.25cm,
+ width=middle,
+ height=middle]
+
+\startJSpreamble stepper used now
+
+ var state = 0 ;
+ var more = 0 ;
+ var step = 0 ;
+
+ function step_clock() {
+ try {
+ if (more == 60) {
+ more = 0 ;
+ Walk_Field("more") ;
+ } else {
+ }
+ more += 1 ;
+ Walk_Field("clock") ;
+ this.dirty = false ;
+ } catch (e) {
+ }
+ }
+
+ function start_clock() {
+ try {
+ if (state == 0) {
+ step = app.setInterval ("step_clock()", 1000) ;
+ step.count = 0 ;
+ state = 1 ;
+ } else if (state == 1) {
+ app.clearInterval (step) ;
+ state = 2 ;
+ } else if (state == 2) {
+ app.clearInterval (step) ;
+ Reset_Fields("more") ;
+ Reset_Fields("clock") ;
+ Set_Field("more", "1") ;
+ Set_Field("clock", "1") ;
+ more = 0 ;
+ state = 0 ;
+ }
+ } catch(e) {
+ }
+ }
+
+ function stop_clock () {
+ try {
+ app.clearInterval(step) ;
+ } catch(e) {
+ }
+ }
+
+\stopJSpreamble
+
+\definereference[StopClock] [JS(stop_clock)]
+\definereference[StartClock][JS(start_clock)]
+
+\setupinteraction
+ [state=start,
+ closeaction={StopClock,ForgetChanges},
+ closepageaction={StopClock}]
+
+\startreusableMPgraphic{common}
+ drawoptions(withpen pencircle scaled 1mm withcolor .4white) ;
+ fill fullsquare scaled 2.5cm ;
+ drawoptions(withpen pencircle scaled 1mm withcolor .6green) ;
+ draw fullsquare scaled 2.5cm ;
+ drawoptions(withpen pencircle scaled 1mm withcolor .6red) ;
+ draw fullcircle scaled 2cm ;
+ drawoptions(withpen pencircle scaled 2mm withcolor .6yellow) ;
+ for i=1 upto 12 :
+ draw (0,1cm) rotated ((i-1)*(360/12)) ;
+ endfor ;
+\stopreusableMPgraphic
+
+\startuseMPgraphic{clock}
+ numeric stp ; stp := (\MPvar{n}-1)*(360/60) ;
+ pair p ; p := (0,\MPvar{l}-.5mm) ;
+ drawoptions(withpen pencircle scaled 1mm withcolor .6\MPvar{c}) ;
+ draw (origin -- p) rotated -stp ;
+ draw (p shifted (-2mm,-2.5mm)--p--p shifted (2mm,-2.5mm)) rotated -stp ;
+ setbounds currentpicture to fullsquare scaled 2cm ;
+ drawoptions(withpen pencircle scaled 2mm withcolor .6white) ;
+ draw origin ;
+\stopuseMPgraphic
+
+\defineoverlay [common] [\reuseMPgraphic{common}]
+\defineoverlay [start] [\overlaybutton{StartClock}]
+
+\setupbackgrounds
+ [page]
+ [background={common,start}]
+
+\let\clocklist\empty
+\let\morelist \empty
+
+\dorecurse {60} {
+ \appendtocommalist{step:#1}\clocklist
+ \definesymbol
+ [step:#1]
+ [\useMPgraphic{clock}{n=#1,l=1cm,c=blue}]
+ \appendtocommalist{more:#1}\morelist
+ \definesymbol
+ [more:#1]
+ [\useMPgraphic{clock}{n=#1,l=.75cm,c=green}]
+}
+
+\definefieldstack
+ [clock]
+ [\clocklist]
+ [width=2cm,height=2cm,offset=overlay,frame=off]
+
+\definefieldstack
+ [more]
+ [\morelist]
+ [width=2cm,height=2cm,offset=overlay,frame=off]
+
+\starttext
+
+ \startoverlay
+ {\fieldstack[more]}
+ {\fieldstack[clock]}
+ \stopoverlay
+
+\stoptext
diff --git a/doc/context/presentations/bachotex/2005/bachotex-2005-fonts.tex b/doc/context/presentations/bachotex/2005/bachotex-2005-fonts.tex
new file mode 100644
index 000000000..930316939
--- /dev/null
+++ b/doc/context/presentations/bachotex/2005/bachotex-2005-fonts.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext % see cld-dante
diff --git a/doc/context/presentations/bachotex/2005/bachotex-2005-hyphenation.tex b/doc/context/presentations/bachotex/2005/bachotex-2005-hyphenation.tex
new file mode 100644
index 000000000..930316939
--- /dev/null
+++ b/doc/context/presentations/bachotex/2005/bachotex-2005-hyphenation.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext % see cld-dante
diff --git a/doc/context/presentations/bachotex/2009/bachotex-2009-luatex.tex b/doc/context/presentations/bachotex/2009/bachotex-2009-luatex.tex
new file mode 100644
index 000000000..930316939
--- /dev/null
+++ b/doc/context/presentations/bachotex/2009/bachotex-2009-luatex.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext % see cld-dante
diff --git a/doc/context/presentations/bachotex/2009/bachotex-2009-math.tex b/doc/context/presentations/bachotex/2009/bachotex-2009-math.tex
new file mode 100644
index 000000000..930316939
--- /dev/null
+++ b/doc/context/presentations/bachotex/2009/bachotex-2009-math.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext % see cld-dante
diff --git a/doc/context/presentations/bachotex/2009/bachotex-2009-opentype.tex b/doc/context/presentations/bachotex/2009/bachotex-2009-opentype.tex
new file mode 100644
index 000000000..930316939
--- /dev/null
+++ b/doc/context/presentations/bachotex/2009/bachotex-2009-opentype.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext % see cld-dante
diff --git a/doc/context/presentations/bachotex/2011/bachotex-2011-ebook.tex b/doc/context/presentations/bachotex/2011/bachotex-2011-ebook.tex
new file mode 100644
index 000000000..930316939
--- /dev/null
+++ b/doc/context/presentations/bachotex/2011/bachotex-2011-ebook.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext % see cld-dante
diff --git a/doc/context/presentations/bachotex/2011/bachotex-2011-math.tex b/doc/context/presentations/bachotex/2011/bachotex-2011-math.tex
new file mode 100644
index 000000000..930316939
--- /dev/null
+++ b/doc/context/presentations/bachotex/2011/bachotex-2011-math.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext % see cld-dante
diff --git a/doc/context/presentations/bachotex/2011/bachotex-2011-metapost.tex b/doc/context/presentations/bachotex/2011/bachotex-2011-metapost.tex
new file mode 100644
index 000000000..930316939
--- /dev/null
+++ b/doc/context/presentations/bachotex/2011/bachotex-2011-metapost.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext % see cld-dante
diff --git a/doc/context/presentations/bachotex/2012/bachotex-2012-context.tex b/doc/context/presentations/bachotex/2012/bachotex-2012-context.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/bachotex/2012/bachotex-2012-context.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/bachotex/2012/bachotex-2012-future.tex b/doc/context/presentations/bachotex/2012/bachotex-2012-future.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/bachotex/2012/bachotex-2012-future.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/bachotex/2014/bachotex-2014-luatex.tex b/doc/context/presentations/bachotex/2014/bachotex-2014-luatex.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/bachotex/2014/bachotex-2014-luatex.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/bachotex/2014/bachotex-2014-metapost.tex b/doc/context/presentations/bachotex/2014/bachotex-2014-metapost.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/bachotex/2014/bachotex-2014-metapost.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/bachotex/2018/bachotex-2018-fonteffects.pdf b/doc/context/presentations/bachotex/2018/bachotex-2018-fonteffects.pdf
new file mode 100644
index 000000000..eb9abd07a
--- /dev/null
+++ b/doc/context/presentations/bachotex/2018/bachotex-2018-fonteffects.pdf
Binary files differ
diff --git a/doc/context/presentations/bachotex/2018/bachotex-2018-fonteffects.tex b/doc/context/presentations/bachotex/2018/bachotex-2018-fonteffects.tex
new file mode 100644
index 000000000..330fc3340
--- /dev/null
+++ b/doc/context/presentations/bachotex/2018/bachotex-2018-fonteffects.tex
@@ -0,0 +1,912 @@
+% language=uk
+
+\definecolor[red] [r=.6]
+\definecolor[green] [g=.6]
+\definecolor[blue] [b=.6]
+
+\definecolor[cyan] [g=.6,b=.6]
+\definecolor[magenta][r=.6,b=.6]
+\definecolor[yellow] [r=.6,g=.6]
+
+\usemodule[abbreviations-smallcaps]
+\usemodule[scite]
+\usemodule[scite]
+
+\setuptyping[option=TEX]
+\setuptype[option=TEX]
+
+\dontcomplain
+
+\usebodyfont [modern]
+\usebodyfont[pagella]
+\usebodyfont [dejavu]
+
+\setuppapersize[S6]
+
+\definebodyfontenvironment[24pt]
+
+\definecolor[maincolor][r=.6]
+\definecolor[maintrans][r=.6,t=.5,a=1]
+\definecolor[moretrans][g=.6,t=.5,a=1]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ margin=0cm,
+ header=0cm,
+ footer=0cm,
+ topspace=1cm,
+ bottomspace=1cm,
+ backspace=1cm]
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=darkgray]
+
+\setupbackgrounds
+ [text][text]
+ [background=color,
+ backgroundoffset=5mm,
+ backgroundcolor=middlegray]
+
+\definefontfeature[bbox][boundingbox=frame]
+
+\definefont
+ [LargeFont]
+ [SansBold*default,boldened-20,bbox @ 40pt]
+
+\definefont
+ [SmallFont]
+ [SansBold*default,boldened-20 @ 20pt]
+
+\definefont
+ [HeadFont]
+ [SansBold*default,boldened-30 @ 30pt]
+
+\setupbodyfont
+ [modernlatin,14.4pt]
+
+\setuphead
+ [title]
+ [style=\HeadFont,
+ color=maincolor,
+ align=middle]
+
+\definefontsynonym[BenchMark][lmroman10regular]
+
+\starttext
+
+\startstandardmakeup[footerstate=start]
+ \LargeFont \maincolor \setupalign[middle]
+ \vfil
+ \dontleavehmode\scale[width=.6\textwidth]{\setstrut\strut Modern}
+ \vfil
+ \dontleavehmode\scale[width=.8\textwidth]{\setstrut\strut Latin}
+ \vfil
+ \vfil
+ \SmallFont \darkgray Bacho\TeX\ 2018\enspace\emdash\enspace Hans Hagen
+\stopstandardmakeup
+
+\starttitle[title=Why oh why]
+
+\startitemize
+\startitem
+ In \CONTEXT\ we have a mechanism to apply effects to a glyph stream.
+\stopitem
+\startitem
+ An active user on the \CONTEXT\ mailing list wondered if that could be
+ applied to specific fonts.
+\stopitem
+\startitem
+ The particular interest concerned the possibility to bolden fonts.
+\stopitem
+\startitem
+ I don't really like effects and not all fonts are suitable for it.
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=What are effects]
+
+Normal effects are implemented using the \quote {effects} mechanism, which
+already dates way back in \MKII\ times and of course is also available for
+\MKIV.
+
+\defineeffect [inner] [alternative=inner,rulethickness=1.25pt]
+\defineeffect [outer] [alternative=outer,rulethickness=1.25pt]
+\defineeffect [both] [alternative=both, rulethickness=1.25pt]
+\defineeffect [normal] [alternative=normal]
+
+\starttyping
+\defineeffect
+ [outer]
+ [alternative=outer,
+ rulethickness=1.25pt]
+
+effect \starteffect[outer]effect\stopeffect
+\stoptyping
+
+\startlinecorrection
+
+ \definefont[DemoFont][BenchMark*default @ 70pt]
+
+ \scale[width=\textwidth]{\startcombination[3*2]
+ {\DemoFont\setstrut\strut\starteffect [inner]effect\stopeffect}
+ {\startoverlay
+ {\DemoFont\setstrut\strut\maintrans \starteffect[inner]effect\stopeffect}
+ {\DemoFont\setstrut\strut\moretrans effect}
+ \stopoverlay}
+ {\DemoFont\setstrut\strut\starteffect [outer]effect\stopeffect}
+ {\startoverlay
+ {\DemoFont\setstrut\strut\maintrans \starteffect[outer]effect\stopeffect}
+ {\DemoFont\setstrut\strut\moretrans effect}
+ \stopoverlay}
+ {\DemoFont\setstrut\strut\starteffect [both]effect\stopeffect}
+ {\startoverlay
+ {\DemoFont\setstrut\strut\maintrans \starteffect [both]effect\stopeffect}
+ {\DemoFont\setstrut\strut\moretrans effect}
+ \stopoverlay}
+ {\startoverlay
+ {\DemoFont\setstrut\strut\moretrans effect}
+ {\DemoFont\setstrut\strut\maintrans \starteffect[inner]effect\stopeffect}
+ \stopoverlay}
+ {\tttf inner}
+ {\startoverlay
+ {\DemoFont\setstrut\strut\moretrans effect}
+ {\DemoFont\setstrut\strut\maintrans \starteffect[outer]effect\stopeffect}
+ \stopoverlay}
+ {\tttf outer}
+ {\startoverlay
+ {\DemoFont\setstrut\strut\moretrans effect}
+ {\DemoFont\setstrut\strut\maintrans \starteffect [both]effect\stopeffect}
+ \stopoverlay}
+ {\tttf both}
+ \stopcombination}
+
+\stoplinecorrection
+
+\stoptitle
+
+\starttitle[title=How tricky is this]
+
+\startitemize
+\startitem
+ Of course the only way to deal with this nicely is by using runtime created
+ virtual fonts.
+\stopitem
+\startitem
+ So called \PDF\ literals can interfere badly with font switches at the \PDF\
+ level and are therefore very inefficient.
+\stopitem
+\startitem
+ In order to properly support effects at the font level, we need to be able to
+ inject the right \PDF\ code in a more clever way.
+\stopitem
+\startitem
+ Two new keys were added to the font file definition table: \type{width} and
+ \type {mode}. When set these inject a \PDF\ line width operation and trigger the
+ right rendering mode (backend).
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=What interface do we need]
+
+\startbuffer
+\definefontfeature[effect-1][effect={width=0.8}]
+\definefontfeature[bbox] [boundingbox=frame]
+
+\definefont
+ [EffectiveFont]
+ [BenchMark*default,effect-1,bbox @ 12pt]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[2*big]
+\scale[width=\textwidth]{\backgroundline[maincolor]{\EffectiveFont effective}}
+\stoplinecorrection
+
+\page
+
+\startbuffer
+\definefontfeature[effect-2][effect={width=1.1,wdelta=1.20}]
+\definefontfeature[effect-3][effect={width=1.1,wdelta=1.80}]
+
+\definefont
+ [EffectiveFontA]
+ [BenchMark*default,effect-2 @ 12pt]
+
+\definefont
+ [EffectiveFontB]
+ [BenchMark*default,effect-3 @ 12pt]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\scale[width=\textwidth]{\darkgray\showglyphs \EffectiveFontA effect \EffectiveFontB effect}
+
+\stoptitle
+
+\starttitle[title=Can we do better]
+
+\startitemize
+\startitem
+ This is still not good enough so next came playing with extended shapes. This is an
+ old feature inherited from \POSTSCRIPT\ times and \PDFTEX.
+\stopitem
+\startitem
+ The \LUATEX\ backend is very efficient with this kind of trickery and combines
+ it with font scaling.
+\stopitem
+\startitem
+ It was trivial to add a similar scaling in the vertical direction.
+\stopitem
+\stopitemize
+
+\page
+
+\startbuffer
+\definefontfeature[effect-4]
+ [effect={width=0.5,wdelta=1.5}]
+
+\definefontfeature[effect-5]
+ [effect={width=0.5,wdelta=1.5,extend=1.2}]
+
+\definefont
+ [EffectiveFontA]
+ [BenchMark*default,effect-4 @ 12pt]
+
+\definefont
+ [EffectiveFontB]
+ [BenchMark*default,effect-5 @ 12pt]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[2*big]
+\scale[width=\textwidth]{\darkgray\showglyphs \EffectiveFontA effect \EffectiveFontB effect}
+\stoplinecorrection
+
+\page
+
+\startbuffer
+\definefontfeature[effect-6]
+ [effect={width=0.5,wdelta=1.50}]
+
+\definefontfeature[effect-7]
+ [effect={width=0.5,wdelta=1.50,squeeze=1.2}]
+
+\definefont
+ [EffectiveFontA]
+ [BenchMark*default,effect-6 @ 12pt]
+
+\definefont
+ [EffectiveFontB]
+ [BenchMark*default,effect-7 @ 12pt]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection[2*big]
+\scale[width=\textwidth]{\darkgray\showglyphs \EffectiveFontA effect \EffectiveFontB effect}
+\stoplinecorrection
+
+\stoptitle
+
+\starttitle[title=How about math]
+
+\startitemize
+\startitem
+ I never really needed this kind of trickery but it might be handy for
+ bold math in titles.
+\stopitem
+\startitem
+ But math is kind of special as it has extensibles, uses rules and is controlled
+ by math parameters.
+\stopitem
+\startitem
+ Math parameters are global for a formula so that doesn't work out well for mixed
+ families using fonts with different design parameters.
+\stopitem
+\stopitemize
+
+\page
+
+\starttyping
+\switchtobodyfont[modern]
+
+$\sqrt{\frac{\frac{1}{a}}{\frac{2}{b}}}$
+
+\switchtobodyfont[modernlatin]
+
+$\mr \sqrt{\frac{\frac{1}{a}}{\frac{2}{b}}}$
+$\mb \sqrt{\frac{\frac{1}{a}}{\frac{2}{b}}}$
+\stoptyping
+
+\startlinecorrection
+\startcombination[3*1]
+ {\maincolor\switchtobodyfont [modern]\scale[height=.25\textwidth]{$\sqrt{\frac{\frac{1}{a}}{\frac{2}{b}}}$}} {\tttf latinmodern}
+ {\maincolor\switchtobodyfont[modernlatin]\scale[height=.25\textwidth]{$\sqrt{\frac{\frac{1}{a}}{\frac{2}{b}}}$}} {\tttf modernlatin}
+ {\maincolor\switchtobodyfont[modernlatin]\scale[height=.25\textwidth]{$\sqrt{\frac{\frac{1}{a}}{\frac{2}{b}}}$}} {\tttf modernlatin}
+\stopcombination
+\stoplinecorrection
+
+\stoptitle
+
+\starttitle[title=Is it useful]
+
+\startitemize
+\startitem
+ \start \definedfont[BenchMark*default]%
+ For reading on a different medium than paper a bit bolder font often
+ works better. This is a normal Latin Modern.\stop
+\stopitem
+\startitem
+ Here we use the \type {modernlatin} For reading on a different medium than
+ paper a bit bolder font often works better.
+\stopitem
+\startitem
+ In my opinion a slightly bolder Latin Modern looks a bit more modern, but
+ that's of course just an opinion.
+\stopitem
+\startitem
+ I'm not sure if and when I will use this new trickery; maybe to compensate the
+ lack of bold math fonts.
+\stopitem
+\startitem
+ Performance wise there is no penalty. File don't get larger. Rendering seems to
+ be somewhat slower.
+\stopitem
+\startitem
+ In the end it's probably just another example of feature creep or \TEX\ hobbyism.
+\stopitem
+\stopitemize
+
+\stoptitle
+
+\starttitle[title=Kerning]
+
+\startMPinclusions
+ def SampleShapes(expr dx, offset, pw, k) =
+ picture p ; p := image (
+ draw fullcircle scaled 1cm withcolor "maincolor" ;
+ draw fullsquare scaled 1cm shifted (dx+k,0) withcolor "maincolor" ;
+ draw point 8 of (fullcircle scaled 1cm) withcolor white ;
+ draw point 3.5 of (fullsquare scaled 1cm) shifted (dx+k,0) withcolor white ;
+ ) shifted (offset,0) ;
+ draw p withpen pencircle scaled pw ;
+ draw boundingbox p withcolor white ;
+ enddef ;
+\stopMPinclusions
+
+\startitemize
+\startitem
+ To what extent do we need to compensate dimensions in order to get the kerning
+ acceptable.
+\stopitem
+\startitem
+ Messing around with font features is fragile because there is not much consistency in
+ how these are organized.
+\stopitem
+\stopitemize
+
+\startlinecorrection[2*big]
+\startMPcode
+ SampleShapes(15mm, 0mm,1mm,0mm) ;
+ SampleShapes(15mm, 40mm,2mm,0mm) ;
+ SampleShapes(17mm, 80mm,2mm,0mm) ;
+\stopMPcode
+\stoplinecorrection
+
+\startlinecorrection[2*big]
+\startMPcode
+ SampleShapes(15mm, 0mm,1mm,0mm) ;
+ SampleShapes(15mm, 40mm,2mm,2mm) ;
+ SampleShapes(17mm, 80mm,2mm,2mm) ;
+\stopMPcode
+\stoplinecorrection
+
+\startlinecorrection[2*big]
+\startMPcode
+ SampleShapes(10mm, 0mm,1mm,0mm) ;
+ SampleShapes(10mm, 40mm,1mm,1mm) ;
+ SampleShapes(10mm, 80mm,2mm,0mm) ;
+ SampleShapes(10mm,120mm,2mm,2mm) ;
+\stopMPcode
+\stoplinecorrection
+
+\stoptitle
+
+\starttitle[title=Ligatures]
+
+\definefontfeature
+ [demo-1]
+ [default]
+ [hlig=yes]
+
+\definefontfeature
+ [demo-2]
+ [demo-1]
+ [effect=0.5]
+
+\startitemize
+\startitem
+ Ligatures are even less predictable so this is why we cannot apply too much
+ effect.
+\stopitem
+\startitem
+ There can be artifacts due to the way characters are combined (like in Latin
+ Modern).
+\stopitem
+\stopitemize
+
+\startlinecorrection
+\startcombination[1*3]
+ { \scale [width=.8\textwidth] {
+ \definedfont[texgyrepagellaregular*demo-1]fist effe
+ \par
+ \definedfont[texgyrepagellaregular*demo-2]fist effe
+ } } {
+ \tttf \maincolor texgyre pagella regular
+ } { \scale [width=.8\textwidth] {
+ \definedfont[cambria*demo-1]fist effe
+ \par
+ \definedfont[cambria*demo-2]fist effe
+ } } {
+ \tttf \maincolor cambria
+ } { \scale [width=.8\textwidth] {
+ \definedfont[ebgaramond12regular*demo-1]fist effe
+ \par
+ \definedfont[ebgaramond12regular*demo-2]fist effe
+ } } {
+ \tttf \maincolor ebgaramond 12 regular
+ }
+\stopcombination
+\stoplinecorrection
+
+\stoptitle
+
+\starttitle[title=Finetuning]
+
+\startbuffer
+\definefontfeature[lm-bald]
+ [effect={width=0.25,effect=both}]
+\definefontfeature[pg-bald]
+ [effect={width=0.25,effect=both}]
+\definefontfeature[dj-bald]
+ [effect={width=0.35,effect=both}]
+
+\definefontfeature[lm-bold]
+ [effect={width=0.25,hdelta=0,ddelta=0,effect=both,
+ extend=1.10}]
+
+\definefontfeature[pg-bold]
+ [effect={width=0.25,hdelta=0,ddelta=0,effect=both,
+ extend=1.00}]
+
+\definefontfeature[dj-bold]
+ [effect={width=0.35,hdelta=0,ddelta=0,effect=both,
+ extend=1.05}]
+\stopbuffer
+
+\definefont[lmbald][Serif*default,lm-bald sa d]
+\definefont[pgbald][Serif*default,pg-bald sa d]
+\definefont[djbald][Serif*default,dj-bald sa d]
+
+\definefont[lmbold][Serif*default,lm-bold sa d]
+\definefont[pgbold][Serif*default,pg-bold sa d]
+\definefont[djbold][Serif*default,dj-bold sa d]
+
+\typebuffer \getbuffer
+
+\page
+
+\starttabulate[|l|l|l|l|]
+\NC
+ \NC
+ \tt \maincolor modern \NC
+ \tt \maincolor pagella \NC
+ \tt \maincolor dejavu \NC
+\NR
+\NC
+ \maincolor \type{\tfd} \NC
+ \switchtobodyfont [modern,24pt]\strut\ruledhbox{\tfd ABC}\NC
+ \switchtobodyfont[pagella,24pt]\strut\ruledhbox{\tfd ABC}\NC
+ \switchtobodyfont [dejavu,24pt]\strut\ruledhbox{\tfd ABC}\NC
+\NR
+\NC
+ \maincolor \type{\..bald} \NC
+ \switchtobodyfont [modern,24pt]\strut\ruledhbox{\lmbald ABC}\NC
+ \switchtobodyfont[pagella,24pt]\strut\ruledhbox{\pgbald ABC}\NC
+ \switchtobodyfont [dejavu,24pt]\strut\ruledhbox{\djbald ABC}\NC
+\NR
+\NC
+ \maincolor \type{\bfd} \NC
+ \switchtobodyfont [modern,24pt]\strut\ruledhbox{\bfd ABC}\NC
+ \switchtobodyfont[pagella,24pt]\strut\ruledhbox{\bfd ABC}\NC
+ \switchtobodyfont [dejavu,24pt]\strut\ruledhbox{\bfd ABC}\NC
+\NR
+\NC
+ \maincolor \type{\..bold} \NC
+ \switchtobodyfont [modern,24pt]\strut\ruledhbox{\lmbold ABC}\NC
+ \switchtobodyfont[pagella,24pt]\strut\ruledhbox{\pgbold ABC}\NC
+ \switchtobodyfont [dejavu,24pt]\strut\ruledhbox{\djbold ABC}\NC
+\NR
+\stoptabulate
+
+\stoptitle
+
+\starttitle[title=Pagella]
+
+\startbuffer
+\definefontfeature
+ [pg-fake-1]
+ [effect={width=0.25,effect=both}]
+
+\definefontfeature
+ [pg-fake-2]
+ [effect={width=0.25,hdelta=0,ddelta=0,effect=both}]
+
+\definefont[pgregular] [Serif*default]
+\definefont[pgbold] [SerifBold*default]
+\definefont[pgfakebolda][Serif*default,pg-fake-1]
+\definefont[pgfakeboldb][Serif*default,pg-fake-2]
+
+\definecolor[color-pgregular] [t=.5,a=1,r=.6]
+\definecolor[color-pgbold] [t=.5,a=1,g=.6]
+\definecolor[color-pgfakebolda][t=.5,a=1,b=.6]
+\definecolor[color-pgfakeboldb][t=.5,a=1,r=.6,g=.6]
+\stopbuffer
+
+\typebuffer
+
+\page
+
+\startbuffer[sample]
+
+\start \switchtobodyfont[pagella] \getbuffer
+
+\startcombination[2*2]
+ {
+ \scale [width=\measure{combination}] {
+ \ruledhbox{\showglyphs\pgregular \SampleWord}
+ }
+ } {
+ regular
+ } {
+ \scale [width=\measure{combination}] {
+ \ruledhbox{\showglyphs\pgbold \SampleWord}
+ }
+ } {
+ bold
+ } {
+ \scale [width=\measure{combination}] {
+ \ruledhbox{\showglyphs\pgfakebolda \SampleWord}
+ }
+ } {
+ fakebolda
+ } {
+ \scale [width=\measure{combination}] {
+ \ruledhbox{\showglyphs\pgfakeboldb \SampleWord}
+ }
+ } {
+ fakeboldb
+ }
+\stopcombination
+
+\stop
+
+\page
+
+\start \switchtobodyfont[pagella] \getbuffer
+
+\startcombination[2*3]
+ {
+ \scale [width=.35\textwidth] {
+ \startoverlay
+ {\color[color-pgregular] {\pgregular \SampleWord}}
+ {\color[color-pgbold] {\pgbold \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ bold over regular
+ } {
+ \scale [width=.35\textwidth] {
+ \startoverlay
+ {\color[color-pgregular] {\pgregular \SampleWord}}
+ {\color[color-pgfakeboldb]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ fakebolda over regular
+ } {
+ \scale [width=.35\textwidth] {
+ \startoverlay
+ {\color[color-pgregular] {\pgregular \SampleWord}}
+ {\color[color-pgfakebolda]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ fakeboldb over regular
+ } {
+ \scale [width=.35\textwidth] {
+ \startoverlay
+ {\color[color-pgbold] {\pgbold \SampleWord}}
+ {\color[color-pgfakeboldb]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ fakeboldb over bold
+ } {
+ \scale [width=.35\textwidth] {
+ \startoverlay
+ {\color[color-pgfakebolda]{\pgfakebolda \SampleWord}}
+ {\color[color-pgfakeboldb]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ fakeboldb over fakebolda
+ } {
+ \scale [width=.35\textwidth] {
+ \startoverlay
+ {\color[color-pgregular] {\pgregular \SampleWord}}
+ {\color[color-pgbold] {\pgbold \SampleWord}}
+ {\color[color-pgfakebolda]{\pgfakebolda \SampleWord}}
+ {\color[color-pgfakeboldb]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ all four overlayed
+ }
+\stopcombination
+
+\stop
+
+\stopbuffer
+
+\def\SampleWord{\^o\"ep\c s} \getbuffer[sample]
+\def\SampleWord{London Grammar} \getbuffer[sample]
+
+\stoptitle
+
+\starttitle[title=Arabic]
+
+\startbuffer
+\definefontfeature
+ [bolden-arabic-1]
+ [effect={width=0.4}]
+
+\definefontfeature
+ [bolden-arabic-2]
+ [effect={width=0.4,effect=outer}]
+
+\definefontfeature
+ [bolden-arabic-3]
+ [effect={width=0.5,wdelta=0.5,ddelta=.2,hdelta=.2,factor=.1}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+
+\setupalign
+ [righttoleft]
+
+\setupinterlinespace
+ [1.5]
+
+\start
+ \definedfont[arabictest*arabic,bolden-arabic-1 @ 30pt]
+ \samplefile{khatt-ar}\blank
+ \definedfont[arabictest*arabic,bolden-arabic-2 @ 30pt]
+ \samplefile{khatt-ar}\blank
+ \definedfont[arabictest*arabic,bolden-arabic-3 @ 30pt]
+ \samplefile{khatt-ar}\blank
+\stop
+\stopbuffer
+
+\page \start \definefontsynonym[arabictest][arabtype] \getbuffer\stop
+
+\page \start \definefontsynonym[arabictest][husayni] \getbuffer\stop
+
+\stoptitle
+
+\starttitle[title=Marks and cursive]
+
+\startitemize
+\startitem
+ Marks are tricky because they can be anchored at any location and we can
+ only guess what should be done.
+\stopitem
+\startitem
+ Cursive connections still need to connect and we don't know in advance
+ how shapes overlap.
+\stopitem
+\stopitemize
+
+\startMPinclusions
+ def DrawShapes(expr how) =
+ def SampleShapes(expr offset, pw, xc, xs, xt, yc, ys, yt, txt, more) =
+ numeric l ; l := pw * mm ;
+ picture p ; p := image (
+ draw fullcircle scaled 10 ;
+ draw fullcircle scaled 3 shifted (-3+xc ,8+yc) withcolor "darkred" ;
+ draw fullsquare scaled 3 shifted ( 6+xs ,7+ys) withcolor "darkblue";
+ draw fulltriangle scaled 4 shifted ( 6+xt+5,6+yt) withcolor "darkgreen";
+ ) shifted (offset,0) scaled mm ;
+ draw p
+ withpen pencircle
+ if how = 2 :
+ xscaled l yscaled (l/2) rotated 30 ;
+ else :
+ scaled l ;
+ fi ;
+ draw boundingbox p
+ withcolor "darkyellow" ;
+ draw textext(txt)
+ shifted (xpart center p, -8mm) ;
+ draw textext(more)
+ shifted (xpart center p, -11mm) ;
+ enddef ;
+ SampleShapes( 0,1, 0,0,0, 0, 0, 0, "\tinyfont \setstrut \strut original", "\tinyfont \setstrut \strut ") ;
+ SampleShapes( 25,2, 0,0,0, 0, 0, 0, "\tinyfont \setstrut \strut instance", "\tinyfont \setstrut \strut ") ;
+ SampleShapes( 50,2,-1,1,0, 0, 0, 0, "\tinyfont \setstrut \strut mark", "\tinyfont \setstrut \strut x only") ;
+ SampleShapes( 75,2,-1,1,1, 0, 0, 0, "\tinyfont \setstrut \strut mark + mkmk","\tinyfont \setstrut \strut x only") ;
+ SampleShapes(100,2,-1,1,1, 1, 1, 1, "\tinyfont \setstrut \strut mark + mkmk","\tinyfont \setstrut \strut x and y") ;
+ SampleShapes(125,2,-1,2,2,-1/2,-1/2,-1/2,"\tinyfont \setstrut \strut mark + mkmk","\tinyfont \setstrut \strut x and -y") ;
+ enddef ;
+\stopMPinclusions
+
+\startlinecorrection[2*big]
+\scale
+ [width=\textwidth]
+ {\startMPcode DrawShapes(1) ; \stopMPcode}
+\stoplinecorrection
+
+\startlinecorrection[2*big]
+\scale
+ [width=\textwidth]
+ {\startMPcode DrawShapes(2) ; \stopMPcode}
+\stoplinecorrection
+
+\stoptitle
+
+\starttitle[title=Radicals and such]
+
+Radicals are constructed using rules and extensible characters. Especially the rules
+need to be adapted.
+
+\startbuffer[mathblob]
+\def\MathSample
+ {2\times\sqrt{\frac{\sqrt{\frac{\sqrt{2}}{\sqrt{2}}}}
+ {\sqrt{\frac{\sqrt{2}}{\sqrt{2}}}}}}
+\stopbuffer
+
+\startbuffer
+$\mr \darkblue \MathSample \quad
+ \mb \darkgreen \MathSample $
+\stopbuffer
+
+\getbuffer[mathblob]
+
+\typebuffer
+
+\startlinecorrection[blank]
+\scale[width=\textwidth]{\switchtobodyfont[modernlatin,24pt]\getbuffer}
+\stoplinecorrection
+
+\page
+
+\startbuffer
+\dostepwiserecurse {1} {30} {5} {
+ $
+ \mr \sqrt{\blackrule[width=2mm,height=#1mm,color=darkblue]}
+ \quad
+ \mb \sqrt{\blackrule[width=2mm,height=#1mm,color=darkgreen]}
+ $
+}
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection[blank]
+\scale[width=\textwidth]{\switchtobodyfont[modernlatin,24pt]\getbuffer}
+\stoplinecorrection
+
+\page
+
+\definecolor[colormr] [t=.5,a=1,b=.6]
+\definecolor[colormb] [t=.5,a=1,g=.6]
+
+% and a fix in \LUATEX: pickup the value from the font instead of the currently
+
+\startlinecorrection
+\midaligned{\scale[height=.6\textheight]{\startoverlay
+ {\color[colormb]{$\mb\sqrt{\frac{1}{x}}$}}
+ {\color[colormr]{$ \sqrt{\frac{1}{x}}$}}
+\stopoverlay}}
+\stoplinecorrection
+
+\page
+
+\unexpanded\def\ShowMathSample#1%
+ {\switchtobodyfont[#1,14.4pt]%
+ \mathematics{%
+ \mr \darkblue \MathSample \quad
+ \mb \darkgreen \MathSample
+ }}
+
+\unexpanded\def\ShowMathCaption#1%
+ {\switchtobodyfont[#1]%
+ #1:
+ $
+ {\mr2\enspace \scriptstyle2\enspace \scriptscriptstyle2}
+ \enspace
+ {\mb2\enspace \scriptstyle2\enspace \scriptscriptstyle2}
+ $}
+
+\midaligned{\startcombination[3*2]
+ {\ShowMathSample {dejavu}} {\ShowMathCaption{dejavu}}
+ {\ShowMathSample{pagella}} {\ShowMathCaption{pagella}}
+ {\ShowMathSample {termes}} {\ShowMathCaption{termes}}
+ {\ShowMathSample {bonum}} {\ShowMathCaption{bonum}}
+ {\ShowMathSample {schola}} {\ShowMathCaption{schola}}
+ {\ShowMathSample{cambria}} {\ShowMathCaption{cambria}}
+\stopcombination}
+
+\page
+
+\starttyping
+\definefontfeature
+ [boldened-30]
+ [effect={width=0.3,extend=1.15,squeeze=0.985,%
+ delta=1,hdelta=0.225,ddelta=0.225,vshift=0.225}]
+
+\definefontfeature
+ [boldened-30]
+ [effect={width=0.30,auto=yes}]
+\stoptyping
+
+\stoptitle
+
+\starttitle[title=An application]
+
+\def\MathSample
+ {\overbrace{2 +
+ \sqrt{\frac{\sqrt{\frac{\sqrt{2}}{\sqrt{2}}}}
+ {\sqrt{\frac{\sqrt{\underbar{2}}}{\sqrt{\overbar{2}}}}}}}}
+
+\startbuffer
+\definehead [mysectiona] [section]
+\definehead [mysectionb] [mysectiona]
+
+\setuphead
+ [mysectiona]
+ [style=\tfc,
+ color=darkblue,
+ before=\blank,
+ after=\blank]
+
+\setuphead
+ [mysectionb]
+ [style=\bfc,
+ color=darkred]
+
+\mysectiona{Regular\quad$\MathSample\quad\mb\MathSample$}
+\mysectionb{Bold \quad$\MathSample\quad\mb\MathSample$}
+\stopbuffer
+
+\typebuffer \page \getbuffer \page
+
+\startcolumns
+ \switchtobodyfont[modern,12pt] \setupinterlinespace[15pt] \samplefile{poe} \column
+ \switchtobodyfont[modernlatin,12pt] \setupinterlinespace[15pt] \samplefile{poe} % \column
+\stopcolumns
+
+\stoptitle
+
+\stoptext
diff --git a/doc/context/presentations/bachotex/2018/bachotex-2018-mp.pdf b/doc/context/presentations/bachotex/2018/bachotex-2018-mp.pdf
new file mode 100644
index 000000000..11d0a33c9
--- /dev/null
+++ b/doc/context/presentations/bachotex/2018/bachotex-2018-mp.pdf
Binary files differ
diff --git a/doc/context/presentations/bachotex/2018/bachotex-2018-mp.tex b/doc/context/presentations/bachotex/2018/bachotex-2018-mp.tex
new file mode 100644
index 000000000..020ec179c
--- /dev/null
+++ b/doc/context/presentations/bachotex/2018/bachotex-2018-mp.tex
@@ -0,0 +1,1856 @@
+
+\startbuffer[colors]
+\definecolor[red] [r=.6]
+\definecolor[green] [g=.6]
+\definecolor[blue] [b=.6]
+
+\definecolor[cyan] [g=.6,b=.6]
+\definecolor[magenta][r=.6,b=.6]
+\definecolor[yellow] [r=.6,g=.6]
+\stopbuffer
+
+\getbuffer[colors]
+
+\usemodule[abbreviations-smallcaps]
+\usemodule[scite]
+
+\setuptyping[option=TEX]
+\setuptype[option=TEX]
+
+\dontcomplain
+
+\usebodyfont [modern]
+\usebodyfont[pagella]
+\usebodyfont [dejavu]
+
+\setuppapersize[S6]
+
+\definecolor[maincolor][r=.6]
+\definecolor[maintrans][r=.6,t=.5,a=1]
+\definecolor[moretrans][g=.6,t=.5,a=1]
+
+\setupwhitespace[line]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ margin=0cm,
+ header=0cm,
+ footer=0cm,
+ topspace=1cm,
+ bottomspace=1cm,
+ backspace=1cm]
+
+\setupbackgrounds
+ [page]
+ [background=color,
+ backgroundcolor=darkgray]
+
+\setupbackgrounds
+ [text][text]
+ [background=color,
+ backgroundoffset=5mm,
+ backgroundcolor=middlegray]
+
+\definefont
+ [LargeFont]
+ [SansBold*default,boldened-20 @ 40pt]
+
+\definefont
+ [SmallFont]
+ [SansBold*default,boldened-20 @ 20pt]
+
+\definefont
+ [HeadFont]
+ [SansBold*default,boldened-30 @ 30pt]
+
+\setupbodyfont
+ [modernlatin,12pt]
+
+\setuphead
+ [title]
+ [style=\HeadFont,
+ color=maincolor,
+ align=middle]
+
+\starttext
+
+\startstandardmakeup[footerstate=start]
+ \LargeFont \maincolor \setupalign[middle]
+ \vfil
+ \dontleavehmode\scale[width=.6\textwidth]{\setstrut\strut MetaPost}
+ \vfil
+ \dontleavehmode\scale[width=.6\textwidth]{\setstrut\strut Extensions}
+ \vfil
+ \dontleavehmode\scale[width=.7\textwidth]{\setstrut\strut A few examples}
+ \vfil
+ \vfil
+ \vfil
+ \SmallFont \darkgray Bacho\TeX\ 2018\enspace\emdash\enspace Hans Hagen
+\stopstandardmakeup
+
+\starttitle[title=History]
+
+\startitemize
+ \startitem
+ We started using \METAPOST\ some two decades ago and immediately went
+ the \PDF\ route.
+ \stopitem
+ \startitem
+ We used special colors plus specials to communicate extensions, for instance
+ \CMYK\ colors and shades.
+ \stopitem
+ \startitem
+ This mechanism was stepwise improved and extended. Some mechanisms, like texts,
+ needed an extra pass.
+ \stopitem
+ \startitem
+ When we moved to \LUATEX\ and \MPLIB\ we started using pre- and postscripts to
+ carry information with the paths.
+ \stopitem
+ \startitem
+ Currently we use a bit of \LUA\ from within \MPLIB\ to communicate during the
+ \METAPOST\ run with \CONTEXT. This permits cleaner interfaces.
+ \stopitem
+\stopitemize
+
+\stoptitle
+
+%%%% COLORS %%%%
+
+\starttitle[title=Colors]
+
+\startbuffer
+\startMPcode
+ draw image (
+ draw image (
+ fill unitcircle rotated 45 withcolor "red" ;
+ fill unitcircle rotated 165 withcolor "green" ;
+ fill unitcircle rotated 285 withcolor "blue" ;
+ ) shifted (-1.25,0) ;
+ draw image (
+ fill unitcircle rotated 45 withcolor "cyan" ;
+ fill unitcircle rotated 165 withcolor "magenta" ;
+ fill unitcircle rotated 285 withcolor "yellow" ;
+ ) shifted ( 1.25,0) ;
+ ) xsized TextWidth;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \page \getbuffer \page
+
+\startbuffer
+\startMPcode
+ draw image (
+ draw image (
+ fill unitcircle rotated 45 withcolor "red" ;
+ fill unitcircle rotated 165 withcolor "green" ;
+ fill unitcircle rotated 285 withcolor "blue" ;
+ fill unitcircle rotated 45 scaled 2/4 withcolor (1,0,0) ;
+ fill unitcircle rotated 165 scaled 2/4 withcolor (0,1,0) ;
+ fill unitcircle rotated 285 scaled 2/4 withcolor (0,0,1) ;
+ ) shifted (-1.25,0) ;
+ draw image (
+ fill unitcircle rotated 45 withcolor "cyan" ;
+ fill unitcircle rotated 165 withcolor "magenta" ;
+ fill unitcircle rotated 285 withcolor "yellow" ;
+ fill unitcircle rotated 45 scaled 2/4 withcolor (1,0,0,0) ;
+ fill unitcircle rotated 165 scaled 2/4 withcolor (0,1,0,0) ;
+ fill unitcircle rotated 285 scaled 2/4 withcolor (0,0,1,0) ;
+ ) shifted ( 1.25,0) ;
+ ) xsized TextWidth;
+\stopMPcode
+\stopbuffer
+
+\typebuffer[colors] \typebuffer \page \getbuffer \page
+
+\startbuffer[colors]
+\definecolor [whatever] [c=1,a=1,t=0.5]
+
+\definecolor [blue] [c=1,m=.38,y=0,k=.64] % pantone pms 2965 uncoated m
+\definecolor [yellow] [c=0,m=.28,y=1,k=.06] % pantone pms 124 uncoated m
+
+\definespotcolor [blue-100] [blue] [p=1]
+\definespotcolor [yellow-100] [yellow] [p=1]
+
+\definemultitonecolor [somecolor] [blue=.12,yellow=.28] [c=.1,m=.1,y=.3,k=.1]
+\stopbuffer
+
+\typebuffer[colors] \page
+
+\startbuffer
+% \enabletrackers[metapost.lua]
+\startMPcode
+vardef C(expr r,dx) = fullcircle scaled r shifted (dx,0) enddef ;
+
+draw image (
+ fill C(3cm,1cm) withcolor (0,1,1,0) ;
+ fill C(3cm,2cm) withcolor transparent(1,0.5,(1,1,0,0)) ;
+ fill C(3cm,3cm) withcolor transparent(1,0.5,"blue-100") ;
+ fill C(3cm,4cm) withcolor 0.75*transparent(1,0.5,"green") ;
+ fill C(3cm,5cm) withcolor spotcolor("blue-100",(.3,.4,.5)) ;
+ fill C(3cm,6cm) withcolor 0.75 * spotcolor("blue-100",(.3,.4,.5)) ;
+ fill C(3cm,7cm) withcolor namedcolor("blue-100") ;
+ fill C(3cm,8cm) withcolor "blue-100" ;
+ fill C(3cm,9cm) withcolor (0,1,1,0) withtransparency (1,0.5);
+) xsized TextWidth;
+\stopMPcode
+\stopbuffer
+
+\typebuffer {\getbuffer[colors] \getbuffer }\page
+
+\stoptitle
+
+%%%% SHADES %%%%
+
+\starttitle[title=Shades]
+
+\startbuffer
+\startMPcode
+ draw image (
+ fill fullcircle scaled 10cm
+ withshademethod "circular"
+ withshadevector (5cm,1cm)
+ withshadecenter (.1,.5)
+ withshadedomain (.2,.6)
+ withshadefactor 1.2
+ withshadecolors ("red","green")
+ ;
+ fill fullcircle scaled 10cm shifted (12cm,0)
+ withshademethod "circular"
+ withshadevector (4cm,2cm)
+ withshadecenter (.2,.8)
+ withshadedomain (.2,.8)
+ withshadefactor 1.5
+ withshadecolors ("blue","green")
+ ;
+ ) xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \page \getbuffer \page
+
+\starttabulate[|l|p|]
+\BC domain \NC The range over which the colors run, with a minimum of 0 and maximum of 1. \NC \NR
+\BC color \NC A color to start from and one to end with, we default from black to white. \NC \NR
+\BC type \NC The shading can be linear or circular. \NC \NR
+\BC center \NC The origin of the shade vector. \NC \NR
+\BC radius \NC The radius vector of a circular shade. \NC \NR
+\BC vector \NC Where we start and end the shading. \NC \NR
+\stoptabulate
+
+For a {\bf linear} shade the centers are the lower left and upper right corners,
+for a circular shade it's the center of the path. For a {\bf circular} shade the
+radius runs from zero to the maximum distance from the center as determined by
+the boundingbox.
+
+The vector is used as follows: the first coordinate (xpart) determines the point
+on the path where we start, the second coordinate (ypart) the point on the
+path where we end.
+
+\startbuffer
+\startreusableMPgraphic{bullet}
+ fill fullcircle
+ scaled (.75EmWidth)
+ withshademethod "circular"
+ withcolor "red" shadedinto "blue" ;
+\stopreusableMPgraphic
+
+\definesymbol[1][\hbox{\lower.125ex\hbox{\reuseMPgraphic{bullet}}}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startitemize[packed]
+ \startitem This is item one! \stopitem
+ \startitem This is item two! \stopitem
+\stopitemize
+
+\page
+
+A triangle has three points. Using 1 and 2 as second vector value gives the same
+results as do values in the range 0 upto 1 and 2 upto 3 (0 again).
+
+\startbuffer
+\startMPcode
+fill fulltriangle xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (0.25,0.75)
+ withshadecolors (darkred,darkgreen)
+;
+
+draw fulltriangle xyscaled (TextWidth,1cm)
+ shownshadevector (0.25,0.75)
+ withpen pencircle scaled 2
+ withcolor white ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+The shadevector relates to (the x coordinates of) points on the path. A variant is
+to use the boundingbox:
+
+\startbuffer
+\startMPcode
+for i=1 upto 3 :
+ fill fulltriangle xyscaled (TextWidth,1cm) shifted (0,-i*15mm)
+ withshademethod "linear"
+ withshadedirection (1,1-i/4)
+ withshadecolors (darkgreen,darkblue)
+ ;
+endfor ;
+for i=1 upto 3 :
+ draw fulltriangle xyscaled (TextWidth,1cm) shifted (0,-i*15mm)
+ shownshadevector (1,1-i/4)
+ withpen pencircle scaled 2
+ withcolor white ;
+endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\stopbuffer
+
+
+To make life convenient we provide a few constants that indicate directions:
+
+\starttyping
+\startMPcode
+pair shadedup ; shadedup := (0.5,2.5) ;
+pair shadeddown ; shadeddown := (2.5,0.5) ;
+pair shadedleft ; shadedleft := (1.5,3.5) ;
+pair shadedright ; shadedright := (3.5,1.5) ;
+\stopMPcode
+\stoptyping
+
+\startbuffer
+\startMPcode
+for d = shadedup, shadeddown, shadedleft, shadedright :
+ fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadedirection d
+ withshadecolors (darkgreen,darkblue)
+ ;
+ currentpicture := currentpicture shifted (0,15mm) ;
+endfor ;
+
+currentpicture := currentpicture shifted (0,-60mm) ;
+
+for d = shadedup, shadeddown, shadedleft, shadedright :
+ draw fullsquare xyscaled (TextWidth,1cm)
+ shownshadedirection d
+ withpen pencircle scaled 2
+ withcolor .5white ;
+ currentpicture := currentpicture shifted (0,15mm) ;
+endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+In case of a circular shade another method comes in handy. Here the values relate
+to the center of path i.e.\ they shift the center by the given fraction of the
+width and height of the boundingbox devided by 2.
+
+\startbuffer
+\startMPcode
+fill fullcircle xyscaled (TextWidth,4cm)
+ withshademethod "circular"
+ withshadecenter (.7,.9)
+ withshadecolors (darkblue,darkyellow)
+;
+
+draw fullcircle xyscaled (TextWidth,4cm)
+ shownshadecenter (.7,.9)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+You can set a center directly i.e.\ unrelated to the center of the path as
+follows:
+
+\startbuffer
+\startMPcode
+fill fullcircle xyscaled (TextWidth,4cm)
+ withshademethod "circular"
+ withshadeorigin (-30mm,-15mm)
+ withshadecolors (darkblue,darkyellow)
+;
+
+draw fullcircle xyscaled (TextWidth,4cm)
+ shownshadeorigin (-30mm,-15mm)
+ withpen pencircle scaled 2
+ withcolor .5white ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+In a similar way you can set an explicit radius:
+
+\startbuffer
+\startMPcode
+fill fullcircle xyscaled (TextWidth,3cm)
+ withshademethod "circular"
+ withshaderadius (10mm,50mm)
+ withshadecolors (darkblue,darkyellow)
+;
+
+currentpicture := currentpicture shifted (0,40mm) ;
+
+fill fullcircle xyscaled (TextWidth,3cm)
+ withshademethod "circular"
+ withshaderadius (50mm,10mm)
+ withshadecolors (darkgreen,darkred)
+;
+
+currentpicture := currentpicture shifted (0,40mm) ;
+
+fill fullcircle xyscaled (TextWidth,3cm)
+ withshademethod "circular"
+ withshaderadius (20mm,30mm)
+ withshadecolors (darkmagenta,darkcyan)
+;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+This one is made for Mojca:
+
+\startbuffer
+\startMPcode
+fill fullsquare xyscaled (TextWidth,1cm)
+ withshademethod "linear"
+ withshadevector (0,1)
+ withshadestep (
+ withshadefraction .3
+ withshadecolors (red,green)
+ )
+ withshadestep (
+ withshadefraction .5
+ withshadecolors (green,blue)
+ )
+ withshadestep (
+ withshadefraction .7
+ withshadecolors (blue,red)
+ )
+ withshadestep (
+ withshadefraction 1
+ withshadecolors (red,yellow)
+ )
+;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+Shades work well with colors and transparencies. This involves quite some
+resource managament in the backend but it's hidden by the interface.
+
+\startbuffer
+\startMPcode
+draw image (
+ fill fullsquare scaled 5cm
+ withshademethod "linear"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadevector (0.5,2.75)
+ withshadecolors (red,green) ;
+
+ fill fullcircle scaled 6cm
+ withshademethod "circular"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadecenter (.25,.25)
+ withshadecolors (green,blue) ;
+
+ fill fulltriangle scaled 7cm
+ withshademethod "circular"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadecenter (.25,.25)
+ withshadecolors (blue,yellow) ;
+) ysized TextHeight ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\startbuffer
+\startMPcode
+draw image (
+ fill fullsquare scaled 5cm
+ withshademethod "linear"
+ withshadevector (0.5,2.75)
+ withshadecolors (red,green)
+ withtransparency (1,.5) ;
+
+ fill fullcircle scaled 6cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withshadecolors (green,blue)
+ withtransparency (1,.5) ;
+
+ fill fulltriangle scaled 7cm
+ withshademethod "circular"
+ withshadecenter (.25,.25)
+ withcolor blue shadedinto yellow
+ withtransparency (1,.5) ;
+) ysized TextHeight ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\startbuffer
+\startMPcode
+defineshade myshade
+ withshademethod "circular"
+ withshadefactor 1
+ withshadedomain (0,1)
+ withshadecolors (black,white)
+ withtransparency (1,.5)
+;
+
+draw image (
+ for i=1 upto 5 :
+ fill fullcircle randomized 1 xyscaled(5cm,3cm)
+ shaded myshade ;
+ endfor ;
+
+ draw image (
+ for i=1 upto 5 :
+ fill fullcircle randomized 1
+ shaded myshade
+ withshadecolors (yellow,blue) ;
+ endfor ;
+ ) xyscaled(5cm,3cm) shifted (5cm,0) ;
+) xysized (TextWidth, TextHeight) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+
+\startbuffer
+\startMPcode
+fill fullsquare xyscaled (15mm, 15mm)
+ withshademethod "linear"
+ withshadedirection shadedright
+ withshadecolors (red,(1,1,1)) ;
+
+fill fullsquare xyscaled (10mm, 10mm)
+ withshademethod "circular"
+ withshadecolors (green,blue) ;
+
+currentpicture := currentpicture xysized (.4TextWidth,30mm) ;
+currentpicture := currentpicture shifted (5mm,5mm) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\startbuffer
+\startMPcode
+fill fullsquare xyscaled (15mm, 15mm)
+ withshademethod "linear"
+ withshadetransform "no"
+ withshadedirection shadedright
+ withshadecolors (red,(1,1,1)) ;
+
+fill fullsquare xyscaled (10mm, 10mm)
+ withshademethod "circular"
+ withshadetransform "no"
+ withshadecolors (green,blue) ;
+
+currentpicture := currentpicture xysized (.4TextWidth,30mm) ;
+currentpicture := currentpicture shifted (5mm,5mm) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\stoptitle
+
+\starttitle[title=Bitmaps]
+
+\startbuffer
+\startMPcode
+ draw
+ bitmapimage(2,2,"334455 667788 99aabb ccddee")
+ scaled 3cm
+ rotated 15 ;
+ draw
+ bitmapimage(2,2,"33 55 77 99")
+ scaled 2cm
+ rotated 30 ;
+ draw
+ bitmapimage(2,2,"0000ff00 ff00ff00 00ff0000 ffff0000")
+ scaled 1cm
+ rotated 45 ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\starttyping
+\startMPcode
+draw bitmapimage (
+ 128, 128,
+ "
+ dbdefadbdffbdbdffbdbdffbdbdffbdbdff.....
+ dcdffbdcdffbdcdffbdcdffbdcdffbdcdff.....
+ dcdffbdcdffbdcdffbdcdffbdcdffbdcdff.....
+ ......
+ "
+) rotated 15 ysized 4cm ;
+\stopMPcode
+\stoptyping
+
+\startMPcode
+draw bitmapimage (
+ 128, 128,
+ "
+ dbdefadbdffbdbdffbdbdffbdbdffbdbdffbdbdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffb
+ dcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffb
+ dcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffb
+ dcdffbdcdffbdcdffbdcdffbdce0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fb
+ dde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fb
+ dde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fb
+ dde0fbdde0fbdde0fbdde0fbdee0fbdee0fbdee0fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fb
+ dee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fbdee1fb
+ daddfadaddfadaddfadaddfadaddfadaddfadadefadadefadadefadadefadadefadadefadadefadadefadadefadadefa
+ dbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefa
+ dbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefa
+ dbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdffbdbdffbdbdffbdbdffbdbdffbdbdffbdcdffb
+ dcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffb
+ dcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffb
+ dcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdce0fbdde0fbdde0fbdde0fb
+ dde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fbdde0fb
+ d9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9ddfad9ddfad9ddfad9ddfad9ddfa
+ d9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfadaddfadaddfadaddfadaddfadaddfadaddfa
+ daddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfa
+ daddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadadefadadefa
+ dadefadadefadadefadadefadadefadadefadadefadadefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefa
+ dbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefa
+ dbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefadbdefa
+ dbdefadbdffbdbdffbdbdffbdbdffbdbdffbdbdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffbdcdffb
+ d8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dcfa
+ d8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfa
+ d8dcfad8dcfad8dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfa
+ d9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfa
+ d9dcfad9dcfad9dcfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfad9ddfa
+ d9ddfad9ddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfa
+ daddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfadaddfa
+ daddfadaddfadaddfadaddfadaddfadaddfadadefadadefadadefadadefadadefadadefadadefadadefadadefadadefa
+ d7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafa
+ d7dafad7dafad7dafad7dafad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfa
+ d7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad8dbfad8dbfad8dbfa
+ d8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfa
+ d8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfa
+ d8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad8dcfad9dcfad9dcfad9dcfad9dcfad9dcfa
+ d9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfa
+ d9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9dcfad9ddfad9ddfad9ddfad9ddfad9ddfa
+ d5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fa
+ d6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6dafad6dafad6dafad6dafad6dafad6dafad6dafa
+ d6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafa
+ d6dafad6dafad6dafad6dafad6dafad6dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafa
+ d7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dbfad7dbfad7dbfad7dbfa
+ d7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfad7dbfa
+ d7dbfad7dbfad7dbfad7dbfad7dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfa
+ d8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dbfad8dcfa
+ d4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fa
+ d4d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d9fad5d9fa
+ d5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fa
+ d5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad6d9fa
+ d6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fa
+ d6d9fad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafa
+ d6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad6dafad7dafad7dafa
+ d7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafad7dafa
+ d3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fa
+ d3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad4d7fad4d7fad4d7fad4d7fad4d7fad4d7fa
+ d4d7fad4d7fad4d7fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fa
+ d4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fa
+ d4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d8fa
+ d5d8fad5d8fad5d8fad5d8fad5d8fad5d8fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fa
+ d5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fa
+ d5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad5d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fad6d9fa
+ d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9
+ d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9
+ d2d6f9d2d6f9d2d6f9d2d6f9d3d6f9d3d6f9d3d6f9d3d6f9d3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fa
+ d3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fa
+ d3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fa
+ d3d7fad3d7fad4d7fad4d7fad4d7fad4d7fad4d7fad4d7fad4d7fad4d7fad4d7fad4d8fad4d8fad4d8fad4d8fad4d8fa
+ d4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fa
+ d4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fad4d8fa
+ d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9
+ d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9
+ d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d6f9d2d6f9d2d6f9d2d6f9
+ d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9
+ d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9
+ d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d3d6f9d3d6f9d3d6f9d3d6f9
+ d3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fa
+ d3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fad3d7fa
+ cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9
+ d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9
+ d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9
+ d0d4f9d0d5f9d0d5f9d0d5f9d0d5f9d0d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9
+ d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9
+ d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9
+ d1d5f9d1d5f9d1d5f9d1d5f9d1d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9
+ d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9d2d6f9
+ ced2f9ced2f9ced2f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9
+ ced3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9
+ cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9
+ cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9
+ d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9
+ d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9
+ d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d5f9d0d5f9d0d5f9d0d5f9d0d5f9d1d5f9d1d5f9
+ d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9d1d5f9
+ cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9
+ cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9ced2f9ced2f9ced2f9ced2f9ced2f9
+ ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9
+ ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced3f9ced3f9ced3f9ced3f9ced3f9
+ ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9
+ cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9
+ cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd3f9cfd4f9cfd4f9
+ cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9cfd4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9d0d4f9
+ ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd1f9ccd1f9ccd1f9
+ ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9
+ ccd1f9ccd1f9ccd1f9ccd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9
+ cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9
+ cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9
+ cdd2f9cdd2f9cdd2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9
+ ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9ced2f9
+ ced2f9ced2f9ced2f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9ced3f9
+ cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9
+ cbcff9cbcff9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9
+ cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9ccd0f9ccd0f9ccd0f9
+ ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9
+ ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9
+ ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9ccd1f9cdd1f9cdd1f9cdd1f9cdd1f9
+ cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9
+ cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd1f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9cdd2f9
+ c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8
+ cacef8cacef8cacef8cacef8cacef8cacef8cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9
+ cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9
+ cacff9cacff9cacff9cacff9cacff9cacff9cacff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9
+ cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9
+ cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9
+ cbd0f9cbd0f9cbd0f9cbd0f9cbd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9
+ ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd0f9ccd1f9ccd1f9ccd1f9
+ c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8
+ c8cdf8c8cdf8c9cdf8c9cdf8c9cdf8c9cdf8c9cdf8c9cdf8c9cdf8c9cdf8c9cdf8c9cef8c9cef8c9cef8c9cef8c9cef8
+ c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8
+ c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8
+ cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacff9cacff9
+ cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9
+ cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cacff9cbcff9
+ cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9cbcff9
+ c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8
+ c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c8ccf8c8ccf8c8ccf8c8ccf8c8ccf8
+ c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8
+ c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8
+ c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c9cdf8c9cdf8c9cdf8c9cdf8c9cdf8c9cdf8
+ c9cdf8c9cdf8c9cdf8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8
+ c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8
+ c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8c9cef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8cacef8
+ c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8
+ c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8
+ c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8
+ c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8
+ c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8
+ c7ccf8c7ccf8c7ccf8c8ccf8c8ccf8c8ccf8c8ccf8c8ccf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8
+ c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8
+ c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8c8cdf8
+ c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8
+ c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8
+ c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5cbf8c5cbf8c5cbf8c5cbf8c6cbf8c6cbf8
+ c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8020204020204020204020204
+ 020204020204c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8
+ c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c7ccf8c7ccf8c7ccf8
+ c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8
+ c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8c7ccf8
+ c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8
+ c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8
+ c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4caf8
+ c4caf8c4caf8c4caf8c4caf8c4caf8c4caf8c4caf8c5caf8c5caf8020204020204020204020204020204020204020204
+ 020204020204020204020204020204c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8
+ c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8
+ c5caf8c5caf8c5cbf8c5cbf8c5cbf8c5cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8
+ c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8c6cbf8
+ c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8
+ c2c8f8c2c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8
+ c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8
+ c3c8f8c3c8f8c3c8f8c3c8f8c3c9f8c3c9f8c3c9f8020204020204020204020204020204020204020204020204020204
+ 020204020204020204020204020204020204020204020204c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8
+ c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8
+ c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4caf8c4caf8c4caf8c4caf8c4caf8c4caf8c4caf8c4caf8c5caf8
+ c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8c5caf8
+ c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8
+ c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c2c7f8c2c7f8c2c7f8c2c7f8
+ c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8
+ c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8020204020204020204020204020204020204020204020204020204020204
+ 0202040202040202040202040a0604020204020204020204020204c2c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8
+ c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8
+ c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c8f8c3c9f8c3c9f8c3c9f8c3c9f8
+ c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c3c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8c4c9f8
+ c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7
+ c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7
+ c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7
+ c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7020204020204020204020204020204020204020204020204020204020204020204
+ 0202040202040202040c0c0c343434343434141413020204020204020204c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8
+ c1c7f8c1c7f8c1c7f8c1c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8
+ c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8c2c7f8
+ c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8c2c8f8
+ bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc5f7
+ bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7
+ bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7c0c5f7c0c5f7
+ c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7020204020204020204020204020204020204020204020204020204020204020204
+ 0202040202040202041414135c5c5c7c7c7c505050242424020204020204020204c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7
+ c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c1c6f7c1c6f7c1c6f7
+ c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7
+ c1c6f7c1c6f7c1c6f7c1c6f7c1c6f7c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8c1c7f8
+ bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bec3f7bec3f7bec3f7bec3f7bec3f7bec3f7bec3f7
+ bec3f7bec3f7bec3f7bec3f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7
+ bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7
+ bec4f7bec4f7bec4f7bec4f7020204020204020204020204020204020204020204020204020204020204020204020204
+ 0202040202040202041c1c1b6464646c6c6b505050343434141413020204020204bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7
+ bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7
+ bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7bfc5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7
+ c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c5f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7c0c6f7
+ bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7
+ bcc2f7bcc2f7bcc2f7bdc2f7bdc2f7bdc2f7bdc2f7bdc2f7bdc2f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7
+ bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7
+ bdc3f7bdc3f7bdc3f7bdc3f7020204020204020204020204020204020204020204020204020204020204020204020204
+ 0202040202040202041c1c1b5050504444442c2c2c1c1c1b0c0c0c020204020204020204bec4f7bec4f7bec4f7bec4f7
+ bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7
+ bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7bec4f7
+ bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc4f7bfc5f7
+ bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7
+ bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bcc1f7bcc1f7bcc2f7bcc2f7
+ bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7
+ bcc2f7bcc2f7bcc2f7020204020204020204020204020204020204020204020204020204020204020204020204020204
+ 020204020204020204141413242424141413020204020204020204020204020204020204bdc2f7bdc2f7bdc2f7bdc2f7
+ bdc2f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7
+ bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7
+ bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bdc3f7bec3f7bec3f7bec3f7bec3f7bec3f7bec3f7bec3f7
+ bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7
+ bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7
+ bac0f7bac0f7bac1f7bac1f7bac1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7
+ bbc1f7bbc1f7bbc1f7020204020204020204020204020204020204020204020204020204020204020204020204020204
+ 020204020204020204020204020204020204020204020204020204020204020204020204020204bbc1f7bbc1f7bbc1f7
+ bbc1f7bbc1f7bbc1f7bbc1f7bcc1f7bcc1f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7
+ bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7
+ bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7bcc2f7
+ b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7
+ b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7
+ b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9c0f7b9c0f7b9c0f7b9c0f7b9c0f7b9c0f7b9c0f7b9c0f7bac0f7
+ bac0f7bac0f7bac0f7020204020204020204020204020204020204020204020204020204020204020204020204020204
+ 020204020204020204020204020204020204020204020204020204020204020204020204020204bac0f7bac0f7bac0f7
+ bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac1f7bac1f7bac1f7bbc1f7bbc1f7bbc1f7
+ bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7
+ bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7bbc1f7
+ b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6
+ b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6
+ b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bff7b8bff7b8bff7b8bff7
+ b8bff7b8bff7b8bff7020204020204020204020204020204020204020204020204020204020204020204020204020204
+ 020204020204020204020204020204020204020204020204020204020204020204020204020204020204b9bff7b9bff7
+ b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9c0f7
+ b9c0f7b9c0f7b9c0f7b9c0f7b9c0f7b9c0f7b9c0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7
+ bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7bac0f7
+ b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6
+ b6bdf6b6bdf6b6bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6
+ b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6
+ b7bdf6b7bef6b7bef60202040202040202040c0c0c0a06042424240c0c0c020204020204020204020204020204020204
+ 0202040202040202040202040c0c0c505050141413020204020204020204020204020204020204020204b8bef6b8bef6
+ b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6
+ b8bef6b8bef6b8bef6b8bef6b8bff7b8bff7b8bff7b8bff7b8bff7b8bff7b8bff7b8bff7b8bff7b8bff7b8bff7b8bff7
+ b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7b9bff7
+ b5bbf6b5bbf6b5bbf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6
+ b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b6bcf6b6bcf6b6bcf6b6bcf6
+ b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6
+ b6bcf6b6bcf6b6bcf60202040202040202040202042424240202040c0c0c343434020204020204020204020204020204
+ 0a06045c5c5c7c7c7c9494945c5c5c0202041c1c1b141413020204020204020204020204020204020204b7bdf6b7bdf6
+ b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6
+ b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bdf6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6
+ b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b7bef6b8bef6b8bef6b8bef6b8bef6b8bef6b8bef6
+ b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6
+ b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6
+ b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6
+ b5bbf6b5bbf6b5bbf60202040202041c1c1b949494bebdbcbebdbc141413020204020204020204020204020204020204
+ 747474949494a4a4a4acacacc4c4c49c9c9c0a06040a0604020204020204020204020204020204020204b5bcf6b5bcf6
+ b5bcf6b5bcf6b5bcf6b5bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6
+ b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bcf6b6bdf6b6bdf6
+ b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6b6bdf6
+ b2b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3baf6b3baf6b3baf6b3baf6
+ b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6
+ b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b4baf6
+ b4baf6b4baf6b4baf60202040202047c7c7cacacacccccccbebdbc8d8d8c0c0c0c020204020204020204020204565654
+ b5b4b3dddddce4e4e4e4e4e4d4d4d4a4a4a4505050020204020204020204020204020204020204020204b4bbf6b4bbf6
+ b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b5bbf6b5bbf6
+ b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6b5bbf6
+ b5bbf6b5bbf6b5bbf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6b5bcf6
+ b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b2b8f6b2b8f6b2b8f6b2b8f6b2b8f6b2b8f6
+ b2b8f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6
+ b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6
+ b2b9f6b2b9f6b2b9f6020204020204e4e4e4f4f4f4c4c4c4f4f4f4fefefc9c9c9c020204020204020204020204cccccc
+ fefefcfefefc3434340c0c0cfefefcfefefce4e4e4020204020204020204020204020204020204020204b3baf6b3baf6
+ b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6
+ b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b3baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6
+ b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4baf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6b4bbf6
+ b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6
+ b0b7f6b0b7f6b0b7f6b0b7f6b1b7f6b1b7f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6
+ b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6
+ b1b8f6b1b8f6b1b8f6020204020204f4f4f40202043c3c3c3c3c3cfefefcf4f4f40c0c0c0202040a0604020204d4d4d4
+ fefefc141413020204747474242424f4f4f4fefefc1c1c1b020204020204020204020204020204020204b2b9f6b2b9f6
+ b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6
+ b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6b2b9f6
+ b2b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3b9f6b3baf6b3baf6b3baf6b3baf6
+ afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5
+ afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb7f6afb7f6b0b7f6b0b7f6b0b7f6
+ b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6
+ b0b7f6b0b7f6b0b7f6020204020204f4f4f4020204020204747474e4e4e4f4f4f41414131c1c1b5050500a0604d4d4d4
+ f4f4f4020204020204020204747474acacacfefefc747474020204020204020204020204020204020204b1b8f6b1b8f6
+ b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6
+ b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6
+ b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b1b8f6b2b8f6b2b8f6b2b8f6b2b8f6b2b8f6b2b8f6
+ aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5
+ aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5
+ aeb6f5aeb6f5aeb6f5aeb6f5aeb6f5aeb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5
+ afb6f5afb6f5afb6f5020204020204f4f4f40a06040202044444446c6c6bececec0202040202040202040c0c0cacacac
+ e4e4e4020204020204020204141413646464fefefca4a4a4020204020204020204020204020204020204afb6f5afb6f5
+ afb6f5afb6f5afb6f5afb7f6afb7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6
+ b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6
+ b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6b0b7f6
+ acb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5
+ adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5
+ adb4f5adb4f5adb4f5adb4f5adb4f5adb5f5adb5f5adb5f5adb5f5adb5f5adb5f5adb5f5adb5f5adb5f5adb5f5adb5f5
+ aeb5f5aeb5f5aeb5f5020204020204f4f4f4020204020204020204646464aa7e0ae1b40ae5ac09ecb40be1b40a96720b
+ f4f4f4020204020204020204020204ccccccfefefc7c7c7c020204020204020204020204020204020204aeb5f5aeb5f5
+ aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb6f5aeb6f5aeb6f5aeb6f5aeb6f5aeb6f5afb6f5afb6f5
+ afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5
+ afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5afb6f5
+ abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5acb3f5acb3f5acb3f5acb3f5acb3f5
+ acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5
+ acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5
+ acb4f5acb4f5acb4f5020204020204ecececacacac020204291c04b67e0ad19b09ebbc0bebbc0bd7ac098e6a07c39a0e
+ ebbc0b5e4a04020204020204242424fefefcfefefc0c0c0c020204020204020204020204020204020204adb4f5adb4f5
+ adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb5f5adb5f5adb5f5
+ adb5f5adb5f5adb5f5adb5f5adb5f5adb5f5adb5f5adb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5
+ aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5aeb5f5
+ aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5
+ aab2f5aab2f5aab2f5aab2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5
+ abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb3f5abb3f5
+ abb3f5abb3f5abb3f5020204020204c4c4c4fefefca2895cb98309e5ac09f2b60cebbc0be2bc0cebc40cebc40cf5cd31
+ f3cd0cebc40cebbc0bc2930becececfefefcd4d4d4020204020204020204020204020204020204020204020204acb3f5
+ acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5acb3f5
+ acb3f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5acb4f5
+ acb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5adb4f5
+ a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5
+ a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5aab1f5aab1f5aab1f5
+ aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5
+ aab1f5aab1f5aab1f50202040202040c0c0ca2895cb98309d19b09ecb40becb40bebbc0bebc40cedcc0ef1d42af2da2c
+ f6da4af6da14f3cd0cf3c40bebbc0bdaa309946c09020204020204020204020204020204020204020204020204abb2f5
+ abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5
+ abb2f5abb2f5abb2f5abb2f5abb2f5abb2f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5
+ abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5abb3f5acb3f5acb3f5acb3f5acb3f5acb3f5
+ a8aff5a8aff5a8aff5a8aff5a8aff5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5
+ a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5
+ a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5
+ a9b0f5a9b0f5a9b0f5020204020204a5720ab67e0acf9407dfa509ebbc0bebbc0bebc40cedcc0ef1d311f2da2cf6da4a
+ f6da14f6da14f6da14f6da14f6d50df1d311f5cd31a4770a020204020204020204020204020204020204020204a9b1f5
+ a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5
+ aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab1f5aab2f5aab2f5aab2f5aab2f5aab2f5
+ aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5aab2f5
+ a6aef4a6aef4a7aef4a7aef4a7aef4a7aef4a7aef4a7aef4a7aef4a7aef4a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5
+ a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5
+ a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5
+ a8aff5a8aff5a8aff50202040c0c0cb37907c08507d89c08e5ac09ecb40bebbc0be2bc0cedcc0ef1d42af6da4af6d50d
+ f6da14f6d50df6d50df6d50dac8c04a4770ae5ac097c5b0a020204020204020204020204020204020204020204a8b0f5
+ a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a9b0f5
+ a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5a9b0f5
+ a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5a9b1f5
+ a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a6adf4a6adf4a6adf4a6adf4a6aef4
+ a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4
+ a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4
+ a6aef4a6aef4a6aef40202040c0c0cb37907cf9407daa309ecb40bf2b60cebc40cebc40cedcc0ef6da4af6d50df6d50d
+ f6d50df6d50df1d3118e6a07cf9407daa309d89c085c4309020204020204020204020204020204020204020204a7aff5
+ a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5
+ a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5a8aff5a8aff5a8aff5a8aff5a8aff5a8aff5a8aff5a8aff5
+ a8aff5a8aff5a8aff5a8aff5a8aff5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5a8b0f5
+ a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4
+ a4acf4a4acf4a4acf4a4adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4
+ a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4
+ a5adf4a5adf4a5adf4020204020204603e05ac8409e5ac09ecb40bf5bd0cebc40cf1d311f1d311f6da14f6da14f1d311
+ ebc40c885f07ce8e08d89c08daa309d89c08ce8e080c0c0c0202040202046464640a0604020204020204020204020204
+ a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4
+ a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4a6aef4
+ a6aef4a6aef4a7aef4a7aef4a7aef4a7aef4a7aef4a7aef4a7aef4a7aef4a7aff5a7aff5a7aff5a7aff5a7aff5a7aff5
+ a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4
+ a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3acf4a3acf4a3acf4a3acf4a3acf4a3acf4a4acf4a4acf4
+ a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4
+ a4acf4a4acf4a4acf40202040202041c1c1b7c5b0a7c5b0ae1b40af3c40bebcd28ebcd28f1d311f1d311e2bc0c7e620c
+ b37907cf9407d89c08d89c08cf9418b57e2fa69b871414130202040202042c2c2c8383845c5c5c0c0c0c020204020204
+ a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4
+ a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4
+ a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a5adf4a6adf4a6adf4a6adf4a6adf4a6aef4
+ a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4
+ a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2abf4a2abf4a2abf4
+ a2abf4a2abf4a2abf4a2abf4a2abf4a2abf4a2abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4
+ a3abf4a3abf4a3abf4020204020204141413bebdbc906007885f078a66048e6a078a66048a6604ad780ab98309c98e07
+ cf9407ce8e08cf9407b98309bebdbcbebdbcbebdbca4a4a40202040202040202047c7c7c7c7c7c4a4a4c020204020204
+ a3acf4a3acf4a3acf4a3acf4a3acf4a3acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4
+ a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4
+ a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4a4acf4
+ a0a9f4a0a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4
+ a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4
+ a1a9f4a1a9f4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4
+ a1aaf4a2aaf4a2aaf40202040202043c3c3cbebdbcbebdbc976105a4770ad9b30de1b40ad89c08d7960dd7960dce8e08
+ c78a08b98309b58c35bebdbcc4c4c4ccccccc4c4c4bebdbc0202040202040202046464648383845c5c5c0a0604020204
+ 020204a2aaf4a2aaf4a2aaf4a2aaf4a2abf4a2abf4a2abf4a2abf4a2abf4a2abf4a2abf4a2abf4a2abf4a2abf4a3abf4
+ a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4
+ a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4a3abf4
+ 9fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f4a0a8f4a0a8f4a0a8f4a0a8f4
+ a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4
+ a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4
+ a0a9f4a0a9f4a0a9f4020204020204343434bebdbcbebdbcbebdbc885f079d6a07b67e0ab67e0ab37907a46d05a46d05
+ ba8330bebdbcbfb5a4bebdbcd4d4d4ecececfefefcececec0c0c0c020204020204020204141413020204020204020204
+ 020204020204a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4
+ a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a1aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4
+ a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4a2aaf4
+ 9ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f4
+ 9ea7f49ea7f49ea7f49ea7f49ea7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f4
+ 9fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa8f49fa8f49fa8f49fa8f4
+ 9fa8f49fa8f40202040202040202042c2c2cd4d4d4c4c4c4bebdbcbebdbca2895c906007906007976105a3713fb8a378
+ bebdbcbebdbcbebdbcd4d4d4fefefcfefefcfefefcfefefcacacac020204020204020204020204020204020204020204
+ 0202040c0c0ca0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a8f4a0a9f4
+ a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4a0a9f4
+ a0a9f4a0a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4a1a9f4
+ 9da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f3
+ 9da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39ea6f39ea6f3
+ 9ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f3
+ 9ea6f39ea7f4020204020204020204fefefcecececccccccbebdbcbebdbcbebdbcbebdbcbebdbcbebdbcbebdbcbebdbc
+ bebdbcc4c4c4d4d4d4f4f4f4fefefcfefefcfefefcfefefcfefefc0c0c0c020204020204020204020204020204020204
+ 0202040202041414139fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f49fa7f4
+ 9fa7f49fa7f49fa7f49fa7f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f4
+ 9fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f49fa8f4a0a8f4a0a8f4a0a8f4a0a8f4
+ 9ca4f39ca4f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f3
+ 9ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f3
+ 9ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39da5f39da5f39da5f39da5f39da5f39da5f39da5f39da5f3
+ 9da5f31414130a06040202040a0604fefefcfefefcecececbebdbcbebdbcbebdbcbebdbcbebdbcbebdbcbebdbcbebdbc
+ d4d4d4e4e4e4f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcbebdbc020204020204020204020204020204020204
+ 0202040202040a06049da6f39da6f39da6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f3
+ 9ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea6f39ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f4
+ 9ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f49ea7f4
+ 9aa3f39aa3f39aa3f39ba3f39ba3f39ba3f39ba3f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f3
+ 9ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f3
+ 9ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f3
+ 0202040c0c0c020204020204ecececfefefcfefefcfefefce4e4e4bebdbcbebdbcbebdbcbebdbcbebdbccccccce4e4e4
+ fefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc2c2c2c020204020204020204020204020204
+ 0202040202040202040202049ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f3
+ 9da5f39da5f39da5f39da5f39da5f39da5f39da5f39da5f39da5f39da5f39da5f39da5f39da5f39da6f39da6f39da6f3
+ 9da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f39da6f3
+ 99a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f39aa3f39aa3f39aa3f39aa3f3
+ 9aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f3
+ 9aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f3
+ 020204020204020204838384fefefcfefefcfefefcfefefcf4f4f4d4d4d4c4c4c4bebdbcbebdbcdddddcf4f4f4fefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4020204020204020204020204020204
+ 0202040202040202040202040202049ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f3
+ 9ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ca4f39ca4f39ca4f39ca4f39ca4f39ca4f39ca4f3
+ 9ca4f39ca4f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f39ca5f3
+ 98a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f3
+ 98a1f398a2f398a2f398a2f398a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f3
+ 99a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f3020204
+ 020204020204020204fefefcfefefcfefefcfefefcfefefcfefefcfefefcececece4e4e4f4f4f4fefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc020204020204020204020204020204
+ 0202040202040202040202040202049aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f3
+ 9aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f39aa3f3
+ 9aa3f39aa3f39aa3f39ba3f39ba3f39ba3f39ba3f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f39ba4f3
+ 97a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f3
+ 97a0f397a0f397a0f397a0f397a0f397a0f397a1f397a1f397a1f397a1f397a1f397a1f397a1f397a1f397a1f398a1f3
+ 98a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f3020204020204
+ 020204020204e4e4e4fefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc0a0604020204020204020204020204
+ 02020402020402020402020402020402020499a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f3
+ 99a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f3
+ 99a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f399a2f39aa3f39aa3f39aa3f39aa3f3
+ 969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3
+ 969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff396a0f396a0f396a0f396a0f396a0f3
+ 96a0f396a0f396a0f396a0f396a0f396a0f396a0f396a0f397a0f397a0f397a0f397a0f397a0f3020204020204020204
+ 020204242424e4e4e4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc2c2c2c020204020204020204020204
+ 02020402020402020402020402020402020402020498a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f3
+ 98a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f3
+ 98a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f398a1f3
+ 949ef2949ef2949ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2
+ 959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ff3
+ 959ff3959ff3959ff3959ff3959ff3959ff3959ff3959ff3959ff3959ff3959ff3959ff3020204020204020204020204
+ 020204838384dddddcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4f4f4f4ecececbebdbc0a0604020204020204020204
+ 02020402020402020402020402020402020402020402020496a0f396a0f396a0f396a0f396a0f396a0f396a0f396a0f3
+ 97a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f3
+ 97a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f397a0f3
+ 939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2949df2949df2949df2949df2
+ 949df2949df2949df2949df2949df2949df2949df2949df2949df2949df2949df2949df2949df2949df2949df2949df2
+ 949df2949df2949df2949df2949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2020204020204020204020204
+ 0202049c9c9cc4c4c4f4f4f4f4f4f4fefefcfefefcfefefcf4f4f4f4f4f4ececece4e4e4ecececf4f4f4fefefcfefefc
+ fefefcf4f4f4fefefcfefefcf4f4f4f4f4f4ececececececdddddcd4d4d4dddddcececec0c0c0c020204020204020204
+ 020204020204020204020204020204020204020204020204020204959ff3959ff3959ff3959ff3959ff3959ff3959ff3
+ 959ff3959ff3959ff3959ff3959ff3959ff3959ff3959ff3959ff3959ff3969ff3969ff3969ff3969ff3969ff3969ff3
+ 969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3969ff3
+ 929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2
+ 929cf2929cf2929cf2929cf2929cf2929cf2939cf2939cf2939cf2939cf2939cf2939cf2939cf2939cf2939cf2939cf2
+ 939cf2939cf2939cf2939cf2939cf2939cf2939cf2939cf2939cf2939df2939df2020204020204020204020204020204
+ 1414139c9c9ca4a4a4bebdbcd4d4d4ecececf4f4f4fefefcfefefcfefefcdddddce4e4e4f4f4f4fefefcfefefcfefefc
+ fefefcfefefcf4f4f4e4e4e4ccccccc4c4c4bebdbcbebdbcbebdbcc4c4c4c4c4c4d4d4d4bebdbc020204020204020204
+ 020204020204020204020204020204020204020204020204020204020204949df2949df2949ef2949ef2949ef2949ef2
+ 949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2949ef2
+ 949ef2949ef2949ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2959ef2
+ 919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2
+ 919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2929bf2
+ 929bf2929bf2929bf2929bf2929bf2929bf2929bf2929bf2929bf2929bf2020204020204020204020204020204020204
+ 1c1c1ba4a4a4bebdbce4e4e4f4f4f4fefefcfefefcfefefcfefefcfefefce4e4e4f4f4f4fefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcf4f4f4ecececdddddcd4d4d4c4c4c4bebdbcbebdbcc4c4c4e4e4e4646464020204020204
+ 565654242424020204020204020204020204020204020204020204020204939cf2939cf2939cf2939cf2939cf2939cf2
+ 939cf2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2
+ 939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2939df2949df2949df2949df2949df2
+ 909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2
+ 909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2
+ 909af2909af2909af2909af2909af2909af2909af2909af2909af2919af2020204020204020204020204020204020204
+ 141413ccccccecececf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcecececfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcecececdddddcccccccc4c4c4ccccccf4f4f40a0604020204
+ 0202040c0c0c444444020204020204020204020204020204020204020204929bf2929bf2929bf2929bf2929bf2929bf2
+ 929bf2929bf2929bf2929bf2929bf2929bf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2
+ 929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2929cf2
+ 8e98f28e98f28e98f28e98f28f98f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f2
+ 8f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f2
+ 8f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f20202040202040202043c3c3c0202040c0c0c
+ bebdbcecececfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4d4d4d4bebdbcdddddcf4f4f4020204
+ 020204020204020204444444020204020204020204020204020204020204020204909af2909af2909af2909af2909af2
+ 909af2919af2919af2919af2919af2919af2919af2919af2919af2919af2919af2919bf2919bf2919bf2919bf2919bf2
+ 919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2919bf2
+ 8d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d98f28d98f28d98f28d98f28e98f28e98f28e98f2
+ 8e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f2
+ 8e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f20202040202045c5c5c020204020204505050
+ f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4f4f4f4f4f4f4
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcdddddcc4c4c4e4e4e4020204
+ 0202040202040a06040202043c3c3c0202040202040202040202040202040202048f99f28f99f28f99f28f99f28f99f2
+ 8f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f29099f29099f29099f29099f29099f29099f2
+ 909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2909af2
+ 8c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c97f28c97f2
+ 8c97f28c97f28c97f28c97f28c97f28c97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f2
+ 8d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f20202040202041414130c0c0c0202040c0c0cf4f4f4
+ fefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcdddddcc4c4c4acacac
+ 0202040c0c0c2424241c1c1b1414131414130202040202040202040202040202040202048e98f28e98f28e98f28e98f2
+ 8e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f28e98f2
+ 8e98f28e98f28e98f28e98f28f98f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f28f99f2
+ 8b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f1
+ 8b95f18b95f18b95f18b96f18b96f18b96f18b96f18b96f18b96f18b96f18b96f18b96f18b96f18b96f18b96f18b96f1
+ 8c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f1020204020204646464020204020204747474fefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcf4f4f4fefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcf4f4f4f4f4f4
+ 0202040c0c0c3434343c3c3c0c0c0c4a4a4c0202040202040202040202040202040202048d97f28d97f28d97f28d97f2
+ 8d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f2
+ 8d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d97f28d98f28d98f28d98f28d98f28e98f28e98f28e98f2
+ 8a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f1
+ 8a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a95f18a95f18a95f18a95f18a95f18a95f18a95f18a95f1
+ 8a95f18a95f18a95f18a95f18a95f18a95f18a95f18a95f1020204020204242424020204020204020204fefefcfefefc
+ fefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ 1c1c1b1414133434341c1c1b0c0c0c0202043c3c3c0202040202040202040202040202040202048c96f18c96f18c96f1
+ 8c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f1
+ 8c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c96f18c97f28c97f2
+ 8893f18893f18893f18893f18993f18993f18993f18993f18993f18993f18993f18993f18993f18993f18993f18993f1
+ 8993f18993f18993f18993f18993f18993f18993f18993f18993f18993f18993f18993f18993f18994f18994f18994f1
+ 8994f18994f18994f18994f18994f18994f18994f18994f10202040202045656540202040202041c1c1bfefefcf4f4f4
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefce4e4e4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcf4f4f4f4f4f4fefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ a4a4a40202040a06040202040202040202045656540202040202040202040202040202040202048a95f18a95f18a95f1
+ 8a95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f1
+ 8b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f18b95f1
+ 8792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18892f18892f18892f1
+ 8892f18892f18892f18892f18892f18892f18892f18892f18892f18892f18892f18892f18892f18892f18892f18892f1
+ 8892f18892f18893f18893f18893f18893f18893f18893f10202040202040a0604020204020204d4d4d4fefefcfefefc
+ fefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcf4f4f4ecececfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcf4f4f4f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc0202040202040202040202040202041c1c1b0202040202040202040202040202040202048994f18994f18994f1
+ 8994f18994f18994f18994f18994f18994f18994f18994f18994f18994f18994f18a94f18a94f18a94f18a94f18a94f1
+ 8a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f18a94f1
+ 8691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f1
+ 8691f18691f18691f18691f18691f18691f18691f18791f18791f18791f18791f18791f18791f18791f18791f18791f1
+ 8791f18791f18791f18791f18791f18791f18791f1020204020204141413020204020204141413fefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4f4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc0202040202040202040202040202040202040a06040202040202040202040202040202048893f18893f18893f1
+ 8893f18893f18893f18893f18893f18893f18893f18893f18893f18893f18893f18893f18893f18893f18893f18893f1
+ 8893f18893f18893f18893f18993f18993f18993f18993f18993f18993f18993f18993f18993f18993f18993f18993f1
+ 8590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f1
+ 8590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f1
+ 8690f18690f18690f18690f18690f18690f18690f10202040202045c5c5c020204020204bebdbcfefefcf4f4f4fefefc
+ fefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcecececf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc0202040202040202040202040202040202040202040202040202040202040202040202040202048791f18792f1
+ 8792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f1
+ 8792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18792f18892f18892f18892f1
+ 848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1
+ 848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1
+ 848ff1848ff1848ff1848ff1848ff1848ff1020204020204020204242424020204020204fefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcecececf4f4f4fefefcfefefcfefefcfefefcfefefcf4f4f4
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc0202040202040202040202040202040202040202040202040202040202040202040202040202048690f18690f1
+ 8690f18690f18690f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f1
+ 8691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f18691f1
+ 828df0828df0828ef0828ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0
+ 838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0
+ 838ef0838ef0838ef0838ef0838ef0838ef00202040202040c0c0c0c0c0c0202040c0c0cfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcecececf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc0c0c0c020204020204020204020204141413020204020204020204020204020204020204020204848ff1848ff1
+ 848ff1848ff1858ff1858ff1858ff1858ff1858ff1858ff18590f18590f18590f18590f18590f18590f18590f18590f1
+ 8590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f18590f1
+ 818cf0818cf0818cf0818cf0818cf0818cf0818cf0818df0818df0818df0818df0818df0818df0818df0828df0828df0
+ 828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0
+ 828df0828df0828df0828df0828df00202040202040202040c0c0c0c0c0c020204444444fefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcf4f4f4fefefcf4f4f4dddddcf4f4f4fefefcfefefcfefefcfefefcf4f4f4fefefc
+ fefefcfefefcfefefcf4f4f4fefefcfefefcf4f4f4fefefcf4f4f4f4f4f4f4f4f4fefefcfefefcfefefcf4f4f4fefefc
+ f4f4f41c1c1b0202040202040202040202043c3c3c020204020204020204020204020204020204020204838ef0838ef0
+ 838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0848ef0848ef0848ff1848ff1848ff1
+ 848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1848ff1
+ 808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808cf0808cf0808cf0808cf0
+ 808cf0808cf0808cf0808cf0808cf0808cf0808cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0
+ 818cf0818cf0818cf0818cf002022f0202040202040202041c1c1b141413020204949494fefefcfefefcfefefcfefefc
+ f4f4f4fefefcfefefcfefefcfefefcfefefcf4f4f4fefefcdddddcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ f4f4f4f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc3434340202040202040202040202045c5c5c020204020204020204020204020204020204020204828df0828df0
+ 828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0828df0
+ 828df0828df0828ef0828ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0838ef0
+ 7f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af0
+ 7f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf07f8bf0
+ 7f8bf0808bf0808bf0808bf00202040202040202040202042c2c2c2c2c2c020204b5b4b3fefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcdddddcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcf4f4f4f4f4f4fefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc3c3c3c020204020204020204020204141413020204020204020204020204020204020204020204818cf0818cf0
+ 818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0818cf0
+ 818cf0818cf0818cf0818cf0818cf0818cf0818cf0818df0818df0818df0818df0818df0818df0818df0828df0828df0
+ 7e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f0
+ 7e89f07e89f07e89f07e89f07e89f07e8af07e8af07e8af07e8af07e8af07e8af07e8af07e8af07e8af07e8af07e8af0
+ 7e8af07e8af07e8af07e8af00202040202040202041414134a4a4c747474020204d4d4d4fefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcdddddcf4f4f4fefefcfefefcfefefcfefefcfefefcf4f4f4
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc4a4a4c0202040202040202040c0c0c020204020204020204020204020204020204020204020204808bf0808bf0
+ 808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0
+ 808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808bf0808cf0808cf0808cf0808cf0
+ 7c88f07c88f07c88f07c88f07c88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f0
+ 7d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d89f07d89f07d89f07d89f07d89f07d89f0
+ 7d89f07d89f07d89f07d89f00202040202040202040202040c0c0c5c5c5c020204dddddcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcdddddcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcf4f4f4f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefc
+ fefefc2424240202040202040202043c3c3c0202040202040202040202040202040202040202040202047e8af07e8af0
+ 7e8af07e8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af0
+ 7f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af07f8af0
+ 7b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07c87f07c87f0
+ 7c87f07c87f07c87f07c87f07c87f07c87f07c87f07c87f07c87f07c87f07c87f07c87f07c87f07c87f07c87f07c88f0
+ 7c88f07c88f07c88f07c88f00202040202040202040202040202040c0c0c020204ccccccfefefcfefefcfefefcfefefc
+ f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcdddddcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc0c0c0c0202040202043c3c3c2424241414132424240c0c0c0202040202040202040202040202047d89f07d89f0
+ 7d89f07d89f07d89f07d89f07d89f07d89f07d89f07d89f07d89f07d89f07d89f07d89f07e89f07e89f07e89f07e89f0
+ 7e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f07e89f0
+ 7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef
+ 7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7b86ef7b86ef7b86ef7b86ef7b86ef7b86ef7b86ef7b86ef
+ 7b86ef7b86ef7b86ef7b86ef020204020204885f077453070c0c0c020204444444acacacfefefcfefefcfefefcf4f4f4
+ fefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcdddddcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefc0202040c0c0c1414130202040202040202040202040c0c0c3c3c3c4444440202040202040202047c88f07c88f0
+ 7c88f07c88f07c88f07c88f07c88f07c88f07c88f07c88f07c88f07c88f07c88f07c88f07c88f07c88f07c88f07c88f0
+ 7c88f07c88f07c88f07c88f07c88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f07d88f0
+ 7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef
+ 7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef
+ 7985ef7a85ef7a85ef7a85ef744e22d89c08f5bd0cf5bd0cf2b60c291c040202044a4a4cfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcf4f4f4fefefcdddddcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ ececec0202041414130202040202040202040202040202040202040202043c3c3c6c6c6b0a06040202047b87f07b87f0
+ 7b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f0
+ 7b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07b87f07c87f07c87f0
+ 7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef
+ 7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef
+ 7884ef7884ef7884ef7884efcf9418f2b60cf5bd0cf5bd0cf5bd0cf5bd0c392a0c0202040c0c0cdddddcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefce4e4e4f4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcdfa509f3c40bf3cd0c
+ f5bd0cc39a0e0202040202040202040202040202040202040202040202043434342424241414137a85ef7a85ef7a85ef
+ 7a85ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef
+ 7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef7a86ef
+ 7683ef7683ef7683ef7683ef7683ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef
+ 7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef
+ 7783ef7783ef7783efc08507d89c08ecb40bf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c1414130202041c1c1bf4f4f4fefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefce4e4e4fefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcf4f4f4fefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcf4f4f4e5ac09f3c40bf6d50d
+ f6d50d946c090202040202040202040202040202040202040202040a06041c1c1b0a0604a4770af1d3117884ef7884ef
+ 7884ef7884ef7884ef7984ef7984ef7984ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef
+ 7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef7985ef
+ 7581ef7581ef7581ef7581ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7682ef
+ 7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef
+ 7682ef7682ef7682efcf9407dfa509f2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cd7ac09020204020204141413dddddc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcdddddcecececf4f4f4fefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcdfa509f5bd0cf3c40b
+ ebc40c5c4309020204020204020204020204020204020204020204020204020204140d04ebc40cf1d311d7ac097783ef
+ 7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7784ef7784ef7884ef7884ef7884ef7884ef
+ 7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef7884ef
+ 7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7481ef7481ef7481ef7481ef7481ef7481ef7481ef
+ 7481ef7481ef7481ef7481ef7481ef7481ef7481ef7481ef7581ef7581ef7581ef7581ef7581ef7581efb67e0ab67e0a
+ b57e2fb67e0ac78a08d89c08e5ac09f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf3c40bc2930b0202040202040c0c0c
+ acacacfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4dfa509f2b60cf5bd0c
+ e1b40a784e04020204020204020204020204020204020204020204020204020204d19b09ebc40cf3c40bebbc0b7682ef
+ 7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7682ef7683ef
+ 7683ef7683ef7683ef7683ef7683ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef7783ef
+ 737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef7380ef7380ef
+ 7380ef7380ef7380ef7380ef7380ef7380ef7380ef7380ef7380ef7380ef7380efb98309cf9418daa309dfa509daa309
+ d89c08dfa509e5ac09ebb316f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf3cd0cb98309020204020204
+ 020204444444fefefcf4f4f4f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcccccccc4c4c4d89c08f2b60cecb40b
+ dfa509b67e0a1f16040202040202040202040202040202040202040a0604c08507e1b40aebbc0bf2b60cf2b60c7581ef
+ 7581ef7581ef7581ef7581ef7581ef7581ef7581ef7581ef7581ef7581ef7581ef7581ef7581ef7581ef7581ef7581ef
+ 7581ef7581ef7581ef7581ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7582ef7682ef
+ 727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee
+ 727eee727eee727eee727fef727fef727fef727fef727fef727fef727fef727fefcf9418dfa509ebb316ecb40bebb316
+ e5ac09ecb40bf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cebbc0bf3c40be2bc0c020204020204
+ 0202040202041c1c1becececfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcf4f4f4fefefcfefefcf4f4f4fefefcfefefcfefefcfefefce4e4e4c4c4c4c4c4c4d89c08ecb40be5ac09
+ d89c08b98309ab7205020204020204020204020204020204291c04a4770ad89c08e1b40aebbc0bf2b60cf2b60c7480ef
+ 7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef
+ 7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7480ef7481ef7481ef7481ef7481ef7481ef7481ef7481ef
+ 707dee707dee707dee707dee707dee707dee717dee717dee717dee717dee717dee717dee717dee717dee717dee717dee
+ 717dee717dee717dee717dee717dee717dee717dee717dee717eee717eee717eeed7960de5ac09ecb40bf5bd0cf2b60c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cedcc0e946c09020204
+ 0202040202040202040c0c0cc4c4c4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcd4d4d4c4c4c4c4c4c4d7960de5ac09e5ac09
+ daa309c98e07b98309ad780aa5720aa46d05a46d05ad780ab67e0ac2930be5ac09f2b60cf2b60cf5bd0cf5bd0c727fef
+ 727fef727fef727fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef
+ 737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef737fef7380ef7380ef
+ 6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee707cee
+ 707cee707cee707cee707cee707cee707cee707cee707cee707cee707cee707ceed19b09e5ac09f2b60cf5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf2b60cf3c40be2bc0c312305
+ 020204020204020204020204020204a4a4a4fefefcf4f4f4fefefcfefefcfefefcfefefcfefefcf4f4f4f4f4f4fefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcd4d4d4c4c4c4c4c4c4cf9418e5ac09ecb40b
+ dfa509d89c08cf9407c78a08c78a08c78a08c78a08cf9407d89c08e5ac09f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cebb316
+ 717eee717eee717eee717eee717eee717eee717eee717eee717eee717eee717eee717eee727eee727eee727eee727eee
+ 727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee727eee
+ 6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee
+ 6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6f7bee6f7beecf9418e5ac09f2b60cf5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cedcc0ed19b09
+ 0202040202040202040202040202040a0604ecececfefefcfefefcf4f4f4fefefcfefefcf4f4f4fefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcdddddcc4c4c4bebdbcc18b0ad89c08ecb40b
+ ecb40bdfa509d89c08d89c08cf9407cf9407d19b09daa309e5ac09ecb40bf5bd0cf5bd0cf5bd0cf5bd0cebbc0bf2b60c
+ d7ac09707dee707dee707dee707dee707dee707dee707dee707dee707dee707dee707dee707dee707dee707dee707dee
+ 707dee707dee707dee707dee707dee707dee717dee717dee717dee717dee717dee717dee717dee717dee717dee717dee
+ 6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee
+ 6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aeec98e07dfa509ebb316f2b60cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cebc40c
+ a5720a020204020204020204020204020204838384fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4ecececc4c4c4c4c4c4b98309d89c08ecb40b
+ ecb40becb40be5ac09dfa509daa309dfa509e5ac09e5ac09ecb40bf2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cebb316
+ f2b60cd19b096f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee
+ 6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee6f7cee707cee
+ 6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee
+ 6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79eec98e07d89c08ebb316f5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cedcc0e
+ d7ac09020204020204020204020204020204505050fefefcfefefcf4f4f4f4f4f4fefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4eedec4c4c4242424c08507d89c08ecb40b
+ f2b60cf2b60cecb40be5ac09e5ac09e5ac09e5ac09ecb40bf2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ ebb316ebbc0bc39a0e6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee
+ 6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee6e7bee
+ 6a78ee6a78ee6a78ee6a78ee6a78ee6a78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee
+ 6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78eec08507d89c08e5ac09f5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cebbc0b
+ f3cd0cc98e07020204020204020204020204f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcf4eede141413402c07b98309d89c08ecb40b
+ f2b60cf5bd0cf5bd0cf5bd0cf2b60cf2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cdaa3096d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee
+ 6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee6d7aee
+ 6976ed6976ed6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee
+ 6a77ee6a77ee6a77ee6a77ee6a77ee6a77ee6a77ee6a77ee6a77ee6a77ee6a77eec78a08d89c08ebb316f5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ ebbc0bebc40c4930060c0c0c444444fefefcf4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcf4f4f4f4f4f4fefefcfefefc3c3c3c0202044c3604b98309d89c08ecb40b
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cdaa3096b78ee6b78ee6b79ee6b79ee6b79ee6b79ee6b79ee6c79ee6c79ee6c79ee
+ 6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee6c79ee
+ 6875ed6875ed6875ed6875ed6875ed6875ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed
+ 6876ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed6976ed6976edc78a08d89c08ebb316f5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ ebbc0bedcc0ed19b09a4a4a4fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ f4f4f4fefefcf4f4f4f4f4f4fefefcfefefcfefefcfefefcf4f4f41c1c1b020204020204654307b98309d89c08ecb40b
+ f2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cdaa3096a77ee6a77ee6a77ee6a77ee6a77ee6a77ee6a77ee6a78ee6a78ee6a78ee
+ 6a78ee6a78ee6a78ee6a78ee6a78ee6a78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee6b78ee
+ 6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6775ed6775ed6775ed6775ed6775ed
+ 6775ed6775ed6775ed6775ed6775ed6775ed6775ed6775ed6775ed6775ed6775edc78a08d89c08f2b60cf2b60cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f2b60cebc40ce2bc0cb98309fefefcfefefcfefefcf4f4f4f4f4f4fefefcfefefcfefefcfefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefc020204020204020204020204784e04b98309dfa509ecb40b
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf2b60cebb316cf94186976ed6976ed6976ed6976ed6976ed6976ed6976ed6976ed6976ed6976ed
+ 6976ed6976ed6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee6977ee
+ 6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed
+ 6674ed6674ed6674ed6674ed6674ed6674ed6674ed6674ed6674ed6674ed6674edc78a08dfa509f2b60cf5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cebbc0be2bc0cdfa509906007fefefcfefefcfefefcfefefcfefefcfefefcfefefcfefefcf4f4f4fefefcfefefc
+ fefefcfefefcfefefcfefefcfefefcfefefc1c1c1b020204020204020204020204020204745307b67e0adaa309f2b60c
+ f2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cf5bd0cebb316d89c08ce8e086875ed6875ed6875ed6875ed6875ed6875ed6875ed6875ed6875ed6875ed6875ed
+ 6875ed6875ed6875ed6875ed6875ed6875ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed6876ed
+ 6472ed6472ed6472ed6472ed6472ed6472ed6472ed6572ed6572ed6572ed6572ed6572ed6572ed6572ed6572ed6572ed
+ 6572ed6572ed6572ed6572ed6572ed6573ed6573ed6573ed6573ed6573edb37907cf9407f2b60cf5bd0cf5bd0cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cf2b60ce1b40adfa509aa7e0a444444f4f4f4f4f4f4fefefcfefefcfefefcf4f4f4fefefcfefefcfefefcfefefc
+ fefefcfefefcfefefcfefefc3c3c3c020204020204020204020204020204020204140d04744904b67e0adaa309f2b60c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf2b60c
+ f2b60ce5ac09d89c08b57e2f6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed
+ 6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6774ed6775ed6775ed6775ed6775ed6775ed
+ 6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed
+ 6471ed6471ed6471ed6471ed6471ed6471ed6471ed6471ed6471ed6471edc08507dfa509ecb40bf5bd0cf2b60cf5bd0c
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf2b60c
+ f5bd0cf2b60ce5ac09daa309b983095b3a050202048d8d8cf4f4f4f4f4f4fefefcfefefcfefefcfefefcf4f4f4fefefc
+ f4f4f4c4c4c42424240202040202040202040202040202040202040202040202041f1604784e04b98309daa309f2b60c
+ f2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf2b60cebb316dfa509
+ d89c08ce8e086573ed6573ed6573ed6573ed6573ed6573ed6573ed6573ed6573ed6573ed6573ed6673ed6673ed6673ed
+ 6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed6673ed
+ 6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed
+ 6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270edc78a08d7960de5ac09f2b60cf2b60cf2b60c
+ f5bd0cf5bd0cf5bd0cf2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cf5bd0ce5ac09d89c08b98309784e04140d04020204020204020204020204020204020204020204020204020204
+ 020204020204020204020204020204020204020204020204020204020204020204402c07875805b98309d89c08ecb40b
+ f5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cebb316ebb316ebb316dfa509c78a08976105
+ 6472ed6472ed6472ed6472ed6472ed6472ed6472ed6472ed6472ed6472ed6472ed6472ed6472ed6472ed6472ed6472ed
+ 6472ed6472ed6472ed6472ed6472ed6472ed6472ed6572ed6572ed6572ed6572ed6572ed6572ed6572ed6572ed6572ed
+ 616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed
+ 616fed616fed616fed616fed616fed616fed616fed616fed616fed616fedb67e0ac98e07cf9407d89c08dfa509e5ac09
+ e5ac09e5ac09e5ac09f2b60cf2b60cf5bd0cf5bd0cf2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cf2b60ce5ac09d89c08b37907784e04493006020204020204020204020204020204020204020204020204020204
+ 020204020204020204020204020204020204020204020204020204020204020204493006875805b67e0ad19b09ecb40b
+ f2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0cf2b60ce5ac09e5ac09daa309ce8e08b67e0a6371ed6371ed
+ 6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed
+ 6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed6371ed
+ 606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec
+ 606eec606eec606eec606eec606eec606eec606eec606eec606eec606eecad780ab37907b67e0ab98309c18b0ace8e08
+ cf9407d89c08d89c08dfa509dfa509e5ac09e5ac09ecb40bf5bd0cf2b60cf2b60cf5bd0cf5bd0cf5bd0cf5bd0cf5bd0c
+ f5bd0cf2b60cdaa309c78a08ab72057d5305533606020204020204020204020204020204020204020204020204020204
+ 020204020204020204020204020204020204020204020204020204020204020204493006835204b37907c98e07dfa509
+ f2b60cf5bd0cf2b60cf2b60cf5bd0cf5bd0cf2b60cebb316dfa509d7960dce8e08c78a087449046270ed6270ed6270ed
+ 6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed
+ 6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed6270ed
+ 5e6dec5e6dec5e6dec5e6dec5e6dec5e6dec5e6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec
+ 5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec9761059d6a07ab7205
+ b37907b37907c08507c08507c78a08c78a08cf9407d89c08d89c08dfa509f2b60cf2b60cf2b60cf5bd0cf5bd0cf2b60c
+ f2b60ce5ac09cf9407b37907976105744904493006020204020204020204020204020204020204020204020204020204
+ 020204020204020204020204020204020204020204020204020204020204020204402c07744904ab7205b98309d89c08
+ e5ac09ecb40bf2b60cf2b60cf2b60cebb316e5ac09dfa509d7960dc08507b37907606eec606eec606eec606eec606eec
+ 606fed606fed606fed606fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed
+ 616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed616fed
+ 5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec
+ 5d6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec
+ 5e6cec8352048f5a049761059b66059b6605a46d05ad780ab37907b98309cf9407d7960dd89c08dfa509dfa509e5ac09
+ d89c08c78a08b67e0a9b66058352045b3a05291c040202040202040202040202045e6dec5e6dec5e6dec5e6dec5f6dec
+ 5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec020204020204020204020204382605654307976105ab7205c18b0a
+ d89c08dfa509dfa509e5ac09dfa509d89c08cf9407b98309ab7205784e045f6dec5f6dec5f6dec5f6dec5f6dec5f6dec
+ 5f6dec5f6dec5f6dec5f6dec5f6dec5f6eec5f6eec5f6eec5f6eec5f6eec5f6eec5f6eec5f6eec5f6eec606eec606eec
+ 606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec606eec
+ 5c6aec5c6aec5c6aec5c6aec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec
+ 5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec
+ 5d6bec5d6bec5d6bec5d6bec5d6bec6c4505784e04885f07906007976105ab7205b37907b67e0ab98309c98e07c78a08
+ c08507ab72059761058352046c45054930060202045d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec
+ 5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5e6cec5e6cec402c075b3a058f5a049b6605b37907
+ b98309c08507c78a08c98e07c08507b98309b379079d6a077449045e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec
+ 5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6cec5e6dec5e6dec5e6dec5e6dec5e6dec5e6dec
+ 5e6dec5e6dec5e6dec5e6dec5e6dec5e6dec5e6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec5f6dec
+ 5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec
+ 5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec
+ 5b6aec5b6aec5b6aec5c6aec5c6aec5c6aec5c6aec5c6aec472f1f603e058352048f5a049761059b66059d6a079b6605
+ 9761058352047449046c45055b3a055c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6bec5c6bec5c6bec5c6bec
+ 5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec4930067449048f5a04a46d05
+ ab7205b37907ad780ab37907ad780aa46d059761055336065d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec
+ 5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6bec5d6cec
+ 5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec5d6cec
+ 5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a69ec5a69ec5a69ec
+ 5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec
+ 5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5b3a05744904744904784e04784e04
+ 744904744904603e054930063926205b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec
+ 5b69ec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec493006603e05875805
+ 9761059b66059b66059b6605976105784e046543075b6aec5b6aec5b6aec5b6aec5c6aec5c6aec5c6aec5c6aec5c6aec
+ 5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec5c6aec
+ 5c6aec5c6aec5c6aec5c6aec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec5c6bec
+ 5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5967ec5967ec5967ec5967ec5967ec5967ec5967ec5967ec
+ 5967ec5967ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec
+ 5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec493006493006
+ 493006402c075968ec5968ec5968ec5968ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec
+ 5a68ec5a68ec5a68ec5a68ec5a68ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec493006
+ 493006533606533606493006402c075a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec5a69ec
+ 5a69ec5a69ec5a69ec5a69ec5a69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec
+ 5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b69ec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec5b6aec
+ 5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb
+ 5766eb5866eb5866eb5866eb5866eb5866eb5866eb5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec
+ 5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec
+ 5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec
+ 5967ec5967ec5967ec5967ec5967ec5967ec5967ec5967ec5967ec5967ec5968ec5968ec5968ec5968ec5968ec5968ec
+ 5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec
+ 5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5968ec5a68ec5a68ec
+ 5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a68ec5a69ec5a69ec5a69ec
+ 5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb
+ 5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5765eb5766eb5766eb5766eb5766eb
+ 5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb
+ 5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb
+ 5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5866eb5866eb5866eb5866eb5866eb5866eb5867ec
+ 5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec
+ 5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec
+ 5867ec5867ec5867ec5867ec5867ec5867ec5867ec5867ec5967ec5967ec5967ec5967ec5967ec5967ec5967ec5967ec
+ 5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb
+ 5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb
+ 5564eb5565eb5565eb5565eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb
+ 5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb
+ 5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb
+ 5665eb5665eb5665eb5765eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb
+ 5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb
+ 5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb5766eb
+ 5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb
+ 5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb
+ 5463eb5463eb5463eb5463eb5463eb5463eb5464eb5464eb5464eb5464eb5464eb5464eb5464eb5564eb5564eb5564eb
+ 5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb
+ 5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb
+ 5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5565eb5565eb5565eb5665eb5665eb5665eb5665eb
+ 5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb
+ 5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb5665eb
+ 5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb
+ 5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb
+ 5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5363eb5363eb5363eb5363eb5363eb
+ 5363eb5363eb5363eb5363eb5363eb5363eb5363eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb
+ 5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb
+ 5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5464eb5464eb
+ 5464eb5464eb5464eb5464eb5464eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb
+ 5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb5564eb
+ 5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb
+ 5161eb5161eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb
+ 5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5262eb
+ 5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb
+ 5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb
+ 5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb
+ 5362eb5362eb5362eb5363eb5363eb5363eb5363eb5363eb5363eb5363eb5363eb5363eb5363eb5363eb5363eb5463eb
+ 5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb5463eb
+ 505feb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb
+ 5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5160eb5160eb5160eb5160eb5160eb
+ 5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb
+ 5160eb5160eb5160eb5160eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb
+ 5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5261eb5261eb5261eb5261eb5261eb5261eb
+ 5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb5261eb
+ 5261eb5261eb5261eb5261eb5261eb5261eb5261eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb
+ 5262eb5262eb5262eb5262eb5262eb5262eb5262eb5262eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb5362eb
+ 4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb
+ 4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb
+ 4f5feb4f5feb4f5feb4f5feb505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb
+ 505feb505feb505feb505feb505feb505feb505feb505feb505feb5060eb5060eb5060eb5060eb5060eb5060eb5060eb
+ 5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb
+ 5060eb5060eb5060eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb
+ 5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5160eb5161eb5161eb5161eb5161eb
+ 5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb5161eb
+ 4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5eea4e5eea4e5eea4e5eea4e5eea
+ 4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea
+ 4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4f5eea4f5eea
+ 4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5feb4f5feb
+ 4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb
+ 4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb505feb505feb505feb505feb
+ 505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb505feb
+ 505feb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb5060eb
+ 4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4d5cea4d5cea4d5cea4d5cea4d5cea4d5cea4d5cea
+ 4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea
+ 4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea
+ 4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea
+ 4e5dea4e5dea4e5dea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea
+ 4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea
+ 4e5eea4e5eea4e5eea4e5eea4e5eea4e5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea
+ 4f5eea4f5eea4f5eea4f5eea4f5eea4f5eea4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb4f5feb
+ 4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea
+ 4b5bea4b5bea4c5bea4c5bea4c5bea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea
+ 4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea
+ 4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea
+ 4c5cea4d5cea4d5cea4d5cea4d5cea4d5cea4d5cea4d5cea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea
+ 4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea
+ 4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4d5dea4e5dea
+ 4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5dea4e5eea4e5eea4e5eea4e5eea4e5eea
+ 4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea
+ 4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5bea4a5bea4b5bea4b5bea4b5bea4b5bea4b5bea
+ 4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea
+ 4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea
+ 4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4c5bea4c5bea4c5bea4c5cea4c5cea4c5cea
+ 4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea
+ 4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea
+ 4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4c5cea4d5cea4d5cea4d5cea4d5cea4d5cea4d5cea4d5cea
+ 4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea
+ 4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea495aea495aea
+ 495aea495aea495aea495aea495aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea
+ 4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea
+ 4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea
+ 4a5aea4a5bea4a5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea
+ 4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea
+ 4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea4b5bea
+ 4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea
+ 4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea
+ 4858ea4858ea4858ea4859ea4859ea4859ea4859ea4859ea4859ea4859ea4859ea4859ea4859ea4859ea4959ea4959ea
+ 4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea
+ 4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea
+ 4959ea4959ea4959ea4959ea4959ea4959ea495aea495aea495aea495aea495aea495aea495aea4a5aea4a5aea4a5aea
+ 4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea
+ 4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea4a5aea
+ 4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea
+ 4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea
+ 4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea
+ 4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea
+ 4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea
+ 4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4859ea4859ea4859ea4859ea4859ea
+ 4859ea4859ea4859ea4859ea4859ea4859ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea
+ 4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea4959ea
+ 4556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e9
+ 4556e94556e94556e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e9
+ 4656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94657ea4657ea4657ea
+ 4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea
+ 4657ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea
+ 4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea
+ 4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea4758ea
+ 4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea4858ea
+ 4455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e9
+ 4455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94555e94555e94555e94555e9
+ 4555e94555e94555e94555e94555e94555e94555e94555e94555e94555e94555e94555e94555e94555e94555e94555e9
+ 4555e94555e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e9
+ 4556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94656e94656e94656e94656e94656e9
+ 4656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e94656e9
+ 4656e94656e94656e94656e94656e94657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea
+ 4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4657ea4757ea4757ea4757ea4757ea4757ea4757ea4757ea
+ 4353e94353e94353e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e9
+ 4354e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e94354e9
+ 4354e94354e94354e94354e94354e94454e94454e94454e94454e94454e94454e94454e94454e94454e94454e94454e9
+ 4454e94454e94454e94454e94454e94454e94454e94455e94455e94455e94455e94455e94455e94455e94455e94455e9
+ 4455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e94455e9
+ 4455e94455e94455e94455e94555e94555e94555e94555e94555e94555e94555e94555e94555e94555e94555e94555e9
+ 4555e94555e94555e94555e94555e94555e94555e94555e94555e94555e94556e94556e94556e94556e94556e94556e9
+ 4556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e94556e9
+ "
+) rotated 15 ysized 4cm ;
+\stopMPcode
+
+\stoptitle
+
+\starttitle[title=Layers]
+
+\startbuffer
+\defineviewerlayer[rotation:30]
+\defineviewerlayer[rotation:60]
+\defineviewerlayer[rotation:90]
+
+\startMPcode
+draw image (
+
+ fill fullsquare scaled 8cm rotated 30
+ withcolor red
+ withtransparency(1,.5)
+ onlayer "rotation:30" ;
+
+ fill fullsquare scaled 8cm rotated 60
+ withcolor green
+ withtransparency(1,.5)
+ onlayer "rotation:60" ;
+
+ fill fullsquare scaled 8cm rotated 90
+ withcolor blue
+ withtransparency(1,.5)
+ onlayer "rotation:90" ;
+
+) ysized TextHeight ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\stoptitle
+
+\starttitle[title=Outlines]
+
+% \startMPcode
+% graphictext ("Hi There!") scaled 10 ;
+% \stopMPcode
+
+\startbuffer
+\startMPcode
+ draw outlinetext.d
+ ("Hi There!")
+ (withcolor "red" withpen pencircle scaled 1/10 )
+ scaled 10 ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\startbuffer
+\startMPcode
+ draw outlinetext.f
+ ("Hi There!")
+ (withcolor "green")
+ scaled 10 ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\startbuffer
+\startMPcode
+ draw outlinetext.b
+ ("Hi There!")
+ (withcolor "green")
+ (withcolor "red" withpen pencircle scaled 1/10 )
+ scaled 10 ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\startbuffer
+\startMPcode
+ draw outlinetext.r
+ ("Hi There!")
+ (withcolor "green")
+ (withcolor "red" withpen pencircle scaled 1/10 )
+ scaled 10 ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\startbuffer
+\startMPcode
+ draw outlinetext.d
+ ("\framed[align=normal]{\input klein }")
+ (withcolor "white" withpen pencircle scaled 1/10 )
+ xsized TextWidth ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\stoptitle
+
+\starttitle[title=Images]
+
+\startbuffer
+\startMPcode
+ draw externalfigure ("cow.pdf") xsized 4cm ;
+\stopMPcode
+
+\startMPcode
+ draw figure ("cow.pdf") rotated -25 xsized 2cm shifted (14cm,-3cm) ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\stoptitle
+
+\starttitle[title=Text]
+
+\startbuffer
+\startMPcode
+draw textext("\bfd Hello, {\green does} this work?")
+ shifted (4cm,2cm)
+ rotated 10
+ withcolor white ;
+
+draw textext("\bfd Hello, {\green does} this work?")
+ shifted (4cm,-2cm)
+ rotated -10
+ withcolor white
+ withtransparency (1,0.5);
+
+for i=1 step 10 until 360:
+ draw textext(decimal i)
+ shifted (0,4.5cm)
+ rotated i
+ withcolor i/360 ;
+endfor ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\stoptitle
+
+\starttitle[title=Paths]
+
+\startbuffer
+\startMPcode
+draw image (
+ path p ; p := reverse fullcircle scaled 4cm ;
+ draw p ;
+ draw followtext(p,
+ "A nice clip: Rai Thistlethwayte's Betty Page @ Keyscape.\quad")
+) ysized .6TextHeight ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\startbuffer
+\startMPcode
+draw image (
+ path p ; p := fullcircle scaled 4cm ;
+ fill p withcolor white ;
+ draw followtext(reverse p,"\obeydiscretionaries\samplefile{sapolsky}") ;
+) ysized .6TextHeight ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer \getbuffer \page
+
+\startbuffer
+\startMPcode
+draw image (
+ path p ; p := fullcircle scaled 4cm ;
+ fill p withcolor white ;
+ draw followtext(reverse p,"\obeydiscretionaries\samplefile{sapolsky}") ;
+) ysized TextHeight ;
+\stopMPcode
+\stopbuffer
+
+{\showfontkerns \getbuffer} \page
+
+\stoptitle
+
+\starttitle[title=So \unknown]
+
+\startitemize
+ \startitem
+ Get rid of old code snippets. And maybe translate some experiments into useful code.
+ \stopitem
+ \startitem
+ Optimize some of the code. On the average the code is quite efficient but less
+ is often better.
+ \stopitem
+ \startitem
+ Check the \METAFUN\ manual for recent additions. And maybe remove older
+ (more \MPII ish) solutions.
+ \stopitem
+ \startitem
+ Think about a way to circumvent unwanted suffix expansion so that we can use more keywords
+ without problems. (Maybe I should come up with a decent \METAPOST\ extension. Needs discussion
+ with Alan Braslau.)
+ \stopitem
+\stopitemize
+
+\stoptitle
+
+\stoptext
diff --git a/doc/context/presentations/context/2007/context-2007-luatex.tex b/doc/context/presentations/context/2007/context-2007-luatex.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/context/2007/context-2007-luatex.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/context/2007/context-2007-mkiv.tex b/doc/context/presentations/context/2007/context-2007-mkiv.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/context/2007/context-2007-mkiv.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/context/2010/context-2010-just-in-time-1.tex b/doc/context/presentations/context/2010/context-2010-just-in-time-1.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/context/2010/context-2010-just-in-time-1.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/context/2010/context-2010-just-in-time-2.tex b/doc/context/presentations/context/2010/context-2010-just-in-time-2.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/context/2010/context-2010-just-in-time-2.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/context/2010/context-2010-requirements.tex b/doc/context/presentations/context/2010/context-2010-requirements.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/context/2010/context-2010-requirements.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/context/2010/context-2010-structure-matters.tex b/doc/context/presentations/context/2010/context-2010-structure-matters.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/context/2010/context-2010-structure-matters.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/context/2010/context-2010-workflows.tex b/doc/context/presentations/context/2010/context-2010-workflows.tex
new file mode 100644
index 000000000..dc4b4890b
--- /dev/null
+++ b/doc/context/presentations/context/2010/context-2010-workflows.tex
@@ -0,0 +1 @@
+\starttext todo \stoptext
diff --git a/doc/context/presentations/examples/present-steps-001.pdf b/doc/context/presentations/examples/present-steps-001.pdf
new file mode 100644
index 000000000..c9ad75613
--- /dev/null
+++ b/doc/context/presentations/examples/present-steps-001.pdf
Binary files differ
diff --git a/doc/context/presentations/examples/present-steps-001.tex b/doc/context/presentations/examples/present-steps-001.tex
new file mode 100644
index 000000000..7a20779fb
--- /dev/null
+++ b/doc/context/presentations/examples/present-steps-001.tex
@@ -0,0 +1,114 @@
+\usemodule[present-steps]
+
+\setuppapersize
+ [S6]
+
+\setupinteraction
+ [state=start]
+
+
+\setupwhitespace
+ [big]
+
+\setupheadertexts
+ []
+
+\setupbodyfont
+ [modernlatin]
+
+\setuplist
+ [chapter]
+ [interaction=all]
+
+\defineoverlay
+ [go-on]
+ [\overlaybutton{nextpage}]
+
+\setupbackgrounds
+ [page]
+ [background=go-on]
+
+\starttext
+
+\title{Contents}
+
+\placelist
+ [chapter]
+
+\startsteps
+ \startstep
+ \ifnum\currentstep > 1
+ \repeathead[chapter]
+ \else
+ \chapter{Step Set 1}
+ \fi
+ \stopstep
+
+ \startstep
+ STEP ONE
+ \stopstep
+
+ \startstep
+ STEP TWO
+ \stopstep
+
+ \startstep
+ STEP THREE
+ \stopstep
+
+ \startstep
+ STEP FOUR
+ \stopstep
+
+\stopsteps
+
+\startsteps
+
+ \startstep[option=title]
+ \chapter{Step Set 2}
+ \stopstep
+
+ \startstep[option=repeat]
+ \repeathead[chapter]
+ \stopstep
+
+ \startstep[n=2]
+ this is a formula
+ \startformula
+ \startsubstep e = \stopsubstep
+ \startsubstep m c^2 \stopsubstep
+ \stopformula
+ \stopstep
+
+ \startstep
+ \startitemize
+ \startitem STEP 1a \stopitem
+ \startitem STEP 1b \stopitem
+ \stopitemize
+ \stopstep
+
+ \startstep[n=2]
+ this is a formula
+ \startformula
+ \startsubstep e = \stopsubstep
+ \startsubstep m c^2 \stopsubstep
+ \stopformula
+ \stopstep
+
+ \startstep
+ \startitemize[continue]
+ \startitem STEP 2a \stopitem
+ \startitem STEP 2b \stopitem
+ \stopitemize
+ \stopstep
+
+ \startstep
+ \startitemize[continue]
+ \startitem STEP 3a \stopitem
+ \startitem STEP 3b \stopitem
+ \stopitemize
+ \stopstep
+
+\stopsteps
+
+\stoptext
diff --git a/doc/context/presentations/tug/2001/tug-2001-ideas.pdf b/doc/context/presentations/tug/2001/tug-2001-ideas.pdf
new file mode 100644
index 000000000..ca841c206
--- /dev/null
+++ b/doc/context/presentations/tug/2001/tug-2001-ideas.pdf
Binary files differ
diff --git a/doc/context/presentations/tug/2001/tug-2001-ideas.tex b/doc/context/presentations/tug/2001/tug-2001-ideas.tex
new file mode 100644
index 000000000..48eb8fd3b
--- /dev/null
+++ b/doc/context/presentations/tug/2001/tug-2001-ideas.tex
@@ -0,0 +1,445 @@
+\usemodule[present-dark]
+
+\usemodule[abr-01]
+
+\startdocument
+
+\StartIdea
+ [ title={Hans Hagen},
+ remark={PRAGMA ADE, Hasselt NL},
+ url={www.pragma-ade.com}]
+
+{\bfd \setstrut \strut TUG 2001}
+
+{\bfa \setstrut \strut A \TEX\ Odyssey}
+
+\blank[2*big]
+
+\startitemize [packed]
+ \startitem what way are we heading \stopitem
+ \startitem will there be documents \stopitem
+ \startitem is typography still needed \stopitem
+ \startitem are we still talking \TEX \stopitem
+\stopitemize
+
+\StopIdea
+
+\StartIdea
+
+Until now, the main source of information is books. In the next couple of slides,
+I will present some quotes from books I read the last couple of years, written
+by: Arthur \remark {Clarke} {physics}, Greg \remark {Bear} {psychology}, Graham
+\remark {Hancock} {journalism}, Peter \remark {Wilbur} {ergonomics} and Michael
+Burke, Jared \remark {Diamond} {history}, Edward \remark {Tufte} {design}, Peter
+Ward and Donald \remark {Brownlee} {biology}, Steve \remark{Reich} {music} and
+Beryl Korot, Richard \remark {Kadrey} {fantasy}, Brian \remark {Butterworth}
+{math} and of course Donald \remark {Knuth} {informatics}.
+
+\StopIdea
+
+\StartIdea
+ [ title={ed. David G. Stork},
+ remark={Hal's Legacy, 1997}]
+
+[Arthur Clarke:] Although I've never considered 2001 as a strict
+predict\-ion|<|but as more of a vision, a way things could work|>|I have long
+kept track, informally, of how our vision compares with computer science reality.
+Some things we got right---even righter than we ever had reason to suspect.
+Others, well, who could have \remark {known} {so, to what extent can we predict
+the future of documents}.
+
+[Summary:] much of the science predicted in 1968 is okay, but with regards to
+\remark {computers} {in this respect, \TeX\ is surprisingly up|-|to|-|date} a
+couple of points are missed: they have become smaller, \remark {AI} {and
+automated text processing is still difficult} is far from operational, natural
+speech, reasoning and lipreading are not really available, fault tolerance is
+there, we have lcd's, graphical user interfaces and windows, don't communicate in
+terminal messages, have mice and other means of input.
+
+\StopIdea
+
+\StartIdea
+ [ title={Arthur Clarke},
+ remark={2001, A space Odyssey, p. 66, 1968}]
+
+After a short walk through a tunnel packed with pipes and \remark {cables} {we
+are already going wireless}, and echoing hollowly with rhythmic thumbing and
+throbbings, they arrived in executive territory, and Floyd found himself back in
+the familiar environment of \remark {typewriters} {the good old times of \quote
+{think before you key}}, \remark {office} {indeed, most of today's users run
+\quote {office}} computers, \remark {girl} {everyone is now a typist} assistants,
+\remark {wall} {when will we go virtual} charts and ringing telephones.
+
+\StopIdea
+
+\StartIdea
+ [ title={Arthur Clarke},
+ remark={2001, A space Odyssey, p. 67, 1968}]
+
+There was plenty to occupy his time, even if he did nothing but sit and read.
+When he tired of official reports and memoranda and minutes he would \remark
+{plug} {documents will be in the air} his foolscap|-|sized newspad into the
+ship's information circuit and scan the latest reports from Earth. One by one he
+would conjure up the world's major electronic papers; he knew the \remark {codes}
+{who is using codes today} of the more important ones by heart, and had no need
+to consult the list on the back of his pad. Switching to the display's unit's
+short|-|term memory, he would hold the front page while he quickly \remark
+{searched} {we are very good in quick browsing} the headlines and noted the items
+that interested him. Each had its own \remark {two|-|digit} {aren't we running
+out of 256.256.256.256 already} reference; when he punched that, the
+postage|-|stamp|-|sized rectangle would expand until it neatly filled the screen,
+and he could read it with comfort. When had finished he would flash back to the
+complete remark {page} {will we keep on using composed mixed content pages} and
+select a new subject for detailed examination.
+
+\StopIdea
+
+\StartIdea
+ [ title={Arthur Clarke},
+ remark={2001, A space Odyssey, p. 109, 1968}]
+
+Bowman had been a student for more than a half his life; he would continue to be
+one until he retired. Thanks to the Twentieth Century \remark {revolution} {that
+has been a pretty quiet revolution then} in training and information|-|handling
+techniques, he already possessed the \remark {equivalent} {we will stop talking
+in those qualifications} of two or three college educations|=|and, what was more,
+he could \remark {remember} {with or without implant} \remark {ninety} {is this
+still needed with information everywhere} per cent of what he had learned.
+
+\StopIdea
+
+\StartIdea
+ [ title={Arthur Clarke},
+ remark={2001, A space Odyssey, p. 132, 1968}]
+
+The information flashed on the display screen; simultaneously, a sheet of paper
+slit out of the slot immediately \remark {beneath} {but aren't screens becoming
+like paper} it. Despite all the electronic read|-|outs, there were times when
+good, old|-|fashioned printed material was the most \remark {convenient} {good,
+because paper is a great invention} form of record.
+
+\StopIdea
+
+\StartIdea
+ [ title={Greg Bear},
+ remark={Eon, p. 30, 1985}]
+
+The office was neatly organized but still looked cluttered. A small desk
+manufactured from OTV tank baffles was flanked by chromium bins filled with
+\remark {rolls} {not much paper will be used in space, I guess} of paper. A
+narrow shelf of \remark {real} {that sounds pretty sad for around 2000} books
+hung next to \remark {racks} {will there be such a physical need} of memory
+blocks sealed behind tough, alarm-equipped plastic panels. \remark {Maps} {we
+will probably always need an overview} and \remark {diagrams} {and for that we
+need large projections} were taped to the wall.
+
+\StopIdea
+
+\StartIdea
+ [ title={Greg Bear},
+ remark={Eon, p. 132, 1985}]
+
+Still, she agreed with a nod and settled into the seat, manipulating the controls
+with one hand. A simple \remark {circular} {will we move away from rectangular
+presentations} graphic display \remark {hovered} {that's indeed what we want}
+before her, as crisp and \remark {clear} {good} as something \remark {solid}
+{even better}. Takahashi had misinformed her on one point, and her fumbling
+triggered a tutorial. It corrected her errors and informed her|<|in only slightly
+\remark {accented} {-)} American \remark {English} {what a pitty for dislectic
+people}|>|how to operate the equipment properly. Then it provided her with call
+\remark {numbers} {we really love numbers, don't we} and codes for other types of
+information.
+
+\StopIdea
+
+\StartIdea
+ [ title={Greg Bear},
+ remark={Eon, pp. 132/135, 1985}]
+
+The \remark {illusion} {physical presence will become less important} was
+perfect|<|even providing her with a memory of what her apartment looked like. She
+could turn her head and look completely behind her if she wished|>|indeed, she
+could walk around, even through she knew she was sitting down. \unknown\ The
+information had come in \remark {printed} {don't throw away eons of experience}
+displays, selected \remark {visuals} {will we keep on changing interfaces} and
+even more selected \remark {sounds} {we should have started recording already}.
+Where documentation of the multimedia sort was lacking, print took over, but with
+subtle and clear vocal accompaniment. Compared to this, simple reading was
+\remark {torture} {hm, \unknown} and current video methods as \remark {archaic}
+{eh, \unknown} as cave \remark {paintings} {let's be humble then}.
+
+\StopIdea
+
+\StartIdea
+ [ title={Greg Bear},
+ remark={Eon, p. 258, 1985}]
+
+\quotation {The P.M.\ has no suspicion of this when you alone were sent?} Toller
+\remark {picted} {finally ideographic scripts will win the game}. The symbols
+that flashed between the two men came from pictor torques around their necks,
+\remark {devices} {we really need an physical update} that had developed over the
+centuries in the Thistledown and in the Axis City.
+
+\StopIdea
+
+\StartIdea
+ [ title={Graham Hancock},
+ remark={Fingerprints of the gods, Graham Hancock, p. 120, 1995}]
+
+More systematically, all over Central America, vast repositories of knowledge
+\remark {accumulated} {as today in libraries, on servers and in our houses} since
+ancient times were painstakingly gathered, heaped up and burned by zealous
+friars. In July 1562, for example, in the main square of Mani (just south of
+modern Merida in Yucatan Province) Fr Diego de Landa \remark {burned} {and all
+can get lost forever} thousands of Maya codices, story paintings and hieroglyphs
+inscribed on rolled|-|up deer \remark {skins} {how about bits curled up on
+CDROM's}.
+
+\StopIdea
+
+\StartIdea
+ [ title={Graham Hancock},
+ remark={Fingerprints of the gods, Graham Hancock, p. 520/526, 1995}]
+
+We know that out late twentieth|-|century, post|-|industrial civilization is
+about to be destroyed by an \remark {inescapable} {not that imaginary, it has
+happened before} cosmic or geological cataclysm.
+
+We know|<|because our science is pretty good|>|that the destruction is going to
+be \remark {{\em near|-|total}} {one 10-30 km meteor or even one lunatic
+president will do}.
+
+\blank \unknown \blank
+
+I'm sure that we'd want to say more than just \quote {Kilroy was here}.
+
+\blank \unknown \blank
+
+And, yes, \remark {they} {pyramid builders 12,000 years ago} found an ingenious
+way to tell \remark {us} {who more and more think short|-|term} that they were
+\remark {here} {what will we leave behind}.
+
+\StopIdea
+
+\StartIdea
+ [ title={Jared Diamond},
+ remark={Guns, Germs and Steel, A Short History of Everybody for the Last
+ 13,000 years, p. 260, 1997}]
+
+Human technology developed from the first stone tools, in use by two and a half
+million years ago, to the 1996 laser \remark {printer} {the ones that produced
+sticky fading print|-|outs} that replaced my already outdated 1992 \remark
+{laser} {and now we want color on the desktop} printer and that was used to print
+this book's manuscript. The rate of development was undetectably slow at the
+beginning, when hundreds of thousands of years passed with no discernible change
+in out stone tools and with no surviving evidence for artifacts and of other
+materials. Today, technology advances so \remark {rapidly} {so let's be careful
+in claiming advance} that it is reported in the daily \remark {newspaper} {less
+and less people read them}.
+
+\StopIdea
+
+\StartIdea
+ [ title={Jared Diamond},
+ remark={Guns, Germs and Steel, A Short History of Everybody for the Last
+ 13,000 years, p. 418, 1997}]
+
+The decision could have gone to another keyboard at any of numerous stages
+between the 1860s and the 1880's; nothing about the American environment favored
+the \hbox {QWERTY} keyboard over its rivals. \unknown\ For example, if the \hbox
+{QWERTY} keyboard of the United States had not been adopted elsewhere in the
+world as well|<|say, if Japan or Europe had adopted the more \remark {efficient}
+{so why don't we take that one} Dvorak keyboard|>|that trivial decision in the
+19\high{th} century might have had big consequences for the competative position
+of the 20\high{th}|-|century \remark {American} {isn't \TeX\ also best tuned for
+english} technology.
+
+\StopIdea
+
+\StartIdea
+ [ title={Peter Wilbur \& Michael Burke},
+ remark={Information Graphics, Innovative Solutions in Contemporary Design,
+ p. 87, 1998}]
+
+It was generally \remark {agreed} {so let's judge with care} at that time that
+products which tried to fulfil two or more \remark {functions} {how many
+functions are there in a book} were compromises and therefore inferior to a
+single|-|function product.
+
+\StopIdea
+
+\StartIdea
+ [ title={Peter Wilbur \& Michael Burke},
+ remark={Information Graphics, Innovative Solutions in Contemporary Design,
+ p. 17, 1998}]
+
+All of this implies that design students of the future will need to have a much
+wider range of skills than most graphic and multimedia students possess today.
+The coming \remark {together} {which is better: overloaded CNN news screens or
+the more traditional ones} of typography, graphics, the moving image, sound and
+music requires training in both \remark {aesthetic} {let's hope for the best}
+judgment and technical skills, as well as the ability to implement and commission
+\remark {multimedia} {the current hype will become a decent craft} productions.
+Such a program hardly exists today, and it may be that \remark {designers} {or
+will machines do the work} of the future will find themselves on courses equal in
+duration and related in structure to those followed by architects.
+
+\StopIdea
+
+\StartIdea
+ [ title={Greg Bear},
+ remark={Darwin's radio, p. 271, 1999}]
+
+\quotation {As far as it goes}, Kaye said. \quotation {I believe our genome is
+much more \remark {clever} {let's hope that we can cope with the future} than we
+are. It's taken us tens of thousands of years to get to to the point where we
+have a hope of understanding how life works. \unknown\ The Earth species have
+learned how to anticipate climate change and respond to it in advance, get a head
+start, and I believe, in our case, our genome is now responding to social \remark
+{change} {like writing, reading, processing, collecting information} and the
+\remark {stress} {ability to keep track of things} it causes.}
+
+\StopIdea
+
+\StartIdea
+ [ title={Greg Bear},
+ remark={Darwin's radio, p. 404, 1999}]
+
+She looked at the cover and laughed out loud. It was a copy of WIRED, and on the
+brilliant orange cover was printed the black silhouette of a curled fetus with a
+green question mark across the middle. The log line read \quotation {\em Human
+3.0: Not a Virus, but an \remark {Upgrade} {or: complex talking & communicating
+in color, smell and taste}?}
+
+\StopIdea
+
+\StartIdea
+ [title={Edward R. Tufte}]
+
+We thrive in information|-|thick worlds because of our marvelous and everyday
+\remark {capacity} {that is us, now, or maybe until recently} to select, edit,
+single out, structure, highlight, group, pair, merge, harmonize, synthesize,
+focus, organize, condense, reduce, boil down, choose, categorize, catalog,
+classify, list, abstract, scan, look into, idealize, isolate, discriminate,
+distinguish, screen, pigeonhole, pick over, sort, integrate, blend, inspect,
+filter, lump, skip, smooth, chunk, average, approximate, cluster, aggregate,
+outline, summarize, itemize, review, dip into, flip through, browse, glance into,
+leaf through, skim, refine, enumerate, glean, synopsize, \remark {winnow} {do we
+really} the wheat from the chaff and separate the sheep from the goats.
+
+\StopIdea
+
+\StartIdea
+ [ title={Donald E. Knuth},
+ remark={Selected Papers in Computer Science, p. 95, 1996}]
+
+I believe that the real reason underlying the fact that Computer Science has
+become a thriving discipline at essential all of the world's universities,
+although it was totally \remark {unknown} {much more is yet unknown, but we don't
+know what} twenty years ago, is {\em not} that computers exist in quantity; the
+real reason is that the algorithmic thinkers among scientists of the world never
+before had a home. We are brought \remark {together} {there will be more new
+disciplines} in Computer Science departments {\em because we find people who
+think like we do}. At least, that seems a viable hypothesis, which hasn't been
+contradicted by my observations during the last half dozen or so years since the
+possibility occurred to me.
+
+\StopIdea
+
+\StartIdea
+ [ title={Brian Butterworth},
+ remark={The Mathematical Brain, p. 162, 1999}]
+
+Nevertheless, it is now abundantly clear that infants are born with a \remark
+{capacity} {what more is lurking there} to recognize distinct numerosities up to
+about~4, and to respond to changes in numerosity. They also possess arithmical
+expectations: ....
+
+\StopIdea
+
+\StartIdea
+ [ title={Brian Butterworth},
+ remark={The Mathematical Brain, p. 275, 1999}]
+
+Imagine, if you can, asking Archimed, the greatest mathematician of antiquity, to
+solve the equation:
+
+\startformula
+2a^2 + 3ab - 4b^2 = 0
+\stopformula
+
+\remark {He} {would your parents recognize \type {<tags>} as such} would have
+less chance than an average educated fourteen|-|year|-|old, simply because he
+would not know what the strange \remark {symbols} {or recognize hyperlinks} $0$,
+$2$, $3$, and $4$ mean because thet weren't invented till seven centuries after
+his murder; nor $+$ and $-$, German inventions of the fifteenth century; not to
+mention \remark {$=$} {or be able to interpret a regular expression}, which was
+invented by the Englishman Robert Recorde in the sixteenth century. He would also
+have had a problem with the \remark {idea} {or be able to picture the internet}
+that equations can have negative roots.
+
+\StopIdea
+
+\StartIdea
+ [ title={Richard Kadrey},
+ remark={From Myst to Riven, the Creations and Inspirations, p. 16, 1997}]
+
+Some of basics of the D'ni bookmaking are known, but the most important \remark
+{details} {can we still make Gutenberg bibles} have been \remark {lost} {how do
+we preserve what we have} over time. \unknown\ From the few existing \remark
+{records} {how much is really new} lost it appears that the D'ni have been using
+their Linking books for millenia, and that they \remark {linked} {then they
+manage their links better than we do} to the earth around 10,000 terrestial years
+ago.
+
+\StopIdea
+
+\StartIdea
+ [ title={Richard Kadrey},
+ remark={From Myst to Riven, the Creations and Inspirations, p. 81,1997}]
+
+Glancing at the surface of thing, {\em Myst} and {\em Riven} might seem more of a
+technical achievement in computer \remark {artistry} {for this a real new way of
+thinking is needed} and the fine points of modeling frames for objects and
+designing surface textures and shader programs to reflect hyper|-|reality. It is
+very easy to focus exclusively on the cool factor of what you see and to overlook
+what is the underlying key to the success of these games: they are \remark
+{story} {authorship will change} driven. What really sucks the player in is that
+there is a deeply felt {\em purpose} to playing the \remark {game} {and the less
+we need to work, the more we will game}.
+
+\StopIdea
+
+\StartIdea
+ [ title={Steve Reich \& Beryl Korot},
+ remark={The Cave, 1995}]
+
+The true underpinnings were our interest in making a \remark {new} {the time is
+ready for revolutionary new ways of presenting information} kind of musical
+theater based on videotaped documentary sources. The idea was that you would be
+able to see and hear people as they spoke on the videotape and simultaneously you
+would see and hear on|-|stage musicians \remark {doubling} {also accompanied by
+char|-|by|-|char typesetting} them|=|actually playing their speech melodies as
+they spoke.
+
+\StopIdea
+
+\StartIdea
+ [ title={Peter D. Ward \& Donald Brownlee},
+ remark={Rare Earth, Why Complex Life us Uncommon in the Universe, p. xxiv,
+ 2000}]
+
+If it is found to be correct, however, the Rare Earth Hypothesis will reverse
+that decentering trend. What if the Earth, with its cargo of advanced animals, is
+virtually unique in this quadrant of the galaxy|=|the most diverse planet, say,
+in the nearest 10,000 light|-|years? What if it is utterly unique: the only
+planet with animals in this galaxy or even in the visible Universe, a bastion of
+animals amid a sea of microbe|-|infested worlds? If that is the case, how much
+greater the loss the Universe sustains for each species of animals or planet
+driven to extinction trough the \remark {careless} {like more and more paper}
+stewardship of Homo Sapiens? \crlf Welcome \remark {aboard} {but let's move on
+with care}.
+
+\StopIdea
+
+\stopdocument
diff --git a/doc/context/presentations/tug/2007/tug-2007-fonts.pdf b/doc/context/presentations/tug/2007/tug-2007-fonts.pdf
new file mode 100644
index 000000000..53b97ddc7
--- /dev/null
+++ b/doc/context/presentations/tug/2007/tug-2007-fonts.pdf
Binary files differ
diff --git a/doc/context/scripts/mkii/ctxtools.man b/doc/context/scripts/mkii/ctxtools.man
index 54a0a442c..374ffcc80 100644
--- a/doc/context/scripts/mkii/ctxtools.man
+++ b/doc/context/scripts/mkii/ctxtools.man
@@ -1,4 +1,4 @@
-.TH "ctxtools" "1" "01-01-2018" "version 1.3.5" "CtxTools"
+.TH "ctxtools" "1" "01-01-2019" "version 1.3.5" "CtxTools"
.SH NAME
.B ctxtools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/imgtopdf.man b/doc/context/scripts/mkii/imgtopdf.man
index 11cc46f95..033d5a1ab 100644
--- a/doc/context/scripts/mkii/imgtopdf.man
+++ b/doc/context/scripts/mkii/imgtopdf.man
@@ -1,4 +1,4 @@
-.TH "imgtopdf" "1" "01-01-2018" "version 1.1.2" "ImgToPdf"
+.TH "imgtopdf" "1" "01-01-2019" "version 1.1.2" "ImgToPdf"
.SH NAME
.B imgtopdf
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/mptopdf.man b/doc/context/scripts/mkii/mptopdf.man
index c6f4655e0..56be81806 100644
--- a/doc/context/scripts/mkii/mptopdf.man
+++ b/doc/context/scripts/mkii/mptopdf.man
@@ -1,4 +1,4 @@
-.TH "mptopdf" "1" "01-01-2018" "version 1.4.1" "convert MetaPost figures to PDF"
+.TH "mptopdf" "1" "01-01-2019" "version 1.4.1" "convert MetaPost figures to PDF"
.SH NAME
.B mptopdf
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/pdftools.man b/doc/context/scripts/mkii/pdftools.man
index 556035a0f..910bce660 100644
--- a/doc/context/scripts/mkii/pdftools.man
+++ b/doc/context/scripts/mkii/pdftools.man
@@ -1,4 +1,4 @@
-.TH "pdftools" "1" "01-01-2018" "version 1.2.1" "PDFTools"
+.TH "pdftools" "1" "01-01-2019" "version 1.2.1" "PDFTools"
.SH NAME
.B pdftools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/pstopdf.man b/doc/context/scripts/mkii/pstopdf.man
index 1502fa168..607fa1112 100644
--- a/doc/context/scripts/mkii/pstopdf.man
+++ b/doc/context/scripts/mkii/pstopdf.man
@@ -1,4 +1,4 @@
-.TH "pstopdf" "1" "01-01-2018" "version 2.0.1" "PStoPDF"
+.TH "pstopdf" "1" "01-01-2019" "version 2.0.1" "PStoPDF"
.SH NAME
.B pstopdf
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/rlxtools.man b/doc/context/scripts/mkii/rlxtools.man
index 56bc3c690..d2a128b41 100644
--- a/doc/context/scripts/mkii/rlxtools.man
+++ b/doc/context/scripts/mkii/rlxtools.man
@@ -1,4 +1,4 @@
-.TH "rlxtools" "1" "01-01-2018" "version 1.0.1" "RlxTools"
+.TH "rlxtools" "1" "01-01-2019" "version 1.0.1" "RlxTools"
.SH NAME
.B rlxtools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/texexec.man b/doc/context/scripts/mkii/texexec.man
index 8de194d39..d6b057b65 100644
--- a/doc/context/scripts/mkii/texexec.man
+++ b/doc/context/scripts/mkii/texexec.man
@@ -1,4 +1,4 @@
-.TH "texexec" "1" "01-01-2018" "version 6.2.1" "TeXExec"
+.TH "texexec" "1" "01-01-2019" "version 6.2.1" "TeXExec"
.SH NAME
.B texexec
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/texmfstart.html b/doc/context/scripts/mkii/texmfstart.html
index 6e1f7f618..e7656a159 100644
--- a/doc/context/scripts/mkii/texmfstart.html
+++ b/doc/context/scripts/mkii/texmfstart.html
@@ -47,9 +47,7 @@
<tr><th>--internal</th><td></td><td>run script using built in libraries (same as --ctxlua)</td></tr>
<tr><th>--locate</th><td></td><td>locate given filename in database (default) or system (--first --all --detail)</td></tr>
<tr><th/><td/><td/></tr>
- <tr><th>--autotree</th><td></td><td>use texmf tree cf. env texmfstart_tree or texmfstarttree</td></tr>
<tr><th>--tree</th><td>pathtotree</td><td>use given texmf tree (default file: setuptex.tmf)</td></tr>
- <tr><th>--environment</th><td>name</td><td>use given (tmf) environment file</td></tr>
<tr><th>--path</th><td>runpath</td><td>go to given path before execution</td></tr>
<tr><th>--ifchanged</th><td>filename</td><td>only execute when given file has changed (md checksum)</td></tr>
<tr><th>--iftouched</th><td>old,new</td><td>only execute when given file has changed (time stamp)</td></tr>
@@ -66,7 +64,7 @@
<tr><th>--systeminfo</th><td>str</td><td>show current operating system, processor, etc</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--edit</th><td></td><td>launch editor with found file</td></tr>
- <tr><th>--launch</th><td></td><td>launch files like manuals, assumes os support (--all)</td></tr>
+ <tr><th>--launch</th><td></td><td>launch files like manuals, assumes os support (--all,--list)</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--timedrun</th><td></td><td>run a script and time its run</td></tr>
<tr><th>--autogenerate</th><td></td><td>regenerate databases if needed (handy when used to run context in an editor)</td></tr>
diff --git a/doc/context/scripts/mkii/texmfstart.man b/doc/context/scripts/mkii/texmfstart.man
index fdff5103c..70dd035c4 100644
--- a/doc/context/scripts/mkii/texmfstart.man
+++ b/doc/context/scripts/mkii/texmfstart.man
@@ -1,4 +1,4 @@
-.TH "mtxrun" "1" "01-01-2018" "version 1.33" "ConTeXt TDS Runner Tool"
+.TH "mtxrun" "1" "01-01-2019" "version 1.33" "ConTeXt TDS Runner Tool"
.SH NAME
.B mtxrun
.SH SYNOPSIS
@@ -32,15 +32,9 @@ run script using built in libraries (same as --ctxlua)
.B --locate
locate given filename in database (default) or system (--first --all --detail)
.TP
-.B --autotree
-use texmf tree cf. env texmfstart_tree or texmfstarttree
-.TP
.B --tree=pathtotree
use given texmf tree (default file: setuptex.tmf)
.TP
-.B --environment=name
-use given (tmf) environment file
-.TP
.B --path=runpath
go to given path before execution
.TP
@@ -81,7 +75,7 @@ show current operating system, processor, etc
launch editor with found file
.TP
.B --launch
-launch files like manuals, assumes os support (--all)
+launch files like manuals, assumes os support (--all,--list)
.TP
.B --timedrun
run a script and time its run
diff --git a/doc/context/scripts/mkii/texmfstart.xml b/doc/context/scripts/mkii/texmfstart.xml
index 0fc6505f4..8f501ff66 100644
--- a/doc/context/scripts/mkii/texmfstart.xml
+++ b/doc/context/scripts/mkii/texmfstart.xml
@@ -16,9 +16,7 @@
<flag name="locate"><short>locate given filename in database (default) or system (<ref name="first"/> <ref name="all"/> <ref name="detail"/>)</short></flag>
</subcategory>
<subcategory>
- <flag name="autotree"><short>use texmf tree cf. env texmfstart_tree or texmfstarttree</short></flag>
<flag name="tree" value="pathtotree"><short>use given texmf tree (default file: setuptex.tmf)</short></flag>
- <flag name="environment" value="name"><short>use given (tmf) environment file</short></flag>
<flag name="path" value="runpath"><short>go to given path before execution</short></flag>
<flag name="ifchanged" value="filename"><short>only execute when given file has changed (md checksum)</short></flag>
<flag name="iftouched" value="old,new"><short>only execute when given file has changed (time stamp)</short></flag>
@@ -38,7 +36,7 @@
</subcategory>
<subcategory>
<flag name="edit"><short>launch editor with found file</short></flag>
- <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>)</short></flag>
+ <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>,<ref name="list"/>)</short></flag>
</subcategory>
<subcategory>
<flag name="timedrun"><short>run a script and time its run</short></flag>
diff --git a/doc/context/scripts/mkii/textools.man b/doc/context/scripts/mkii/textools.man
index d355ccf5d..8fad158af 100644
--- a/doc/context/scripts/mkii/textools.man
+++ b/doc/context/scripts/mkii/textools.man
@@ -1,4 +1,4 @@
-.TH "textools" "1" "01-01-2018" "version 1.3.1" "TeXTools"
+.TH "textools" "1" "01-01-2019" "version 1.3.1" "TeXTools"
.SH NAME
.B textools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/texutil.man b/doc/context/scripts/mkii/texutil.man
index 918660e45..cad1b72e8 100644
--- a/doc/context/scripts/mkii/texutil.man
+++ b/doc/context/scripts/mkii/texutil.man
@@ -1,4 +1,4 @@
-.TH "texutil" "1" "01-01-2018" "version 9.1.0" "TeXUtil"
+.TH "texutil" "1" "01-01-2019" "version 9.1.0" "TeXUtil"
.SH NAME
.B texutil
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/tmftools.man b/doc/context/scripts/mkii/tmftools.man
index 68550bb00..465579ded 100644
--- a/doc/context/scripts/mkii/tmftools.man
+++ b/doc/context/scripts/mkii/tmftools.man
@@ -1,4 +1,4 @@
-.TH "tmftools" "1" "01-01-2018" "version 1.1.0" "TMFTools"
+.TH "tmftools" "1" "01-01-2019" "version 1.1.0" "TMFTools"
.SH NAME
.B tmftools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkii/xmltools.man b/doc/context/scripts/mkii/xmltools.man
index aacd5ee78..d3ed28a7a 100644
--- a/doc/context/scripts/mkii/xmltools.man
+++ b/doc/context/scripts/mkii/xmltools.man
@@ -1,4 +1,4 @@
-.TH "xmltools" "1" "01-01-2018" "version 1.2.2" "XMLTools"
+.TH "xmltools" "1" "01-01-2019" "version 1.2.2" "XMLTools"
.SH NAME
.B xmltools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/context.html b/doc/context/scripts/mkiv/context.html
index cb841477a..2c64bf8df 100644
--- a/doc/context/scripts/mkiv/context.html
+++ b/doc/context/scripts/mkiv/context.html
@@ -61,6 +61,7 @@
<tr><th>--trackers</th><td>list</td><td>set tracker variables (show list with --showtrackers)</td></tr>
<tr><th>--directives</th><td>list</td><td>set directive variables (show list with --showdirectives)</td></tr>
<tr><th>--silent</th><td>list</td><td>disable logcatgories (show list with --showlogcategories)</td></tr>
+ <tr><th>--strip</th><td></td><td>strip Lua code (only meant for production where no errors are expected)</td></tr>
<tr><th>--errors</th><td>list</td><td>show errors at the end of a run, quit when in list (also when ----silent)</td></tr>
<tr><th>--noconsole</th><td></td><td>disable logging to the console (logfile only)</td></tr>
<tr><th>--purgeresult</th><td></td><td>purge result file before run</td></tr>
@@ -103,6 +104,7 @@
<tr><th>--timing</th><td></td><td>generate timing and statistics overview</td></tr>
<tr><th>--keeptuc</th><td></td><td>keep previous tuc files (jobname-tuc-[run].tmp)</td></tr>
<tr><th>--keeplog</th><td></td><td>keep previous log files (jobname-log-[run].tmp)</td></tr>
+ <tr><th>--lmtx</th><td></td><td>force lmtx mode (when available)</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--extra=name</th><td></td><td>process extra (mtx-context-... in distribution)</td></tr>
<tr><th>--extras</th><td></td><td>show extras</td></tr>
diff --git a/doc/context/scripts/mkiv/context.man b/doc/context/scripts/mkiv/context.man
index 39882b77e..eed6a5723 100644
--- a/doc/context/scripts/mkiv/context.man
+++ b/doc/context/scripts/mkiv/context.man
@@ -1,4 +1,4 @@
-.TH "mtx-context" "1" "01-01-2018" "version 1.01" "ConTeXt Process Management"
+.TH "mtx-context" "1" "01-01-2019" "version 1.01" "ConTeXt Process Management"
.SH NAME
.B mtx-context
.SH SYNOPSIS
@@ -65,6 +65,9 @@ set directive variables (show list with --showdirectives)
.B --silent=list
disable logcatgories (show list with --showlogcategories)
.TP
+.B --strip
+strip Lua code (only meant for production where no errors are expected)
+.TP
.B --errors=list
show errors at the end of a run, quit when in list (also when ----silent)
.TP
@@ -165,6 +168,9 @@ keep previous tuc files (jobname-tuc-[run].tmp)
.B --keeplog
keep previous log files (jobname-log-[run].tmp)
.TP
+.B --lmtx
+force lmtx mode (when available)
+.TP
.B --extra=name
process extra (mtx-context-... in distribution)
.TP
diff --git a/doc/context/scripts/mkiv/context.xml b/doc/context/scripts/mkiv/context.xml
index 9003b549a..8c21eaa8c 100644
--- a/doc/context/scripts/mkiv/context.xml
+++ b/doc/context/scripts/mkiv/context.xml
@@ -70,6 +70,9 @@
<flag name="silent" value="list">
<short>disable logcatgories (show list with <ref name="showlogcategories"/>)</short>
</flag>
+ <flag name="strip">
+ <short>strip Lua code (only meant for production where no errors are expected)</short>
+ </flag>
<flag name="errors" value="list">
<short>show errors at the end of a run, quit when in list (also when <ref name="--silent"/>)</short>
</flag>
@@ -187,6 +190,9 @@
<flag name="keeplog">
<short>keep previous log files (jobname-log-[run].tmp)</short>
</flag>
+ <flag name="lmtx">
+ <short>force lmtx mode (when available)</short>
+ </flag>
</subcategory>
<subcategory>
<flag name="extra=name">
diff --git a/doc/context/scripts/mkiv/luatools.man b/doc/context/scripts/mkiv/luatools.man
index 8cdcf0fd6..6750af537 100644
--- a/doc/context/scripts/mkiv/luatools.man
+++ b/doc/context/scripts/mkiv/luatools.man
@@ -1,4 +1,4 @@
-.TH "luatools" "1" "01-01-2018" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
+.TH "luatools" "1" "01-01-2019" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
.SH NAME
.B luatools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-babel.man b/doc/context/scripts/mkiv/mtx-babel.man
index 712911333..68b94478d 100644
--- a/doc/context/scripts/mkiv/mtx-babel.man
+++ b/doc/context/scripts/mkiv/mtx-babel.man
@@ -1,4 +1,4 @@
-.TH "mtx-babel" "1" "01-01-2018" "version 1.20" "Babel Input To UTF Conversion"
+.TH "mtx-babel" "1" "01-01-2019" "version 1.20" "Babel Input To UTF Conversion"
.SH NAME
.B mtx-babel
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-base.man b/doc/context/scripts/mkiv/mtx-base.man
index c38347353..757537b1d 100644
--- a/doc/context/scripts/mkiv/mtx-base.man
+++ b/doc/context/scripts/mkiv/mtx-base.man
@@ -1,4 +1,4 @@
-.TH "mtx-base" "1" "01-01-2018" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
+.TH "mtx-base" "1" "01-01-2019" "version 1.35" "ConTeXt TDS Management Tool (aka luatools)"
.SH NAME
.B mtx-base
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-bibtex.man b/doc/context/scripts/mkiv/mtx-bibtex.man
index 9553b900d..a2ddce859 100644
--- a/doc/context/scripts/mkiv/mtx-bibtex.man
+++ b/doc/context/scripts/mkiv/mtx-bibtex.man
@@ -1,4 +1,4 @@
-.TH "mtx-bibtex" "1" "01-01-2018" "version 1.00" "bibtex helpers"
+.TH "mtx-bibtex" "1" "01-01-2019" "version 1.00" "bibtex helpers"
.SH NAME
.B mtx-bibtex
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-cache.man b/doc/context/scripts/mkiv/mtx-cache.man
index 188e72078..e659dd3b8 100644
--- a/doc/context/scripts/mkiv/mtx-cache.man
+++ b/doc/context/scripts/mkiv/mtx-cache.man
@@ -1,4 +1,4 @@
-.TH "mtx-cache" "1" "01-01-2018" "version 0.10" "ConTeXt & MetaTeX Cache Management"
+.TH "mtx-cache" "1" "01-01-2019" "version 0.10" "ConTeXt & MetaTeX Cache Management"
.SH NAME
.B mtx-cache
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-chars.man b/doc/context/scripts/mkiv/mtx-chars.man
index 8914c9ed5..dd6c3c6ca 100644
--- a/doc/context/scripts/mkiv/mtx-chars.man
+++ b/doc/context/scripts/mkiv/mtx-chars.man
@@ -1,4 +1,4 @@
-.TH "mtx-chars" "1" "01-01-2018" "version 0.10" "MkII Character Table Generators"
+.TH "mtx-chars" "1" "01-01-2019" "version 0.10" "MkII Character Table Generators"
.SH NAME
.B mtx-chars
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-check.man b/doc/context/scripts/mkiv/mtx-check.man
index 9c1f02a49..6331a2e53 100644
--- a/doc/context/scripts/mkiv/mtx-check.man
+++ b/doc/context/scripts/mkiv/mtx-check.man
@@ -1,4 +1,4 @@
-.TH "mtx-check" "1" "01-01-2018" "version 0.10" "Basic ConTeXt Syntax Checking"
+.TH "mtx-check" "1" "01-01-2019" "version 0.10" "Basic ConTeXt Syntax Checking"
.SH NAME
.B mtx-check
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-colors.man b/doc/context/scripts/mkiv/mtx-colors.man
index de271e01b..4ef9fab0b 100644
--- a/doc/context/scripts/mkiv/mtx-colors.man
+++ b/doc/context/scripts/mkiv/mtx-colors.man
@@ -1,4 +1,4 @@
-.TH "mtx-colors" "1" "01-01-2018" "version 0.10" "ConTeXt Color Management"
+.TH "mtx-colors" "1" "01-01-2019" "version 0.10" "ConTeXt Color Management"
.SH NAME
.B mtx-colors
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-context.html b/doc/context/scripts/mkiv/mtx-context.html
index cb841477a..2c64bf8df 100644
--- a/doc/context/scripts/mkiv/mtx-context.html
+++ b/doc/context/scripts/mkiv/mtx-context.html
@@ -61,6 +61,7 @@
<tr><th>--trackers</th><td>list</td><td>set tracker variables (show list with --showtrackers)</td></tr>
<tr><th>--directives</th><td>list</td><td>set directive variables (show list with --showdirectives)</td></tr>
<tr><th>--silent</th><td>list</td><td>disable logcatgories (show list with --showlogcategories)</td></tr>
+ <tr><th>--strip</th><td></td><td>strip Lua code (only meant for production where no errors are expected)</td></tr>
<tr><th>--errors</th><td>list</td><td>show errors at the end of a run, quit when in list (also when ----silent)</td></tr>
<tr><th>--noconsole</th><td></td><td>disable logging to the console (logfile only)</td></tr>
<tr><th>--purgeresult</th><td></td><td>purge result file before run</td></tr>
@@ -103,6 +104,7 @@
<tr><th>--timing</th><td></td><td>generate timing and statistics overview</td></tr>
<tr><th>--keeptuc</th><td></td><td>keep previous tuc files (jobname-tuc-[run].tmp)</td></tr>
<tr><th>--keeplog</th><td></td><td>keep previous log files (jobname-log-[run].tmp)</td></tr>
+ <tr><th>--lmtx</th><td></td><td>force lmtx mode (when available)</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--extra=name</th><td></td><td>process extra (mtx-context-... in distribution)</td></tr>
<tr><th>--extras</th><td></td><td>show extras</td></tr>
diff --git a/doc/context/scripts/mkiv/mtx-context.man b/doc/context/scripts/mkiv/mtx-context.man
index 39882b77e..eed6a5723 100644
--- a/doc/context/scripts/mkiv/mtx-context.man
+++ b/doc/context/scripts/mkiv/mtx-context.man
@@ -1,4 +1,4 @@
-.TH "mtx-context" "1" "01-01-2018" "version 1.01" "ConTeXt Process Management"
+.TH "mtx-context" "1" "01-01-2019" "version 1.01" "ConTeXt Process Management"
.SH NAME
.B mtx-context
.SH SYNOPSIS
@@ -65,6 +65,9 @@ set directive variables (show list with --showdirectives)
.B --silent=list
disable logcatgories (show list with --showlogcategories)
.TP
+.B --strip
+strip Lua code (only meant for production where no errors are expected)
+.TP
.B --errors=list
show errors at the end of a run, quit when in list (also when ----silent)
.TP
@@ -165,6 +168,9 @@ keep previous tuc files (jobname-tuc-[run].tmp)
.B --keeplog
keep previous log files (jobname-log-[run].tmp)
.TP
+.B --lmtx
+force lmtx mode (when available)
+.TP
.B --extra=name
process extra (mtx-context-... in distribution)
.TP
diff --git a/doc/context/scripts/mkiv/mtx-context.xml b/doc/context/scripts/mkiv/mtx-context.xml
index 9003b549a..8c21eaa8c 100644
--- a/doc/context/scripts/mkiv/mtx-context.xml
+++ b/doc/context/scripts/mkiv/mtx-context.xml
@@ -70,6 +70,9 @@
<flag name="silent" value="list">
<short>disable logcatgories (show list with <ref name="showlogcategories"/>)</short>
</flag>
+ <flag name="strip">
+ <short>strip Lua code (only meant for production where no errors are expected)</short>
+ </flag>
<flag name="errors" value="list">
<short>show errors at the end of a run, quit when in list (also when <ref name="--silent"/>)</short>
</flag>
@@ -187,6 +190,9 @@
<flag name="keeplog">
<short>keep previous log files (jobname-log-[run].tmp)</short>
</flag>
+ <flag name="lmtx">
+ <short>force lmtx mode (when available)</short>
+ </flag>
</subcategory>
<subcategory>
<flag name="extra=name">
diff --git a/doc/context/scripts/mkiv/mtx-dvi.man b/doc/context/scripts/mkiv/mtx-dvi.man
index 29c5dd772..e16f2d5b6 100644
--- a/doc/context/scripts/mkiv/mtx-dvi.man
+++ b/doc/context/scripts/mkiv/mtx-dvi.man
@@ -1,4 +1,4 @@
-.TH "mtx-dvi" "1" "01-01-2018" "version 0.01" "ConTeXt DVI Helpers"
+.TH "mtx-dvi" "1" "01-01-2019" "version 0.01" "ConTeXt DVI Helpers"
.SH NAME
.B mtx-dvi
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-epub.man b/doc/context/scripts/mkiv/mtx-epub.man
index 3e6875204..ffd6d78ed 100644
--- a/doc/context/scripts/mkiv/mtx-epub.man
+++ b/doc/context/scripts/mkiv/mtx-epub.man
@@ -1,4 +1,4 @@
-.TH "mtx-epub" "1" "01-01-2018" "version 1.10" "ConTeXt EPUB Helpers"
+.TH "mtx-epub" "1" "01-01-2019" "version 1.10" "ConTeXt EPUB Helpers"
.SH NAME
.B mtx-epub
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-evohome.html b/doc/context/scripts/mkiv/mtx-evohome.html
index dc21f7721..c8ec42b95 100644
--- a/doc/context/scripts/mkiv/mtx-evohome.html
+++ b/doc/context/scripts/mkiv/mtx-evohome.html
@@ -40,6 +40,7 @@
<tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
<tr><th/><td/><td/></tr>
<tr><th>--collect</th><td></td><td>collect data from device</td></tr>
+ <tr><th>--update</th><td></td><td>update data from device</td></tr>
<tr><th>--presets</th><td></td><td>file with authenciation data</td></tr>
<tr><th>--auto</th><td></td><td>fetch temperature data every hour</td></tr>
<tr><th>--port</th><td></td><td>server port when running the service, default: 8068</td></tr>
diff --git a/doc/context/scripts/mkiv/mtx-evohome.man b/doc/context/scripts/mkiv/mtx-evohome.man
index 3c20161dc..61355fec1 100644
--- a/doc/context/scripts/mkiv/mtx-evohome.man
+++ b/doc/context/scripts/mkiv/mtx-evohome.man
@@ -1,4 +1,4 @@
-.TH "mtx-evohome" "1" "01-01-2018" "version 1.00" "Evohome Fetcher"
+.TH "mtx-evohome" "1" "01-01-2019" "version 1.00" "Evohome Fetcher"
.SH NAME
.B mtx-evohome
.SH SYNOPSIS
@@ -14,6 +14,9 @@
.B --collect
collect data from device
.TP
+.B --update
+update data from device
+.TP
.B --presets
file with authenciation data
.TP
diff --git a/doc/context/scripts/mkiv/mtx-evohome.xml b/doc/context/scripts/mkiv/mtx-evohome.xml
index 7224d4183..abdb9fb99 100644
--- a/doc/context/scripts/mkiv/mtx-evohome.xml
+++ b/doc/context/scripts/mkiv/mtx-evohome.xml
@@ -9,6 +9,7 @@
<category name="basic">
<subcategory>
<flag name="collect"><short>collect data from device</short></flag>
+ <flag name="update"><short>update data from device</short></flag>
<flag name="presets"><short>file with authenciation data</short></flag>
<flag name="auto"><short>fetch temperature data every hour</short></flag>
<flag name="port"><short>server port when running the service, default: 8068</short></flag>
diff --git a/doc/context/scripts/mkiv/mtx-fcd.man b/doc/context/scripts/mkiv/mtx-fcd.man
index 7b668b091..65f21761d 100644
--- a/doc/context/scripts/mkiv/mtx-fcd.man
+++ b/doc/context/scripts/mkiv/mtx-fcd.man
@@ -1,4 +1,4 @@
-.TH "mtx-fcd" "1" "01-01-2018" "version 1.00" "Fast Directory Change"
+.TH "mtx-fcd" "1" "01-01-2019" "version 1.00" "Fast Directory Change"
.SH NAME
.B mtx-fcd
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-flac.man b/doc/context/scripts/mkiv/mtx-flac.man
index 02c977d76..26acb7e41 100644
--- a/doc/context/scripts/mkiv/mtx-flac.man
+++ b/doc/context/scripts/mkiv/mtx-flac.man
@@ -1,4 +1,4 @@
-.TH "mtx-flac" "1" "01-01-2018" "version 0.10" "ConTeXt Flac Helpers"
+.TH "mtx-flac" "1" "01-01-2019" "version 0.10" "ConTeXt Flac Helpers"
.SH NAME
.B mtx-flac
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-fonts.man b/doc/context/scripts/mkiv/mtx-fonts.man
index c27731e33..a65915e72 100644
--- a/doc/context/scripts/mkiv/mtx-fonts.man
+++ b/doc/context/scripts/mkiv/mtx-fonts.man
@@ -1,4 +1,4 @@
-.TH "mtx-fonts" "1" "01-01-2018" "version 1.00" "ConTeXt Font Database Management"
+.TH "mtx-fonts" "1" "01-01-2019" "version 1.00" "ConTeXt Font Database Management"
.SH NAME
.B mtx-fonts
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-grep.man b/doc/context/scripts/mkiv/mtx-grep.man
index 19675cc51..cd7d52735 100644
--- a/doc/context/scripts/mkiv/mtx-grep.man
+++ b/doc/context/scripts/mkiv/mtx-grep.man
@@ -1,4 +1,4 @@
-.TH "mtx-grep" "1" "01-01-2018" "version 0.10" "Simple Grepper"
+.TH "mtx-grep" "1" "01-01-2019" "version 0.10" "Simple Grepper"
.SH NAME
.B mtx-grep
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-interface.man b/doc/context/scripts/mkiv/mtx-interface.man
index 2dbba85df..026a5f67b 100644
--- a/doc/context/scripts/mkiv/mtx-interface.man
+++ b/doc/context/scripts/mkiv/mtx-interface.man
@@ -1,4 +1,4 @@
-.TH "mtx-interface" "1" "01-01-2018" "version 0.13" "ConTeXt Interface Related Goodies"
+.TH "mtx-interface" "1" "01-01-2019" "version 0.13" "ConTeXt Interface Related Goodies"
.SH NAME
.B mtx-interface
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-metapost.man b/doc/context/scripts/mkiv/mtx-metapost.man
index e8e7b465e..11586b727 100644
--- a/doc/context/scripts/mkiv/mtx-metapost.man
+++ b/doc/context/scripts/mkiv/mtx-metapost.man
@@ -1,4 +1,4 @@
-.TH "mtx-metapost" "1" "01-01-2018" "version 0.10" "MetaPost to PDF processor"
+.TH "mtx-metapost" "1" "01-01-2019" "version 0.10" "MetaPost to PDF processor"
.SH NAME
.B mtx-metapost
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-metatex.html b/doc/context/scripts/mkiv/mtx-metatex.html
deleted file mode 100644
index 18866c0d0..000000000
--- a/doc/context/scripts/mkiv/mtx-metatex.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<!-- compare with lmx framework variant -->
-
-<!--
- filename : context-base.xml
- comment : companion to mtx-server-ctx-startup.tex
- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
- copyright: PRAGMA ADE / ConTeXt Development Team
- license : see context related readme files
--->
-
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
- <head>
- <title>MetaTeX Process Management 0.10</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <style type="text/css">
- body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
- </style>
- <style type="text/css">
- </style>
- </head>
- <body>
- <div id="top"> <div id="top-one">
- <div id="top-two">MetaTeX Process Management 0.10 </div>
- </div>
- </div>
- <div id="bottom"> <div id="bottom-one">
- <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
- </div>
- </div>
- <div id="left"></div>
- <div id="right"></div>
- <div id="main">
- <div id='main-settings'>
- <h1>Command line options</h1>
-<table>
- <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
- <tr><th/><td/><td/></tr>
- <tr><th>--run</th><td></td><td>process (one or more) files (default action)</td></tr>
- <tr><th>--make</th><td></td><td>create metatex format(s)</td></tr>
- </table>
-<br/>
- </div>
- </div>
- </body>
-</html>
diff --git a/doc/context/scripts/mkiv/mtx-metatex.man b/doc/context/scripts/mkiv/mtx-metatex.man
deleted file mode 100644
index fd45e312f..000000000
--- a/doc/context/scripts/mkiv/mtx-metatex.man
+++ /dev/null
@@ -1,30 +0,0 @@
-.TH "mtx-metatex" "1" "01-01-2018" "version 0.10" "MetaTeX Process Management"
-.SH NAME
-.B mtx-metatex
-.SH SYNOPSIS
-.B mtxrun --script metatex [
-.I OPTIONS ...
-.B ] [
-.I FILENAMES
-.B ]
-.SH DESCRIPTION
-.B MetaTeX Process Management
-.SH OPTIONS
-.TP
-.B --run
-process (one or more) files (default action)
-.TP
-.B --make
-create metatex format(s)
-.SH AUTHOR
-More information about ConTeXt and the tools that come with it can be found at:
-
-
-.B "maillist:"
-ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
-
-.B "webpage:"
-http://www.pragma-ade.nl / http://tex.aanhet.net
-
-.B "wiki:"
-http://contextgarden.net
diff --git a/doc/context/scripts/mkiv/mtx-metatex.xml b/doc/context/scripts/mkiv/mtx-metatex.xml
deleted file mode 100644
index 649673fbf..000000000
--- a/doc/context/scripts/mkiv/mtx-metatex.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-metatex</entry>
- <entry name="detail">MetaTeX Process Management</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="run"><short>process (one or more) files (default action)</short></flag>
- <flag name="make"><short>create metatex format(s)</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
diff --git a/doc/context/scripts/mkiv/mtx-modules.man b/doc/context/scripts/mkiv/mtx-modules.man
index 2ca40f90f..56172bd0d 100644
--- a/doc/context/scripts/mkiv/mtx-modules.man
+++ b/doc/context/scripts/mkiv/mtx-modules.man
@@ -1,4 +1,4 @@
-.TH "mtx-modules" "1" "01-01-2018" "version 1.00" "ConTeXt Module Documentation Generators"
+.TH "mtx-modules" "1" "01-01-2019" "version 1.00" "ConTeXt Module Documentation Generators"
.SH NAME
.B mtx-modules
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-package.man b/doc/context/scripts/mkiv/mtx-package.man
index 958e4a975..d0bbd6398 100644
--- a/doc/context/scripts/mkiv/mtx-package.man
+++ b/doc/context/scripts/mkiv/mtx-package.man
@@ -1,4 +1,4 @@
-.TH "mtx-package" "1" "01-01-2018" "version 0.10" "Distribution Related Goodies"
+.TH "mtx-package" "1" "01-01-2019" "version 0.10" "Distribution Related Goodies"
.SH NAME
.B mtx-package
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-patterns.html b/doc/context/scripts/mkiv/mtx-patterns.html
deleted file mode 100644
index 7d5da995d..000000000
--- a/doc/context/scripts/mkiv/mtx-patterns.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<!-- compare with lmx framework variant -->
-
-<!--
- filename : context-base.xml
- comment : companion to mtx-server-ctx-startup.tex
- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
- copyright: PRAGMA ADE / ConTeXt Development Team
- license : see context related readme files
--->
-
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
- <head>
- <title>ConTeXt Pattern File Management 0.20</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <style type="text/css">
- body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
- </style>
- <style type="text/css">
- </style>
- </head>
- <body>
- <div id="top"> <div id="top-one">
- <div id="top-two">ConTeXt Pattern File Management 0.20 </div>
- </div>
- </div>
- <div id="bottom"> <div id="bottom-one">
- <div id="bottom-two">wiki: http://contextgarden.net | mail: ntg-context@ntg.nl | website: http://www.pragma-ade.nl</div>
- </div>
- </div>
- <div id="left"></div>
- <div id="right"></div>
- <div id="main">
- <div id='main-settings'>
- <h1>Command line options</h1>
-<table>
- <tr><th style="width: 10em">flag</th><th style="width: 8em">value</th><th>description</th></tr>
- <tr><th/><td/><td/></tr>
- <tr><th>--convert</th><td></td><td>generate context language files (mnemonic driven, if not given then all)</td></tr>
- <tr><th>--check</th><td></td><td>check pattern file (or those used by context when no file given)</td></tr>
- <tr><th>--path</th><td></td><td>source path where hyph-foo.tex files are stored</td></tr>
- <tr><th>--destination</th><td></td><td>destination path</td></tr>
- <tr><th>--specification</th><td></td><td>additional patterns: e.g.: =cy,hyph-cy,welsh</td></tr>
- <tr><th>--compress</th><td></td><td>compress data</td></tr>
- <tr><th>--words</th><td></td><td>update words in given file</td></tr>
- <tr><th>--hyphenate</th><td></td><td>show hypephenated words</td></tr>
- </table>
-<br/>
-<h1>Examples</h1>
-<tt>mtxrun --script pattern --check hyph-*.tex</tt>
-<br/><tt>mtxrun --script pattern --check --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns</tt>
-<br/><tt>mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex --destination=e:/tmp/patterns</tt>
-<br/><tt>mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/txt --destination=e:/tmp/patterns</tt>
-<br/><tt>mtxrun --script pattern --hyphenate --language=nl --left=3 nogalwiedes inderdaad</tt>
-<br/><br/> </div>
- </div>
- </body>
-</html>
diff --git a/doc/context/scripts/mkiv/mtx-patterns.man b/doc/context/scripts/mkiv/mtx-patterns.man
deleted file mode 100644
index 1b7906b23..000000000
--- a/doc/context/scripts/mkiv/mtx-patterns.man
+++ /dev/null
@@ -1,48 +0,0 @@
-.TH "mtx-patterns" "1" "01-01-2018" "version 0.20" "ConTeXt Pattern File Management"
-.SH NAME
-.B mtx-patterns
-.SH SYNOPSIS
-.B mtxrun --script patterns [
-.I OPTIONS ...
-.B ] [
-.I FILENAMES
-.B ]
-.SH DESCRIPTION
-.B ConTeXt Pattern File Management
-.SH OPTIONS
-.TP
-.B --convert
-generate context language files (mnemonic driven, if not given then all)
-.TP
-.B --check
-check pattern file (or those used by context when no file given)
-.TP
-.B --path
-source path where hyph-foo.tex files are stored
-.TP
-.B --destination
-destination path
-.TP
-.B --specification
-additional patterns: e.g.: =cy,hyph-cy,welsh
-.TP
-.B --compress
-compress data
-.TP
-.B --words
-update words in given file
-.TP
-.B --hyphenate
-show hypephenated words
-.SH AUTHOR
-More information about ConTeXt and the tools that come with it can be found at:
-
-
-.B "maillist:"
-ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
-
-.B "webpage:"
-http://www.pragma-ade.nl / http://tex.aanhet.net
-
-.B "wiki:"
-http://contextgarden.net
diff --git a/doc/context/scripts/mkiv/mtx-patterns.xml b/doc/context/scripts/mkiv/mtx-patterns.xml
deleted file mode 100644
index 86f3aa480..000000000
--- a/doc/context/scripts/mkiv/mtx-patterns.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-patterns</entry>
- <entry name="detail">ConTeXt Pattern File Management</entry>
- <entry name="version">0.20</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="convert"><short>generate context language files (mnemonic driven, if not given then all)</short></flag>
- <flag name="check"><short>check pattern file (or those used by context when no file given)</short></flag>
- <flag name="path"><short>source path where hyph-foo.tex files are stored</short></flag>
- <flag name="destination"><short>destination path</short></flag>
- <flag name="specification"><short>additional patterns: e.g.: =cy,hyph-cy,welsh</short></flag>
- <flag name="compress"><short>compress data</short></flag>
- <flag name="words"><short>update words in given file</short></flag>
- <flag name="hyphenate"><short>show hypephenated words</short></flag>
- </subcategory>
- </category>
- </flags>
- <examples>
- <category>
- <title>Examples</title>
- <subcategory>
- <example><command>mtxrun --script pattern --check hyph-*.tex</command></example>
- <example><command>mtxrun --script pattern --check --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns</command></example>
- <example><command>mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex --destination=e:/tmp/patterns</command></example>
- <example><command>mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/txt --destination=e:/tmp/patterns</command></example>
- <example><command>mtxrun --script pattern --hyphenate --language=nl --left=3 nogalwiedes inderdaad</command></example>
- </subcategory>
- </category>
- </examples>
-</application>
diff --git a/doc/context/scripts/mkiv/mtx-pdf.html b/doc/context/scripts/mkiv/mtx-pdf.html
index b156c154e..e724148ca 100644
--- a/doc/context/scripts/mkiv/mtx-pdf.html
+++ b/doc/context/scripts/mkiv/mtx-pdf.html
@@ -41,8 +41,9 @@
<tr><th/><td/><td/></tr>
<tr><th>--info</th><td></td><td>show some info about the given file</td></tr>
<tr><th>--metadata</th><td></td><td>show metadata xml blob</td></tr>
+ <tr><th>--pretty</th><td></td><td>replace newlines in metadata</td></tr>
<tr><th>--fonts</th><td></td><td>show used fonts (--detail)</td></tr>
- <tr><th>--linearize</th><td></td><td>linearize given file</td></tr>
+ <tr><th/><td/><td/></tr>
</table>
<br/>
</div>
diff --git a/doc/context/scripts/mkiv/mtx-pdf.man b/doc/context/scripts/mkiv/mtx-pdf.man
index 30aacc03a..8595fcbaf 100644
--- a/doc/context/scripts/mkiv/mtx-pdf.man
+++ b/doc/context/scripts/mkiv/mtx-pdf.man
@@ -1,4 +1,4 @@
-.TH "mtx-pdf" "1" "01-01-2018" "version 0.10" "ConTeXt PDF Helpers"
+.TH "mtx-pdf" "1" "01-01-2019" "version 0.10" "ConTeXt PDF Helpers"
.SH NAME
.B mtx-pdf
.SH SYNOPSIS
@@ -17,11 +17,11 @@ show some info about the given file
.B --metadata
show metadata xml blob
.TP
+.B --pretty
+replace newlines in metadata
+.TP
.B --fonts
show used fonts (--detail)
-.TP
-.B --linearize
-linearize given file
.SH AUTHOR
More information about ConTeXt and the tools that come with it can be found at:
diff --git a/doc/context/scripts/mkiv/mtx-pdf.xml b/doc/context/scripts/mkiv/mtx-pdf.xml
index bc4a9d795..9b3d8f8fe 100644
--- a/doc/context/scripts/mkiv/mtx-pdf.xml
+++ b/doc/context/scripts/mkiv/mtx-pdf.xml
@@ -10,8 +10,13 @@
<subcategory>
<flag name="info"><short>show some info about the given file</short></flag>
<flag name="metadata"><short>show metadata xml blob</short></flag>
+ <flag name="pretty"><short>replace newlines in metadata</short></flag>
<flag name="fonts"><short>show used fonts (<ref name="detail)"/></short></flag>
- <flag name="linearize"><short>linearize given file</short></flag>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script pdf --info foo.pdf</command></example>
+ <example><command>mtxrun --script pdf --metadata foo.pdf</command></example>
+ <example><command>mtxrun --script pdf --metadata --pretty foo.pdf</command></example>
</subcategory>
</category>
</flags>
diff --git a/doc/context/scripts/mkiv/mtx-plain.man b/doc/context/scripts/mkiv/mtx-plain.man
index fbdf301f7..a242a4a24 100644
--- a/doc/context/scripts/mkiv/mtx-plain.man
+++ b/doc/context/scripts/mkiv/mtx-plain.man
@@ -1,4 +1,4 @@
-.TH "mtx-plain" "1" "01-01-2018" "version 1.00" "Plain TeX Runner"
+.TH "mtx-plain" "1" "01-01-2019" "version 1.00" "Plain TeX Runner"
.SH NAME
.B mtx-plain
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-profile.man b/doc/context/scripts/mkiv/mtx-profile.man
index fefc60e74..1e38a3b5a 100644
--- a/doc/context/scripts/mkiv/mtx-profile.man
+++ b/doc/context/scripts/mkiv/mtx-profile.man
@@ -1,4 +1,4 @@
-.TH "mtx-profile" "1" "01-01-2018" "version 1.00" "ConTeXt MkIV LuaTeX Profiler"
+.TH "mtx-profile" "1" "01-01-2019" "version 1.00" "ConTeXt MkIV LuaTeX Profiler"
.SH NAME
.B mtx-profile
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-rsync.man b/doc/context/scripts/mkiv/mtx-rsync.man
index 6b7e6e8bc..49a139cb4 100644
--- a/doc/context/scripts/mkiv/mtx-rsync.man
+++ b/doc/context/scripts/mkiv/mtx-rsync.man
@@ -1,4 +1,4 @@
-.TH "mtx-rsync" "1" "01-01-2018" "version 0.10" "Rsync Helpers"
+.TH "mtx-rsync" "1" "01-01-2019" "version 0.10" "Rsync Helpers"
.SH NAME
.B mtx-rsync
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-scite.man b/doc/context/scripts/mkiv/mtx-scite.man
index 58733624d..a37d38fde 100644
--- a/doc/context/scripts/mkiv/mtx-scite.man
+++ b/doc/context/scripts/mkiv/mtx-scite.man
@@ -1,4 +1,4 @@
-.TH "mtx-scite" "1" "01-01-2018" "version 1.00" "Scite Helper Script"
+.TH "mtx-scite" "1" "01-01-2019" "version 1.00" "Scite Helper Script"
.SH NAME
.B mtx-scite
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-server.man b/doc/context/scripts/mkiv/mtx-server.man
index dfda87e71..da0c4c05d 100644
--- a/doc/context/scripts/mkiv/mtx-server.man
+++ b/doc/context/scripts/mkiv/mtx-server.man
@@ -1,4 +1,4 @@
-.TH "mtx-server" "1" "01-01-2018" "version 0.10" "Simple Webserver For Helpers"
+.TH "mtx-server" "1" "01-01-2019" "version 0.10" "Simple Webserver For Helpers"
.SH NAME
.B mtx-server
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-texworks.man b/doc/context/scripts/mkiv/mtx-texworks.man
index 1e29cb7db..016aa1f7d 100644
--- a/doc/context/scripts/mkiv/mtx-texworks.man
+++ b/doc/context/scripts/mkiv/mtx-texworks.man
@@ -1,4 +1,4 @@
-.TH "mtx-texworks" "1" "01-01-2018" "version 1.00" "TeXworks Startup Script"
+.TH "mtx-texworks" "1" "01-01-2019" "version 1.00" "TeXworks Startup Script"
.SH NAME
.B mtx-texworks
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-timing.man b/doc/context/scripts/mkiv/mtx-timing.man
index 785c40d78..479506c70 100644
--- a/doc/context/scripts/mkiv/mtx-timing.man
+++ b/doc/context/scripts/mkiv/mtx-timing.man
@@ -1,4 +1,4 @@
-.TH "mtx-timing" "1" "01-01-2018" "version 0.10" "ConTeXt Timing Tools"
+.TH "mtx-timing" "1" "01-01-2019" "version 0.10" "ConTeXt Timing Tools"
.SH NAME
.B mtx-timing
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-tools.man b/doc/context/scripts/mkiv/mtx-tools.man
index d3a92138d..1cee94d9d 100644
--- a/doc/context/scripts/mkiv/mtx-tools.man
+++ b/doc/context/scripts/mkiv/mtx-tools.man
@@ -1,4 +1,4 @@
-.TH "mtx-tools" "1" "01-01-2018" "version 1.01" "Some File Related Goodies"
+.TH "mtx-tools" "1" "01-01-2019" "version 1.01" "Some File Related Goodies"
.SH NAME
.B mtx-tools
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-unicode.man b/doc/context/scripts/mkiv/mtx-unicode.man
index a4665374f..e82ee65ee 100644
--- a/doc/context/scripts/mkiv/mtx-unicode.man
+++ b/doc/context/scripts/mkiv/mtx-unicode.man
@@ -1,4 +1,4 @@
-.TH "mtx-unicode" "1" "01-01-2018" "version 1.02" "Checker for char-dat.lua"
+.TH "mtx-unicode" "1" "01-01-2019" "version 1.02" "Checker for char-dat.lua"
.SH NAME
.B mtx-unicode
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-unzip.man b/doc/context/scripts/mkiv/mtx-unzip.man
index f2a382ad1..f0243c38c 100644
--- a/doc/context/scripts/mkiv/mtx-unzip.man
+++ b/doc/context/scripts/mkiv/mtx-unzip.man
@@ -1,4 +1,4 @@
-.TH "mtx-unzip" "1" "01-01-2018" "version 0.10" "Simple Unzipper"
+.TH "mtx-unzip" "1" "01-01-2019" "version 0.10" "Simple Unzipper"
.SH NAME
.B mtx-unzip
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-update.man b/doc/context/scripts/mkiv/mtx-update.man
index 79743d7d5..4ec518b0d 100644
--- a/doc/context/scripts/mkiv/mtx-update.man
+++ b/doc/context/scripts/mkiv/mtx-update.man
@@ -1,4 +1,4 @@
-.TH "mtx-update" "1" "01-01-2018" "version 1.03" "ConTeXt Minimals Updater"
+.TH "mtx-update" "1" "01-01-2019" "version 1.03" "ConTeXt Minimals Updater"
.SH NAME
.B mtx-update
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-watch.man b/doc/context/scripts/mkiv/mtx-watch.man
index 82dccbb8e..8cc32f4a5 100644
--- a/doc/context/scripts/mkiv/mtx-watch.man
+++ b/doc/context/scripts/mkiv/mtx-watch.man
@@ -1,4 +1,4 @@
-.TH "mtx-watch" "1" "01-01-2018" "version 1.00" "ConTeXt Request Watchdog"
+.TH "mtx-watch" "1" "01-01-2019" "version 1.00" "ConTeXt Request Watchdog"
.SH NAME
.B mtx-watch
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtx-youless.html b/doc/context/scripts/mkiv/mtx-youless.html
index a95170344..78543414c 100644
--- a/doc/context/scripts/mkiv/mtx-youless.html
+++ b/doc/context/scripts/mkiv/mtx-youless.html
@@ -14,7 +14,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
- <title>YouLess Fetcher 1.100</title>
+ <title>YouLess Fetcher 1.10</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<style type="text/css">
body { color: #FFFFFF; background-color: #808080; font-family: optima, verdana, futura, "lucida sans", arial, geneva, helvetica, sans; font-size: 12px; line-height: 18px; } a:link, a:active, a:visited { color: #FFFFFF; } a.dir-view:link, a.dir-view:active, a.dir-view:visited { color: #FFFFFF; text-decoration: underline; } .valid { color: #00FF00; } .invalid { color: #FF0000; } .invisible { visibility: hidden; } button, .commonlink, .smallbutton { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; border-color: #7F7F7F; border-style: solid; border-width: .125ex; background-color: #FFFFFF; padding: .5ex; } .smallbutton { width: 1em; } a.commonlink:link, a.commonlink:active, a.commonlink:visited, a.smalllink:link, a.smalllink:active, a.smalllink:visited { font-weight: bold; font-size: 12px; text-decoration: none; color: #000000; } h1, .title { font-style: normal; font-weight: normal; font-size: 18px; line-height: 18px; margin-bottom: 20px; } h2, .subtitle { font-style: normal; font-weight: normal; font-size: 12px; margin-top: 18px; margin-bottom: 18px; } table { line-height: 18px; font-size: 12px; margin: 0; } th { font-weight: bold; text-align: left; padding-bottom: 6px; } .tc { font-weight: bold; text-align: left; } p, li { max-width: 60em; } .empty-line { margin-top: 4px; } .more-room { margin-right: 1.5em; } .much-more-room { margin-right: 3em; } #main { position: absolute; left: 10%; top: 10%; right: 10%; bottom: 10%; z-index: 2; width: 80%; height: 80%; padding: 0%; margin: 0%; overflow: auto; border-style: none; border-width: 0; background-color: #3F3F3F; } #main-settings { margin: 12px; x_max-width: 60em; line-height: 18px; font-size: 12px; } #left { position: absolute; top : 10%; left: 0%; bottom: 0%; right: 90%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; } #right { position: absolute; top : 0%; left: 90%; bottom: 10%; right: 0%; z-index: 1; width: 10%; height: 90%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #4F6F6F; _margin-left: -15px; } #bottom { position: absolute; left: 10%; right: 0%; top: 90%; bottom: 0%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top { position: absolute; left: 0%; right: 10%; top: 0%; bottom: 90%; z-index: 1; width: 90%; height: 10%; padding: 0%; margin: 0%; font-size: 16px; border-style: none; border-width: 0; background-color: #6F6F8F; } #top-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #top-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: right; vertical-align: middle; } #bottom-one { position: absolute; bottom: 50%; width: 100%; buggedheight: 100%; } #bottom-two { position: relative; margin-bottom: -9px; margin-left: 12px; margin-right: 12px; line-height: 18px; text-align: left; vertical-align: middle; } #left-one { position: absolute; width: 100%; buggedheight: 100%; } #left-two { position: relative; margin-top: 12px; line-height: 18px; text-align: center; vertical-align: top; } #right-one { display: table; height: 100%; width: 100%; } #right-two { display: table-row; height: 100%; width: 100%; } #right-three { display: table-cell; width: 100%; vertical-align: bottom; _position: absolute; _top: 100%; } #right-four { text-align: center; margin-bottom: 2ex; _position: relative; _top: -100%; } #more-top { position: absolute; top: 0%; left: 90%; bottom: 90%; right: 0%; z-index: 3; width: 10%; height: 10%; padding: 0%; margin: 0%; border-style: none; border-width: 0; } #more-top-settings { text-align: center; } #more-right-settings { margin-right: 12px; margin-left: 12px; line-height: 18px; font-size: 10px; text-align: center; } #right-safari { _display: table; width: 100%; height: 100%; }
@@ -24,7 +24,7 @@
</head>
<body>
<div id="top"> <div id="top-one">
- <div id="top-two">YouLess Fetcher 1.100 </div>
+ <div id="top-two">YouLess Fetcher 1.10 </div>
</div>
</div>
<div id="bottom"> <div id="bottom-one">
diff --git a/doc/context/scripts/mkiv/mtx-youless.man b/doc/context/scripts/mkiv/mtx-youless.man
index 043edd071..fa650a0b6 100644
--- a/doc/context/scripts/mkiv/mtx-youless.man
+++ b/doc/context/scripts/mkiv/mtx-youless.man
@@ -1,4 +1,4 @@
-.TH "mtx-youless" "1" "01-01-2018" "version 1.100" "youless Fetcher"
+.TH "mtx-youless" "1" "01-01-2019" "version 1.100" "youless Fetcher"
.SH NAME
.B mtx-youless
.SH SYNOPSIS
diff --git a/doc/context/scripts/mkiv/mtxrun.html b/doc/context/scripts/mkiv/mtxrun.html
index 3df54da6e..f0eef2ae7 100644
--- a/doc/context/scripts/mkiv/mtxrun.html
+++ b/doc/context/scripts/mkiv/mtxrun.html
@@ -47,9 +47,7 @@
<tr><th>--internal</th><td></td><td>run script using built in libraries (same as --ctxlua)</td></tr>
<tr><th>--locate</th><td></td><td>locate given filename in database (default) or system (--first --all --detail)</td></tr>
<tr><th/><td/><td/></tr>
- <tr><th>--autotree</th><td></td><td>use texmf tree cf. env texmfstart_tree or texmfstarttree</td></tr>
<tr><th>--tree</th><td>pathtotree</td><td>use given texmf tree (default file: setuptex.tmf)</td></tr>
- <tr><th>--environment</th><td>name</td><td>use given (tmf) environment file</td></tr>
<tr><th>--path</th><td>runpath</td><td>go to given path before execution</td></tr>
<tr><th>--ifchanged</th><td>filename</td><td>only execute when given file has changed (md checksum)</td></tr>
<tr><th>--iftouched</th><td>old,new</td><td>only execute when given file has changed (time stamp)</td></tr>
@@ -66,7 +64,7 @@
<tr><th>--systeminfo</th><td>str</td><td>show current operating system, processor, etc</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--edit</th><td></td><td>launch editor with found file</td></tr>
- <tr><th>--launch</th><td></td><td>launch files like manuals, assumes os support (--all)</td></tr>
+ <tr><th>--launch</th><td></td><td>launch files like manuals, assumes os support (--all,--list)</td></tr>
<tr><th/><td/><td/></tr>
<tr><th>--timedrun</th><td></td><td>run a script and time its run</td></tr>
<tr><th>--autogenerate</th><td></td><td>regenerate databases if needed (handy when used to run context in an editor)</td></tr>
diff --git a/doc/context/scripts/mkiv/mtxrun.man b/doc/context/scripts/mkiv/mtxrun.man
index fdff5103c..70dd035c4 100644
--- a/doc/context/scripts/mkiv/mtxrun.man
+++ b/doc/context/scripts/mkiv/mtxrun.man
@@ -1,4 +1,4 @@
-.TH "mtxrun" "1" "01-01-2018" "version 1.33" "ConTeXt TDS Runner Tool"
+.TH "mtxrun" "1" "01-01-2019" "version 1.33" "ConTeXt TDS Runner Tool"
.SH NAME
.B mtxrun
.SH SYNOPSIS
@@ -32,15 +32,9 @@ run script using built in libraries (same as --ctxlua)
.B --locate
locate given filename in database (default) or system (--first --all --detail)
.TP
-.B --autotree
-use texmf tree cf. env texmfstart_tree or texmfstarttree
-.TP
.B --tree=pathtotree
use given texmf tree (default file: setuptex.tmf)
.TP
-.B --environment=name
-use given (tmf) environment file
-.TP
.B --path=runpath
go to given path before execution
.TP
@@ -81,7 +75,7 @@ show current operating system, processor, etc
launch editor with found file
.TP
.B --launch
-launch files like manuals, assumes os support (--all)
+launch files like manuals, assumes os support (--all,--list)
.TP
.B --timedrun
run a script and time its run
diff --git a/doc/context/scripts/mkiv/mtxrun.xml b/doc/context/scripts/mkiv/mtxrun.xml
index d307239c3..5e2c81c9f 100644
--- a/doc/context/scripts/mkiv/mtxrun.xml
+++ b/doc/context/scripts/mkiv/mtxrun.xml
@@ -17,9 +17,7 @@
<flag name="locate"><short>locate given filename in database (default) or system (<ref name="first"/> <ref name="all"/> <ref name="detail"/>)</short></flag>
</subcategory>
<subcategory>
- <flag name="autotree"><short>use texmf tree cf. env texmfstart_tree or texmfstarttree</short></flag>
<flag name="tree" value="pathtotree"><short>use given texmf tree (default file: setuptex.tmf)</short></flag>
- <flag name="environment" value="name"><short>use given (tmf) environment file</short></flag>
<flag name="path" value="runpath"><short>go to given path before execution</short></flag>
<flag name="ifchanged" value="filename"><short>only execute when given file has changed (md checksum)</short></flag>
<flag name="iftouched" value="old,new"><short>only execute when given file has changed (time stamp)</short></flag>
@@ -39,7 +37,7 @@
</subcategory>
<subcategory>
<flag name="edit"><short>launch editor with found file</short></flag>
- <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>)</short></flag>
+ <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>,<ref name="list"/>)</short></flag>
</subcategory>
<subcategory>
<flag name="timedrun"><short>run a script and time its run</short></flag>
diff --git a/doc/context/sources/general/fonts/fonts/fonts-demo-rule.lua b/doc/context/sources/general/fonts/fonts/fonts-demo-rule.lua
new file mode 100644
index 000000000..667d1e43c
--- /dev/null
+++ b/doc/context/sources/general/fonts/fonts/fonts-demo-rule.lua
@@ -0,0 +1,47 @@
+local startactualtext = backends.codeinjections.startunicodetoactualtext
+local stopactualtext = backends.codeinjections.stopunicodetoactualtext
+
+return function(specification)
+ local features = specification.features.normal
+ local name = features.original or "dejavu-serif"
+ local option = features.option -- we only support "line"
+ local size = specification.size -- always set
+ local detail = specification.detail -- e.g. default
+ if detail then
+ name = name .. "*" .. detail
+ end
+ local f, id = fonts.constructors.readanddefine(name,size)
+ if f then
+ f.properties.name = specification.name
+ f.properties.virtualized = true
+ f.fonts = {
+ { id = id },
+ }
+ for s in string.gmatch("aeuioy",".") do
+ local n = utf.byte(s)
+ local c = f.characters[n]
+ if c then
+ local w = c.width or 0
+ local h = c.height or 0
+ local d = c.depth or 0
+ if option == "line" then
+ f.characters[n].commands = {
+ { "special", "pdf:direct:" .. startactualtext(n) },
+ { "rule", option == "line" and size/10, w },
+ { "special", "pdf:direct:" .. stopactualtext() },
+ }
+ else
+ f.characters[n].commands = {
+ { "special", "pdf:direct:" .. startactualtext(n) },
+ { "down", d },
+ { "rule", h + d, w },
+ { "special", "pdf:direct:" .. stopactualtext() },
+ }
+ end
+ else
+ -- probably a real bad font
+ end
+ end
+ end
+ return f
+end
diff --git a/doc/context/sources/general/fonts/fonts/fonts-extensions.tex b/doc/context/sources/general/fonts/fonts/fonts-extensions.tex
index ace0f771e..afe6fd823 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-extensions.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-extensions.tex
@@ -718,6 +718,8 @@ the comma also pulls the preceding character into the margin.
\getbuffer [example]
\stopplacefigure
+\stopsubsubject
+
\stopsection
\startsection[title=Expansion]
@@ -822,6 +824,8 @@ You can see what happens in \in {figure} [expansion:visualized].
\getbuffer [example]
\stopplacefigure
+\stopsubsubject
+
\startsubsubject[title=Expansion and kerning]
When we expand glyphs we also need to look at the font kerns between them. In the
@@ -1763,7 +1767,6 @@ only when we touch a space:
},
},
}
-
\stopluacode
\stopbuffer
@@ -2220,9 +2223,11 @@ fonts.handlers.otf.addfeature {
{
type = "pair",
data = {
- [<char|code>] = { [<char|code>] = {
- false | { <value>, <value>, <value>, <value> },
- false | { <value>, <value>, <value>, <value> }
+ [<char|code>] = {
+ [<char|code>] = {
+ false | { <value>, <value>, <value>, <value> },
+ false | { <value>, <value>, <value>, <value> }
+ }
}
}
},
diff --git a/doc/context/sources/general/fonts/fonts/fonts-features.tex b/doc/context/sources/general/fonts/fonts/fonts-features.tex
index 73d1cd96d..bf9f39385 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-features.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-features.tex
@@ -2667,7 +2667,7 @@ We can enable and disable features any time in the input by using the
\startbuffer
\definefont
[WeirdShapes]
- [file:linlibertiner*default]
+ [file:libertiner*default]
\definefontfeature
[hist]
diff --git a/doc/context/sources/general/fonts/fonts/fonts-tricks.tex b/doc/context/sources/general/fonts/fonts/fonts-tricks.tex
index b8903b5ed..65b210e2c 100644
--- a/doc/context/sources/general/fonts/fonts/fonts-tricks.tex
+++ b/doc/context/sources/general/fonts/fonts/fonts-tricks.tex
@@ -386,3 +386,5 @@ and in the distribution.
\stopsection
\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/about/about-metafun.tex b/doc/context/sources/general/manuals/about/about-metafun.tex
index d289dd803..bc298e995 100644
--- a/doc/context/sources/general/manuals/about/about-metafun.tex
+++ b/doc/context/sources/general/manuals/about/about-metafun.tex
@@ -727,15 +727,15 @@ We load the data in datasets:
\startbuffer
\startMPcode
- lua.mp.datasets.load("foo","foo.tmp") ;
- lua.mp.datasets.load("bar","bar.tmp") ;
+ lua.mp.datasets("load","foo","foo.tmp") ;
+ lua.mp.datasets("load","bar","bar.tmp") ;
fill area
- lua.mp.datasets.foo.Line()
+ lua.mp.datasets("foo","line")
xysized (HSize/2-EmWidth,10ExHeight)
withpen pencircle scaled .25ExHeight
withcolor green/2 ;
fill area
- lua.mp.datasets.bar.Line()
+ lua.mp.datasets("bar","line")
xysized (HSize/2-EmWidth,10ExHeight)
shifted (HSize/2+EmWidth,0)
withpen pencircle scaled .25ExHeight
@@ -755,8 +755,8 @@ following is valid:
\starttyping
\startMPcode
- lua.mp.datasets.load("foo.tmp") ;
- lua.mp.datasets.load("bar.tmp") ;
+ lua.mp.datasets("load","foo.tmp") ;
+ lua.mp.datasets("load","bar.tmp") ;
\stopMPcode
\stoptyping
diff --git a/doc/context/sources/general/manuals/cld/cld-moreonfunctions.tex b/doc/context/sources/general/manuals/cld/cld-moreonfunctions.tex
index fab22515e..da3d6fe46 100644
--- a/doc/context/sources/general/manuals/cld/cld-moreonfunctions.tex
+++ b/doc/context/sources/general/manuals/cld/cld-moreonfunctions.tex
@@ -173,24 +173,27 @@ example of why coding in \TEX\ makes sense as it looks more intuitive:
\test{test 4 \test{test 5} test 6}
\stoptyping
-There is also another mechanism available. In the next example the second
-argument is actually a string.
-
-\starttyping
-local nested = context.nested
-
-context.test("test 8",nested.test("test 9"),"test 10")
-\stoptyping
-
-There is a pitfall here: a nested context command needs to be flushed explicitly,
-so in the case of:
-
-\starttyping
-context.nested.test("test 9")
-\stoptyping
-
-a string is created but nothing ends up at the \TEX\ end. Flushing is up to you.
-Beware: \type {nested} only works with the regular \CONTEXT\ catcode regime.
+The \type {context.nested} variant is now an alias to \type {context.delayed} and
+no longer builds a string representation.
+
+% There is also another mechanism available. In the next example the second
+% argument is actually a string.
+%
+% \starttyping
+% local nested = context.nested
+%
+% context.test("test 8",nested.test("test 9"),"test 10")
+% \stoptyping
+%
+% There is a pitfall here: a nested context command needs to be flushed explicitly,
+% so in the case of:
+%
+% \starttyping
+% context.nested.test("test 9")
+% \stoptyping
+%
+% a string is created but nothing ends up at the \TEX\ end. Flushing is up to you.
+% Beware: \type {nested} only works with the regular \CONTEXT\ catcode regime.
\stopsection
diff --git a/doc/context/sources/general/manuals/graphics/graphics.tex b/doc/context/sources/general/manuals/graphics/graphics.tex
new file mode 100644
index 000000000..7c1000c4e
--- /dev/null
+++ b/doc/context/sources/general/manuals/graphics/graphics.tex
@@ -0,0 +1,415 @@
+% language=uk
+
+\usemodule[article-basic]
+\usemodule[abbreviations-smallcaps]
+\usemodule[setups-basics]
+\usemodule[scite]
+
+% \setupbodyfont
+% [dejavu]
+
+\loadsetups[context-en]
+
+\definecolor
+ [mysetupscolora]
+ [a=1,
+ t=.25,
+ r=.5,
+ g=.5]
+
+\definecolor
+ [mysetupscolorb]
+ [a=1,
+ t=.25,
+ g=.25,
+ b=.25]
+
+\definetextbackground
+ [mysetups]
+ [before=\blank,
+ after=\blank,
+ topoffset=10pt,
+ leftoffset=10pt,
+ location=paragraph,
+ backgroundcolor=mysetupscolora,
+ backgroundcolor=mysetupscolorb,
+ frame=off]
+
+\startsetups xml:setups:start
+ \starttextbackground[mysetups]
+\stopsetups
+
+\startsetups xml:setups:stop
+ \stoptextbackground
+\stopsetups
+
+\starttext
+
+\startbuffer[image]
+ \startluacode
+
+ local min, max, random = math.min, math.max, math.random
+
+ -- kind of self-explaining:
+
+ local xsize = 210
+ local ysize = 297
+ local colordepth = 1
+ local usemask = true
+ local colorspace = "rgb"
+
+ -- initialization:
+
+ local bitmap = graphics.bitmaps.new(xsize,ysize,colorspace,colordepth,usemask)
+
+ -- filling the bitmap:
+
+ local data = bitmap.data
+ local mask = bitmap.mask
+ local minmask = 100
+ local maxmask = 200
+
+ for i=1,ysize do
+ local d = data[i]
+ local m = mask[i]
+ for j=1,xsize do
+ d[j] = { i, max(i,j), j, min(i,j) }
+ m[j] = random(minmask,maxmask)
+ end
+ end
+
+ -- flushing the lot:
+
+ graphics.bitmaps.tocontext(bitmap)
+
+ \stopluacode
+\stopbuffer
+
+\definelayer
+ [page]
+ [width=\paperwidth,
+ height=\paperheight]
+
+\setlayer
+ [page]
+ {\scale
+ [width=\paperwidth]
+ {\ignorespaces
+ \getbuffer[image]%
+ \removeunwantedspaces}}
+
+\setlayer
+ [page]
+ [preset=rightbottom,
+ hoffset=10mm,
+ voffset=45mm]
+ {\scale
+ [width=.6\paperwidth]
+ {Graphics}}
+
+% \setlayer
+% [page]
+% [preset=righttop,
+% hoffset=10mm,
+% voffset=20mm]
+% {\rotate{\scale
+% [width=.3\paperheight]
+% {\ConTeXt\ MkIV}}}
+
+\setlayer
+ [page]
+ [preset=rightbottom,
+ hoffset=10mm,
+ voffset=20mm]
+ {\scale
+ [width=.6\paperwidth]
+ {Hans Hagen}}
+
+\startpagemakeup
+ \flushlayer[page]
+ \vfill
+\stoppagemakeup
+
+\startsubject[title=Introduction]
+
+This manual is about integrating graphics your document. Doing this is not really
+that complex so this manual will be short. Because graphic inclusion is related
+to the backend some options will discussed. It's typical one of these manuals
+that can grow over time.
+
+\stopsubject
+
+\startsubject[title=Basic formats]
+
+In \TEX\ a graphic is not really known as graphic. The core task of the engine is
+to turn input into typeset paragraphs. By the time that happens the input has
+become a linked list of so called nodes: glyphs, kerns, glue, rules, boxes and a
+couple of more items. But, when doing the job, \TEX\ is only interested in
+dimensions.
+
+In traditional \TEX\ an image inclusion happens via the extension primitive
+\type {\special}, so you can think of something:
+
+\starttyping
+\vbox to 10cm {%
+ \hbox to 4cm {%
+ \special{image foo.png width 4cm height 10cm}%
+ \hss
+ }%
+}
+\stoptyping
+
+When typesetting \TEX\ sees a box and uses its dimensions. It doesn't care what
+is inside. The special itself is just a so called whatsit that is not
+interpreted. When the page is eventually shipped out, the \DVI|-|to|-|whatever
+driver interprets the special's content and embeds the image.
+
+It will be clear that this will only work correctly when the image dimensions are
+communicated. That can happen in real dimensions, but using scale factors is also
+a variant. In the latter case one has to somehow determine the original dimensions
+in order to calculate the scale factor. When you embed \EPS\ images, which is the
+usual case in for instance \DVIPS, you can use \TEX\ macros to figure out the
+(high res) boundingbox, but for bitmaps that often meant that some external
+program had to do the analysis.
+
+It sounds complex but in practice this was all quite doable. I say \quote {was}
+because nowadays most \TEX\ users use an engine like \PDFTEX\ that doesn't need
+an external program for generating the final output format. As a consequence it
+has built-in support for analyzing and including images. There are additional
+primitives that analyze the image and additional ones that inject them.
+
+\starttyping
+\pdfximage
+ {foo.png}%
+\pdfrefximage
+ \pdflastximage
+ width 4cm
+ height 10cm
+\relax
+\stoptyping
+
+A difference with traditional \TEX\ is that one doesn't need to wrap them into a
+box. This is easier on the user (not that it matters much as often a macro
+package hides this) but complicates the engine because suddenly it has to check a
+so called extension whatsit node (representing the image) for dimensions.
+
+Therefore in \LUATEX\ this model has been replaced by one where an image
+internally is a special kind of rule, which in turn means that the code for
+checking the whatsit could go away as rules are already taken into account. The
+same is true for reuseable boxes (xforms in \PDF\ speak).
+
+\starttyping
+\useimageresource
+ {foo.png}%
+\saveimageresource
+ \lastsavedimageresourceindex
+ width 4cm
+ height 10cm
+\relax
+\stoptyping
+
+While \DVIPS\ supported \EPS\ images, \PDFTEX\ and \LUATEX\ natively support
+\PNG, \JPG\ en \PDF\ inclusion. The easiest to support is \JPG\ because the PDF\
+format supports so called \JPG\ compression in its full form. The engine only has
+to pass the image blob plus a bit of extra information. Analyzing the file for
+resolution, dimensions and colorspace is relative easy: consult some tables that
+have this info and store it. No special libraries are needed for this kind of
+graphics.
+
+A bit more work is needed for \PDF\ images. A \PDF\ file is a collection of
+(possibly compressed) objects. These objects can themselves refer to other
+objects so basically we we have a tree of objects. This means that when we embed
+a page from a \PDF\ file, we start with embedding the (content stream of the)
+page object and then embed all the objects it refers to, which is a recursive
+process because those objects themselves can refer to objects. In the process we
+keep track of which objects are copied so that when we include another page we
+don't copy duplicates.
+
+A dedicated library is used for opening the file, and looking for objects that
+tell us the dimensions and fetching objects that we need to embed. In \PDFTEX\
+the poppler library is used, but in \LUATEX\ we have switched to pplib which is
+specially made for this engine (by Pawel Jackowski) as a consequence of some
+interchange that we had at the 2018 Bacho\TEX\ meeting. This change of library
+gives us a greater independency and a much smaller code base. After all, we only
+need access to \PDF\ files and its objects.
+
+One can naively think that \PNG\ inclusion is as easy as \JPG\ inclusion because
+\PDF\ supports \PNG\ compression. Well, this is indeed true, but it only supports
+so called \PNG\ filter based compression. The image blob in a \PNG\ file
+describes pixels in rows and columns where each row has a filter byte telling how
+that row is to be interpreted. Pixel information can be derived from preceding
+pixels, pixels above it, or a combination. Also some averaging can come into
+play. This way repetitive information can (for instance) become for instance a
+sequence of zeros because no change in pixel values took place. And such a
+sequence can be compressed very well which is why the whole blob is compressed
+with zlib.
+
+In \PDF\ zlib compression can be applied to object streams so that bit is
+covered. In addition a stream can be \PNG\ compressed, which means that it can
+have filter bytes that need to be interpreted. But the \PNG\ can do more: the
+image blob is actual split in chunks that need to be assembled. The image
+information can be interlaced which means that the whole comes in 7~seperate
+chunks thet get overlayed in increasing accuracy. Then there can be an image mask
+part of the blob and that mask needs to be separated in \PDF\ (think of
+transparency). Pixels can refer to a palette (grayscale or color) and pixels can
+be codes in~1, 2, 4, 8 or 16~bits where color images can have 3~bytes. When
+multiple pixels are packed into one byte they need to be expanded.
+
+This all means that embedding \PNG\ file can demand a conversion and when you
+have to do that each run, it has a performance hit. Normally, in a print driven
+workflow, one will have straightforward \PNG\ images: 1 byte or 3 bytes which no
+mask and not interlaced. These can be transferred directly to the \PDF\ file. In
+all other cases it probably makes sense to convert the images beforehand (to
+simple \PNG\ or just \PDF).
+
+So, to summarize the above: a modern \TEX\ engine supports image inclusion
+natively but for \PNG\ images you might need to convert them beforehand if
+runtime matters and one has to run many times.
+
+\stopsubject
+
+\startsubject[title=Inclusion]
+
+The command to include an image is:
+
+\showsetup{externalfigure}
+
+and its related settings are:
+
+\showsetup{setupexternalfigure}
+
+So you can say:
+
+\starttyping[option=TEX]
+\externalfigure[cow.pdf][width=4cm]
+\stoptyping
+
+The suffix is optional, which means that this will also work:
+
+\starttyping[option=TEX]
+\externalfigure[cow][width=4cm]
+\stoptyping
+
+\stopsubject
+
+\startsubject[title=Defining]
+
+{\em todo}
+
+\showsetup{useexternalfigure}
+\showsetup{defineexternalfigure}
+\showsetup{registerexternalfigure}
+
+\stopsubject
+
+\startsubject[title=Analyzing]
+
+{\em todo}
+
+\showsetup{getfiguredimensions}
+
+\showsetup{figurefilename}
+\showsetup{figurefilepath}
+\showsetup{figurefiletype}
+\showsetup{figurefullname}
+\showsetup{figureheight}
+\showsetup{figurenaturalheight}
+\showsetup{figurenaturalwidth}
+\showsetup{figuresymbol}
+\showsetup{figurewidth}
+
+\showsetup{noffigurepages}
+
+\stopsubject
+
+\startsubject[title=Collections]
+
+{\em todo}
+
+\showsetup{externalfigurecollectionmaxheight}
+\showsetup{externalfigurecollectionmaxwidth}
+\showsetup{externalfigurecollectionminheight}
+\showsetup{externalfigurecollectionminwidth}
+\showsetup{externalfigurecollectionparameter}
+\showsetup{startexternalfigurecollection}
+
+\stopsubject
+
+\startsubject[title=Conversion]
+
+{\em todo}
+
+\stopsubject
+
+\startsubject[title=Figure databases]
+
+{\em todo}
+
+\showsetup{usefigurebase}
+
+\stopsubject
+
+\startsubject[title=Overlays]
+
+{\em todo}
+
+\showsetup{overlayfigure}
+\showsetup{pagefigure}
+
+\stopsubject
+
+\startsubject[title=Scaling]
+
+Images are normally scaled proportionally but if needed you can give an
+explicit height and width. The \type {\scale} command shares this property
+and can be used to scale in the same way as \type {\externalfigure}. I will
+illustrate this with an example.
+
+You can define your own bitmaps, like I did with the cover of this manual:
+
+\typebuffer[image][option=LUA]
+
+The actually inclusion of this image happened with:
+
+\starttyping[option=TEX]
+\scale
+ [width=\paperwidth]
+ {\getbuffer[image]}
+\stoptyping
+
+\stopsubject
+
+% \startsubject[title=The backend]
+%
+% Traditionally \TEX\ sees an image as just a box with dimensions and in \LUATEX\
+% it is actually a special kind of rule that carries information about what to
+% inject in the final (\PDF) file. In regular \LUATEX\ the core formats \type
+% {pdf}, \type {png}, \type {jpg} and \type {jp2} are dealt with by the backend but
+% in \CONTEXT\ we can use \LUA\ instead. We might default to that method at some
+% point but for now you need to enable that explicitly:
+%
+% \starttyping[option=TEX]
+% \enabledirectrive[graphics.pdf.uselua]
+% \enabledirectrive[graphics.jpg.uselua]
+% \enabledirectrive[graphics.jp2.uselua]
+% \enabledirectrive[graphics.png.uselua]
+% \stoptyping
+%
+% All four can be enabled with:
+%
+% \starttyping[option=TEX]
+% \enabledirectrive[graphics.uselua]
+% \stoptyping
+%
+% Performance|-|wise only \PNG\ inclusion can be less efficient, but only when you
+% use interlaced images or large images with masks. It makes no real sense in a
+% professional workflow to use the (larger) interlaced images, and masks are seldom
+% used at high resolutions, so in practice one will not really notice loss of
+% performance.
+%
+% The advantage of this method is that we can provide more options, intercept bad
+% images that make the backend abort and lessen the dependency on libraries.
+%
+% \stopsubject
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/interaction/interaction-actions.tex b/doc/context/sources/general/manuals/interaction/interaction-actions.tex
new file mode 100644
index 000000000..a5caf2c0b
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-actions.tex
@@ -0,0 +1,204 @@
+% language=uk
+
+\environment interaction-style
+
+\usemodule[references-identify]
+
+\startcomponent interaction-actions
+
+\startchapter[title=Actions]
+
+The reference mechanism not only deals with the more traditional cross
+references, but also takes care of navigation, launching applications (although
+that is often limited by viewers), running \JAVASCRIPT, etc. By integrating these
+features in one mechanism, we limit the number of commands needed for hyperlinks,
+menus and buttons. Normally such actions are driven by the \type {\goto} command,
+but you can also use buttons:
+
+\starttyping
+\goto[inner reference]
+\goto[outer reference::]
+\goto[outer reference::inner reference]
+\stoptyping
+
+The inner reference is normally a user defined one, for instance a reference to a
+named location like a chapter or figure. The outer reference refers to a file or
+\URL and is normally defined at the document level and is accessed by the \type
+{::}. By using symbolic names updating them becomes easier.
+
+There are also predefined references, like \type {nextpage} to go to the next
+page or \type {forward} to cycle, \type {nextcontents} for the next level table
+of contents in a linked list of such tables, etc. Some keywords are actually
+shortcuts to actions that are delegated to the viewer. Here you need to keep in
+mind that nowadays we're talking of \PDF\ viewers, but originally (\MKII) we also
+supported \DVI\ viewers. A special class of references are the viewer control
+ones, like \type {CloseDocument} or \type {PreviousJump}. They can be recognized
+by their capitals.
+
+When we speak of a reference, we actually refer to a whole bunch of possible
+references. We already mentioned inner and outer references, but special actions
+are also possible. These are actually plugins. Examples are the \JAVASCRIPT\ and
+\URL\ plugins. The interface evolved a bit over a few decades but most has been
+there right from the start, which is why we keep it as is. Actually, there is not
+that much new functionality added in \MKIV, although the implementation was
+mostly rewritten. Here is a overview of the syntax, just to give you an idea.
+
+\starttyping
+\goto[inner]
+\goto[inner(foo,bar)]
+\goto[inner{argument,argument}]
+\goto[inner{argument}]
+\goto[outer::]
+\goto[outer::inner]
+\goto[outer::special(operation{argument,argument})]
+\goto[outer::special(operation)]
+\goto[outer::special()]
+\goto[outer::inner{argument}]
+\goto[special(operation{argument})]
+\goto[special(operation{argument,argument})]
+\goto[special(operation)]
+\goto[special(outer::operation)]
+\goto[special(operation)]
+\goto[special(operation(whatever))]
+\goto[special(operation{argument,argument{whatever}})]
+\goto[special(operation{argument{whatever}})]
+\stoptyping
+
+There can be multiple actions, separated by a comma, think of: go to the page
+with label \quote {foo} and start video \quote {bar}.
+
+\showsetup{goto}
+
+Examples of operations are \type {page}, \type {program}, \type {action}, \type
+{url} and \type {JS}. \footnote {There are a few more operations but not all make
+sense at the user level.} The \type {page} operation accepts a pagenumber as
+well as relevant keywords. One can prefix a pagenumber by a file or \URL\ tag.
+The \type {program} operation starts up a program. It is an example of an old
+feature that has proven to be unstable, simply because viewers change behaviour
+over time.
+
+\showsetup{definereference}
+
+The built|-|in actions are interfaces via shortcuts with camelcase names. In most
+cases the name is a good indication of what to expect:
+
+\starttyping
+\definereference [CloseDocument] [action(close)]
+\definereference [ExitViewer] [action(exit)]
+\definereference [FirstPage] [action(first)]
+\definereference [LastPage] [action(last)]
+\definereference [NextJump] [action(forward)]
+\definereference [NextPage] [action(next)]
+\definereference [PauseMovie] [action(pausemovie)]
+\definereference [PauseSound] [action(pausesound)]
+\definereference [PauseRendering] [action(pauserendering)]
+\definereference [PreviousJump] [action(backward)]
+\definereference [PreviousPage] [action(previous)]
+\definereference [PrintDocument] [action(print)]
+\definereference [SaveForm] [action(exportform)]
+\definereference [LoadForm] [action(importform)]
+\definereference [ResetForm] [action(resetform)]
+\definereference [ResumeMovie] [action(resumemovie)]
+\definereference [ResumeSound] [action(resumesound)]
+\definereference [ResumeRendering] [action(resumerendering)]
+\definereference [SaveDocument] [action(save)]
+\definereference [SaveNamedDocument][action(savenamed)]
+\definereference [OpenNamedDocument][action(opennamed)]
+\definereference [SearchDocument] [action(search)]
+\definereference [SearchAgain] [action(searchagain)]
+\definereference [StartMovie] [action(startmovie)]
+\definereference [StartSound] [action(startsound)]
+\definereference [StartRendering] [action(startrendering)]
+\definereference [StopMovie] [action(stopmovie)]
+\definereference [StopSound] [action(stopsound)]
+\definereference [StopRendering] [action(stoprendering)]
+\definereference [SubmitForm] [action(submitform)]
+\definereference [ToggleViewer] [action(toggle)]
+\definereference [ViewerHelp] [action(help)]
+\definereference [HideField] [action(hide)]
+\definereference [ShowField] [action(show)]
+\definereference [GotoPage] [action(gotopage)]
+\definereference [Query] [action(query)]
+\definereference [QueryAgain] [action(queryagain)]
+\definereference [FitWidth] [action(fitwidth)]
+\definereference [FitHeight] [action(fitheight)]
+\definereference [ShowThumbs] [action(thumbnails)]
+\definereference [ShowBookmarks] [action(bookmarks)]
+\definereference [HideLayer] [action(hidelayer)]
+\definereference [VideLayer] [action(videlayer)]
+\definereference [ToggleLayer] [action(togglelayer)]
+\stoptyping
+
+In the \type {java-imp-*.mkiv} files you will find examples of similar shortcuts,
+for instance:
+
+\starttyping
+\definereference [SetupStepper] [JS(SetupStepper{step,50})]
+\definereference [ResetStepper] [JS(ResetStepper)]
+\definereference [CheckStepper] [JS(CheckStepper{\StepCounter})]
+\definereference [InvokeStepper] [JS(InvokeStepper)]
+\stoptyping
+
+Other examples of redefined references are:
+
+\starttyping
+\definereference [firstpage] [page(firstpage)]
+\definereference [previouspage] [page(previouspage)]
+\definereference [nextpage] [page(nextpage)]
+\definereference [lastpage] [page(lastpage)]
+\definereference [forward] [page(forward)]
+\definereference [backward] [page(backward)]
+\definereference [firstsubpage] [page(firstsubpage)]
+\definereference [previoussubpage] [page(previoussubpage)]
+\definereference [nextsubpage] [page(nextsubpage)]
+\definereference [lastsubpage] [page(lastsubpage)]
+\stoptyping
+
+Some of these actions expect arguments, for instance:
+
+\starttyping
+\goto{start}[StartMovie{mymovie}]
+\stoptyping
+
+You can load the module \type {references-identify} which gives you
+a command:
+
+\startbuffer
+\showreference[page(123),StartMovie{mymovie}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\showreference[JS(Forget_Changes),CloseDocument]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\showreference[manual::contents]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+You should be careful with colons in references. This gives you an idea how
+\CONTEXT\ interprets what you requested.
+
+\starttabulate[|T|p|]
+\NC prefix:whatever \NC The \type {prefix} creates a namespace. When references are
+ resolved and there is no hit a lookup without prefix
+ takes place. \NC \NR
+\NC document::whatever \NC The \type {document} is a symbolic reference to an external
+ resource. This is explained elsewhere. \NC \NR
+\NC component:::whatever \NC The \type {component} is a symbolic reference to a component in
+ a product. References defined in such a component are loaded on
+ demand. \NC \NR
+\stoptabulate
+
+% url(http://a,b.c)
+% url(http://a,b.c)
+% url(http://a.b.c)
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-annotations.tex b/doc/context/sources/general/manuals/interaction/interaction-annotations.tex
new file mode 100644
index 000000000..e61a0953d
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-annotations.tex
@@ -0,0 +1,106 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-annotations
+
+\startchapter[title=Annotations]
+
+Before we discuss interactive features (in following chapter) a few words will be
+spent on so called annotations. This term is used in Acrobat and is somewhat
+confusing as hyperlinks conceptually are not really annotations while comments
+are. The term relates to the way \PDF\ files can have added functionality. It
+might help understand the following chapters better when you know what model is
+used inside a \PDF.
+
+If you open a \PDF\ file in an editor you will finds lots of objects. Numbers are
+an object, as are strings and booleans. Symbols (represented as strings with a
+leading slash) are also objects. Objects can be collected in indexed tables
+(arrays) and hash tables (dictionaries). Serialized arrays are bounded by square
+brackets:
+
+\starttyping
+[ (value1) (value2) ]
+[ 1 2 3 ]
+[ 1 2 (value1) (value3) true /foo ]
+\stoptyping
+
+and hashes by double angle brackets:
+
+\starttyping
+<<
+ /Key1 (value1)
+ /Key2 (value2)
+ /Key3 123
+ /Key4 true
+ /Key5 [ 1 2 3 4 ]
+>>
+\stoptyping
+
+A \PDF\ file is a collection of objects:
+
+\starttyping
+1 0 obj
+ ...
+endobj
+\stoptyping
+
+Instead of a number, string, boolean, array or dictionary an object can also be
+a stream of bytes:
+
+\starttyping
+1 0 obj << /Length 123 >>
+stream
+... 123 bytes ...
+endstream
+endobj
+\stoptyping
+
+Objects can refer to each other and can be looked up via a so called xref table.
+We refer to object with number one and revision zero as follows:
+
+\starttyping
+/foo 1 0 R
+\stoptyping
+
+When an object is updated it can be added to the end of the file and the version
+number can get bumped. A program that does something with the \PDF\ is supposed
+to do something clever with these numbers. More often the revision stays zero.
+
+A document is normally a sequence of pages. When a file is opened the cross
+reference table is loaded and the so called catalog is looked up. From there
+pages can be found. Pages have a content stream and can refer to resources, like
+fonts, special color spaces, complex objects (xforms) and among other things
+annotations.
+
+The page is rendered from the content stream but that stream has no information
+about hyperlinks and such. The \type {/Link} annotation objects that implement
+interactivity are independent and kind of layered over the rendered page. They
+describe rectangular areas that a viewer can use to intercept mouse clicks. If
+you want to see where the actions happens, search for \type {/Dest} and \type
+{/Annot} in an (uncompressed) \PDF file. When you process a file with
+
+\starttyping
+\nopdfcompression
+\stoptyping
+
+you get an uncompressed file and with an appropriate editor you can see where
+annotations end up.
+
+The main reason for mentioning these details is that when you are checking a file
+for problems you need to look for annotation objects instead of the page stream.
+You also need to realize that these annotations in no way interfere with the page
+stream. They only exist because a viewer can use that information to add
+functionality. Their reference point is the lower left corner of the page. This
+is a conceptual difference with \HTML\ where hyperlinks are often in|-|line and
+part of the content stream. Both approaches have their advantages and
+disadvantages. From the perspective of quality typesetting it makes much sense to
+have them overlayed and explicitly defined (in terms of dimensions) but users
+will of course in most cases define them inline. This means that in order to make
+the \PDF\ some analyzing and juggling has to take place. In \CONTEXT\ we always
+have done as much as possible at the \TEX\ (therefore bypassing some limitations
+in the engine) end in \MKIV\ we don't use the engine's features at all.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-attachments.tex b/doc/context/sources/general/manuals/interaction/interaction-attachments.tex
new file mode 100644
index 000000000..6ae9b6310
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-attachments.tex
@@ -0,0 +1,174 @@
+% language=uk
+
+% Written while intermittently watching those always positive "Walk off the Earth"
+% videos to keep me in the mood. They make what's normally not my kind of music
+% into something very interesting. I hope that this chapter is kind of interesting
+% in the end too.
+
+\environment interaction-style
+
+\enabletrackers[attachments.anchors]
+
+\setupattachment
+ [location=inmargin]
+
+\startcomponent interaction-attachments
+
+\startchapter[title=Attachments]
+
+Attachments are (normally) embedded files that the reader can extract. A viewer
+can decide to just show the content or call an associated program to deal with
+the file (which one depends on the operating system). As with other annotations
+they started out depicted by symbols but then browsers started showing them in
+lists next to the displayed page.
+
+\startbuffer
+\attachment
+ [attachment 1]
+ [file=interaction-attached-001.txt,
+ title=Just some text,
+ width=2em,
+ height=2em,
+ author=Hans,
+ subtitle=Plain text]
+
+\attachment
+ [attachment 2]
+ [file=cow.mp,
+ title=Just a graphic,
+ author=Hans,
+ subtitle=Some MetaPost,
+ method=hidden]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+These two attachments differ in one aspect: the second one is hidden, i.e. it has
+no icon in the text. However, the attachment is in the file and is (often)
+visible in the side bar. The symbol for the visible one is in the margin, which
+is achieved with:
+
+\starttyping
+\setupattachment
+ [location=inmargin]
+\stoptyping
+
+You can use your own icon, for instance:
+
+\startbuffer
+\startuniqueMPgraphic{cow}{height,s:color}
+ loadfigure "cow.mp" number 1 ;
+ refill currentpicture withcolor "\MPvar{color}" ;
+ currentpicture := currentpicture ysized \MPvar{height} ;
+\stopuniqueMPgraphic
+
+\definesymbol
+ [attachment-normal]
+ [\uniqueMPgraphic{cow}{height=4ex,color=darkblue}]
+\definesymbol
+ [attachment-down]
+ [\uniqueMPgraphic{cow}{height=4ex,color=darkyellow}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+% \startattachment[hello][symbol={attachment-normal,attachment-down}]
+% oeps
+% \stopattachment
+
+\attachment
+ [symbol={attachment-normal,attachment-down},
+ file=cow.pdf,
+ title=A cow,
+ author=Hans,
+ subtitle=graphic]
+
+This time we get a cow as icon and the cow is also embedded as image. When
+writing this manual a click in Sumatra just opens the \PDF\ file, but when I
+embed an mp3 file, a save-as window pops up.
+
+The previous examples directly injected the attachment using the \type
+{\attachment} commands with the appropriate arguments. You can add titles, define
+a name that will be used when the attachment is saved:
+
+\starttyping
+\attachment[sometag][extra specs]
+\attachment[test.tex]
+\attachment[file=test.tex]
+\attachment[file=test.tex,method=hidden]
+\attachment[name=newname,file=test.tex]
+\attachment[title=mytitle,name=newname,file=test.tex]
+\stoptyping
+
+but there's also a more indirect way, for instance here we define some
+attachments:
+
+\starttyping
+\defineattachment[whatever-1][file=test.tex]
+\defineattachment[whatever-2][file=test.tex,method=hidden]
+\stoptyping
+
+that later can be called up with:
+
+\starttyping
+\attachment[whatever-1][method=hidden]
+\attachment[whatever-2]
+\stoptyping
+
+where of course hidden is to be omitted when you want an icon. The commands that
+are used to define and tune an instance are:
+
+\showsetup{defineattachment}
+
+\showsetup{setupattachment}
+
+There is one predefined instance:
+
+\starttyping
+\defineattachment[attachment]
+\stoptyping
+
+So we have:
+
+\showsetup{startattachment:instance}
+
+\showsetup{attachment:instance}
+
+Yet another level of abstraction can be achieved with:
+
+\showsetup{registerattachment}
+
+For example:
+
+\starttyping
+\registerattachment
+ [sometag]
+ [name=fool.txt,
+ file=foo.txt,
+ title=Fool me,
+ subtitle=Not you,
+ author= Joker]
+\stoptyping
+
+This is the \MKIV\ replacement for the \MKII\ method:
+
+\starttyping
+\useattachment[test.tex]
+\useattachment[whatever][test.tex]
+\useattachment[whatever][newname][test.tex]
+\useattachment[whatever][title][newname][test.tex]
+\stoptyping
+
+or with all options:
+
+\starttyping
+\useattachment[name][file][author][title][subtitle]
+\stoptyping
+
+The \type {\use...} variant stays around for old times sake and just maps onto
+\type {\registerattachment}, you can better use that one because it frees you
+from remembering which arguments is what for.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-bookmarks.tex b/doc/context/sources/general/manuals/interaction/interaction-bookmarks.tex
new file mode 100644
index 000000000..04dd3f89d
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-bookmarks.tex
@@ -0,0 +1,75 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-bookmarks
+
+\startchapter[title=Bookmarks]
+
+Bookmarks are a sort of table of contents displayed by the viewer and as such
+they take up extra space on the screen. You need to turn on interaction in
+order to get bookmark data embedded in the document.
+
+\starttyping
+\placebookmarks
+ [chapter,section,subsection,mylist]
+ [chapter]
+\stoptyping
+
+A bookmark list is added to the document only when interaction is enabled. The
+list in the first argument are bookmarked while the second argument specifies
+what bookmark (sub)trees are opened. if you don't get what you expect, check your
+document structure! Also, use the \type {\start}|-|\type {stop} alternatives.
+
+Bookmarks are taken from the section title, but you can overload the title
+as follows:
+
+\starttyping
+\startchapter[title=Foot,bookmark=food]
+ ...
+\stopchapter
+\stoptyping
+
+If you have a more complex typeset title you can also try:
+
+\starttyping
+\enabledirectives[references.bookmarks.preroll]
+\stoptyping
+
+From \MKII\ we inherit the option to overload the last set bookmark but the
+previously mentioned approach is better.
+
+\starttyping
+\chapter {the first chapter}
+\bookmark {the first bookmark}
+\stoptyping
+
+You can add entries to a bookmark list:
+
+\starttyping
+\bookmark[mylist]{whatever}
+\stoptyping
+
+This assumes that you have defined the list.
+
+\showsetup {bookmark}
+
+If you want to have the bookmark tab open when you start a document, you
+can say:
+
+\starttyping
+\setupinteractionscreen[option=bookmark]
+\stoptyping
+
+There are only a few options that you can use. The \type {number} parameter can
+be used to hide section numbers. The \type {sectionblock} parameter controls the
+addition of section block entries, something that can be handy when you have
+multiple section blocks with similar section titles. With \type {force} you force
+an entry to the file, bypassing mechanisms that to be clever.
+
+\showsetup{setupbookmark}
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/doc/context/sources/general/manuals/interaction/interaction-buttons.tex b/doc/context/sources/general/manuals/interaction/interaction-buttons.tex
new file mode 100644
index 000000000..d083a61a7
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-buttons.tex
@@ -0,0 +1,98 @@
+\environment interaction-style
+
+\startcomponent interaction-buttons
+
+\startchapter[title={Buttons}]
+
+There is not much to tell about buttons. They are clickable areas on the screen
+that when clicked on bring you some location or invoke some action in the viewer,
+for instance triggered by a \JAVASCRIPT. As usual with many commands, you can
+define categories of buttons and set them up globally or per category.
+
+\showsetup{definebutton}
+
+\showsetup{setupbutton}
+
+The default button command is:
+
+\showsetup{button}
+
+Buttons are an example of a construct that builds upon \type {\framed} so the
+keys that apply there also apply to buttons. You can enable or disable buttons
+with the \type {state} parameter. As usual there are a \type {style} and \type
+{color} parameters and an additional \type {contrastcolor} option for tuning the
+color of a button which action let you stay on the same page. Actually, when you
+do stay on the same page, the \type {samepage} parameter let you control if the
+button should be empty, hidden or whatever.
+
+\starttabulate[|B|c|c|c|]
+\NC \BC frame \BC text \BC shown \NC \NR
+\NC \type {yes} \NC + \NC + \NC + \NC \NR % 0
+\NC \type {empty} \NC + \NC - \NC + \NC \NR % 1
+\NC \type {no} \NC - \NC - \NC + \NC \NR % 2
+\NC \type {none} \NC - \NC - \NC - \NC \NR % 3
+\NC \type {normal} \NC + \NC + \NC + \NC \NR % 1
+\NC \type {default} \NC + \NC + \NC + \NC \NR % 1
+\stoptabulate
+
+Here is an example of a button:
+
+\startbuffer
+\button
+ [background=color,backgroundcolor=darkred,
+ style=bold,color=white,
+ framecolor=blue,rulethickness=2pt,
+ width=3cm,height=1.5cm]
+ {go to the next page}
+ [nexpage]
+\stopbuffer
+
+\typebuffer
+
+This colorful button shows up as:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+When you use interaction in presentations you might want to make the page
+and|/|or text area active. Here is an example.
+
+\starttyping
+\defineoverlay
+ [PrevPage]
+ [\overlaybutton{PrevPage}]
+
+\setupbackgrounds
+ [page]
+ [background=PrevPage]
+
+\setuptexttexts
+ [\overlaybutton{NextPage}]
+\stoptyping
+
+We provide two variants: the normal one with square brackets, but also a more
+direct one that accepts curly braces, which is handy when you pass an overlay
+button as argument.
+
+\showsetup {overlaybutton}
+\showsetup {overlaybutton:direct}
+
+The difference in usage is shown here:
+
+\starttyping
+\setuptexttexts [\overlaybutton{NextPage}]
+\setuptexttexts[{\overlaybutton[NextPage]}]
+\stoptyping
+
+An overlay button adapts its size to the current overlay so you don't need to
+worry about passing dimensions.
+
+It is possible to define more complex buttons, like roll|-|over buttons or
+buttons that change appearance when you clock on them. These are more resource
+hungry and also depend on the viewer. These will discussed in the chapter about
+widgets.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-comments.tex b/doc/context/sources/general/manuals/interaction/interaction-comments.tex
new file mode 100644
index 000000000..b19894d57
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-comments.tex
@@ -0,0 +1,194 @@
+\environment interaction-style
+
+\enabletrackers[comments.anchors]
+
+\startcomponent interaction-comments
+
+\setupcomment
+ [location=inmargin]
+
+\startchapter[title={Comments}]
+
+Many \PDF\ viewers support text annotations. These are small notes that can be
+popped up. In \CONTEXT\ we call them comments, because often that's what they are
+used for. Comments evolved from simple ones using a limited encoding into more
+advanced ones with representations. A comment looks like:
+
+\startbuffer
+\startcomment
+ Hello beautiful world!
+\stopcomment
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+When you open a document with comment you will likely see some symbol depicting
+it. But, it's one of those features that is viewer dependent so when it looks odd
+or unexpected, check in \ACROBAT\ first. The position and size can differ per
+viewer and when you zoom in the size can either stay the same or scale. The
+viewer can show the pop up text at the same location or someplace else. Although
+in principle there is control over this, my experience is that viewers (also
+Acrobat) keep changing this (not always for the best). Just assume the worst: it
+will never look good and although for a while we kept up with viewers, the
+inconsistency (and accumulated waste of time) led us to the current minimalistic
+approach.
+
+By default, in \CONTEXT\ comments are placed at the spot a bit raised. In this
+document we put them in the margin, by saying:
+
+\starttyping
+\setupcomment
+ [location=inmargin]
+\stoptyping
+
+Comments can have titles and properties but not all viewers support properties.
+Contrary to other environments, the first argument is not a category but a title.
+This because we are compatible with \MKII.
+
+\startbuffer
+\startcomment[french]
+ In France they use «angle bracket glyphs» in subsentences.
+\stopcomment
+
+\startcomment[accents][color=darkgreen]
+ You can used an àçéñţêð character too.
+\stopcomment
+\stopbuffer
+
+\typebuffer \getbuffer
+
+And normally empty lines are also supported (again this can differ per viewer):
+
+\startbuffer
+\startcomment[lines][color=darkblue]
+ How about an
+
+ empty line?
+\stopcomment
+\stopbuffer
+
+\typebuffer \getbuffer
+
+As we can see here, comments are sort of stacked. These examples also show that
+we can pass an optional title and set up some characteristics. An inline comment
+is defined with \type {\comment}:
+
+\startbuffer
+\comment {How I hate those notes spoiling the layout.} Maybe some day
+I can convince myself to add some features \comment {Think of comment classes
+that can be turned on and off and get their own colors.} related to version
+control.
+\stopbuffer
+
+\typebuffer
+
+\inlinebuffer\ Comments hide part of the text and thereby are to be used with
+care. Until now I never used them. Anyhow, from now on, one can happily use:
+
+You can use other symbols than the default, and a couple are predefined in
+the standard: {\tt \cldcontext {table.concat (lpdf.commentsymbols(), ", ")}}.
+
+\startbuffer
+\startcomment[symbol=Help]
+ Do we want this kind of rubish?
+\stopcomment
+\stopbuffer
+
+You can also use your own symbols:
+
+% \definesymbol [comment-normal][{\externalfigure[cow.pdf]}]
+% \definesymbol [comment-down] [{\externalfigure[cow.pdf]}]
+%
+% \unexpanded\def\CowSymbol#1#2%
+% {\scale
+% [height=#1]
+% {\startMPcode
+% loadfigure "cow.mp" number 1 ;
+% refill currentpicture withcolor #2 ;
+% \stopMPcode}}
+%
+% \definesymbol [comment-normal] [\CowSymbol{4ex}{darkred}]
+% \definesymbol [comment-down] [\CowSymbol{4ex}{darkgreen}]
+
+\startbuffer
+\startuniqueMPgraphic{cow}{height,s:color}
+ loadfigure "cow.mp" number 1 ;
+ refill currentpicture withcolor "\MPvar{color}" ;
+ currentpicture := currentpicture ysized \MPvar{height} ;
+\stopuniqueMPgraphic
+
+\definesymbol
+ [comment-normal]
+ [\uniqueMPgraphic{cow}{height=4ex,color=darkred}]
+\definesymbol
+ [comment-down]
+ [\uniqueMPgraphic{cow}{height=4ex,color=darkgreen}]
+
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startcomment[hello][symbol={comment-normal,comment-down}]
+ oeps
+\stopcomment
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Again the way this shows up depends on the viewer capabilities so there might be
+a fallback on the normal comment symbol. You can influence the size of the image
+(icon):
+
+\startbuffer
+\startcomment[hello]
+ [symbol={comment-normal,comment-down},width=\marginwidth]
+ oeps
+\stopcomment
+\stopbuffer
+
+\typebuffer \getbuffer
+
+There are some options that you can use for finetuning the comments.
+
+\showsetup{setupcomment}
+
+A new instance is defined with:
+
+\showsetup{definecomment}
+
+The default instance is predefined by
+
+\starttyping
+\definecomment[comment]
+\stoptyping
+
+You can define your own instances:
+
+\starttyping
+\definecomment[mycomment]
+\stoptyping
+
+The generated commands have a syntax like:
+
+\showsetup{startcomment:instance}
+
+and:
+
+\showsetup{comment:instance}
+
+Most fields explain themselves. With \type {state} you can disable this feature.
+Comments can be hidden in which there is no icon shown. The \type {nx} and \type
+{ny} fields determine the size of the popup.
+
+In case you wonder where the yellow backgrounds come from, here is the trick:
+
+\starttyping
+\enabletrackers[comments.anchors]
+\stoptyping
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-contents.tex b/doc/context/sources/general/manuals/interaction/interaction-contents.tex
new file mode 100644
index 000000000..0b59c1cbb
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-contents.tex
@@ -0,0 +1,11 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-contents
+
+\starttitle[title=Contents]
+ \placelist[chapter][criterium=text]
+\stoptitle
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-enabling.tex b/doc/context/sources/general/manuals/interaction/interaction-enabling.tex
new file mode 100644
index 000000000..8e31ccbe6
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-enabling.tex
@@ -0,0 +1,117 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-enabling
+
+\startchapter[title=Enabling]
+
+Interaction is turned off by default. Of course cross referencing
+work without interaction but there are no hyperlinks. You turn on
+interaction with the \type {\setupinteraction} command:
+
+\showsetup {setupinteraction}
+
+The \type {state} key is the switch you need to use. In addition you might want
+to setup the style and color.
+
+\starttyping
+\setupinteraction
+ [state=start,
+ style=,
+ color=,
+ contrastcolor=]
+\stoptyping
+
+This is the least intrusive way to get interaction in your document. By default
+the style is bold and the \type {color} defaults to green. The \type
+{contrastcolor} is used when a hyperlink refers to the same page and defaults to
+red. A neutral setup makes sense because nowadays the reader kind of knows what
+can be clicked on.
+
+The \type {title}, \type {subtitle}, \type {author}, \type {date} and \type
+{keyword} parameters are passed to the document and will show up when you request
+document information.
+
+The \type {openaction} parameter can for instance be used to start at a specific
+page, while the \type {closeaction} can be used to trigger a \JAVASCRIPT\ cleanup
+script. The \type {openpageaction} and \type {closepageaction} can for instance
+initialize and reset states, something we do in some presentation styles.
+
+The \type {click} parameter controls how a viewer responds to pressing a mouse
+button on an annotation: highlight or not. The \type {display} parameter
+determines if a cross document link opens in the current window.
+
+The \type {menu} parameter is a quick way to disable menus, of which there can be
+many: at each side of the page, stacked or not, etc. The \type {symbolset}
+determines the look and feel of symbols used in for instance menus, buttons and
+status bars.
+
+The \type {page} parameters is a bit special, and it function is an inheritance
+from the early days. Some \DVI\ and \PDF\ viewers supported named destinations,
+others only page references. This parameter can be used to force one or the
+other. There was a time that there was a limit on the number of named references,
+so going page was the only option \footnote {We're talking of 1995 when we made
+documents of many thousands of pages with tens of thousands of hyperlinks, cross
+linked tables of contents, registers, active graphics, etc.\ Think of
+dictionaries used in very specific projects, or quality assurance manuals.}
+
+Personally I consider an electronic document an entity to be seen full screen on
+a dedicated device. However some users prefer the target of a link to fit the
+width of the screen and alike. The \type {focus} parameter can (within)
+reasonable bounds provide this. The \type {focusoffset} is then used to keep
+things a bit visual convenient.
+
+The \type {height} and \type{depth} parameters are sort of special and probably never
+used. When we go back in time, to when we started adding interactivity, there were
+a few issues that needed to be dealt with:
+
+\startitemize[packed]
+\startitem
+ We need to make sure that we have something to click on, so we need to add
+ some offset if needed.
+\stopitem
+\startitem
+ We need to handle nested hyperlinks, which is why \CONTEXT\ didn't use the
+ link features of for instance \PDFTEX\ but built its own.
+\stopitem
+\startitem
+ Hyperlinks should break properly across lines without side effects, again a
+ reason for bypassing some of the \TEX\ engine's behaviour.
+\stopitem
+\startitem
+ We have to make sure that there is at least a consistent height and depth
+ of hyperlinks. These tight links with viewer supplied bounding boxes to
+ click on just look real bad! So, we had to do better.
+\stopitem
+\stopitemize
+
+Normally the two mentioned parameters are not used. However, their value will
+kick in when we say \type {\setfalse \locationstrut}, in which case the given
+height and depth will be used. Some advice: don't mess with this. We only have
+this because it permits special effects.
+
+If you want to see what the target (destinations) and sources (references) of
+links are, you can say:
+
+\starttyping
+\enabletrackers[nodes.references,nodes.destinations]
+\stoptyping
+
+The \type {fieldlayer} parameter can be used to set a so called viewer layer, so
+that you can hide them (given that a viewer supports that). The \type {calculate}
+parameter can associate a calculator (initializer) with the fields.
+
+You can create an interaction environment with:
+
+\showsetup {defineinteraction}
+
+which then can be used with:
+
+\showsetup {startinteraction}
+
+\stopchapter
+
+\stopcomponent
+
+
diff --git a/doc/context/sources/general/manuals/interaction/interaction-hyperlinks.tex b/doc/context/sources/general/manuals/interaction/interaction-hyperlinks.tex
new file mode 100644
index 000000000..f204d502e
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-hyperlinks.tex
@@ -0,0 +1,32 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-hyperlinks
+
+\startchapter[title=Hyperlinks]
+
+A hyperlink is something that you click on and that brings you to nother spot in
+the document. The regular links are a side effect of references. The most commonly
+used references are:
+
+\starttyping
+\in{figure}[fig:foo]
+\at{page}[fig:foo]
+\about[fig:foo]
+\stoptyping
+
+The first argument is what gets prepended to the number and the while can be
+clicked on. Here we create a namespace with \type {fig:}. This can be somewhat
+confusing with respect to prefixes but normally the resolver does a direct lookup
+first.
+
+\showsetup{at}
+\showsetup{in}
+\showsetup{about}
+
+\stopchapter
+
+\stopcomponent
+
+
diff --git a/doc/context/sources/general/manuals/interaction/interaction-importing.tex b/doc/context/sources/general/manuals/interaction/interaction-importing.tex
new file mode 100644
index 000000000..8c36128f6
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-importing.tex
@@ -0,0 +1,73 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-importing
+
+\startchapter[title=Importing]
+
+This is a very short chapter that deals with external figures. Normally an image
+is a graphic with possible some text. There are however workflows where one
+includes pages from other documents. Such documents can contain cross references,
+bookmarks, comments and|/|or fields. Normally annotations of any kind are ignored
+and for good reason: they assume the whole document to be the, not just one or a
+few pages. Merging references for instance is a source for clashes, not only for
+named ones but also for page references.
+
+But when you {\em know} what you're doing, as for instance Taco (who requested
+this feature) does, there is a way to merge annotations. This is controlled by
+the interaction keys in \type {externalfigure}:
+
+\starttyping
+\externalfigure[somedoc][page=1,interaction=yes]
+\externalfigure[somedoc][page=2,interaction={reference,bookmark}]
+\stoptyping
+
+However, only references and bookmarks are officially supported! The other
+annotations are possible but the code is experimental and will be finished
+when we find a good reason for it.
+
+\starttabulate[|B|p|]
+\FL
+\NC \type {reference} \NC named and page references and urls \NC \NR
+\NC \type {comment} \NC comments if possible with relevant icon \NC \NR
+\NC \type {bookmark} \NC text bookmarks that refer to pages \NC \NR
+\NC \type {field} \NC widgets but only within reason \NC \NR
+\NC \type {layer} \NC viewer layers \NC \NR
+\ML
+\NC \type {yes} \NC named and page references, urls and bookmarks \NC \NR
+\NC \type {all} \NC all annotations \NC \NR
+\LL
+\stoptabulate
+
+If things don't work out well, imagine for a while what is involved in supporting
+this: analyzing a page from a document, remapping the annotations onto some
+\CONTEXT\ mechanism, making sure that we don't get clashes, keeping overhead
+acceptable.
+
+Because this is a somewhat tricky feature, tracing can help you to identify
+problems: \typ {figures.merging}, \typ {figures.links}, \typ {figures.comments},
+\typ {figures.fields} and \typ {figures.outlines}.
+
+Another complication when including pages can be the presence of so called marked
+content in the page stream. There is experimental support for removing those but
+right now (2018) you need to explicitly enable this explicitly:
+
+\starttyping
+\enabledirectives[graphics.pdf.uselua]
+\enabledirectives[graphics.pdf.stripmarked]
+%enabledirectives[graphics.pdf.recompress]
+\stoptyping
+
+This will delegate inclusion from the backend to \LUA. This might become the
+default as it is just as efficient as using the backend. That way we can filter
+the content stream. \footnote {We might add a callback to \LUATEX\ for filtering
+the content stream (no hard todo but post version 1.10).}
+
+\stopchapter
+
+\stopcomponent
+
+
+
+
diff --git a/doc/context/sources/general/manuals/interaction/interaction-introduction.tex b/doc/context/sources/general/manuals/interaction/interaction-introduction.tex
new file mode 100644
index 000000000..a6f44b05b
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-introduction.tex
@@ -0,0 +1,58 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-introduction
+
+\startchapter[title=Introduction]
+
+This document introduces the cross reference mechanism, viewer control, fill||in
+fields, \JAVASCRIPT\ support, comments, attachments and more. It is a rewrite of
+the \MKII\ widgets manual. There is (always) more available than discussed in
+manuals so if you miss something, take a look at test suite or when you're brave,
+peek into the source code as there can be examples there.
+
+Interactivity has always been available in \CONTEXT\ and in fact it was one of
+the reasons for writing it. In for instance the YandY \WINDOWS\ previewer, one
+could have hyperlinks and we used that for a while when checking documents. Later
+Acrobat showed up and \PDF\ stepwise added interactive features that we always
+supported right from the start. Unfortunately there is a viewer dependency and
+the documentation of \PDF\ lagged behind, so solutions based on trial and error
+could not work well in a follow up on \PDF. Some features disappeared or became
+so limited that they effectively became useless. Especially multi||media have a
+reputation of unreliability. Because open source viewers never really catched up
+(at least not in this area) the momentum was lost to make sure that documents
+could have audio and video embedded in reliable ways. Even forms and basic
+\JAVASCRIPT\ control of for instance layers is often missing.
+
+That said, we do support a lot but can support more when it makes sense. Deep
+down in \CONTEXT\ we always had the mechanisms to deal with this, so extensions
+are not that hard to program. Somehow we thought that publishers would like these
+features but that never really was the case, so there was no pressure from that
+end. Most features are user driven or just there because at some point we wanted
+to make some fancy presentation. In fact, the \type {s-present-*} files provide
+examples of interactivity.
+
+The original \PDF\ reference was a couple of hundred pages and looked quite nice.
+A later print has many more pages and still looks ok, but nowadays we have to do
+with a \PDF\ document. If you want to see what \PDF\ supports you can study this
+(now about) 750 page standard. It is, being an \ISO\ standard, not public but
+you can probably find a (maybe older) copy someplace on the web.
+
+When reading this manual you need to keep in mind that we assume that you design
+a decent layout and when you make something for an electronic medium, we hope
+that you pay attention to the way you can enhance accessibility.
+
+If you miss something here, don't hesitate to ask for clarification, or even
+better, provide an example that we then can use to discuss (an aspect of) some
+mechanism.
+
+\stopchapter
+
+\stopcomponent
+
+% A nice double page e-ink device can be seen at:
+%
+% https://www.youtube.com/watch?v=QdOXCn1vvzI :
+%
+% vkgoeswild: Playing Pink Floyds Great Gig in the Sky on Imperial by Bösendorfer
diff --git a/doc/context/sources/general/manuals/interaction/interaction-javascript.tex b/doc/context/sources/general/manuals/interaction/interaction-javascript.tex
new file mode 100644
index 000000000..64e784464
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-javascript.tex
@@ -0,0 +1,136 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-javascript
+
+\startchapter[title={JavaScript}]
+
+Annotations can be controlled with \JAVASCRIPT\ but it really depends on the
+viewer if it works out well. Using these scripts is a multi||step process where
+common functions and data structures can be shared and collected in preambles:
+
+\starttyping
+\startJSpreamble {name}
+ MyCounter = 0 ;
+\stopJSpreamble
+\stoptyping
+
+The more action oriented scripts are defined as:
+
+\starttyping
+\startJScode {increment}
+ MyCounter = MyCounter + 1 ; // or: ++MyCounter ;
+\stopJScode
+\stoptyping
+
+This script is executed with:
+
+\starttyping
+\goto {advance by one} [JS(increment)]
+\stoptyping
+
+Nicer is to define a function:
+
+\starttyping
+\startJSpreamble {helpers} used now
+ function Increment(n) {
+ MyCounter = MyCounter + n ;
+ }
+\stopJSpreamble
+\stoptyping
+
+and then say:
+
+\starttyping
+\goto {advance by one} [JS(Increment{5})]
+\stoptyping
+
+The distribution contains a collection of scripts that can be preloaded and used
+when needed. You can recognize the files by the \type {java-imp-} prefix. To
+prevent all preambles ending up in the \PDF\ file, we can say:
+
+\starttyping
+\startJSpreamble {something} used later
+\stopJSpreamble
+\stoptyping
+
+We already saw that one can also say \type {used now} and there's also a way
+to filter specific preambles on usage:
+
+\starttyping
+\startJScode {mything} uses {something}
+\stopJScode
+\stoptyping
+
+One should be aware of the fact that there is no decent way to check if every
+script is all right! Even worse, the \JAVASCRIPT\ interpreter currently used in
+the \ACROBAT\ tools is not reentrant, and breaks down on typos
+
+The full repertoire of commands is:
+
+\showsetup{startJScode}
+
+\showsetup{startJSpreamble}
+
+\showsetup{addtoJSpreamble}
+
+\showsetup{setJSpreamble}
+
+As we're into \LUA\ and because \LUA\ is so lightweight I've wondered several
+times now if it would make sense to embed \LUA\ in \PDF\ viewers. After all,
+annotations are an extension mechanism. In the early days of \PDF\ this was
+actually quite doable because \ACROBAT\ reader (and exchange) had a plugin model.
+However, the more functionality ended up in the program, the least interesting
+(and popular) the plugins mechanism became. Some open source viewers have an
+\API\ so in principle adding the lightweight \LUA\ interpreter (of course with
+\LPEG, and quite probably without file \IO) is possible. It has been discussed at
+a recent \CONTEXT\ meeting, so who knows \unknown For now we're stuck with
+\JAVASCRIPT.
+
+An example of \JAVASCRIPT\ usage is the following, where we load a video and add
+some controls. Beware that this kind of functionality is very viewer dependent
+and therefore also very unstable over time. Even worse, if you look at the loaded
+\JAVASCRIPT\ file you will notice a dependency on soon obsolete (in \ACROBAT\ at
+least) shockwave support. First we load a library that will predefine a video
+graphic: and then create an instance:
+
+\starttyping
+\useJSscripts[vplayer]
+
+\setupinteraction
+ [state=start]
+
+\externalfigure
+ [shockwave]
+ [frame=on,
+ width=480pt,
+ height=270pt,
+ file=test.mp4,
+ label=foo]
+\stoptyping
+
+The controls are defined with:
+
+\starttyping
+\goto{START} [JS(StartShockwave{foo})]
+\goto{REWIND}[JS(RewindShockwave{foo})]
+\goto{PAUSE} [JS(PauseShockwave{foo})]
+\goto{STOP} [JS(StopShockwave{foo})]
+\stoptyping
+
+or, as we have some defined reference shortcuts:
+
+\starttyping
+\goto{START} [StartShockwave{foo}]
+\goto{REWIND}[RewindShockwave{foo}]
+\goto{PAUSE} [PauseShockwave{foo}]
+\goto{STOP} [StopShockwave{foo}]
+\stoptyping
+
+It's actually not that hard to add all kind of functionality if only we could be
+sure of stable support and continuity.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-menus.tex b/doc/context/sources/general/manuals/interaction/interaction-menus.tex
new file mode 100644
index 000000000..6e002b5cd
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-menus.tex
@@ -0,0 +1,12 @@
+\environment interaction-style
+
+\startcomponent interaction-menus
+
+\startchapter[title={Menus}]
+
+ {\em This chapter will discuss interaction menus that normally end up in the
+ margins.}
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-progress.tex b/doc/context/sources/general/manuals/interaction/interaction-progress.tex
new file mode 100644
index 000000000..c077337b3
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-progress.tex
@@ -0,0 +1,11 @@
+\environment interaction-style
+
+\startcomponent interaction-progress
+
+\startchapter[title={Progress}]
+
+ {\em This chapter will discuss progress bars.}
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-structure.tex b/doc/context/sources/general/manuals/interaction/interaction-structure.tex
new file mode 100644
index 000000000..793139d6c
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-structure.tex
@@ -0,0 +1,76 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-structure
+
+\startchapter[title=Structure]
+
+There is a lot of structure in \CONTEXT:
+
+\startitemize[packed]
+\startitem document structure: projects, products, components, environments \stopitem
+\startitem sectioning, with or without numbers (visible), support for lists and userdata \stopitem
+\startitem lists, most often related to sections, but there are more \stopitem
+\startitem registers \stopitem
+\startitem itemized lists \stopitem
+\startitem images, \METAPOST\ graphics, different types of tables \stopitem
+\startitem typographical objects: constructions, descriptions and enumerations \stopitem
+\startitem notes, like footnotes, endnotes, linenotes \stopitem
+\startitem marginal notes \stopitem
+\startitem formulas (and subformulas) \stopitem
+\startitem text areas, layers, overlays \stopitem
+\startitem graphic placement with captions and references \stopitem
+\startitem cross references to most structural components \stopitem
+\startitem bibliographic databases and citations \stopitem
+\blank
+\startitem \unknown\ and more \unknown \stopitem
+\stopitemize
+
+Most of them in some way carry information about their location in the document
+and on the page, and sometimes their exact position. This also means that we can
+use that information for annotations. But most users will use the standard
+functionality.
+
+\starttyping
+\startsection[title=Whatever]
+ ...
+\stopsection
+\stoptyping
+
+In addition to typesetting this will add the title to a list. In order to do that
+some anchor has to be placed in the text, because we need to register the exact
+location in order to get the right pagenumber after \TEX\ has broken the flow into
+pages.
+
+\starttyping
+\placelist[section][criterium=text]
+\stoptyping
+
+This will place a list of all sections. If you want the whole entry to be a
+clickable areas, you can say:
+
+\starttyping
+\placelist[section][interaction=all]
+\stoptyping
+
+Otherwise only clicking on the title will bring you to the spot. If you also say:
+
+\starttyping
+\setuphead[interaction=list]
+\stoptyping
+
+Clicking on the head will bring you back to the table of contents. There are
+special list rendering alternatives for interactive documents (\typ
+{alternative=e} onwards). You can use the \type {list} and \type {bookmark}
+parameters to a section head to deviate from the given \type {title}.
+
+Many commands accept a \type {reference} as optional argument and when you use
+an alternative with key|/|values a \type {reference} key will do the job.
+
+{\em What should go into this chapter.}
+
+\stopchapter
+
+\stopcomponent
+
diff --git a/doc/context/sources/general/manuals/interaction/interaction-style.tex b/doc/context/sources/general/manuals/interaction/interaction-style.tex
new file mode 100644
index 000000000..e9922fb14
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-style.tex
@@ -0,0 +1,59 @@
+\startenvironment interaction-style
+
+\usemodule[abr-02]
+\usemodule[scite]
+\usemodule[setups-basics]
+
+\loadsetups[context-en]
+
+\setupbodyfont[plex,rm]
+
+\setupwhitespace
+ [big]
+
+\setuptolerance
+ [verytolerant,stretch]
+
+\setuppagenumbering
+ [alternative=doublesided]
+
+\setuplayout
+ [footer=0cm,
+ backspace=3cm,
+ cutspace=2cm,
+ width=middle,
+ height=middle,
+ margin=1.75cm,
+ margindistance=5mm]
+
+\setupfloats
+ [ntop=100]
+
+\setupinteraction
+ [state=start,
+ style=,
+ color=,
+ contrastcolor=]
+
+\setuphead
+ [interaction=list]
+
+\setuphead
+ [chapter]
+ [header=high,
+ style=\bfd]
+
+\setuphead
+ [section]
+ [style=\bfb]
+
+% \definecolor[backcolor][r=.8,b=.7,g=.8]
+\definecolor[backcolor][s=.8]
+
+\setupframedtext
+ [setuptext]
+ [frame=off,
+ background=color,
+ backgroundcolor=backcolor]
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/interaction/interaction-tagging.tex b/doc/context/sources/general/manuals/interaction/interaction-tagging.tex
new file mode 100644
index 000000000..d38c922f2
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-tagging.tex
@@ -0,0 +1,26 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-tagging
+
+\startchapter[title=Tagging]
+
+In a tagged \PDF\ document the page stream is enriched (or polluted) by marks
+that indicate what kind of content is involved.
+
+\starttyping
+\setuptagging[state=start]
+\stoptyping
+
+Only the \type {state} parameters is of general use.
+
+\showsetup {setuptagging}
+
+The \TEX\ end of this mechanism overlaps with the export related tagging so when
+you add your own elements that will be reflected in the tagging. And indeed: the
+keyword here is structure. The worse the structure, the worse the tagging.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-titlepage.tex b/doc/context/sources/general/manuals/interaction/interaction-titlepage.tex
new file mode 100644
index 000000000..43b29baf9
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-titlepage.tex
@@ -0,0 +1,47 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-titlepage
+
+\startMPpage
+
+ StartPage ;
+ numeric w, h, sh ; transform t ; path p ; pair c ;
+ w := PaperWidth ;
+ h := PaperHeight ;
+ p := Page ;
+ fill p withcolor .4white ;
+ sh := define_linear_shade(llcorner p, urcorner p, .6yellow, .6blue) ;
+ c := center boundingbox outlinetext.p("\ss\bf INTERACTIVITY") ;
+ set_grid(w, h, w/8, h/8) ;
+ forever :
+ if new_on_grid(uniformdeviate w,uniformdeviate h) :
+ t := identity
+ scaled (3+uniformdeviate 3)
+ shifted ((dx,dy) - c)
+ ;
+ draw outlinetext.b
+ ("\bf\ss INTERACTIVITY")
+ (transformed t withshade sh)
+ (transformed t withpen pencircle scaled 3 withcolor .6white)
+ ;
+ fi ;
+ exitif grid_full ;
+ endfor ;
+ draw anchored.lrt (
+ textext("\bf\ss \ConTeXt") xsized .6PaperWidth,
+ lrcorner p shifted (-10mm,40mm)
+ ) withcolor white ;
+ draw anchored.lrt (
+ textext("\bf\ss Hans Hagen") xsized .6PaperWidth,
+ lrcorner p shifted (-10mm,15mm)
+ ) withcolor white ;
+ StopPage;
+
+\stopMPpage
+
+\page[empty]
+\page[right]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-transitions.tex b/doc/context/sources/general/manuals/interaction/interaction-transitions.tex
new file mode 100644
index 000000000..0cde28040
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-transitions.tex
@@ -0,0 +1,64 @@
+% language=uk
+
+\environment interaction-style
+
+\startcomponent interaction-transitions
+
+\startchapter[title={Page transitions}]
+
+I'm not sure if this feature is still used but in the early days of \PDF\ support
+in \TEX, users loved it. I never really used it myself. Page transitions only
+make sense in presentations, and unfortunately the ones provided by the Acrobat
+viewers are just ugly. Anyhow, one automatically gets them by saying:
+
+\starttyping
+\setuppagetransitions[random]
+\stoptyping
+
+This way one gets random transitions. Resetting transitions is done by:
+
+\starttyping
+\setuppagetransitions[reset]
+\stoptyping
+
+If needed one can specify transitions but I strongly advice against this, because
+these commands are very viewer dependant, therefore: if in despair, use numbers!
+By default, the next set is used, and one can access them by number,
+
+\starttabulate[|c|l|]
+\HL
+\NC \bf number \NC \bf transition effects \NC\NR
+\HL
+\NC 1\quad 2 \NC \type{{split,in,vertical}}
+ \type{{split,in,horizontal}} \NC\NR
+\NC 3\quad 4 \NC \type{{split,out,vertical}}
+ \type{{split,out,horizontal}} \NC\NR
+\NC 5\quad 6 \NC \type{{blinds,horizontal}}
+ \type{{blinds,vertical}} \NC\NR
+\NC 7\quad 8 \NC \type{{box,in}}
+ \type{{box,out}} \NC\NR
+\NC 9\quad10\quad11\quad12 \NC \type{{wipe,east}}
+ \type{{wipe,west}}
+ \type{{wipe,north}}
+ \type{{wipe,south}} \NC\NR
+\NC 13 \NC \type{dissolve} \NC\NR
+\NC 14\quad15 \NC \type{{glitter,east}}
+ \type{{glitter,south}} \NC\NR
+\HL
+\stoptabulate
+
+The next settings are all valid:
+
+\starttyping
+\setuppagetransitions
+\setuppagetransitions[1]
+\setuppagetransitions[3,5,8,random]
+\stoptyping
+
+Valid setups are:
+
+\setup{setuppagetransitions}
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/interaction/interaction-widgets.tex b/doc/context/sources/general/manuals/interaction/interaction-widgets.tex
new file mode 100644
index 000000000..e4fa136c9
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction-widgets.tex
@@ -0,0 +1,977 @@
+\environment interaction-style
+
+\startcomponent interaction-widgets
+
+\startchapter[title={Widgets}]
+
+ {\em This chapter will discuss forms and special buttons.}
+
+\stopchapter
+
+\stopcomponent
+
+% Below comes from the old widgets manual:
+
+\def\fillinfield#1{}
+
+% \useJSscripts[fld]
+% \setupinteraction[state=start,closeaction=ForgetAll]
+
+\section{Fill||in fields}
+
+Fields come in many disguises. Currently \CONTEXT\ supports
+the field types provided by \PDF, which in turn are derived
+from \HTML. Being a static format and not a programming
+language, \PDF\ only provides the interface. Entering data
+is up to the viewer and validation to the built in
+\JAVASCRIPT\ interpreter. The next paragraph shows an
+application.
+
+\startbuffer
+A few years back, \TEX\ could only produce \fillinfield [dvi]
+{\DVI} output, but nowadays, thanks to \fillinfield {Han The
+Thanh}, we can also directly produce \fillinfield [pdf] {\PDF}!
+Nice eh? Actually, while the first field module was prototyped
+in \ACROBAT, the current implementation was debugged in
+\fillinfield [pdfTeX] {\PDFTEX}. Field support in \fillinfield
+[ConTeXt] {\CONTEXT} is rather advanced and complete and all
+kind of fields are supported. One can hook in appearances, and
+validation \fillinfield [JavaScripts] {\JAVASCRIPT}'s. Fields
+can be cloned and copied, where the latter saves some space. By
+using \fillinfield {objects} when suited, this module saves
+space anyway.
+\stopbuffer
+
+\getbuffer
+
+This paragraph is entered in the source file as:
+
+\typebuffer
+
+I leave it to the imagination of the user how
+\type{\fillinfield} is implemented, but trust me, the
+definition is rather simple and is based on the macros
+mentioned below.
+
+Because I envision documents with many thousands of fields,
+think for instance of tutorials, I rather early decided to
+split the definition from the setup. Due to the fact that
+while typesetting a field upto three independant instances
+of \type{\framed} are called, we would end up with about
+150~hash entries per field, while in the current
+implementation we only need a few. Each field can inherit
+its specific settings from the setup group it belongs to.
+
+Let's start with an example of a {\em radio} field. In fact
+this is a collection of fields. Such a field is defined
+with:
+
+\startbuffer
+\definefield
+ [Logos] [radio] [LogoSetup]
+ [ConTeXt,PPCHTEX,TeXUtil] [PPCHTEX]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Here the fourth argument specifies the subfields and the
+last argument tells which one to use as default. We have to
+define the subfields separately:
+
+\startbuffer
+\definesubfield [ConTeXt] [] [ConTeXtLogo]
+\definesubfield [PPCHTEX] [] [PPCHTEXLogo]
+\definesubfield [TeXUtil] [] [TeXUtilLogo]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+The second argument specifies the setup. In this example
+the setup (\type {LogoSetup}) is inherited from the main
+field. The third arguments tells \CONTEXT\ how the fields
+look like when turned on. These appearances are to be
+defined as symbols:
+
+\startbuffer
+\definesymbol [ConTeXtLogo] [{\externalfigure[mp-cont.502]}]
+\definesymbol [PPCHTEXLogo] [{\externalfigure[mp-cont.503]}]
+\definesymbol [TeXUtilLogo] [{\externalfigure[mp-cont.504]}]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Before we typeset the fields, we specify some settings to use:
+
+\startbuffer
+\setupfield [LogoSetup]
+ [width=4cm,
+ height=4cm,
+ frame=off,
+ background=screen]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Finally we can typeset the fields:
+
+\startbuffer
+\hbox to \hsize
+ {\hss\field[ConTeXt]\hss\field[PPCHTEX]\hss\field[TeXUtil]\hss}
+\stopbuffer
+
+\typebuffer
+
+This shows up as:
+
+\startbaselinecorrection
+\getbuffer
+\stopbaselinecorrection
+
+An important characteristic of field is cloning cq.\
+copying, as demonstrated below:
+
+% \tracefieldstrue
+
+\startbuffer[symbol]
+\definesymbol [yes-a] [$\times$]
+\definesymbol [yes-b] [$\star$]
+\definesymbol [nop-a] [$\bullet$]
+\definesymbol [nop-b] [$-$]
+\stopbuffer
+
+\getbuffer[symbol]
+
+\startbuffer[define]
+\definefield [example-1] [radio] [setup 1] [ex-a,ex-b,ex-c] [ex-c]
+\definesubfield [ex-a,ex-b,ex-c] [setup 1] [yes-a,nop-a]
+\stopbuffer
+
+\getbuffer[define]
+
+\startbuffer[clone]
+\clonefield [ex-a] [ex-p] [setup 2] [yes-b,nop-b]
+\clonefield [ex-b] [ex-q] [setup 2] [yes-b,nop-b]
+\clonefield [ex-c] [ex-r] [setup 2] [yes-b,nop-b]
+\stopbuffer
+
+\getbuffer[clone]
+
+\startbuffer[copy]
+\copyfield [ex-a] [ex-x]
+\copyfield [ex-b] [ex-y]
+\copyfield [ex-c] [ex-z]
+\stopbuffer
+
+\getbuffer[copy]
+
+\startbuffer[setup]
+\setupfield [setup 1] [width=1cm,height=1cm,framecolor=red]
+\setupfield [setup 2] [width=.75cm,height=.75cm]
+\stopbuffer
+
+\getbuffer[setup]
+
+\startbuffer[field]
+\hbox to \hsize
+ {\field[ex-a]\hfil\field[ex-b]\hfil\field[ex-c]\hfil\hfil
+ \field[ex-p]\hfil\field[ex-q]\hfil\field[ex-r]\hfil\hfil
+ \field[ex-x]\hfil\field[ex-y]\hfil\field[ex-z]}
+\stopbuffer
+
+\startbaselinecorrection \getbuffer[field] \stopbaselinecorrection
+
+The next table shows the relations between these fields of type radio:
+
+\startbaselinecorrection
+\showfields
+\stopbaselinecorrection
+
+This table is generated by \type {\showfields} and can be
+used to check the relations between fields, but only when
+we have set \type {\tracefieldstrue}. Radio fields have the
+most complicated relationships of fields, due to the fact
+that only one of them can be activated (on). By saying
+\type {\logfields} one can write the current field
+descriptions to the file \type {fields.log}.
+
+Here we used some \TEX\ mathematical symbols. These are
+functional but sort of dull, so later we will define a more
+suitable visualization.
+
+\typebuffer[symbol]
+
+The parent fields were defined by:
+
+\typebuffer[define]
+
+and the clones, which can have their own appearance, by:
+
+\typebuffer[clone]
+
+The copies are defined using:
+
+\typebuffer[copy]
+
+using the setups
+
+\typebuffer[setup]
+
+Finally all these fields are called using \type {\field}:
+
+\typebuffer[field]
+
+Now we will define a so called {\em check} field. This
+field looks like a radio field but is independant of
+others. First we define some suitable symbols:
+
+\startbuffer
+\definesymbol [yes] [{\externalfigure[mp-cont.502]}]
+\definesymbol [no] []
+\stopbuffer
+
+\getbuffer
+
+\typebuffer
+
+A check field is defined as:
+
+\startbuffer
+\definefield [check-me] [check] [setup 3] [yes,no] [no]
+\stopbuffer
+
+\getbuffer
+
+\typebuffer
+
+This time we say \type{\field[check-me]} and get:
+
+\startbuffer
+\setupfield
+ [setup 3]
+ [width=2cm, height=2cm,
+ rulethickness=3pt, corner=round, framecolor=red]
+\stopbuffer
+
+\getbuffer
+
+\startlinecorrection
+\hbox to \hsize{\hss\field[check-me]\hss}
+\stoplinecorrection
+
+As setup we used:
+
+\typebuffer
+
+We already saw an example of a {\em line} field. By default
+such a line field looks like:
+
+\startbuffer[define]
+\definefield [Email] [line] [ShortLine] [] [pragma@wxs.nl]
+\stopbuffer
+
+\getbuffer[define]
+
+\startbuffer[field]
+\field [Email] [your email]
+\stopbuffer
+
+\startbaselinecorrection \getbuffer[field] \stopbaselinecorrection
+
+We defined this field as:
+
+\typebuffer[define]
+
+and called it using a second, optional, argument:
+
+\typebuffer[field]
+
+As shown, we can influence the way such a field is typeset.
+It makes for instance sense to use a monospaced typeface
+and limit the height. When we set up a field, apart from
+the setup class we pass some general characteristics, and
+three more detailed definitions, concerning the
+surrounding, the label and the field itself.
+
+\startbuffer
+\setupfield
+ [ShortLine]
+ [label,frame,horizontal]
+ [offset=4pt,height=fit,framecolor=green,
+ background=screen,backgroundscreen=.80]
+ [height=18pt,width=80pt,align=middle,
+ background=screen,backgroundscreen=.90,frame=off]
+ [height=18pt,width=80pt,color=red,align=right,style=type,
+ background=screen,backgroundscreen=.90,frame=off]
+\stopbuffer
+
+\typebuffer
+
+So now we get:
+
+\getbuffer
+
+\startbuffer[mainmail]
+\definemainfield [MainMail] [line] [ShortLine] [] [pragma@wxs.nl]
+\stopbuffer
+
+\getbuffer[mainmail]
+
+\startlinecorrection
+\field [MainMail] [your email]
+\stoplinecorrection
+
+Such rather long definitions can be more sparse when we set
+up all fields at once, like:
+
+\startbuffer
+\setupfields
+ [label,frame,horizontal]
+ [offset=4pt,height=fit,framecolor=green,
+ background=screen,backgroundscreen=.80]
+ [height=18pt,width=80pt,
+ background=screen,backgroundscreen=.90,frame=off]
+ [height=18pt,width=80pt,color=red,align=middle,
+ background=screen,backgroundscreen=.90,frame=off]
+\stopbuffer
+
+\typebuffer
+
+So given that we have defined field \type {MainMail} we can
+say:
+
+\startbuffer[MP]
+\startuniqueMPgraphic{button}
+ path p ; p := fullcircle xyscaled (OverlayWidth,OverlayHeight) ;
+ fill p withcolor (.8,.8,.8) ;
+ draw p withcolor OverlayColor withpen pencircle scaled 3 ;
+\stopuniqueMPgraphic
+
+\defineoverlay [normalbutton] [\uniqueMPgraphic{button}]
+\stopbuffer
+
+\getbuffer[MP]
+
+\startbuffer
+\setupfield [LeftLine]
+ [background=normalbutton, backgroundcolor=darkgreen,
+ offset=2ex, height=7ex, width=.25\hsize,
+ style=type, frame=off, align=left]
+\setupfield [MiddleLine]
+ [background=normalbutton, backgroundcolor=darkgreen,
+ offset=2ex, height=7ex, width=.25\hsize,
+ style=type, frame=off, align=middle]
+\setupfield [RightLine]
+ [background=normalbutton, backgroundcolor=darkgreen,
+ offset=2ex, height=7ex, width=.25\hsize,
+ style=type, frame=off, align=right]
+
+\clonefield [MainMail] [LeftMail] [LeftLine]
+\clonefield [MainMail] [MiddleMail] [MiddleLine]
+\clonefield [MainMail] [RightMail] [RightLine]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We get get three connected fields:
+
+\startlinecorrection
+\hbox to \hsize
+ {\field[LeftMail]\hss\field[MiddleMail]\hss\field[RightMail]}
+\stoplinecorrection
+
+(Keep in mind that in \CONTEXT\ left aligned comes down to
+using \type {\raggedleft}, which can be confusing, but
+history cannot be replayed.)
+
+By the way, this shape was generated by \METAPOST\ using
+the overlay mechanism:
+
+\typebuffer[MP]
+
+Due to the fact that a field can have several modes (loner,
+parent, clone or copy), one cannot define a clone or copy
+when the parent field is already typeset. When one knows in
+advance that there will be clones or copies, one should
+use:
+
+\typebuffer[mainmail]
+
+Now we can define copies, clones and even fields with the
+same name, also when the original already is typeset. Use
+\type {\showfields} to check the status of fields. When in
+this table the mode is typeset slanted, the field is not
+yet typeset.
+
+The values set up with \type {\setupfield} are inherited by
+all following setup commands. One can reset these default
+values by:
+
+\startbuffer
+\setupfields[reset]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+When we want more than one line, we use a {\em text} field.
+Like the previous fields, text must be entered in the
+viewer specific encoding, in our case, \PDF\ document
+encoding. To free users from thinking of encoding,
+\CONTEXT\ provides a way to force at least the accented
+glyphs into a text field in a for \TEX\ users familiar way:
+
+\setupfields
+ [horizontal]
+ [offset=4pt,height=fit,framecolor=green,
+ background=screen,backgroundscreen=.80]
+ [height=18pt,width=80pt,
+ background=screen,backgroundscreen=.90,frame=off]
+ [height=18pt,width=80pt,color=red,align=middle,
+ background=screen,backgroundscreen=.90,frame=off]
+
+\definefield
+ [SomeField] [text] [TextSetup]
+ [hi there, try \string\\ \string " e or
+ \string\\ \string~ n to get \"e or \~n]
+
+\setupfield
+ [TextSetup]
+ [label,frame,horizontal][framecolor=green][]
+ [height=80pt,width=240pt,style=\sl,align=middle,
+ enterregion=JS(Initialize_TeX_Key),
+ afterkey=JS(Convert_TeX_Key),
+ validate=JS(Convert_TeX_String)]
+
+\startbaselinecorrection
+\field[SomeField][Just Some Text]
+\stopbaselinecorrection
+
+Now, how is this done? Defining the field is not that hard:
+
+\starttyping
+\definefield [SomeField] [text] [TextSetup] [default text]
+\stoptyping
+
+The conversion is taken care of by a \JAVASCRIPT's. We can assign such
+scripts to mouse and keyboard events, like in:
+
+\starttyping
+\setupfield
+ [TextSetup][...][...][...]
+ [....,
+ regionin=JS(Initialize_TeX_Key),
+ afterkey=JS(Convert_TeX_Key),
+ validate=JS(Convert_TeX_String)]
+\stoptyping
+
+The main reason for using the \type{JS(...)} method here is
+that this permits future extensions and looks familiar at
+the same time. Depending on the assignments, one can
+convert after each keypress and|/|or after all text is
+entered.
+
+\startbuffer
+\definefield
+ [Ugly] [choice] [UglySetup]
+ [ugly,awful,bad] [ugly]
+\setupfield
+ [UglySetup]
+ [width=6em,
+ height=1.2\lineheight,
+ location=low]
+\stopbuffer
+
+\getbuffer
+
+We've arrived at another class of fields: {\em choice},
+{\em pop||up} and {\em combo} fields. All those are menu
+based (and \vbox{\field[Ugly]}). This in||line menu was
+defined as:
+
+\typebuffer
+
+\startbuffer
+\definefield
+ [Ugly2] [popup] [UglySetup]
+ [ugly,awful,bad] [ugly]
+\definefield
+ [Ugly3] [combo] [UglySetup]
+ [ugly,{AWFUL=>awful},bad] [ugly]
+\stopbuffer
+
+\getbuffer
+
+Pop||up fields look like: \vbox{\field[Ugly2]} and combo
+fields permit the user to enter his or her own option:
+\vbox{\field[Ugly3]}. The amount of typographic control
+over these three type of fields is minimal, but one can
+specify what string to show and what string results:
+
+\typebuffer
+
+Here \type{AWFUL} is shown and when selected becomes the
+choice \type{awful}. Just in case one wonders why we use
+\type{=>}, well, it just looks better and the direction
+shows what value will be output.
+
+\startbuffer[uglies]
+\definefieldset [AllUglies] [Ugly, Ugly2, Ugly3]
+\stopbuffer
+
+\getbuffer[uglies]
+
+\startbuffer
+One can for instance \goto {reset the form} [ResetForm] or
+\goto {part of the form} [ResetForm{AllUglies}]. This last
+sentence was typed in as:
+\stopbuffer
+
+A special case of the check type field is a pure {\em push}
+field. Such a field has no export value and has only use as
+a pure interactive element. For the moment, let's forget
+about that one.
+
+Before we demonstrate our last type of fields and show some
+more tricky things, we need to discuss what to do with the
+information provided by filling in the fields. There are
+several actions available related to fields.
+
+\getbuffer
+
+\typebuffer
+
+Hereby \type {AllUglies} is a set of fields to be defined
+on forehand, using
+
+\typebuffer[uglies]
+
+In a similar way one can \goto {submit some or all fields}
+[SubmitForm] using the \type {SubmitForm} directive. This
+action optionally can take two arguments, the first being
+the destination, the second a list of fields to submit, for
+instance:
+
+\starttyping
+\button{submit}[SubmitForm{mailto::pragma@wxs.nl,AllUglies}]
+\stoptyping
+
+Once the fields are submitted (or saved in a file), we can
+convert the resulting \FDF\ file into something \TEX\ with
+the perl program \type{fdf2tex}. One can use \type
+{\ShowFDFFields{filename}} to typeset the values. If you do
+not want to run the \PERL\ converter from within \TEX, say
+\type {\runFDFconverterfalse}. In that case, the (stil)
+less robust \TEX\ based converter will be used.
+
+I already demonstrated how to attach scripts to events, but
+how about changing the appearance of the button itself?
+Consider the next definitions:
+
+\startbuffer
+\definesymbol [my-y] [$\times$]
+\definesymbol [my-r] [?]
+\definesymbol [my-d] [!]
+
+\definefield
+ [my-check] [check] [my-setup]
+ [{my-y,my-r,my-d},{,my-r,my-d}]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Here we omitted the default value, which always is {\em no}
+by default. The setup can look like this:
+
+\startbuffer
+\setupfield
+ [my-setup]
+ [width=1.5cm, height=1.5cm,
+ frame=on, framecolor=red, rulethickness=1pt,
+ backgroundoffset=2pt, background=screen, backgroundscreen=.85]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Now when this field shows up, watch what happens when the
+mouse enters the region and what when we click.
+
+\startbaselinecorrection
+\hbox to \hsize{\hss\field[my-check]\hss}
+\stopbaselinecorrection
+
+So, when instead of something \type{[yes,no]} we give
+triplets, the second element of such a triplet declares the
+roll||over appearance and the third one the push||down
+appearance. The braces are needed!
+
+One application of appearances is to provide help or
+additional information. Consider the next definition:
+
+\startbuffer
+\definefield [Help] [check] [HelpSetup] [helpinfo] [helpinfo]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+This means as much as: define a check field, typeset this
+field using the help specific setup and let \type{helpinfo}
+be the on||value as well as the default. Here we use the
+next setup:
+
+\startbuffer
+\setupfields
+ [reset]
+\setupfield
+ [HelpSetup]
+ [width=fit,height=fit,frame=off,option={readonly,hidden}]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We didn't use options before, but here we have to make sure
+that users don't change the content of the field and by
+default we don't want to show this field at all. The actual
+text is defined as a symbol:
+
+\startbuffer
+\definesymbol [helpinfo] [\SomeHelpText]
+
+\def\SomeHelpText%
+ {\framed
+ [width=\leftmarginwidth,height=fit,align=middle,style=small,
+ frame=on,background=color,backgroundcolor=white,framecolor=red]
+ {Click on the hide button to remove this screen}}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\startbuffer
+\inmargin {\fitfield[Help]} Now we can put the button somewhere and
+turn the help on or off by saying \goto {Hide Help} [HideField{Help}]
+or \goto {Show Help} [ShowField{Help}]. Although it's better to put
+these commands in a dedicated part of the screen. And try \goto
+{Help} [JS(Toggle_Hide{Help})].
+\stopbuffer
+
+\getbuffer
+
+We can place a field anywhere on the page, for instance by
+using the \type {\setup...texts} commands. Here we simply
+said:
+
+\typebuffer
+
+When one uses for instance \type {\setup...texts}, one
+often wants the help text to show up on every next page.
+This can be accomplished by saying:
+
+\starttyping
+\definemainfield [Help] [check] [HelpSetup] [helpinfo] [helpinfo]
+\stoptyping
+
+Every time such a field is called again, a new copy is
+generated automatically. Because fields use the
+objectreference mechanism and because such copies need to
+be known to their parent, field inclusion is a multi||pass
+typesetting job (upto 4 passes can be needed!).
+
+When possible, appearances are shared between fields,
+mainly because this saves space, but at the cost of extra
+object references. This feature is not that important for
+straight forward forms, but has some advantages when
+composing more complicated (educational) documents.
+
+Let us now summarize the commands we have available for
+defining and typesetting fields. The main definition macro
+is:
+
+\setup{definefield}
+
+and for radiofields we need to define the components by:
+
+\setup{definesubfield}
+
+Fields can be cloned and copied, where the latter can not
+be set up independently.
+
+\setup{clonefield}
+
+\setup{copyfield}
+
+Fields can be grouped, and such a group can have its own
+settings. Apart from copied fields, we can define the
+layout of a field and set options using:
+
+\setup{setupfield}
+
+Such a group inherits its settings from the general setup
+command:
+
+\setup{setupfields}
+
+Fields are placed using one of:
+
+\setup{field}
+
+or
+
+\setup{fitfield}
+
+Some pages back I showed an example of:
+
+\setup{fillinfield}
+
+Finally there are two commands to trace fields. These
+commands only make sense when one already has said: \type
+{\tracefieldstrue}.
+
+\setup{showfields}
+
+\setup{logfields}
+
+\section{Tooltips}
+
+\startbuffer
+Chinese people seem to have no problems in recognizing their many
+different pictorial glyphs. \tooltip [left] {Western} {European
+and American} people however seem to have problems in understanding
+what all those \tooltip [middle] {icons} {small graphics} on their
+computer screens represent. But, instead of standardizing on a set
+of icons, computer programmers tend to fill the screen with so
+called tooltips. Well, \tooltip {\CONTEXT} {a \TEX\ macro package}
+can do tooltips too, and although a good design can do without them,
+\TEX\ at least can typeset them correctly.
+\stopbuffer
+
+\getbuffer
+
+The previous paragraph has three of such tooltips under
+{\em western}, {\em icons} and {\em \CONTEXT}, each aligned
+differently. We just typed:
+
+\typebuffer
+
+This is an official command, and thereby we can show its
+definition:
+
+\setup{tooltip}
+
+\section{Fieldstacks}
+
+In due time I will provide more dedicated field commands.
+Currently apart from \type {\fillinfield} and \type
+{\tooltip} we have \type {\fieldstack}. Let's spend a few
+words on those now.
+
+\startbuffer[somemap1]
+\useexternalfigure [map -- -- --] [euro-10] [width=.3\hsize]
+\useexternalfigure [map nl -- --] [euro-11] [map -- -- --]
+\useexternalfigure [map nl de --] [euro-12] [map -- -- --]
+\useexternalfigure [map nl de en] [euro-13] [map -- -- --]
+
+\definesymbol [map -- -- --] [{\externalfigure[map -- -- --]}]
+\definesymbol [map nl -- --] [{\externalfigure[map nl -- --]}]
+\definesymbol [map nl de --] [{\externalfigure[map nl de --]}]
+\definesymbol [map nl de en] [{\externalfigure[map nl de en]}]
+
+\stopbuffer
+
+\startbuffer[somemap2]
+\definefieldstack
+ [somemap]
+ [map -- -- --, map nl -- --, map nl de --, map nl de en]
+ [frame=on]
+\stopbuffer
+
+\startbuffer[somemap3]
+\placefigure
+ [left][fig:somemap]
+ {Do you want to see what interfaces
+ are available? Just click \goto
+ {here} [JS(Walk_Field{somemap})]
+ a few times!}
+ {\fieldstack[somemap]}
+\stopbuffer
+
+\getbuffer[somemap1,somemap2,somemap3]
+
+One can abuse field for educational purposes. Take for
+instance \in{figure}[fig:somemap]. In this figure we can
+sort of walk over different alternatives of the same
+graphic. This illustration was typeset by saying:
+
+\typebuffer[somemap3]
+
+However, before we can ask for such a map, we need to
+define a field set, which in fact is a list of symbols to
+show. This list is defined using:
+
+\typebuffer[somemap2]
+
+which in turn is preceded by:
+
+\typebuffer[somemap1]
+
+\startbuffer
+\placefigure
+ [here][fig:anothermap]
+ {Choose \goto {one} [JS(Set_Field{anothermap,2})] country,
+ \goto {two} [JS(Set_Field{anothermap,3})] countries,
+ \goto {three} [JS(Set_Field{anothermap,4})] countries or
+ \goto {no} [JS(Set_Field{anothermap,1})] countries at all.}
+ {\fieldstack
+ [anothermap]
+ [map -- -- --, map nl -- --, map nl de --, map nl de en]
+ [frame=on]}
+\stopbuffer
+
+\getbuffer
+
+A slightly different illustration is shown in
+\in{figure}[fig:anothermap]. Here we use the same symbols
+but instead say:
+
+\typebuffer
+
+As one can see, we can can skip the definition and pass it
+directly, but I wouldn't call that beautiful.
+
+The formal definitions are:
+
+\setup{definefieldstack}
+
+\setup{fieldstack}
+
+Instead if stacking fields, you can of course also put them
+alongside. This makes sense when you want to use dedicated
+(visible) captions for each image.
+
+\startbuffer
+\useexternalfigure [europe] [euro-10] [width=.3\hsize]
+\useexternalfigure [holland] [euro-nl] [europe]
+\useexternalfigure [germany] [euro-de] [europe]
+\useexternalfigure [england] [euro-en] [europe]
+
+\definesymbol [europe] [{\externalfigure[europe]}]
+\definesymbol [holland] [{\externalfigure[holland]}]
+\definesymbol [germany] [{\externalfigure[germany]}]
+\definesymbol [england] [{\externalfigure[england]}]
+
+\definefield
+ [interface] [radio] [map]
+ [england,germany,holland] [holland]
+
+\definesubfield [holland] [] [holland,europe]
+\definesubfield [germany] [] [germany,europe]
+\definesubfield [england] [] [england,europe]
+
+\setupfield[map][frame=off]
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+We can for instance typeset the fields by saying:
+
+\startbuffer
+\startcombination[3]
+ {\fitfield[holland]} {Dutch Interface}
+ {\fitfield[germany]} {German Interface}
+ {\fitfield[england]} {English Interface}
+\stopcombination
+\stopbuffer
+
+\typebuffer
+
+\startbaselinecorrection
+\getbuffer
+\stopbaselinecorrection
+
+
+
+%D \starttyping
+%D \defineviewerlayer[test]
+%D
+%D \startviewerlayer[test]Hide Me\stopviewerlayer
+%D
+%D \defineoverlay
+%D [WithTest]
+%D [{\overlayrollbutton[HideLayer{test}][VideLayer{test}]}]
+%D
+%D \framed[background=WithTest]{toggle}
+%D \stoptyping
+
+
+
+% \setupinteraction[state=start]
+%
+% \definepushbutton [reset]
+%
+% \startuniqueMPgraphic{whatever}{color}
+% fill fullcircle xysized (OverlayWidth,OverlayHeight) withcolor \MPvar{color} ;
+% \stopuniqueMPgraphic
+%
+% \definepushsymbol [reset] [n] [\uniqueMPgraphic{whatever}{color=red}]
+% \definepushsymbol [reset] [r] [\uniqueMPgraphic{whatever}{color=green}]
+% \definepushsymbol [reset] [d] [\uniqueMPgraphic{whatever}{color=blue}]
+%
+% \starttext
+% \startTEXpage
+% \pushbutton [reset] [page(2)]
+% \stopTEXpage
+% \startTEXpage
+% \pushbutton [reset] [page(1)]
+% \stopTEXpage
+% \stoptext
+
+
+% \setupinteraction[state=start]
+%
+% \definepushbutton [reset]
+%
+% \startuniqueMPgraphic{whatever}{color}
+% fill fullcircle xysized (OverlayWidth,OverlayHeight) withcolor \MPvar{color} ;
+% \stopuniqueMPgraphic
+%
+% \definepushsymbol [reset] [n] [\uniqueMPgraphic{whatever}{color=red}]
+% \definepushsymbol [reset] [r] [\uniqueMPgraphic{whatever}{color=green}]
+% \definepushsymbol [reset] [d] [\uniqueMPgraphic{whatever}{color=blue}]
+%
+% \starttext
+% \startTEXpage
+% \pushbutton [reset] [page(2)]
+% \stopTEXpage
+% \startTEXpage
+% \pushbutton [reset] [page(1)]
+% \stopTEXpage
+% \stoptext
+
+% \appendtoks
+% \let\startrob\scrn_menu_rob_start
+% \let\stoprob \relax
+% \let\rob \scrn_menu_rob_direct
+% \to \everysetmenucommands
+
+% \protect \endinput
diff --git a/doc/context/sources/general/manuals/interaction/interaction.tex b/doc/context/sources/general/manuals/interaction/interaction.tex
new file mode 100644
index 000000000..077e4abd8
--- /dev/null
+++ b/doc/context/sources/general/manuals/interaction/interaction.tex
@@ -0,0 +1,34 @@
+\environment interaction-style
+
+\setuplayout[bottom=1cm,bottomdistance=1cm]
+\setupbottomtexts[\infofont work in progress]
+
+\startdocument
+
+ \component interaction-titlepage
+
+ \startfrontmatter
+ \component interaction-contents
+ \component interaction-introduction
+ \stopfrontmatter
+
+ \startbodymatter
+ \component interaction-annotations
+ \component interaction-enabling
+ \component interaction-actions
+ \component interaction-hyperlinks
+ \component interaction-structure
+ \component interaction-comments
+ \component interaction-attachments
+ \component interaction-bookmarks
+ \component interaction-javascript
+ \component interaction-buttons
+ \component interaction-menus
+ \component interaction-progress
+ \component interaction-widgets
+ \component interaction-transitions
+ \component interaction-importing
+ \component interaction-tagging
+ \stopbodymatter
+
+\stopdocument
diff --git a/doc/context/sources/general/manuals/languages/languages-numbering.tex b/doc/context/sources/general/manuals/languages/languages-numbering.tex
index 3464826df..9752b6271 100644
--- a/doc/context/sources/general/manuals/languages/languages-numbering.tex
+++ b/doc/context/sources/general/manuals/languages/languages-numbering.tex
@@ -296,6 +296,10 @@ can also as a specific one, so {\em jalali} \date [y=1395, m=4, d=18]
\typebuffer \startnarrower \getbuffer \stopnarrower
+For time we have \type {\currenttime} and here the specification is just an \type
+{h}, \type {m} and whatever connects them. Both date and time are
+pre|-|configured in the language definition file \type {lang-def}.
+
\stopsection
% \startsection[title=Counters]
diff --git a/doc/context/sources/general/manuals/luatex/luatex-contents.tex b/doc/context/sources/general/manuals/luatex/luatex-contents.tex
index 6d06b3ef0..2582a81c7 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-contents.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-contents.tex
@@ -1,5 +1,4 @@
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-contents
diff --git a/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex b/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex
index e0119bf7e..b81e1dbda 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-enhancements.tex
@@ -1,22 +1,23 @@
% language=uk
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-enhancements
\startchapter[reference=enhancements,title={Basic \TEX\ enhancements}]
-\section{Introduction}
+\startsection[title={Introduction}]
+
+\startsubsection[title={Primitive behaviour}]
From day one, \LUATEX\ has offered extra features compared to the superset of
-\PDFTEX\ and \ALEPH. This has not been limited to the possibility to execute
-\LUA\ code via \type {\directlua}, but \LUATEX\ also adds functionality via new
-\TEX|-|side primitives or extensions to existing ones.
+\PDFTEX, which includes \ETEX, and \ALEPH. This has not been limited to the
+possibility to execute \LUA\ code via \prm {directlua}, but \LUATEX\ also adds
+functionality via new \TEX|-|side primitives or extensions to existing ones.
When \LUATEX\ starts up in \quote {iniluatex} mode (\type {luatex -ini}), it
defines only the primitive commands known by \TEX82 and the one extra command
-\type {\directlua}. As is fitting, a \LUA\ function has to be called to add the
+\prm {directlua}. As is fitting, a \LUA\ function has to be called to add the
extra primitives to the user environment. The simplest method to get access to
all of the new primitive commands is by adding this line to the format generation
file:
@@ -25,7 +26,7 @@ file:
\directlua { tex.enableprimitives('',tex.extraprimitives()) }
\stoptyping
-But be aware that the curly braces may not have the proper \type {\catcode}
+But be aware that the curly braces may not have the proper \prm {catcode}
assigned to them at this early time (giving a \quote {Missing number} error), so
it may be needed to put these assignments before the above line:
@@ -36,44 +37,62 @@ it may be needed to put these assignments before the above line:
More fine|-|grained primitives control is possible and you can look up the
details in \in {section} [luaprimitives]. For simplicity's sake, this manual
-assumes that you have executed the \type {\directlua} command as given above.
+assumes that you have executed the \prm {directlua} command as given above.
The startup behaviour documented above is considered stable in the sense that
there will not be backward|-|incompatible changes any more. We have promoted some
-rather generic \PDFTEX\ primitives to core \LUATEX\ ones, and the ones inherited
-frome \ALEPH\ (\OMEGA) are also promoted. Effectively this means that we now only
-have the \type {tex}, \type {etex} and \type {luatex} sets left.
+rather generic \PDFTEX\ primitives to core \LUATEX\ ones, and the few that we
+inherited from \ALEPH\ (\OMEGA) are also promoted. Effectively this means that we
+now only have the \type {tex}, \type {etex} and \type {luatex} sets left.
In \in {Chapter} [modifications] we discuss several primitives that are derived
from \PDFTEX\ and \ALEPH\ (\OMEGA). Here we stick to real new ones. In the
chapters on fonts and math we discuss a few more new ones.
-\section{Version information}
+\stopsubsection
+
+\startsubsection[title={Version information}]
-\subsection {\type {\luatexbanner}, \type {\luatexversion} and \type {\luatexrevision}}
+\startsubsubsection[title={\lpr {luatexbanner}, \lpr {luatexversion} and \lpr {luatexrevision}}]
+
+\topicindex{version}
+\topicindex{banner}
There are three new primitives to test the version of \LUATEX:
-\starttabulate[|l|pl|pl|]
-\BC primitive \BC explanation \BC value \NC \NR
-\NC \type {\luatexbanner} \NC the banner reported on the command line \NC \luatexbanner \NC \NR
-\NC \type {\luatexversion} \NC a combination of major and minor number \NC \the\luatexversion \NC \NR
-\NC \type {\luatexrevision} \NC the revision number, the current value is \NC \luatexrevision \NC \NR
+\unexpanded\def\VersionHack#1% otherwise different luatex and luajittex runs
+ {\ctxlua{%
+ local banner = "\luatexbanner"
+ local banner = string.match(banner,"(.+)\letterpercent(") or banner
+ context(string.gsub(banner ,"jit",""))%
+ }}
+
+\starttabulate[|l|l|pl|]
+\DB primitive \BC value
+ \BC explanation \NC \NR
+\TB
+\NC \lpr {luatexbanner} \NC \VersionHack{\luatexbanner}
+ \NC the banner reported on the command line \NC \NR
+\NC \lpr {luatexversion} \NC \the\luatexversion
+ \NC a combination of major and minor number \NC \NR
+\NC \lpr {luatexrevision} \NC \luatexrevision
+ \NC the revision number, the current value is \NC \NR
+\LL
\stoptabulate
The official \LUATEX\ version is defined as follows:
\startitemize
\startitem
- The major version is the integer result of \type {\luatexversion} divided by
+ The major version is the integer result of \lpr {luatexversion} divided by
100. The primitive is an \quote {internal variable}, so you may need to prefix
- its use with \type {\the} depending on the context.
+ its use with \prm {the} depending on the context.
\stopitem
\startitem
- The minor version is the two-digit result of \type {\luatexversion} modulo 100.
+ The minor version is the two|-|digit result of \lpr {luatexversion} modulo 100.
\stopitem
\startitem
- The revision is the given by \type {\luatexrevision}. This primitive expands to
+ The revision is reported by \lpr {luatexrevision}. This primitive expands to
a positive integer.
\stopitem
\startitem
@@ -82,16 +101,28 @@ The official \LUATEX\ version is defined as follows:
\stopitem
\stopitemize
-\subsection{\type {\formatname}}
+\stopsubsubsection
+
+\startsubsubsection[title={\lpr {formatname}}]
-The \type {\formatname} syntax is identical to \type {\jobname}. In \INITEX, the
-expansion is empty. Otherwise, the expansion is the value that \type {\jobname} had
+\topicindex{format}
+
+The \lpr {formatname} syntax is identical to \prm {jobname}. In \INITEX, the
+expansion is empty. Otherwise, the expansion is the value that \prm {jobname} had
during the \INITEX\ run that dumped the currently loaded format. You can use this
token list to provide your own version info.
-\section{\UNICODE\ text support}
+\stopsubsubsection
+
+\stopsubsection
+
+\stopsection
-\subsection {Extended ranges}
+\startsection[title={\UNICODE\ text support}]
+
+\startsubsection[title={Extended ranges}]
+
+\topicindex{\UNICODE}
Text input and output is now considered to be \UNICODE\ text, so input characters
can use the full range of \UNICODE\ ($2^{20}+2^{16}-1 = \hbox{0x10FFFF}$). Later
@@ -101,22 +132,25 @@ always converted to a suitable graphic representation of that character in a
specific font. However, while processing a list of to|-|be|-|typeset nodes, its
contents may still be seen as a character. Inside \LUATEX\ there is no clear
separation between the two concepts. Because the subtype of a glyph node can be
-changed in \LUA\ it is up to the user: subtypes larger than 255 indicate that
+changed in \LUA\ it is up to the user. Subtypes larger than 255 indicate that
font processing has happened.
A few primitives are affected by this, all in a similar fashion: each of them has
-to accommodate for a larger range of acceptable numbers. For instance, \type
-{\char} now accepts values between~0 and $1{,}114{,}111$. This should not be a
+to accommodate for a larger range of acceptable numbers. For instance, \prm
+{char} now accepts values between~0 and $1{,}114{,}111$. This should not be a
problem for well|-|behaved input files, but it could create incompatibilities for
input that would have generated an error when processed by older \TEX|-|based
-engines. The affected commands with an altered initial (left of the equals sign)
-or secondary (right of the equals sign) value are: \type {\char}, \type
-{\lccode}, \type {\uccode}, \type {\catcode}, \type {\sfcode}, \type {\efcode},
-\type {\lpcode}, \type {\rpcode}, \type {\chardef}.
+engines. The affected commands with an altered initial (left of the equal sign)
+or secondary (right of the equal sign) value are: \prm {char}, \prm {lccode},
+\prm {uccode}, \lpr {hjcode}, \prm {catcode}, \prm {sfcode}, \lpr {efcode}, \lpr
+{lpcode}, \lpr {rpcode}, \prm {chardef}.
As far as the core engine is concerned, all input and output to text files is
\UTF-8 encoded. Input files can be pre|-|processed using the \type {reader}
-callback. This will be explained in a later chapter.
+callback. This will be explained in \in {section} [iocallback]. Normalization of
+the \UNICODE\ input is on purpose not built|-|in and can be handled by a macro
+package during callback processing. We have made some practical choices and the
+user has to live with those.
Output in byte|-|sized chunks can be achieved by using characters just outside of
the valid \UNICODE\ range, starting at the value $1{,}114{,}112$ (0x110000). When
@@ -129,58 +163,106 @@ are considered \quote {safe} and therefore printed as|-|is. You can disable
escaping with \type {texio.setescape(false)} in which case you get the normal
characters on the console.
-Normalization of the \UNICODE\ input can be handled by a macro package during
-callback processing (this will be explained in \in {section} [iocallback]).
+\stopsubsection
-\subsection{\type {\Uchar}}
+\startsubsection[title={\lpr {Uchar}}]
-The expandable command \type {\Uchar} reads a number between~0 and $1{,}114{,}111$
+\topicindex{\UNICODE}
+
+The expandable command \lpr {Uchar} reads a number between~0 and $1{,}114{,}111$
and expands to the associated \UNICODE\ character.
-\section{Extended tables}
+\stopsubsection
+
+\startsubsection[title={Extended tables}]
All traditional \TEX\ and \ETEX\ registers can be 16-bit numbers. The affected
commands are:
\startfourcolumns
-\starttyping
-\count
-\dimen
-\skip
-\muskip
-\marks
-\toks
-\countdef
-\dimendef
-\skipdef
-\muskipdef
-\toksdef
-\insert
-\box
-\unhbox
-\unvbox
-\copy
-\unhcopy
-\unvcopy
-\wd
-\ht
-\dp
-\setbox
-\vsplit
-\stoptyping
+\startlines
+\prm {count}
+\prm {dimen}
+\prm {skip}
+\prm {muskip}
+\prm {marks}
+\prm {toks}
+\prm {countdef}
+\prm {dimendef}
+\prm {skipdef}
+\prm {muskipdef}
+\prm {toksdef}
+\prm {insert}
+\prm {box}
+\prm {unhbox}
+\prm {unvbox}
+\prm {copy}
+\prm {unhcopy}
+\prm {unvcopy}
+\prm {wd}
+\prm {ht}
+\prm {dp}
+\prm {setbox}
+\prm {vsplit}
+\stoplines
\stopfourcolumns
Because font memory management has been rewritten, character properties in fonts
-are no longer shared among fonts instances that originate from the same metric
-file.
+are no longer shared among font instances that originate from the same metric
+file. Of course we share fonts in the backend when possible so that the resulting
+\PDF\ file is as efficient as possible, but for instance also expansion and
+protrusion no longer use copies as in \PDFTEX.
+
+\stopsubsection
-\section{Attributes}
+\stopsection
-\subsection{Attribute registers}
+\startsection[title={Attributes}]
+
+\startsubsection[title={Nodes}]
+
+\topicindex {nodes}
+
+When \TEX\ reads input it will interpret the stream according to the properties
+of the characters. Some signal a macro name and trigger expansion, others open
+and close groups, trigger math mode, etc. What's left over becomes the typeset
+text. Internally we get linked list of nodes. Characters become \nod {glyph}
+nodes that have for instance a \type {font} and \type {char} property and \typ
+{\kern 10pt} becomes a \nod {kern} node with a \type {width} property. Spaces are
+alien to \TEX\ as they are turned into \nod {glue} nodes. So, a simple paragraph
+is mostly a mix of sequences of \nod {glyph} nodes (words) and \nod {glue} nodes
+(spaces).
+
+The sequences of characters at some point are extended with \nod {disc} nodes
+that relate to hyphenation. After that font logic can be applied and we get a
+list where some characters can be replaced, for instance multiple characters can
+become one ligature, and font kerns can be injected. This is driven by the
+font properties.
+
+Boxes (like \prm {hbox} and \prm {vbox}) become \nod {hlist} or \nod {vlist}
+nodes with \type {width}, \type {height}, \type {depth} and \type {shift}
+properties and a pointer \type {list} to its actual content. Boxes can be
+constructed explicitly or can be the result of subprocesses. For instance, when
+lines are broken into paragraphs, the lines are a linked list of \nod {hlist}
+nodes.
+
+So, to summarize: all that you enter as content eventually becomes a node, often
+as part of a (nested) list structure. They have a relative small memory footprint
+and carry only the minimal amount of information needed. In traditional \TEX\ a
+character node only held the font and slot number, in \LUATEX\ we also store some
+language related information, the expansion factor, etc. Now that we have access
+to these nodes from \LUA\ it makes sense to be able to carry more information
+with an node and this is where attributes kick in.
+
+\stopsubsection
+
+\startsubsection[title={Attribute registers}]
+
+\topicindex {attributes}
Attributes are a completely new concept in \LUATEX. Syntactically, they behave a
lot like counters: attributes obey \TEX's nesting stack and can be used after
-\type {\the} etc.\ just like the normal \type {\count} registers.
+\prm {the} etc.\ just like the normal \prm {count} registers.
\startsyntax
\attribute <16-bit number> <optional equals> <32-bit number>!crlf
@@ -202,13 +284,22 @@ attached to all nodes created in their scope. These can then be queried from any
attributes for node list processing from \LUA\ is given in~\in {chapter}[nodes].
Attributes are stored in a sorted (sparse) linked list that are shared when
-possible. This permits efficient testing and updating.
+possible. This permits efficient testing and updating. You can define many
+thousands of attributes but normally such a large number makes no sense and is
+also not that efficient because each node carries a (possibly shared) link to a
+list of currently set attributes. But they are a convenient extension and one of
+the first extensions we implemented in \LUATEX.
+
+\stopsubsection
-\subsection{Box attributes}
+\startsubsection[title={Box attributes}]
+
+\topicindex {attributes}
+\topicindex {boxes}
Nodes typically receive the list of attributes that is in effect when they are
created. This moment can be quite asynchronous. For example: in paragraph
-building, the individual line boxes are created after the \type {\par} command has
+building, the individual line boxes are created after the \prm {par} command has
been processed, so they will receive the list of attributes that is in effect
then, not the attributes that were in effect in, say, the first or third line of
the paragraph.
@@ -229,28 +320,64 @@ incompatibility is mostly due to the fact that separate specials and literals ar
a more unnatural approach to colors than attributes.
It is possible to fine-tune the list of attributes that are applied to a \type
-{hbox}, \type {vbox} or \type {vtop} by the use of the keyword \type {attr}. An
-example:
+{hbox}, \type {vbox} or \type {vtop} by the use of the keyword \type {attr}. The
+\type {attr} keyword(s) should come before a \type {to} or \type {spread}, if
+that is also specified. An example is:
-\starttyping
-\attribute2=5
+\startbuffer[tex]
+\attribute997=123
+\attribute998=456
\setbox0=\hbox {Hello}
-\setbox2=\hbox attr1=12 attr2=-"7FFFFFFF{Hello}
-\stoptyping
+\setbox2=\hbox attr 999 = 789 attr 998 = -"7FFFFFFF{Hello}
+\stopbuffer
+
+\startbuffer[lua]
+ for b=0,2,2 do
+ for a=997, 999 do
+ tex.sprint("box ", b, " : attr ",a," : ",tostring(tex.box[b] [a]))
+ tex.sprint("\\quad\\quad")
+ tex.sprint("list ",b, " : attr ",a," : ",tostring(tex.box[b].list[a]))
+ tex.sprint("\\par")
+ end
+ end
+\stopbuffer
+
+\typebuffer[tex]
+
+Box 0 now has attributes 997 and 998 set while box 2 has attributes 997 and 999
+set while the nodes inside that box will all have attributes 997 and 998 set.
+Assigning the maximum negative value causes an attribute to be ignored.
+
+To give you an idea of what this means at the \LUA\ end, take the following
+code:
+
+\typebuffer[lua]
-This will set the attribute list of box~2 to $1=12$, and the attributes of box~0
-will be $2=5$. As you can see, assigning the maximum negative value causes an
-attribute to be ignored.
+Later we will see that you can access properties of a node. The boxes here are so
+called \nod {hlist} nodes that have a field \type {list} that points to the
+content. Because the attributes are a list themselves you can access them by
+indexing the node (here we do that with \type {[a]}. Running this snippet gives:
-The \type {attr} keyword(s) should come before a \type {to} or \type {spread}, if
-that is also specified.
+\start
+ \getbuffer[tex]
+ \startpacked \tt
+ \ctxluabuffer[lua]
+ \stoppacked
+\stop
-\section{\LUA\ related primitives}
+Because some values are not set we need to apply the \type {tostring} function
+here so that we get the word \type {nil}.
-\subsection{\type {\directlua}}
+\stopsubsection
+
+\stopsection
+
+\startsection[title={\LUA\ related primitives}]
+
+\startsubsection[title={\prm {directlua}}]
In order to merge \LUA\ code with \TEX\ input, a few new primitives are needed.
-The primitive \type {\directlua} is used to execute \LUA\ code immediately. The
+The primitive \prm {directlua} is used to execute \LUA\ code immediately. The
syntax is
\startsyntax
@@ -261,10 +388,10 @@ syntax is
The \syntax {<general text>} is expanded fully, and then fed into the \LUA\
interpreter. After reading and expansion has been applied to the \syntax
{<general text>}, the resulting token list is converted to a string as if it was
-displayed using \type {\the\toks}. On the \LUA\ side, each \type {\directlua}
-block is treated as a separate chunk. In such a chunk you can use the \type
-{local} directive to keep your variables from interfering with those used by the
-macro package.
+displayed using \type {\the\toks}. On the \LUA\ side, each \prm {directlua} block
+is treated as a separate chunk. In such a chunk you can use the \type {local}
+directive to keep your variables from interfering with those used by the macro
+package.
The conversion to and from a token list means that you normally can not use \LUA\
line comments (starting with \type {--}) within the argument. As there typically
@@ -281,15 +408,16 @@ say:
\stoptyping
Then \LUA\ line comments can be used, since \TEX\ does not replace line endings
-with spaces.
+with spaces. Of course such an approach depends on the macro package that you
+use.
-Likewise, the \syntax {<16-bit number>} designates a name of a \LUA\ chunk and is
+The \syntax {<16-bit number>} designates a name of a \LUA\ chunk and is
taken from the \type {lua.name} array (see the documentation of the \type {lua}
table further in this manual). When a chunk name starts with a \type {@} it will
be displayed as a file name. This is a side effect of the way \LUA\ implements
error handling.
-The \type {\directlua} command is expandable. Since it passes \LUA\ code to the
+The \prm {directlua} command is expandable. Since it passes \LUA\ code to the
\LUA\ interpreter its expansion from the \TEX\ viewpoint is usually empty.
However, there are some \LUA\ functions that produce material to be read by \TEX,
the so called print functions. The most simple use of these is \type
@@ -320,10 +448,10 @@ will result in
\getbuffer
-Note that the expansion of \type {\directlua} is a sequence of characters, not of
+Note that the expansion of \prm {directlua} is a sequence of characters, not of
tokens, contrary to all \TEX\ commands. So formally speaking its expansion is
null, but it places material on a pseudo-file to be immediately read by \TEX, as
-\ETEX's \type {\scantokens}. For a description of print functions look at \in
+\ETEX's \prm {scantokens}. For a description of print functions look at \in
{section} [sec:luaprint].
Because the \syntax {<general text>} is a chunk, the normal \LUA\ error handling
@@ -337,15 +465,14 @@ can break up \LUATEX\ pretty bad. If you are not careful while working with the
node list interface, you may even end up with assertion errors from within the
\TEX\ portion of the executable.
-The behaviour documented in the above subsection is considered stable in the sense
-that there will not be backward-incompatible changes any more.
+\stopsubsection
-\subsection{\type {\latelua}}
+\startsubsection[title={\lpr {latelua} and \lpr {lateluafunction}}]
-Contrary to \type {\directlua}, \type {\latelua} stores \LUA\ code in a whatsit
+Contrary to \prm {directlua}, \lpr {latelua} stores \LUA\ code in a whatsit
that will be processed at the time of shipping out. Its intended use is a cross
-between \PDF\ literals (often available as \type {\pdfliteral}) and the
-traditional \TEX\ extension \type {\write}. Within the \LUA\ code you can print
+between \PDF\ literals (often available as \orm {pdfliteral}) and the
+traditional \TEX\ extension \prm {write}. Within the \LUA\ code you can print
\PDF\ statements directly to the \PDF\ file via \type {pdf.print}, or you can
write to other output streams via \type {texio.write} or simply using \LUA\ \IO\
routines.
@@ -356,12 +483,19 @@ routines.
\stopsyntax
Expansion of macros in the final \type {<general text>} is delayed until just
-before the whatsit is executed (like in \type {\write}). With regard to \PDF\
-output stream \type {\latelua} behaves as \PDF\ page literals. The \syntax
+before the whatsit is executed (like in \prm {write}). With regard to \PDF\
+output stream \lpr {latelua} behaves as \PDF\ page literals. The \syntax
{name <general text>} and \syntax {<16-bit number>} behave in the same way as
-they do for \type {\directlua}
+they do for \prm {directlua}.
+
+The \lpr {lateluafunction} primitive takes a number and is similar to \lpr
+{luafunction} but gets delated to shipout time. It's just there for completeness.
+
+\stopsubsection
+
+\startsubsection[title={\lpr {luaescapestring}}]
-\subsection{\type {\luaescapestring}}
+\topicindex {escaping}
This primitive converts a \TEX\ token sequence so that it can be safely used as
the contents of a \LUA\ string: embedded backslashes, double and single quotes,
@@ -375,23 +509,24 @@ sequence is fully expanded.
\stopsyntax
Most often, this command is not actually the best way to deal with the
-differences between the \TEX\ and \LUA. In very short bits of \LUA\
-code it is often not needed, and for longer stretches of \LUA\ code it
-is easier to keep the code in a separate file and load it using \LUA's
-\type {dofile}:
+differences between \TEX\ and \LUA. In very short bits of \LUA\ code it is often
+not needed, and for longer stretches of \LUA\ code it is easier to keep the code
+in a separate file and load it using \LUA's \type {dofile}:
\starttyping
\directlua { dofile('mysetups.lua') }
\stoptyping
-\subsection{\type {\luafunction} and \type {\luafunctioncall}}
+\stopsubsection
-The \type {\directlua} commands involves tokenization of its argument (after
+\startsubsection[title={\lpr {luafunction}, \lpr {luafunctioncall} and \lpr {luadef}}]
+
+The \prm {directlua} commands involves tokenization of its argument (after
picking up an optional name or number specification). The tokenlist is then
converted into a string and given to \LUA\ to turn into a function that is
-called. The overhead is rather small but when you use this primitive hundreds of
-thousands of times, it can become noticeable. For this reason there is a variant
-call available: \type {\luafunction}. This command is used as follows:
+called. The overhead is rather small but when you have millions of calls it can
+have some impact. For this reason there is a variant call available: \lpr
+{luafunction}. This command is used as follows:
\starttyping
\directlua {
@@ -417,73 +552,117 @@ in the following example the number \type {8} gets typeset.
}
\stoptyping
-The \type {\luafunctioncall} primitive does the same but is unexpandable, for instance
-in an \type {\edef}.
+The \lpr {luafunctioncall} primitive does the same but is unexpandable, for
+instance in an \prm {edef}. In addition \LUATEX\ provides a definer:
+
+\starttyping
+ \luadef\MyFunctionA 1
+ \global\luadef\MyFunctionB 2
+\protected\global\luadef\MyFunctionC 3
+\stoptyping
-\section {Alignments}
+You should really use these commands with care. Some references get stored in
+tokens and assume that the function is available when that token expands. On the
+other hand, as we have tested this functionality in relative complex situations
+normal usage should not give problems.
-\subsection{\tex {alignmark}}
+\stopsubsection
-This primitive duplicates the functionality of \type {#} inside alignment
-preambles.
+\startsubsection[title={\lpr {luabytecode} and \lpr {luabytecodecall}}]
-\subsection{\tex {aligntab}}
+Analogue to the function callers discussed in the previous section we have byte
+code callers. Again the call variant is unexpandable.
+
+\starttyping
+\directlua {
+ lua.bytecode[9998] = function(s)
+ tex.sprint(s*token.scan_int())
+ end
+ lua.bytecode[5555] = function(s)
+ tex.sprint(s*token.scan_dimen())
+ end
+}
+\stoptyping
+
+This works with:
+
+\starttyping
+\luabytecode 9998 5 \luabytecode 5555 5sp
+\luabytecodecall9998 5 \luabytecodecall5555 5sp
+\stoptyping
-This primitive duplicates the functionality of \type {&} inside alignments and
-preambles.
+The variable \type {s} in the code is the number of the byte code register that
+can be used for diagnostic purposes. The advantage of bytecode registers over
+function calls is that they are stored in the format (but without upvalues).
-\section{Catcode tables}
+\stopsubsection
+
+\stopsection
+
+\startsection[title={Catcode tables}]
+
+\startsubsection[title={Catcodes}]
+
+\topicindex {catcodes}
Catcode tables are a new feature that allows you to switch to a predefined
catcode regime in a single statement. You can have a practically unlimited number
of different tables. This subsystem is backward compatible: if you never use the
following commands, your document will not notice any difference in behaviour
compared to traditional \TEX. The contents of each catcode table is independent
-from any other catcode tables, and their contents is stored and retrieved from
-the format file.
+from any other catcode table, and its contents is stored and retrieved from the
+format file.
-\subsection{\type {\catcodetable}}
+\stopsubsection
+
+\startsubsection[title={\lpr {catcodetable}}]
\startsyntax
\catcodetable <15-bit number>
\stopsyntax
-The primitive \type {\catcodetable} switches to a different catcode table. Such a
+The primitive \lpr {catcodetable} switches to a different catcode table. Such a
table has to be previously created using one of the two primitives below, or it
has to be zero. Table zero is initialized by \INITEX.
-\subsection{\type {\initcatcodetable}}
+\stopsubsection
+
+\startsubsection[title={\lpr {initcatcodetable}}]
\startsyntax
\initcatcodetable <15-bit number>
\stopsyntax
-The primitive \type {\initcatcodetable} creates a new table with catcodes identical
-to those defined by \INITEX:
-
-\starttabulate[|r|l|l|l|]
-\NC 0 \NC \tttf \letterbackslash \NC \NC \type {escape} \NC\NR
-\NC 5 \NC \tttf \letterhat\letterhat M \NC return \NC \type {car_ret} \NC\NR
-\NC 9 \NC \tttf \letterhat\letterhat @ \NC null \NC \type {ignore} \NC\NR
-\NC 10 \NC \tttf <space> \NC space \NC \type {spacer} \NC\NR
-\NC 11 \NC {\tttf a} \endash\ {\tttf z} \NC \NC \type {letter} \NC\NR
-\NC 11 \NC {\tttf A} \endash\ {\tttf Z} \NC \NC \type {letter} \NC\NR
-\NC 12 \NC everything else \NC \NC \type {other} \NC\NR
-\NC 14 \NC \tttf \letterpercent \NC \NC \type {comment} \NC\NR
-\NC 15 \NC \tttf \letterhat\letterhat ? \NC delete \NC \type {invalid_char} \NC\NR
+The primitive \lpr {initcatcodetable} creates a new table with catcodes
+identical to those defined by \INITEX. The new catcode table is allocated
+globally: it will not go away after the current group has ended. If the supplied
+number is identical to the currently active table, an error is raised. The
+initial values are:
+
+\starttabulate[|c|c|l|l|]
+\DB catcode \BC character \BC equivalent \BC category \NC \NR
+\TB
+\NC 0 \NC \tttf \letterbackslash \NC \NC \type {escape} \NC \NR
+\NC 5 \NC \tttf \letterhat\letterhat M \NC return \NC \type {car_ret} \NC \NR
+\NC 9 \NC \tttf \letterhat\letterhat @ \NC null \NC \type {ignore} \NC \NR
+\NC 10 \NC \tttf <space> \NC space \NC \type {spacer} \NC \NR
+\NC 11 \NC {\tttf a} \endash\ {\tttf z} \NC \NC \type {letter} \NC \NR
+\NC 11 \NC {\tttf A} \endash\ {\tttf Z} \NC \NC \type {letter} \NC \NR
+\NC 12 \NC everything else \NC \NC \type {other} \NC \NR
+\NC 14 \NC \tttf \letterpercent \NC \NC \type {comment} \NC \NR
+\NC 15 \NC \tttf \letterhat\letterhat ? \NC delete \NC \type {invalid_char} \NC \NR
+\LL
\stoptabulate
-The new catcode table is allocated globally: it will not go away after the
-current group has ended. If the supplied number is identical to the currently
-active table, an error is raised.
+\stopsubsection
-\subsection{\type {\savecatcodetable}}
+\startsubsection[title={\lpr {savecatcodetable}}]
\startsyntax
\savecatcodetable <15-bit number>
\stopsyntax
-\type {\savecatcodetable} copies the current set of catcodes to a new table with
+\lpr {savecatcodetable} copies the current set of catcodes to a new table with
the requested number. The definitions in this new table are all treated as if
they were made in the outermost level.
@@ -491,55 +670,78 @@ The new table is allocated globally: it will not go away after the current group
has ended. If the supplied number is the currently active table, an error is
raised.
-\section{Suppressing errors}
+\stopsubsection
+
+\stopsection
-\subsection{\type {\suppressfontnotfounderror}}
+\startsection[title={Suppressing errors}]
+
+\startsubsection[title={\lpr {suppressfontnotfounderror}}]
+
+\topicindex {errors}
+
+If this integer parameter is non|-|zero, then \LUATEX\ will not complain about
+font metrics that are not found. Instead it will silently skip the font
+assignment, making the requested csname for the font \prm {ifx} equal to \prm
+{nullfont}, so that it can be tested against that without bothering the user.
\startsyntax
\suppressfontnotfounderror = 1
\stopsyntax
-If this integer parameter is non|-|zero, then \LUATEX\ will not complain about
-font metrics that are not found. Instead it will silently skip the font
-assignment, making the requested csname for the font \type {\ifx} equal to \type
-{\nullfont}, so that it can be tested against that without bothering the user.
+\stopsubsection
+
+\startsubsection[title={\lpr {suppresslongerror}}]
-\subsection{\type {\suppresslongerror}}
+\topicindex {errors}
+
+If this integer parameter is non|-|zero, then \LUATEX\ will not complain about
+\prm {par} commands encountered in contexts where that is normally prohibited
+(most prominently in the arguments of macros not defined as \prm {long}).
\startsyntax
\suppresslongerror = 1
\stopsyntax
-If this integer parameter is non|-|zero, then \LUATEX\ will not complain about
-\type {\par} commands encountered in contexts where that is normally prohibited
-(most prominently in the arguments of non-long macros).
+\stopsubsection
-\subsection{\type {\suppressifcsnameerror}}
+\startsubsection[title={\lpr {suppressifcsnameerror}}]
-\startsyntax
-\suppressifcsnameerror = 1
-\stopsyntax
+\topicindex {errors}
If this integer parameter is non|-|zero, then \LUATEX\ will not complain about
-non-expandable commands appearing in the middle of a \type {\ifcsname} expansion.
+non-expandable commands appearing in the middle of a \prm {ifcsname} expansion.
Instead, it will keep getting expanded tokens from the input until it encounters
-an \type {\endcsname} command. If the input expansion is unbalanced with respect
-to \type {\csname} \ldots \type {\endcsname} pairs, the \LUATEX\ process may hang
+an \prm {endcsname} command. If the input expansion is unbalanced with respect
+to \prm {csname} \ldots \prm {endcsname} pairs, the \LUATEX\ process may hang
indefinitely.
-\subsection{\type {\suppressoutererror}}
-
\startsyntax
-\suppressoutererror = 1
+\suppressifcsnameerror = 1
\stopsyntax
+\stopsubsection
+
+\startsubsection[title={\lpr {suppressoutererror}}]
+
+\topicindex {errors}
+
If this new integer parameter is non|-|zero, then \LUATEX\ will not complain
-about \type {\outer} commands encountered in contexts where that is normally
+about \prm {outer} commands encountered in contexts where that is normally
prohibited.
-\subsection{\type {\suppressmathparerror}}
+\startsyntax
+\suppressoutererror = 1
+\stopsyntax
+
+\stopsubsection
+
+\startsubsection[title={\lpr {suppressmathparerror}}]
+
+\topicindex {errors}
+\topicindex {math}
-The following setting will permit \type {\par} tokens in a math formula:
+The following setting will permit \prm {par} tokens in a math formula:
\startsyntax
\suppressmathparerror = 1
@@ -553,41 +755,30 @@ $ x + 1 =
a $
\stoptyping
-\subsection{\type {\suppressprimitiveerror}}
+\stopsubsection
+
+\startsubsection[title={\lpr {suppressprimitiveerror}}]
+
+\topicindex {errors}
+\topicindex {primitives}
When set to a non|-|zero value the following command will not issue an error:
-\starttyping
+\startsyntax
\suppressprimitiveerror = 1
\primitive\notaprimitive
-\stoptyping
-
-\section {Math}
-
-\subsection{Extensions}
+\stopsyntax
-We will cover math in its own chapter because not only the font subsystem and
-spacing model have been enhanced (thereby introducing many new primitives) but
-also because some more control has been added to existing functionality.
+\stopsubsection
-\subsection{\type {\matheqnogapstep}}
+\stopsection
-By default \TEX\ will add one quad between the equation and the number. This is
-hard coded. A new primitive can control this:
+\startsection[title={Fonts}]
-\startsyntax
-\matheqnogapstep = 1000
-\stopsyntax
+\startsubsection[title={Font syntax}]
-Because a math quad from the math text font is used instead of a dimension, we
-use a step to control the size. A value of zero will suppress the gap. The step
-is divided by 1000 which is the usual way to mimmick floating point factors in
-\TEX.
-
-\section{Fonts}
-
-\subsection{Font syntax}
+\topicindex {fonts}
\LUATEX\ will accept a braced argument as a font name:
@@ -598,20 +789,26 @@ is divided by 1000 which is the usual way to mimmick floating point factors in
This allows for embedded spaces, without the need for double quotes. Macro
expansion takes place inside the argument.
-\subsection{\type {\fontid}}
+\stopsubsection
+
+\startsubsection[title={\lpr {fontid} and \lpr {setfontid}}]
\startsyntax
\fontid\font
\stopsyntax
This primitive expands into a number. It is not a register so there is no need to
-prefix with \type {\number} (and using \type {\the} gives an error). The currently
+prefix with \prm {number} (and using \prm {the} gives an error). The currently
used font id is \fontid\font. Here are some more:
-\starttabulate[|l|c|]
-\NC \type {\bf} \NC \bf \fontid\font \NC \NR
-\NC \type {\it} \NC \it \fontid\font \NC \NR
-\NC \type {\bi} \NC \bi \fontid\font \NC \NR
+\starttabulate[|l|c|c|]
+\DB style \BC command \BC font id \NC \NR
+\TB
+\NC normal \NC \type {\tf} \NC \bf \fontid\font \NC \NR
+\NC bold \NC \type {\bf} \NC \bf \fontid\font \NC \NR
+\NC italic \NC \type {\it} \NC \it \fontid\font \NC \NR
+\NC bold italic \NC \type {\bi} \NC \bi \fontid\font \NC \NR
+\LL
\stoptabulate
These numbers depend on the macro package used because each one has its own way
@@ -620,12 +817,15 @@ order of loading fonts. For instance, when in \CONTEXT\ virtual math \UNICODE\
fonts are used, we can easily get over a hundred ids in use. Not all ids have to
be bound to a real font, after all it's just a number.
-\subsection{\type {\setfontid}}
+The primitive \lpr {setfontid} can be used to enable a font with the given id,
+which of course needs to be a valid one.
-The primitive \type {\setfontid} can be used to enable a font with the given id
-(which of course needs to be a valid one).
+\stopsubsection
-\subsection{\type {\noligs} and \type {\nokerns}}
+\startsubsection[title={\lpr {noligs} and \lpr {nokerns}}]
+
+\topicindex {ligatures+suppress}
+\topicindex {kerns+suppress}
These primitives prohibit ligature and kerning insertion at the time when the
initial node list is built by \LUATEX's main control loop. You can enable these
@@ -642,15 +842,19 @@ kerning functions, i.e.\ by assigning dummy functions to their associated
callbacks. Keep in mind that when you define a font (using \LUA) you can also
omit the kern and ligature tables, which has the same effect as the above.
-\subsection{\type{\nospaces}}
+\stopsubsection
+
+\startsubsection[title={\type{\nospaces}}]
+
+\topicindex {spaces+suppress}
-This new primitive can be used to overrule the usual \type {\spaceskip}
-related heuristics when a space character is seen in a text flow. The
-value~\type{1} triggers no injection while \type{2} results in injection of
-a zero skip. Below we see the results for four characters separated by a
+This new primitive can be used to overrule the usual \prm {spaceskip} related
+heuristics when a space character is seen in a text flow. The value~\type{1}
+triggers no injection while \type{2} results in injection of a zero skip. In \in
+{figure} [fig:nospaces] we see the results for four characters separated by a
space.
-\startlinecorrection
+\startplacefigure[reference=fig:nospaces,title={The \lpr {nospaces} options.}]
\startcombination[3*2]
{\ruledhbox to 5cm{\vtop{\hsize 10mm\nospaces=0\relax x x x x \par}\hss}} {\type {0 / hsize 10mm}}
{\ruledhbox to 5cm{\vtop{\hsize 10mm\nospaces=1\relax x x x x \par}\hss}} {\type {1 / hsize 10mm}}
@@ -659,24 +863,30 @@ space.
{\ruledhbox to 5cm{\vtop{\hsize 1mm\nospaces=1\relax x x x x \par}\hss}} {\type {1 / hsize 1mm}}
{\ruledhbox to 5cm{\vtop{\hsize 1mm\nospaces=2\relax x x x x \par}\hss}} {\type {2 / hsize 1mm}}
\stopcombination
-\stoplinecorrection
+\stopplacefigure
+
+\stopsubsection
+
+\stopsection
+
+\startsection[title={Tokens, commands and strings}]
-\section{Tokens, commands and strings}
+\startsubsection[title={\lpr {scantextokens}}]
-\subsection{\type {\scantextokens}}
+\topicindex {tokens+scanning}
-The syntax of \type {\scantextokens} is identical to \type {\scantokens}. This
-primitive is a slightly adapted version of \ETEX's \type {\scantokens}. The
+The syntax of \lpr {scantextokens} is identical to \prm {scantokens}. This
+primitive is a slightly adapted version of \ETEX's \prm {scantokens}. The
differences are:
\startitemize
\startitem
- The last (and usually only) line does not have a \type {\endlinechar}
+ The last (and usually only) line does not have a \prm {endlinechar}
appended.
\stopitem
\startitem
- \type {\scantextokens} never raises an EOF error, and it does not execute
- \type {\everyeof} tokens.
+ \lpr {scantextokens} never raises an EOF error, and it does not execute
+ \prm {everyeof} tokens.
\stopitem
\startitem
There are no \quote {\unknown\ while end of file \unknown} error tests
@@ -685,7 +895,10 @@ differences are:
\stopitem
\stopitemize
-\subsection{\type {\toksapp}, \type {\tokspre}, \type {\etoksapp} and \type {\etokspre}}
+\stopsubsection
+
+\startsubsection[title={\lpr {toksapp}, \lpr {tokspre}, \lpr {etoksapp}, \lpr {etokspre},
+\lpr {gtoksapp}, \lpr {gtokspre}, \lpr {xtoksapp}, \lpr {xtokspre}}]
Instead of:
@@ -700,15 +913,17 @@ you can use:
\stoptyping
The \type {pre} variants prepend instead of append, and the \type {e} variants
-expand the passed general text.
+expand the passed general text. The \type {g} and \type {x} variants are global.
+
+\stopsubsection
-\subsection{\type {\csstring}, \type {\begincsname} and \type {\lastnamedcs}}
+\startsubsection[title={\prm {csstring}, \lpr {begincsname} and \lpr {lastnamedcs}}]
-These are somewhat special. The \type {\csstring} primitive is like
-\type {\string} but it omits the leading escape character. This can be
-somewhat more efficient that stripping it of afterwards.
+These are somewhat special. The \prm {csstring} primitive is like
+\prm {string} but it omits the leading escape character. This can be
+somewhat more efficient than stripping it afterwards.
-The \type {\begincsname} primitive is like \type {\csname} but doesn't create
+The \lpr {begincsname} primitive is like \prm {csname} but doesn't create
a relaxed equivalent when there is no such name. It is equivalent to
\starttyping
@@ -718,10 +933,8 @@ a relaxed equivalent when there is no such name. It is equivalent to
\stoptyping
The advantage is that it saves a lookup (don't expect much speedup) but more
-important is that it avoids using the \type {\if}.
-
-The \type {\lastnamedcs} is one that should be used with care. The above
-example could be written as:
+important is that it avoids using the \prm {if} test. The \lpr {lastnamedcs}
+is one that should be used with care. The above example could be written as:
\starttyping
\ifcsname foo\endcsname
@@ -731,9 +944,13 @@ example could be written as:
This is slightly more efficient than constructing the string twice (deep down in
\LUATEX\ this also involves some \UTF8 juggling), but probably more relevant is
-that it saves a few tokens and can make code a bit more more readable.
+that it saves a few tokens and can make code a bit more readable.
+
+\stopsubsection
-\subsection{\type {\clearmarks}}
+\startsubsection[title={\lpr {clearmarks}}]
+
+\topicindex {marks}
This primitive complements the \ETEX\ mark primitives and clears a mark class
completely, resetting all three connected mark texts to empty. It is an
@@ -743,71 +960,241 @@ immediate command.
\clearmarks <16-bit number>
\stopsyntax
-\subsection{\type{\letcharcode}}
+\stopsubsection
+
+\startsubsection[title={\lpr {alignmark} and \lpr {aligntab}}]
+
+The primitive \lpr {alignmark} duplicates the functionality of \type {#} inside
+alignment preambles, while \lpr {aligntab} duplicates the functionality of \type
+{&}.
-This primitive is still experimental but can be used to assign a meaning to an active
-character, as in:
+\stopsubsection
+
+\startsubsection[title={\lpr {letcharcode}}]
+
+This primitive can be used to assign a meaning to an active character, as in:
\starttyping
\def\foo{bar} \letcharcode123=\foo
\stoptyping
-This can be a bit nicer that using the uppercase tricks (using the property of
-\type {\uppercase} that it treats active characters special).
+This can be a bit nicer than using the uppercase tricks (using the property of
+\prm {uppercase} that it treats active characters special).
-\section{Boxes, rules and leaders}
+\stopsubsection
-\subsection{\type {\outputbox}}
+\startsubsection[title={\lpr {glet}}]
-\startsyntax
-\outputbox = 65535
-\stopsyntax
+This primitive is similar to:
+
+\starttyping
+\protected\def\glet{\global\let}
+\stoptyping
+
+but faster (only measurable with millions of calls) and probably more convenient
+(after all we also have \type {\gdef}).
+
+\stopsubsection
+
+\startsubsection[title={\lpr {expanded}, \lpr {immediateassignment} and \lpr {immediateassigned}}]
+
+\topicindex {expansion}
+
+The \lpr {expanded} primitive takes a token list and expands it content which can
+come in handy: it avoids a tricky mix of \prm {expandafter} and \prm {noexpand}.
+You can compare it with what happens inside the body of an \prm {edef}. But this
+kind of expansion it still doesn't expand some primitive operations.
+
+\startbuffer
+\newcount\NumberOfCalls
+
+\def\TestMe{\advance\NumberOfCalls1 }
+
+\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+
+\meaning\Tested
+\stopbuffer
+
+\typebuffer
+
+The result is a macro that has the not expanded code in its body:
+
+\getbuffer
+
+Instead we can define \tex {TestMe} in a way that expands the assignment
+immediately. You need of course to be aware of preventing look ahead interference
+by using a space or \tex {relax} (often an expression works better as it doesn't
+leave an \tex {relax}).
+
+\startbuffer
+\def\TestMe{\immediateassignment\advance\NumberOfCalls1 }
+
+\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+
+\meaning\Tested
+\stopbuffer
+
+\typebuffer
+
+This time the counter gets updates and we don't see interference in the
+resulting \tex {Tested} macro:
+
+\getbuffer
+
+Here is a somewhat silly example of expanded comparison:
+
+\startbuffer
+\def\expandeddoifelse#1#2#3#4%
+ {\immediateassignment\edef\tempa{#1}%
+ \immediateassignment\edef\tempb{#2}%
+ \ifx\tempa\tempb
+ \immediateassignment\def\next{#3}%
+ \else
+ \immediateassignment\def\next{#4}%
+ \fi
+ \next}
+
+\edef\Tested
+ {(\expandeddoifelse{abc}{def}{yes}{nop}/%
+ \expandeddoifelse{abc}{abc}{yes}{nop})}
+
+\meaning\Tested
+\stopbuffer
+
+\typebuffer
+
+It gives:
+
+\getbuffer
+
+A variant is:
+
+\starttyping
+\def\expandeddoifelse#1#2#3#4%
+ {\immediateassigned{
+ \edef\tempa{#1}%
+ \edef\tempb{#2}%
+ }%
+ \ifx\tempa\tempb
+ \immediateassignment\def\next{#3}%
+ \else
+ \immediateassignment\def\next{#4}%
+ \fi
+ \next}
+\stoptyping
+
+The possible error messages are the same as using assignments in preambles of
+alignments and after the \prm {accent} command. The supported assignments are the
+so called prefixed commands (except box assignments).
+
+\stopsubsection
+
+\startsubsection[title={\lpr {ifcondition}}]
+
+\topicindex {conditions}
+
+This is a somewhat special one. When you write macros conditions need to be
+properly balanced in order to let \TEX's fast branch skipping work well. This new
+primitive is basically a no||op flagged as a condition so that the scanner can
+recognize it as an if|-|test. However, when a real test takes place the work is
+done by what follows, in the next example \tex {something}.
+
+\starttyping
+\unexpanded\def\something#1#2%
+ {\edef\tempa{#1}%
+ \edef\tempb{#2}
+ \ifx\tempa\tempb}
+
+\ifcondition\something{a}{b}%
+ \ifcondition\something{a}{a}%
+ true 1
+ \else
+ false 1
+ \fi
+\else
+ \ifcondition\something{a}{a}%
+ true 2
+ \else
+ false 2
+ \fi
+\fi
+\stoptyping
+
+If you are familiar with \METAPOST, this is a bit like \type {vardef} where the macro
+has a return value. Here the return value is a test.
+
+\stopsubsection
-This new integer parameter allows you to alter the number of the box that will be
+\stopsection
+
+\startsection[title={Boxes, rules and leaders}]
+
+\startsubsection[title={\lpr {outputbox}}]
+
+\topicindex {output}
+
+This integer parameter allows you to alter the number of the box that will be
used to store the page sent to the output routine. Its default value is 255, and
the acceptable range is from 0 to 65535.
-\subsection{\type {\vpack}, \type {\hpack} and \type {\tpack}}
+\startsyntax
+\outputbox = 12345
+\stopsyntax
+
+\stopsubsection
-These three primitives are like \type {\vbox}, \type {\hbox} and \type {\vtop}
+\startsubsection[title={\prm {vpack}, \prm {hpack} and \prm {tpack}}]
+
+These three primitives are like \prm {vbox}, \prm {hbox} and \prm {vtop}
but don't apply the related callbacks.
-\subsection{\type {\vsplit}}
+\stopsubsection
+
+\startsubsection[title={\prm {vsplit}}]
+
+\topicindex {splitting}
-The \type {\vsplit} primitive has to be followed by a specification of the
-required height. As alternative for the \type {to} keyword you can use \type
-{upto} to get a split of the given size but result has the natural dimensions
-then.
+The \prm {vsplit} primitive has to be followed by a specification of the required
+height. As alternative for the \type {to} keyword you can use \type {upto} to get
+a split of the given size but result has the natural dimensions then.
-\subsection{Images and Forms}
+\stopsubsection
+
+\startsubsection[title={Images and reused box objects},reference=sec:imagedandforms]
These two concepts are now core concepts and no longer whatsits. They are in fact
now implemented as rules with special properties. Normal rules have subtype~0,
saved boxes have subtype~1 and images have subtype~2. This has the positive side
-effect that whenever we need to take content with dimensions into account, when we
-look at rule nodes, we automatically also deal with these two types.
+effect that whenever we need to take content with dimensions into account, when
+we look at rule nodes, we automatically also deal with these two types.
The syntax of the \type {\save...resource} is the same as in \PDFTEX\ but you
should consider them to be backend specific. This means that a macro package
should treat them as such and check for the current output mode if applicable.
-Here are the equivalents:
-\starttabulate[|l|l|]
-\NC \type {\saveboxresource} \EQ \type {\pdfxform} \NC \NR
-\NC \type {\saveimageresource} \EQ \type {\pdfximage} \NC \NR
-\NC \type {\useboxresource} \EQ \type {\pdfrefxform} \NC \NR
-\NC \type {\useimageresource} \EQ \type {\pdfrefximage} \NC \NR
-\NC \type {\lastsavedboxresourceindex} \EQ \type {\pdflastxform} \NC \NR
-\NC \type {\lastsavedimageresourceindex} \EQ \type {\pdflastximage} \NC \NR
-\NC \type {\lastsavedimageresourcepages} \EQ \type {\pdflastximagepages} \NC \NR
+\starttabulate[|l|p|]
+\DB command \BC explanation \NC \NR
+\TB
+\NC \lpr {saveboxresource} \NC save the box as an object to be included later \NC \NR
+\NC \lpr {saveimageresource} \NC save the image as an object to be included later \NC \NR
+\NC \lpr {useboxresource} \NC include the saved box object here (by index) \NC \NR
+\NC \lpr {useimageresource} \NC include the saved image object here (by index) \NC \NR
+\NC \lpr {lastsavedboxresourceindex} \NC the index of the last saved box object \NC \NR
+\NC \lpr {lastsavedimageresourceindex} \NC the index of the last saved image object \NC \NR
+\NC \lpr {lastsavedimageresourcepages} \NC the number of pages in the last saved image object \NC \NR
+\LL
\stoptabulate
\LUATEX\ accepts optional dimension parameters for \type {\use...resource} in the
same format as for rules. With images, these dimensions are then used instead of
-the ones given to \type {\useimageresource} but the original dimensions are not
-overwritten, so that a \type {\useimageresource} without dimensions still
-provides the image with dimensions defined by \type {\saveimageresource}. These
-optional parameters are not implemented for \type {\saveboxresource}.
+the ones given to \lpr {useimageresource} but the original dimensions are not
+overwritten, so that a \lpr {useimageresource} without dimensions still
+provides the image with dimensions defined by \lpr {saveimageresource}. These
+optional parameters are not implemented for \lpr {saveboxresource}.
\starttyping
\useimageresource width 20mm height 10mm depth 5mm \lastsavedimageresourceindex
@@ -820,35 +1207,51 @@ is the \type {type} key. When set to non|-|zero the \type {/Type} entry is
omitted. A value of 1 or 3 still writes a \type {/BBox}, while 2 or 3 will write
a \type {/Matrix}.
-\subsection{\type {\nohrule} and \type {\novrule}}
+\stopsubsection
+
+\startsubsection[title={\lpr {nohrule} and \lpr {novrule}}]
+
+\topicindex {rules}
Because introducing a new keyword can cause incompatibilities, two new primitives
-were introduced: \type {\nohrule} and \type {\novrule}. These can be used to
+were introduced: \lpr {nohrule} and \lpr {novrule}. These can be used to
reserve space. This is often more efficient than creating an empty box with fake
-dimensions).
+dimensions.
+
+\stopsubsection
-\subsection{\type {\gleaders}}
+\startsubsection[title={\lpr {gleaders}}]
+
+\topicindex {leaders}
This type of leaders is anchored to the origin of the box to be shipped out. So
-they are like normal \type {\leaders} in that they align nicely, except that the
+they are like normal \prm {leaders} in that they align nicely, except that the
alignment is based on the {\it largest\/} enclosing box instead of the {\it
smallest\/}. The \type {g} stresses this global nature.
-\section {Languages}
+\stopsubsection
+
+\stopsection
-\subsection{\type {\hyphenationmin}}
+\startsection[title={Languages}]
+
+\startsubsection[title={\lpr {hyphenationmin}}]
+
+\topicindex {languages}
+\topicindex {hyphenation}
This primitive can be used to set the minimal word length, so setting it to a value
of~$5$ means that only words of 6 characters and more will be hyphenated, of course
-within the constraints of the \type {\lefthyphenmin} and \type {\righthyphenmin}
+within the constraints of the \prm {lefthyphenmin} and \prm {righthyphenmin}
values (as stored in the glyph node). This primitive accepts a number and stores
the value with the language.
-\subsection{\type {\boundary}, \type {\noboundary}, \type {\protrusionboundary} and \type
-{\wordboundary}}
+\stopsubsection
+
+\startsubsection[title={\prm {boundary}, \prm {noboundary}, \prm {protrusionboundary} and \prm {wordboundary}}]
-The \type {\noboundary} commands used to inject a whatsit node but now injects a normal
-node with type \type {boundary} and subtype~0. In addition you can say:
+The \prm {noboundary} command is used to inject a whatsit node but now injects a normal
+node with type \nod {boundary} and subtype~0. In addition you can say:
\starttyping
x\boundary 123\relax y
@@ -858,31 +1261,57 @@ This has the same effect but the subtype is now~1 and the value~123 is stored.
The traditional ligature builder still sees this as a cancel boundary directive
but at the \LUA\ end you can implement different behaviour. The added benefit of
passing this value is a side effect of the generalization. The subtypes~2 and~3
-are used to control protrusion and word boundaries in hyphenation.
+are used to control protrusion and word boundaries in hyphenation and have
+related primitives.
-\section{Control and debugging}
+\stopsubsection
-\subsection {Tracing}
+\stopsection
-If \type {\tracingonline} is larger than~2, the node list display will also print
+\startsection[title={Control and debugging}]
+
+\startsubsection[title={Tracing}]
+
+\topicindex {tracing}
+
+If \prm {tracingonline} is larger than~2, the node list display will also print
the node number of the nodes.
-\subsection{\type {\outputmode} and \type {\draftmode}}
+\stopsubsection
-The \type {\outputmode} variable tells \LUATEX\ what it has to produce:
+\startsubsection[title={\lpr {outputmode}}]
+
+\topicindex {output}
+\topicindex {backend}
+
+The \lpr {outputmode} variable tells \LUATEX\ what it has to produce:
\starttabulate[|l|l|]
+\DB value \BC output \NC \NR
+\TB
\NC \type {0} \NC \DVI\ code \NC \NR
\NC \type {1} \NC \PDF\ code \NC \NR
+\LL
\stoptabulate
-The value of the \type {\draftmode} counter signals the backend if it should
-output less. The \PDF\ backend accepts a value of~$1$, while the \DVI\ backend
-ignores the value.
+\stopsubsection
+
+\startsubsection[title={\lpr {draftmode}}]
-\section {Files}
+The value of the \lpr {draftmode} counter signals the backend if it should output
+less. The \PDF\ backend accepts a value of~1, while the \DVI\ backend ignores the
+value. This is no critical feature so we can remove it in future versions when it
+can make the backend cleaner.
-\subsection{File syntax}
+\stopsubsection
+
+\stopsection
+
+\startsection[title={Files}]
+
+\startsubsection[title={File syntax}]
+
+\topicindex {files+names}
\LUATEX\ will accept a braced argument as a file name:
@@ -894,26 +1323,49 @@ ignores the value.
This allows for embedded spaces, without the need for double quotes. Macro
expansion takes place inside the argument.
-The \type {\tracingfonts} primitive that has been inherited from \PDFTEX\ has
+The \lpr {tracingfonts} primitive that has been inherited from \PDFTEX\ has
been adapted to support variants in reporting the font. The reason for this
extension is that a csname not always makes sense. The zero case is the default.
-\starttabulate[|T||]
-\NC 0 \EQ \type{\foo xyz} \NC \NR
-\NC 1 \EQ \type{\foo (bar)} \NC \NR
-\NC 2 \EQ \type{<bar> xyz} \NC \NR
-\NC 3 \EQ \type{<bar @ ..pt> xyz} \NC \NR
-\NC 4 \EQ \type{<id>} \NC \NR
-\NC 5 \EQ \type{<id: bar>} \NC \NR
-\NC 6 \EQ \type{<id: bar @ ..pt> xyz} \NC \NR
+\starttabulate[|l|l|]
+\DB value \BC reported \NC \NR
+\TB
+\NC \type{0} \NC \type{\foo xyz} \NC \NR
+\NC \type{1} \NC \type{\foo (bar)} \NC \NR
+\NC \type{2} \NC \type{<bar> xyz} \NC \NR
+\NC \type{3} \NC \type{<bar @ ..pt> xyz} \NC \NR
+\NC \type{4} \NC \type{<id>} \NC \NR
+\NC \type{5} \NC \type{<id: bar>} \NC \NR
+\NC \type{6} \NC \type{<id: bar @ ..pt> xyz} \NC \NR
+\LL
\stoptabulate
-\subsection{Writing to file}
+\stopsubsection
+
+\startsubsection[title={Writing to file}]
+
+\topicindex {files+writing}
-You can now open upto 127 files with \type {\openout}. When no file is open
+You can now open upto 127 files with \prm {openout}. When no file is open
writes will go to the console and log. As a consequence a system command is
no longer possible but one can use \type {os.execute} to do the same.
+\stopsubsection
+
+\stopsection
+
+\startsection[title={Math}]
+
+\topicindex {math}
+
+We will cover math extensions in its own chapter because not only the font
+subsystem and spacing model have been enhanced (thereby introducing many new
+primitives) but also because some more control has been added to existing
+functionality. Much of this relates to the different approaches of traditional
+\TEX\ fonts and \OPENTYPE\ math.
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/luatex/luatex-firstpage.tex b/doc/context/sources/general/manuals/luatex/luatex-firstpage.tex
new file mode 100644
index 000000000..772fbb3fe
--- /dev/null
+++ b/doc/context/sources/general/manuals/luatex/luatex-firstpage.tex
@@ -0,0 +1,32 @@
+\startcomponent luatex-firstpage
+
+\startstandardmakeup
+
+ \start
+ \raggedleft
+ \definedfont[Bold*default at 48pt]
+ \setupinterlinespace
+ \blue \documentvariable{manual} \endgraf Reference \endgraf Manual \endgraf
+ \stop
+
+ \vfill
+
+ \definedfont[Bold*default at 12pt]
+
+ \starttabulate[|l|l|]
+ \NC copyright \EQ Lua\TeX\ development team \NC \NR
+ \NC more info \EQ www.luatex.org \NC \NR
+ \NC version \EQ \currentdate \doifsomething{\documentvariable{snapshot}}{(snapshot \documentvariable{snapshot})} \NC \NR
+ \stoptabulate
+
+\stopstandardmakeup
+
+\setupbackgrounds
+ [leftpage]
+ [setups=pagenumber:left]
+
+\setupbackgrounds
+ [rightpage]
+ [setups=pagenumber:right]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luatex/luatex-fonts.tex b/doc/context/sources/general/manuals/luatex/luatex-fonts.tex
index ddb64d946..d49c63afe 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-fonts.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-fonts.tex
@@ -1,29 +1,31 @@
% language=uk
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-fonts
\startchapter[reference=fonts,title={Font structure}]
-\section {The font tables}
+\startsection[title={The font tables}]
+
+\topicindex {fonts}
+\topicindex {fonts+tables}
All \TEX\ fonts are represented to \LUA\ code as tables, and internally as
\CCODE~structures. All keys in the table below are saved in the internal font
-structure if they are present in the table returned by the \type {define_font}
+structure if they are present in the table returned by the \cbk {define_font}
callback, or if they result from the normal \TFM|/|\VF\ reading routines if there
-is no \type {define_font} callback defined.
+is no \cbk {define_font} callback defined.
The column \quote {\VF} means that this key will be created by the \type
{font.read_vf()} routine, \quote {\TFM} means that the key will be created by the
-\type {font.read_tfm()} routine, and \quote{used} means whether or not the
-\LUATEX\ engine itself will do something with the key.
-
-The top|-|level keys in the table are as follows:
+\type {font.read_tfm()} routine, and \quote {used} means whether or not the
+\LUATEX\ engine itself will do something with the key. The top|-|level keys in
+the table are as follows:
-\starttabulate[|l|c|c|c|l|p|]
-\BC key \BC vf \BC tfm \BC used \BC value type \BC description \NC \NR
+\starttabulate[|l|c|c|c|l|pl|]
+\DB key \BC vf \BC tfm \BC used \BC value type \BC description \NC \NR
+\TB
\NC \type{name} \NC yes \NC yes \NC yes \NC string \NC metric (file) name \NC \NR
\NC \type{area} \NC no \NC yes \NC yes \NC string \NC (directory) location, typically empty \NC \NR
\NC \type{used} \NC no \NC yes \NC yes \NC boolean \NC indicates usage (initial: false) \NC \NR
@@ -42,52 +44,61 @@ The top|-|level keys in the table are as follows:
\NC \type{fullname} \NC no \NC no \NC yes \NC string \NC output font name, used as a fallback in the \PDF\ output
if the \type {psname} is not set \NC \NR
\NC \type{header} \NC yes \NC no \NC no \NC string \NC header comments, if any \NC \NR
-\NC \type{hyphenchar} \NC no \NC no \NC yes \NC number \NC default: \TEX's \type {\hyphenchar} \NC \NR
+\NC \type{hyphenchar} \NC no \NC no \NC yes \NC number \NC default: \TEX's \prm {hyphenchar} \NC \NR
\NC \type{parameters} \NC no \NC yes \NC yes \NC hash \NC default: 7 parameters, all zero \NC \NR
-\NC \type{size} \NC no \NC yes \NC yes \NC number \NC loaded (at) size. (default: same as designsize) \NC \NR
-\NC \type{skewchar} \NC no \NC no \NC yes \NC number \NC default: \TEX's \type {\skewchar} \NC \NR
+\NC \type{size} \NC no \NC yes \NC yes \NC number \NC the required scaling (by default the same as designsize) \NC \NR
+\NC \type{skewchar} \NC no \NC no \NC yes \NC number \NC default: \TEX's \prm {skewchar} \NC \NR
\NC \type{type} \NC yes \NC no \NC yes \NC string \NC basic type of this font \NC \NR
\NC \type{format} \NC no \NC no \NC yes \NC string \NC disk format type \NC \NR
\NC \type{embedding} \NC no \NC no \NC yes \NC string \NC \PDF\ inclusion \NC \NR
\NC \type{filename} \NC no \NC no \NC yes \NC string \NC the name of the font on disk \NC \NR
\NC \type{tounicode} \NC no \NC yes \NC yes \NC number \NC When this is set to~1 \LUATEX\ assumes per|-|glyph
tounicode entries are present in the font. \NC \NR
-\NC \type{stretch} \NC no \NC no \NC yes \NC number \NC the \quote {stretch} value from \type
- {\expandglyphsinfont} \NC \NR
-\NC \type{shrink} \NC no \NC no \NC yes \NC number \NC the \quote {shrink} value from \type
- {\expandglyphsinfont} \NC \NR
-\NC \type{step} \NC no \NC no \NC yes \NC number \NC the \quote {step} value from \type
- {\expandglyphsinfont} \NC \NR
+\NC \type{stretch} \NC no \NC no \NC yes \NC number \NC the \quote {stretch} value from \lpr {expandglyphsinfont} \NC \NR
+\NC \type{shrink} \NC no \NC no \NC yes \NC number \NC the \quote {shrink} value from \lpr {expandglyphsinfont} \NC \NR
+\NC \type{step} \NC no \NC no \NC yes \NC number \NC the \quote {step} value from \lpr {expandglyphsinfont} \NC \NR
\NC \type{expansion_factor} \NC no \NC no \NC no \NC number \NC the actual expansion factor of an expanded font \NC \NR
-\NC \type{attributes} \NC no \NC no \NC yes \NC string \NC the \type {\pdffontattr} \NC \NR
+\NC \type{attributes} \NC no \NC no \NC yes \NC string \NC the \orm {pdffontattr} \NC \NR
\NC \type{cache} \NC no \NC no \NC yes \NC string \NC This key controls caching of the \LUA\ table on the
\TEX\ end where \type {yes} means: use a reference to
the table that is passed to \LUATEX\ (this is the
- default), and no \type {no} means: don't store the
+ default), and \type {no} means: don't store the
table reference, don't cache any \LUA\ data for this
font while \type {renew} means: don't store the table
reference, but save a reference to the table that is
- created at the first access to one of its fields in font.
- Note: the saved reference is thread|-|local, so be
- careful when you are using coroutines: an error will be
- thrown if the table has been cached in one thread, but
- you reference it from another thread. \NC \NR
+ created at the first access to one of its fields in the
+ font. \NC \NR
\NC \type{nomath} \NC no \NC no \NC yes \NC boolean \NC This key allows a minor speedup for text fonts. If it
is present and true, then \LUATEX\ will not check the
character entries for math|-|specific keys. \NC \NR
\NC \type{oldmath} \NC no \NC no \NC yes \NC boolean \NC This key flags a font as representing an old school \TEX\
math font and disables the \OPENTYPE\ code path. \NC \NR
-\NC \type{slant} \NC no \NC no \NC yes \NC number \NC This has the same semantics as the \type {SlantFont}
- operator in font map files. \NC \NR
-\NC \type{extent} \NC no \NC no \NC yes \NC number \NC This has the same semantics as the \type {ExtendFont}
- operator in font map files. \NC \NR
+\NC \type{slant} \NC no \NC no \NC yes \NC number \NC This parameter will tilt the font and
+ does the same as \type {SlantFont} in the map file for
+ \TYPEONE\ fonts. \NC \NR
+\NC \type{extend} \NC no \NC no \NC yes \NC number \NC This parameter will scale the font horizontally and
+ does the same as \type {ExtendFont} in the map file for
+ \TYPEONE\ fonts. \NC \NR
+\NC \type{squeeze} \NC no \NC no \NC yes \NC number \NC This parameter will scale the font vertically and has
+ no equivalent in the map file. \NC \NR
+\NC \type{width} \NC no \NC no \NC yes \NC number \NC The backend will inject \PDF\ operators that set the
+ penwidth. The value is (as usual in \TEX) divided by 1000.
+ It works with the \type {mode} file. \NC \NR
+\NC \type{mode} \NC no \NC no \NC yes \NC number \NC The backend will inject \PDF\ operators that relate to the
+ drawing mode with 0~being a fill, 1~being an outline,
+ 2~both draw and fill and 3~no painting at all. \NC \NR
+\LL
\stoptabulate
+The saved reference in the \type {cache} option is thread|-|local, so be careful
+when you are using coroutines: an error will be thrown if the table has been
+cached in one thread, but you reference it from another thread.
+
The key \type {name} is always required. The keys \type {stretch}, \type
{shrink}, \type {step} only have meaning when used together: they can be used to
-replace a post|-|loading \type {\expandglyphsinfont} command. The \type
-{auto_expand} option is not supported in \LUATEX. In fact, the primitives
-that create expanded or protruding copies are probably only useful when used with
+replace a post|-|loading \lpr {expandglyphsinfont} command. The \type
+{auto_expand} option is not supported in \LUATEX. In fact, the primitives that
+create expanded or protruding copies are probably only useful when used with
traditional fonts because all these extra \OPENTYPE\ properties are kept out of
the picture. The \type {expansion_factor} is value that can be present inside a
font in \type {font.fonts}. It is the actual expansion factor (a value between
@@ -112,16 +123,14 @@ makes sure that the font's definition is written to the output file (\DVI\ or
signalling the \quote {normal} direction for this font. There are sixteen
possibilities:
-\starttabulate[|c|c|c|c|]
-\BC number \BC meaning \BC number \BC meaning \NC \NR
-\NC \type{0} \NC \type{LT} \NC \type {8} \NC \type{TT} \NC \NR
-\NC \type{1} \NC \type{LL} \NC \type {9} \NC \type{TL} \NC \NR
-\NC \type{2} \NC \type{LB} \NC \type{10} \NC \type{TB} \NC \NR
-\NC \type{3} \NC \type{LR} \NC \type{11} \NC \type{TR} \NC \NR
-\NC \type{4} \NC \type{RT} \NC \type{12} \NC \type{BT} \NC \NR
-\NC \type{5} \NC \type{RL} \NC \type{13} \NC \type{BL} \NC \NR
-\NC \type{6} \NC \type{RB} \NC \type{14} \NC \type{BB} \NC \NR
-\NC \type{7} \NC \type{RR} \NC \type{15} \NC \type{BR} \NC \NR
+\starttabulate[|Tc|c|Tc|c|Tc|c|Tc|c|]
+\DB \# \BC dir \BC \# \BC dir \BC \# \BC dir \BC \# \BC dir \NC \NR
+\TB
+\NC 0 \NC LT \NC 4 \NC RT \NC 8 \NC TT \NC 12 \NC BT \NC \NR
+\NC 1 \NC LL \NC 5 \NC RL \NC 9 \NC TL \NC 13 \NC BL \NC \NR
+\NC 2 \NC LB \NC 6 \NC RB \NC 10 \NC TB \NC 14 \NC BB \NC \NR
+\NC 3 \NC LR \NC 7 \NC RR \NC 11 \NC TR \NC 15 \NC BR \NC \NR
+\LL
\stoptabulate
These are \OMEGA|-|style direction abbreviations: the first character indicates
@@ -138,7 +147,8 @@ gives a nicer user interface.
The names and their internal remapping are:
\starttabulate[|l|c|]
-\BC name \BC remapping \NC \NR
+\DB name \BC remapping \NC \NR
+\TB
\NC \type {slant} \NC 1 \NC \NR
\NC \type {space} \NC 2 \NC \NR
\NC \type {space_stretch} \NC 3 \NC \NR
@@ -146,6 +156,7 @@ The names and their internal remapping are:
\NC \type {x_height} \NC 5 \NC \NR
\NC \type {quad} \NC 6 \NC \NR
\NC \type {extra_space} \NC 7 \NC \NR
+\LL
\stoptabulate
The keys \type {type}, \type {format}, \type {embedding}, \type {fullname} and
@@ -159,37 +170,27 @@ virtual character whose ligatures and kerns are used to handle word boundary
processing. \type {right_boundary} is similar but not actually used for anything
(yet).
-Other index keys are ignored.
-
Each character hash itself is a hash. For example, here is the character \quote
-{f} (decimal 102) in the font \type {cmr10 at 10pt}:
+{f} (decimal 102) in the font \type {cmr10 at 10pt}. The numbers that represent
+dimensions are in scaled points.
\starttyping
[102] = {
- ['width'] = 200250,
- ['height'] = 455111,
- ['depth'] = 0,
- ['italic'] = 50973,
- ['kerns'] = {
+ ["width"] = 200250,
+ ["height"] = 455111,
+ ["depth"] = 0,
+ ["italic"] = 50973,
+ ["kerns"] = {
[63] = 50973,
[93] = 50973,
[39] = 50973,
[33] = 50973,
[41] = 50973
},
- ['ligatures'] = {
- [102] = {
- ['char'] = 11,
- ['type'] = 0
- },
- [108] = {
- ['char'] = 13,
- ['type'] = 0
- },
- [105] = {
- ['char'] = 12,
- ['type'] = 0
- }
+ ["ligatures"] = {
+ [102] = { ["char"] = 11, ["type"] = 0 },
+ [108] = { ["char"] = 13, ["type"] = 0 },
+ [105] = { ["char"] = 12, ["type"] = 0 }
}
}
\stoptyping
@@ -197,16 +198,17 @@ Each character hash itself is a hash. For example, here is the character \quote
The following top|-|level keys can be present inside a character hash:
\starttabulate[|l|c|c|c|l|p|]
-\BC key \BC vf \BC tfm \BC used \BC type \BC description \NC\NR
+\DB key \BC vf \BC tfm \BC used \BC type \BC description \NC\NR
+\TB
\NC \type{width} \NC yes \NC yes \NC yes \NC number \NC character's width, in sp (default 0) \NC\NR
\NC \type{height} \NC no \NC yes \NC yes \NC number \NC character's height, in sp (default 0) \NC\NR
\NC \type{depth} \NC no \NC yes \NC yes \NC number \NC character's depth, in sp (default 0) \NC\NR
\NC \type{italic} \NC no \NC yes \NC yes \NC number \NC character's italic correction, in sp (default zero) \NC\NR
\NC \type{top_accent} \NC no \NC no \NC maybe \NC number \NC character's top accent alignment place, in sp (default zero) \NC\NR
\NC \type{bot_accent} \NC no \NC no \NC maybe \NC number \NC character's bottom accent alignment place, in sp (default zero) \NC\NR
-\NC \type{left_protruding} \NC no \NC no \NC maybe \NC number \NC character's \type {\lpcode} \NC\NR
-\NC \type{right_protruding} \NC no \NC no \NC maybe \NC number \NC character's \type {\rpcode} \NC\NR
-\NC \type{expansion_factor} \NC no \NC no \NC maybe \NC number \NC character's \type {\efcode} \NC\NR
+\NC \type{left_protruding} \NC no \NC no \NC maybe \NC number \NC character's \lpr {lpcode} \NC\NR
+\NC \type{right_protruding} \NC no \NC no \NC maybe \NC number \NC character's \lpr {rpcode} \NC\NR
+\NC \type{expansion_factor} \NC no \NC no \NC maybe \NC number \NC character's \lpr {efcode} \NC\NR
\NC \type{tounicode} \NC no \NC no \NC maybe \NC string \NC character's \UNICODE\ equivalent(s), in \UTF|-|16BE hexadecimal format \NC\NR
\NC \type{next} \NC no \NC yes \NC yes \NC number \NC the \quote {next larger} character index \NC\NR
\NC \type{extensible} \NC no \NC yes \NC yes \NC table \NC the constituent parts of an extensible recipe \NC\NR
@@ -217,19 +219,17 @@ The following top|-|level keys can be present inside a character hash:
\NC \type{commands} \NC yes \NC no \NC yes \NC array \NC virtual font commands \NC\NR
\NC \type{name} \NC no \NC no \NC no \NC string \NC the character (\POSTSCRIPT) name \NC\NR
\NC \type{index} \NC no \NC no \NC yes \NC number \NC the (\OPENTYPE\ or \TRUETYPE) font glyph index \NC\NR
-\NC \type{used} \NC no \NC yes \NC yes \NC boolean \NC typeset already (default: false)? \NC\NR
+\NC \type{used} \NC no \NC yes \NC yes \NC boolean \NC typeset already (default: false) \NC\NR
\NC \type{mathkern} \NC no \NC no \NC yes \NC table \NC math cut-in specifications \NC\NR
+\LL
\stoptabulate
The values of \type {top_accent}, \type {bot_accent} and \type {mathkern} are
-used only for math accent and superscript placement, see the \at {math chapter}
-[math] in this manual for details.
-
-The values of \type {left_protruding} and \type {right_protruding} are used only
-when \type {\protrudechars} is non-zero.
-
-Whether or not \type {expansion_factor} is used depends on the font's global
-expansion settings, as well as on the value of \type {\adjustspacing}.
+used only for math accent and superscript placement, see \at {page} [math] in
+this manual for details. The values of \type {left_protruding} and \type
+{right_protruding} are used only when \lpr {protrudechars} is non-zero. Whether
+or not \type {expansion_factor} is used depends on the font's global expansion
+settings, as well as on the value of \lpr {adjustspacing}.
The usage of \type {tounicode} is this: if this font specifies a \type
{tounicode=1} at the top level, then \LUATEX\ will construct a \type {/ToUnicode}
@@ -245,24 +245,28 @@ enclosing angle brackets. For instance the \type {tounicode} for a \type {fi}
ligature would be \type {00660069}. When you pass a number the conversion will be
done for you.
-The presence of \type {extensible} will overrule \type {next}, if that is also
-present. It in in turn can be overruled by \type {vert_variants}.
-
-The \type {extensible} table is very simple:
+A math character can have a \type {next} field that points to a next larger
+shape. However, the presence of \type {extensible} will overrule \type {next}, if
+that is also present. The \type {extensible} field in turn can be overruled by
+\type {vert_variants}, the \OPENTYPE\ version. The \type {extensible} table is
+very simple:
\starttabulate[|l|l|p|]
-\BC key \BC type \BC description \NC\NR
+\DB key \BC type \BC description \NC\NR
+\TB
\NC \type{top} \NC number \NC top character index \NC\NR
\NC \type{mid} \NC number \NC middle character index \NC\NR
\NC \type{bot} \NC number \NC bottom character index \NC\NR
\NC \type{rep} \NC number \NC repeatable character index \NC\NR
+\LL
\stoptabulate
The \type {horiz_variants} and \type {vert_variants} are arrays of components.
Each of those components is itself a hash of up to five keys:
\starttabulate[|l|l|p|]
-\BC key \BC type \BC explanation \NC \NR
+\DB key \BC type \BC explanation \NC \NR
+\TB
\NC \type{glyph} \NC number \NC The character index. Note that this is an encoding number, not a name. \NC \NR
\NC \type{extender} \NC number \NC One (1) if this part is repeatable, zero (0) otherwise. \NC \NR
\NC \type{start} \NC number \NC The maximum overlap at the starting side (in scaled points). \NC \NR
@@ -270,11 +274,12 @@ Each of those components is itself a hash of up to five keys:
\NC \type{advance} \NC number \NC The total advance width of this item. It can be zero or missing,
then the natural size of the glyph for character \type {component}
is used. \NC \NR
+\LL
\stoptabulate
The \type {kerns} table is a hash indexed by character index (and \quote
{character index} is defined as either a non|-|negative integer or the string
-value \type {right_boundary}), with the values the kerning to be applied, in
+value \type {right_boundary}), with the values of the kerning to be applied, in
scaled points.
The \type {ligatures} table is a hash indexed by character index (and \quote
@@ -283,23 +288,25 @@ value \type {right_boundary}), with the values being yet another small hash, wit
two fields:
\starttabulate[|l|l|p|]
-\BC key \BC type \BC description \NC \NR
+\DB key \BC type \BC description \NC \NR
+\TB
\NC \type{type} \NC number \NC the type of this ligature command, default 0 \NC \NR
\NC \type{char} \NC number \NC the character index of the resultant ligature \NC \NR
+\LL
\stoptabulate
-The \type {char} field in a ligature is required.
-
-The \type {type} field inside a ligature is the numerical or string value of one
-of the eight possible ligature types supported by \TEX. When \TEX\ inserts a new
-ligature, it puts the new glyph in the middle of the left and right glyphs. The
-original left and right glyphs can optionally be retained, and when at least one
-of them is kept, it is also possible to move the new \quote {insertion point}
-forward one or two places. The glyph that ends up to the right of the insertion
-point will become the next \quote {left}.
+The \type {char} field in a ligature is required. The \type {type} field inside a
+ligature is the numerical or string value of one of the eight possible ligature
+types supported by \TEX. When \TEX\ inserts a new ligature, it puts the new glyph
+in the middle of the left and right glyphs. The original left and right glyphs
+can optionally be retained, and when at least one of them is kept, it is also
+possible to move the new \quote {insertion point} forward one or two places. The
+glyph that ends up to the right of the insertion point will become the next
+\quote {left}.
\starttabulate[|l|c|l|l|]
-\BC textual (Knuth) \BC number \BC string \BC result \NC\NR
+\DB textual (Knuth) \BC number \BC string \BC result \NC\NR
+\TB
\NC \type{l + r =: n} \NC 0 \NC \type{=:} \NC \type{|n} \NC\NR
\NC \type{l + r =:| n} \NC 1 \NC \type{=:|} \NC \type{|nr} \NC\NR
\NC \type{l + r |=: n} \NC 2 \NC \type{|=:} \NC \type{|ln} \NC\NR
@@ -308,6 +315,7 @@ point will become the next \quote {left}.
\NC \type{l + r |=:> n} \NC 6 \NC \type{|=:>} \NC \type{l|n} \NC\NR
\NC \type{l + r |=:|> n} \NC 7 \NC \type{|=:|>} \NC \type{l|nr} \NC\NR
\NC \type{l + r |=:|>> n} \NC 11 \NC \type{|=:|>>} \NC \type{ln|r} \NC\NR
+\LL
\stoptabulate
The default value is~0, and can be left out. That signifies a \quote {normal}
@@ -316,7 +324,12 @@ indicates the final insertion point.
The \type {commands} array is explained below.
-\section {Real fonts}
+\stopsection
+
+\startsection[title={Real fonts}]
+
+\topicindex {fonts+real}
+\topicindex {fonts+virtual}
Whether or not a \TEX\ font is a \quote {real} font that should be written to the
\PDF\ document is decided by the \type {type} value in the top|-|level font
@@ -325,141 +338,150 @@ inclusion mechanism will attempt to add the needed font object definitions to th
\PDF. Values for \type {type} are:
\starttabulate[|l|p|]
-\BC value \BC description \NC\NR
+\DB value \BC description \NC\NR
+\TB
\NC \type{real} \NC this is a base font \NC\NR
\NC \type{virtual} \NC this is a virtual font \NC\NR
+\LL
\stoptabulate
The actions to be taken depend on a number of different variables:
\startitemize[packed]
\startitem
- Whether the used font fits in an 8-bit encoding scheme or not.
+ Whether the used font fits in an 8-bit encoding scheme or not. This is true for
+ traditional \TEX\ fonts that communicate via \TFM\ files.
\stopitem
\startitem
- The type of the disk font file.
+ The type of the disk font file, for instance a bitmap file or an outline
+ \TYPEONE, \TRUETYPE\ or \OPENTYPE\ font.
\stopitem
\startitem
- The level of embedding requested.
+ The level of embedding requested, although in most cases a subset of
+ characters is embedded. The times when nothing got embedded are (in our
+ opinion at least) basically gone.
\stopitem
\stopitemize
A font that uses anything other than an 8-bit encoding vector has to be written
-to the \PDF\ in a different way.
-
-The rule is: if the font table has \type {encodingbytes} set to~2, then this is a
-wide font, in all other cases it isn't. The value~2 is the default for \OPENTYPE\
-and \TRUETYPE\ fonts loaded via \LUA. For \TYPEONE\ fonts, you have to set \type
-{encodingbytes} to~2 explicitly. For \PK\ bitmap fonts, wide font encoding is not
-supported at all.
-
-If no special care is needed, \LUATEX\ currently falls back to the
-mapfile|-|based solution used by \PDFTEX\ and \DVIPS. This behaviour might
-silently be removed in the future, in which case the related primitives and \LUA\
-functions will become no|-|ops.
-
-If a \quote {wide} font is used, the new subsystem kicks in, and some
-extra fields have to be present in the font structure. In this case, \LUATEX\
-does not use a map file at all.
-
-The extra fields are: \type {format}, \type {embedding}, \type {fullname}, \type
-{cidinfo} (as explained above), \type {filename}, and the \type {index} key in
-the separate characters.
-
-Values for \type {format} are:
+to the \PDF\ in a different way. When the font table has \type {encodingbytes}
+set to~2, then it is a wide font, in all other cases it isn't. The value~2 is the
+default for \OPENTYPE\ and \TRUETYPE\ fonts loaded via \LUA. For \TYPEONE\ fonts,
+you have to set \type {encodingbytes} to~2 explicitly. For \PK\ bitmap fonts,
+wide font encoding is not supported at all.
+
+If no special care is needed, \LUATEX\ falls back to the mapfile|-|based solution
+used by \PDFTEX\ and \DVIPS, so that legacy fonts are supported transparently. If
+a \quote {wide} font is used, the new subsystem kicks in, and some extra fields
+have to be present in the font structure. In this case, \LUATEX\ does not use a
+map file at all. These extra fields are: \type {format}, \type {embedding}, \type
+{fullname}, \type {cidinfo} (as explained above), \type {filename}, and the \type
+{index} key in the separate characters.
+
+The \type {format} variable can have the following values. \type {type3} fonts
+are provided for backward compatibility only, and do not support the new wide
+encoding options.
\starttabulate[|l|p|]
-\BC value \BC description \NC \NR
+\DB value \BC description \NC \NR
+\TB
\NC \type{type1} \NC this is a \POSTSCRIPT\ \TYPEONE\ font \NC \NR
\NC \type{type3} \NC this is a bitmapped (\PK) font \NC \NR
\NC \type{truetype} \NC this is a \TRUETYPE\ or \TRUETYPE|-|based \OPENTYPE\ font \NC \NR
\NC \type{opentype} \NC this is a \POSTSCRIPT|-|based \OPENTYPE\ font \NC \NR
+\LL
\stoptabulate
-\type {type3} fonts are provided for backward compatibility only, and do not
-support the new wide encoding options.
-
-Values for \type {embedding} are:
+Valid values for the \type {embedding} variable are:
\starttabulate[|l|p|]
-\BC value \BC description \NC \NR
+\DB value \BC description \NC \NR
+\TB
\NC \type{no} \NC don't embed the font at all \NC \NR
\NC \type{subset} \NC include and atttempt to subset the font \NC \NR
\NC \type{full} \NC include this font in its entirety \NC \NR
+\LL
\stoptabulate
-The other fields are used as follows: The \type {fullname} will be the
+The other fields are used as follows. The \type {fullname} will be the
\POSTSCRIPT|/|\PDF\ font name. The \type {cidinfo} will be used as the character
-set (the CID \type {/Ordering} and \type {/Registry} keys). The \type {filename}
+set: the CID \type {/Ordering} and \type {/Registry} keys. The \type {filename}
points to the actual font file. If you include the full path in the \type
{filename} or if the file is in the local directory, \LUATEX\ will run a little
-bit more efficient because it will not have to re|-|run the \type {find_xxx_file}
+bit more efficient because it will not have to re|-|run the \type {find_*_file}
callback in that case.
Be careful: when mixing old and new fonts in one document, it is possible to
create \POSTSCRIPT\ name clashes that can result in printing errors. When this
-happens, you have to change the \type {fullname} of the font.
+happens, you have to change the \type {fullname} of the font to a more unique
+one.
Typeset strings are written out in a wide format using 2~bytes per glyph, using
the \type {index} key in the character information as value. The overall effect
is like having an encoding based on numbers instead of traditional (\POSTSCRIPT)
-name|-|based reencoding. The way to get the correct \type {index} numbers for
-\TYPEONE\ fonts is by loading the font via \type {fontloader.open} and use the table
-indices as \type {index} fields.
+name|-|based reencoding. One way to get the correct \type {index} numbers for
+\TYPEONE\ fonts is by loading the font via \type {fontloader.open} and use the
+table indices as \type {index} fields.
In order to make sure that cut and paste of the final document works okay you can
-best make sure that there is a \type {tounicode} vector enforced.
+best make sure that there is a \type {tounicode} vector enforced. Not all \PDF\
+viewers handle this right so take \ACROBAT\ as reference.
+
+\stopsection
-\section[virtualfonts]{Virtual fonts}
+\startsection[reference=virtualfonts,title={Virtual fonts}]
\subsection{The structure}
+\topicindex {fonts+virtual}
+
You have to take the following steps if you want \LUATEX\ to treat the returned
-table from \type {define_font} as a virtual font:
+table from \cbk {define_font} as a virtual font:
\startitemize[packed]
\startitem
- Set the top|-|level key \type {type} to \type {virtual}.
+ Set the top|-|level key \type {type} to \type {virtual}. In most cases it's
+ optional because we look at the \type {commands} entry anyway.
\stopitem
\startitem
- Make sure there is at least one valid entry in \type {fonts} (see below).
+ Make sure there is at least one valid entry in \type {fonts} (see below),
+ although recent versions of \LUATEX\ add a default entry when this table is
+ missing.
\stopitem
\startitem
- Give a \type {commands} array to every character (see below).
+ Add a \type {commands} array to those characters that matter. A virtual
+ character can itself point to virtual characters but be careful with nesting
+ as you can create loops and overflow the stack (which often indicates an
+ error anyway).
\stopitem
\stopitemize
The presence of the toplevel \type {type} key with the specific value \type
{virtual} will trigger handling of the rest of the special virtual font fields in
the table, but the mere existence of 'type' is enough to prevent \LUATEX\ from
-looking for a virtual font on its own.
-
-Therefore, this also works \quote {in reverse}: if you are absolutely certain
-that a font is not a virtual font, assigning the value \type {base} or \type
-{real} to \type {type} will inhibit \LUATEX\ from looking for a virtual font
-file, thereby saving you a disk search.
+looking for a virtual font on its own. This also works \quote {in reverse}: if
+you are absolutely certain that a font is not a virtual font, assigning the value
+\type {real} to \type {type} will inhibit \LUATEX\ from looking for a virtual
+font file, thereby saving you a disk search. This only matters when we load a
+\TFM\ file.
-The \type {fonts} is another \LUA\ array. The values are one- or two|-|key
+The \type {fonts} is an (indexed) \LUA\ table. The values are one- or two|-|key
hashes themselves, each entry indicating one of the base fonts in a virtual font.
In case your font is referring to itself, you can use the \type {font.nextid()}
function which returns the index of the next to be defined font which is probably
-the currently defined one.
-
-An example makes this easy to understand
+the currently defined one. So, a table looks like this:
\starttyping
fonts = {
- { name = 'ptmr8a', size = 655360 },
- { name = 'psyr', size = 600000 },
- { id = 38 }
+ { name = "ptmr8a", size = 655360 },
+ { name = "psyr", size = 600000 },
+ { id = 38 }
}
\stoptyping
-says that the first referenced font (index 1) in this virtual font is \type
-{ptrmr8a} loaded at 10pt, and the second is \type {psyr} loaded at a little over
-9pt. The third one is previously defined font that is known to \LUATEX\ as font id
-\quote {38}.
-
+The first referenced font (at index~1) in this virtual font is \type {ptrmr8a}
+loaded at 10pt, and the second is \type {psyr} loaded at a little over 9pt. The
+third one is a previously defined font that is known to \LUATEX\ as font id~38.
The array index numbers are used by the character command definitions that are
part of each character.
@@ -468,7 +490,8 @@ with the first entry representing a command and the extra items being the
parameters to that command. The allowed commands and their arguments are:
\starttabulate[|l|l|l|p|]
-\BC command name \BC arguments \BC type \BC description \NC \NR
+\DB command \BC arguments \BC type \BC description \NC \NR
+\TB
\NC \type{font} \NC 1 \NC number \NC select a new font from the local \type {fonts} table \NC \NR
\NC \type{char} \NC 1 \NC number \NC typeset this character number from the current font,
and move right by the character's width \NC \NR
@@ -481,18 +504,20 @@ parameters to that command. The allowed commands and their arguments are:
\NC \type{rule} \NC 2 \NC 2 numbers \NC output a rule $ht*wd$, and move right. \NC \NR
\NC \type{down} \NC 1 \NC number \NC move down on the page \NC \NR
\NC \type{right} \NC 1 \NC number \NC move right on the page \NC \NR
-\NC \type{special} \NC 1 \NC string \NC output a \type {\special} command \NC \NR
+\NC \type{special} \NC 1 \NC string \NC output a \prm {special} command \NC \NR
\NC \type{pdf} \NC 2 \NC 2 strings \NC output a \PDF\ literal, the first string is one of \type {origin},
\type {page}, \type {text}, \type {font}, \type {direct} or \type {raw}; if you
have one string only \type {origin} is assumed \NC \NR
-\NC \type{lua} \NC 1 \NC string \NC execute a \LUA\ script (at \type {\latelua} time) \NC \NR
-\NC \type{image} \NC 1 \NC image \NC output an image (the argument can be either an \type
- {<image>} variable or an \type {image_spec} table) \NC \NR
+\NC \type{lua} \NC 1 \NC string,
+ function \NC execute a \LUA\ script when the glyph is embedded; in case of a
+ function it gets the font id and character code passed \NC \NR
+\NC \type{image} \NC 1 \NC image \NC output an image (the argument can be either an \type {<image>} variable or an \type {image_spec} table) \NC \NR
\NC \type{comment} \NC any \NC any \NC the arguments of this command are ignored \NC \NR
+\LL
\stoptabulate
When a font id is set to~0 then it will be replaced by the currently assigned
-font id. This prevents the need for hackery with future id's (normally one could
+font id. This prevents the need for hackery with future id's. Normally one could
use \type {font.nextid} but when more complex fonts are built in the meantime
other instances could have been loaded.
@@ -500,24 +525,24 @@ The \type {pdf} option also accepts a \type {mode} keyword in which case the
third argument sets the mode. That option will change the mode in an efficient
way (passing an empty string would result in an extra empty lines in the \PDF\
file. This option only makes sense for virtual fonts. The \type {font} mode only
-makes sense in virtual fonts.
-
-These modes are somewhat fuzzy and partially inherited from \PDFTEX.
+makes sense in virtual fonts. Modes are somewhat fuzzy and partially inherited
+from \PDFTEX.
\starttabulate[|l|p|]
-\BC mode \BC description \NC \NR
+\DB mode \BC description \NC \NR
+\TB
\NC \type {origin} \NC enter page mode and set the position \NC \NR
\NC \type {page} \NC enter page mode \NC \NR
\NC \type {text} \NC enter text mode \NC \NR
\NC \type {font} \NC enter font mode (kind of text mode, only in virtual fonts) \NC \NR
\NC \type {always} \NC finish the current string and force a transform if needed \NC \NR
\NC \type {raw} \NC finish the current string \NC \NR
+\LL
\stoptabulate
-You always need to check what \PDF\ code is generated because there can be all kind of
-interferences with optimizations in the backend and fonts are complicated anyway.
-
-Here is a rather elaborate glyph commands example:
+You always need to check what \PDF\ code is generated because there can be all
+kind of interferences with optimization in the backend and fonts are complicated
+anyway. Here is a rather elaborate glyph commands example using such keys:
\starttyping
...
@@ -526,6 +551,7 @@ commands = {
{ "right", 5000 }, -- move right about 0.08pt
{ "font", 3 }, -- select the fonts[3] entry
{ "char", 97 }, -- place character 97 (ASCII 'a')
+ -- { "slot", 2, 97 }, -- an alternative for the previous two
{ "pop" }, -- go all the way back
{ "down", -200000 }, -- move upwards by about 3pt
{ "special", "pdf: 1 0 0 rg" } -- switch to red color
@@ -539,7 +565,7 @@ commands = {
The default value for \type {font} is always~1 at the start of the
\type {commands} array. Therefore, if the virtual font is essentially only a
-re|-|encoding, then you do usually not have create an explicit \quote {font}
+re|-|encoding, then you do usually not have created an explicit \quote {font}
command in the array.
Rules inside of \type {commands} arrays are built up using only two dimensions:
@@ -572,6 +598,8 @@ characters that are already present cannot be altered).
\subsection{Example virtual font}
+\topicindex {fonts+virtual}
+
Finally, here is a plain \TEX\ input file with a virtual font demonstration:
\startbuffer
@@ -579,58 +607,65 @@ Finally, here is a plain \TEX\ input file with a virtual font demonstration:
callback.register('define_font',
function (name,size)
if name == 'cmr10-red' then
- f = font.read_tfm('cmr10',size)
- f.name = 'cmr10-red'
- f.type = 'virtual'
- f.fonts = {{ name = 'cmr10', size = size }}
+ local f = font.read_tfm('cmr10',size)
+ f.name = 'cmr10-red'
+ f.type = 'virtual'
+ f.fonts = {
+ { name = 'cmr10', size = size }
+ }
for i,v in pairs(f.characters) do
- if (string.char(i)):find('[tacohanshartmut]') then
+ if string.char(i):find('[tacohanshartmut]') then
v.commands = {
- {'special','pdf: 1 0 0 rg'},
- {'char',i},
- {'special','pdf: 0 g'},
+ { "special", "pdf: 1 0 0 rg" },
+ { "char", i },
+ { "special", "pdf: 0 g" },
}
- else
- v.commands = {{'char',i}}
end
end
+ return f
else
- f = font.read_tfm(name,size)
+ return font.read_tfm(name,size)
end
- return f
end
)
}
-\font\myfont = cmr10-red at 10pt \myfont This is a line of text \par
-\font\myfontx= cmr10 at 10pt \myfontx Here is another line of text \par
+\font\myfont = cmr10-red at 10pt \myfont This is a line of text \par
+\font\myfontx = cmr10 at 10pt \myfontx Here is another line of text \par
\stopbuffer
\typebuffer
-\section{The \type {vf} library}
+\stopsection
+
+\startsection[title={The \type {vf} library}]
The \type {vf} library can be used when \LUA\ code, as defined in the \type
{commands} of the font, is executed. The functions provided are similar as the
commands: \type {char}, \type {down}, \type {fontid}, \type {image}, \type
-{node}, \type {nop}, \type {pop}, \type {push}, \type {right}, \type {rule},
-\type {special} and \type {pdf}. This library has been present for a while but
-not been advertised and tested much, if only because it's easy to define an
-invalid font (or mess up the \PDF\ stream). Keep in mind that the \LUA\ snippets
-are executed each time when a character is output.
+{node}, \type {nop}, \type {pop}, \type {push}, \type {right}, \nod {rule}, \type
+{special} and \type {pdf}. This library has been present for a while but not been
+advertised and tested much, if only because it's easy to define an invalid font
+(or mess up the \PDF\ stream). Keep in mind that the \LUA\ snippets are executed
+each time when a character is output.
+
+\stopsection
+\startsection[title={The \type {font} library}]
-\section{The \type {font} library}
+\topicindex {fonts+library}
The font library provides the interface into the internals of the font system,
-and also it contains helper functions to load traditional \TEX\ font metrics
+and it also contains helper functions to load traditional \TEX\ font metrics
formats. Other font loading functionality is provided by the \type {fontloader}
library that will be discussed in the next section.
\subsection{Loading a \TFM\ file}
-The behavior documented in this subsection is considered stable in the sense that
-there will not be backward-incompatible changes any more.
+\topicindex {fonts+tfm}
+
+The behaviour documented in this subsection is considered stable in the sense that
+there will not be backward|-|incompatible changes any more.
\startfunctioncall
<table> fnt =
@@ -649,11 +684,10 @@ The number is a bit special:
\stopitem
\stopitemize
-The internal structure of the metrics font table that is returned is explained in
-\in {chapter} [fonts].
-
\subsection{Loading a \VF\ file}
+\topicindex {fonts+vf}
+
The behavior documented in this subsection is considered stable in the sense that
there will not be backward-incompatible changes any more.
@@ -663,10 +697,12 @@ there will not be backward-incompatible changes any more.
\stopfunctioncall
The meaning of the number \type {s} and the format of the returned table are
-similar to the ones in the \type {read_tfm()} function.
+similar to the ones in the \type {read_tfm} function.
\subsection{The fonts array}
+\topicindex {fonts+virtual}
+
The whole table of \TEX\ fonts is accessible from \LUA\ using a virtual array.
\starttyping
@@ -674,9 +710,8 @@ font.fonts[n] = { ... }
<table> f = font.fonts[n]
\stoptyping
-See \in {chapter} [fonts] for the structure of the tables. Because this is a
-virtual array, you cannot call \type {pairs} on it, but see below for the \type
-{font.each} iterator.
+Because this is a virtual array, you cannot call \type {pairs} on it, but see
+below for the \type {font.each} iterator.
The two metatable functions implementing the virtual array are:
@@ -686,9 +721,15 @@ font.setfont(<number> n, <table> f)
\stopfunctioncall
Note that at the moment, each access to the \type {font.fonts} or call to \type
-{font.getfont} creates a \LUA\ table for the whole font. This process can be quite
-slow. In a later version of \LUATEX, this interface will change (it will start
-using userdata objects instead of actual tables).
+{font.getfont} creates a \LUA\ table for the whole font unless you cached it.
+This process can be quite slow.
+
+\startfunctioncall
+<table> p = font.getparameters(<number> n)
+\stopfunctioncall
+
+This one will return a table of the parameters as known to \TEX. These can be
+different from the ones in the cached table.
Also note the following: assignments can only be made to fonts that have already
been defined in \TEX, but have not been accessed {\it at all\/} since that
@@ -709,6 +750,8 @@ changed) or \type {nil} (not a valid font at all).
\subsection{Defining a font directly}
+\topicindex {fonts+define}
+
You can define your own font into \type {font.fonts} by calling this function:
\startfunctioncall
@@ -717,9 +760,8 @@ You can define your own font into \type {font.fonts} by calling this function:
\stopfunctioncall
The return value is the internal id number of the defined font (the index into
-\type {font.fonts}). If the font creation fails, an error is raised. The table
-is a font structure, as explained in \in {chapter} [fonts]. An alternative call
-is:
+\type {font.fonts}). If the font creation fails, an error is raised. The table is
+a font structure. An alternative call is:
\startfunctioncall
<number> i =
@@ -730,6 +772,8 @@ Where the first argument is a reserved font id (see below).
\subsection{Extending a font}
+\topicindex {fonts+extend}
+
Within reasonable bounds you can extend a font after it has been defined. Because
some properties are best left unchanged this is limited to adding characters.
@@ -747,6 +791,8 @@ a more drastic replacer.)
\subsection{Projected next font id}
+\topicindex {fonts+id}
+
\startfunctioncall
<number> i =
font.nextid()
@@ -763,36 +809,37 @@ This can be handy when you create complex virtual fonts.
font.nextid(true)
\stopfunctioncall
-\subsection{Font id}
+\subsection{Font ids}
+
+\topicindex {fonts+id}
+\topicindex {fonts+current}
\startfunctioncall
<number> i =
font.id(<string> csname)
\stopfunctioncall
-This returns the font id associated with \type {csname} string, or $-1$ if \type
+This returns the font id associated with \type {csname}, or $-1$ if \type
{csname} is not defined.
-\subsection{Currently active font}
-
\startfunctioncall
-<number> i = font.current()
-font.current(<number> i)
+<number> i =
+ font.max()
\stopfunctioncall
-This gets or sets the currently used font number.
-
-\subsection{Maximum font id}
+This is the largest used index in \type {font.fonts}.
\startfunctioncall
-<number> i =
- font.max()
+<number> i = font.current()
+font.current(<number> i)
\stopfunctioncall
-This is the largest used index in \type {font.fonts}.
+This gets or sets the currently used font number.
\subsection{Iterating over all fonts}
+\topicindex {fonts+iterate}
+
\startfunctioncall
for i,v in font.each() do
...
@@ -804,6 +851,8 @@ value is the index in \type {font.fonts}, the second the font itself, as a \LUA\
table. The indices are listed incrementally, but they do not always form an array
of consecutive numbers: in some cases there can be holes in the sequence.
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/luatex/luatex-introduction.tex b/doc/context/sources/general/manuals/luatex/luatex-introduction.tex
index d0899147d..5ed80f4c1 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-introduction.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-introduction.tex
@@ -1,7 +1,6 @@
% language=uk
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-introduction
@@ -15,9 +14,9 @@ Additional reference material is published in journals of user groups and
It took about a decade to reach stable version 1.0, but for good reason.
Successive versions brought new functionality, more control, some cleanup of
-internals and experimental features evolved into stable ones or were dropped.
+internals. Experimental features evolved into stable ones or were dropped.
Already quite early \LUATEX\ could be used for production and it was used on a
-daily basis by the authors. Successive versions sometimes demanded a adaption to
+daily basis by the authors. Successive versions sometimes demanded an adaption to
the \LUA\ interfacing, but the concepts were unchanged. The current version can
be considered stable in functionality and there will be no fundamental changes.
Of course we then can decide to move towards version 2.00 with different
@@ -26,9 +25,10 @@ properties.
Don't expect \LUATEX\ to behave the same as \PDFTEX ! Although the core
functionality of that 8 bit engine was starting point, it has been combined with
the directional support of \OMEGA\ (\ALEPH). But, \LUATEX\ can behave different
-due to its wide (32 bit) characters, many registers and large memory support.
-There is native \UTF\ input, support for large (more that 8 bit) fonts, and the
-math machinery is tuned for \OPENTYPE\ math. There is support for directional
+due to its wide (32 bit) characters, many registers and large memory support. The
+\PDF\ code produced differs from \PDFTEX\ but users will normally not notice
+that. There is native \UTF\ input, support for large (more than 8 bit) fonts, and
+the math machinery is tuned for \OPENTYPE\ math. There is support for directional
typesetting too. The log output can differ from other engines and will likely
differ more as we move forward. When you run plain \TEX\ for sure \LUATEX\ runs
slower than \PDFTEX\ but when you run for instance \CONTEXT\ \MKIV\ in many cases
@@ -47,27 +47,29 @@ The organization of the source code is adapted so that it can glue all these
components together. We continue cleaning up side effects of the accumulated
code in \TEX\ engines (especially code that is not needed any longer).
-\startitemize[packed]
+\startitemize [unpacked]
\startitem
- Most of \PDFTEX\ version 1.40.9, converted to \CCODE. Some experimental
- features have been removed and some utility macros are not inherited as
- their functionality can be done in \LUA. The number of backend interface
- commands has been reduced to a few. The extensions are separated from the
- core (which we keep close to the original \TEX\ core). Some mechanisms
- like expansion and protrusion can behave different from the original due
- to some cleanup and optimization. Some whatsit based functionality (image
- support and reusable content) is now core functionality.
+ We started out with most of \PDFTEX\ version 1.40.9. The code base was
+ converted to \CCODE\ and split in modules. Experimental features were
+ removed and utility macros are not inherited because their functionality
+ can be programmed in \LUA. The number of backend interface commands has
+ been reduced to a few. The so called extensions are separated from the
+ core (which we try to keep close to the original \TEX\ core). Some
+ mechanisms like expansion and protrusion can behave different from the
+ original due to some cleanup and optimization. Some whatsit based
+ functionality (image support and reusable content) is now core
+ functionality. We don't stay in sync with \PDFTEX\ development.
\stopitem
\startitem
- The direction model and some other bits from \ALEPH\ RC4 (derived from
- \OMEGA) is included. The related primitives are part of core \LUATEX\ but
- at the node level directional support is no longer based on so called
- whatsits but on real nodes. In fact, whatsits are now only used for
- backend specific extensions.
+ The direction model from \ALEPH\ RC4 (which is derived from \OMEGA) is
+ included. The related primitives are part of core \LUATEX\ but at the
+ node level directional support is no longer based on so called whatsits
+ but on real nodes with relevant properties. The number of directions is
+ limited to the useful set and the backend has been made direction aware.
\stopitem
\startitem
Neither \ALEPH's I/O translation processes, nor tcx files, nor \ENCTEX\
- can be used, these encoding|-|related functions are superseded by a
+ are available. These encoding|-|related functions are superseded by a
\LUA|-|based solution (reader callbacks). In a similar fashion all file
\IO\ can be intercepted.
\stopitem
@@ -80,14 +82,18 @@ code in \TEX\ engines (especially code that is not needed any longer).
\startitem
There are various \TEX\ extensions but only those that cannot be done
using the \LUA\ interfaces. The math machinery often has two code paths:
- one traditional and the other more suitable for wide \OPENTYPE\ fonts.
+ one traditional and the other more suitable for wide \OPENTYPE\ fonts. Here
+ we follow the \MICROSOFT\ specifications as much as possible. Some math
+ functionality has been opened up a bit so that users have more control.
\stopitem
\startitem
The fontloader uses parts of \FONTFORGE\ 2008.11.17 combined with
additional code specific for usage in a \TEX\ engine. We try to minimize
specific font support to what \TEX\ needs: character references and
dimensions and delegate everything else to \LUA. That way we keep \TEX\
- open for extensions without touching the core.
+ open for extensions without touching the core. In order to minimize
+ dependencies at some point we may decide to make this an optional
+ library.
\stopitem
\startitem
The \METAPOST\ library is integral part of \LUATEX. This gives \TEX\ some
@@ -95,33 +101,71 @@ code in \TEX\ engines (especially code that is not needed any longer).
Again \LUA\ is used as glue between the frontend and backend. Further
development of \METAPOST\ is closely related to \LUATEX.
\stopitem
+ \startitem
+ The virtual font technology that comes with \TEX\ has been integrated
+ into the font machinery in a way that permits creating virtual fonts
+ at runtime. Because \LUATEX\ can also act as a \LUA\ interpreter this
+ means that a complete \TEX\ workflow can be built without the need for
+ additional programs.
+ \stopitem
+ \startitem
+ The versions starting from 1.09 no longer use the poppler library for
+ inclusion but a lightweight dedicated one. This removes a dependency but
+ also makes the inclusion code of \LUATEX\ different from \PDFTEX. In fact
+ it was already much different due to the \LUA\ image interfacing.
+ \stopitem
\stopitemize
We try to keep upcoming versions compatible but intermediate releases can contain
-experimental features. A general rule is that versions that end up on \TEX live
-and|/|or are released around \CONTEXT\ meetings are stable. Future versions will
-probably become a bit leaner and meaner. Some libraries might become external as
-we don't want to bloat the binary and also don't want to add more hard coded
-solutions. After all, with \LUA\ you can extend the core functionality. The less
-dependencies, the better.
-
-The \TEXLIVE\ version is to be considered the current stable version. Any version
-between the yearly \TEXLIVE\ releases are to be considered beta. The beta
-releases are normally available via the \CONTEXT\ distribution channels (the
-garden and so called minimals).
-
-\blank[1*big]
-
-Hans Hagen, Harmut Henkel, \crlf
-Taco Hoekwater \& Luigi Scarso
+experimental features. A general rule is that versions that end up on \TEXLIVE\
+and|/|or are released around \CONTEXT\ meetings are stable. Any version between
+the yearly \TEXLIVE\ releases are to be considered beta and in the repository end
+up as trunk releases. We have an experimental branch that we use for development
+but there is no support for any of its experimental features. Intermediate
+releases (from trunk) are normally available via the \CONTEXT\ distribution
+channels (the garden and so called minimals).
+
+Version 1.10 is more or less an endpoint in development: this is what you get.
+Because not only \CONTEXT, that we can adapt rather easily, uses \LUATEX, we
+cannot change fundamentals without unforeseen consequences. By now it has been
+proven that \LUA\ can be used to extend the core functionality so there is no
+need to add more, and definitely no hard coded solutions for (not so) common
+problems. Of course there will be bug fixes, maybe some optimization, and there
+might even be some additions or non|-|intrusive improvements, but only after
+testing outside the stable release. After all, the binary is already more than
+large enough and there is not that much to gain.
+
+You might find \LUA\ helpers that are not yet documented. These are considered
+experimental, although when you encounter them in a \CONTEXT\ version that has
+been around for a while you can assume that they will stay. Of course it can just
+be that we forgot to document them yet.
+
+A manual like this is not really meant as tutorial, for that we refer to
+documents that ship with \CONTEXT, articles, etc. It is also never complete
+enough for all readers. We try to keep up but the reader needs to realize that
+it's all volunteer work done in spare time. And for sure, complaining about a bad
+manual or crappy documentation will not really motivate us to spend more time on
+it. That being said, we hope that this document is useful.
+
+\blank[big]
+
+\testpage[5]
+
+\startlines
+Hans Hagen
+Harmut Henkel
+Taco Hoekwater
+Luigi Scarso
+\stoplines
\blank[3*big]
-\starttabulate
+\starttabulate[|||]
\NC Version \EQ \currentdate \NC \NR
-\NC \LUATEX \EQ version \cldcontext{status.luatex_version/100},
- revision \cldcontext{status.luatex_revision},
- number \cldcontext{environment.luatexversion} \NC \NR
+\NC \LUATEX \EQ \cldcontext{LUATEXENGINE} %
+ \cldcontext{LUATEXVERSION} / %
+ \cldcontext{LUATEXFUNCTIONALITY}
+ \NC \NR
\NC \CONTEXT \EQ MkIV \contextversion \NC \NR
\stoptabulate
diff --git a/doc/context/sources/general/manuals/luatex/luatex-languages.tex b/doc/context/sources/general/manuals/luatex/luatex-languages.tex
index 365e87f26..d4a7bda60 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-languages.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-languages.tex
@@ -1,19 +1,22 @@
% language=uk
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-languages
\startchapter[reference=languages,title={Languages, characters, fonts and glyphs}]
+\startsection[title={Introduction}]
+
+\topicindex {languages}
+
\LUATEX's internal handling of the characters and glyphs that eventually become
typeset is quite different from the way \TEX82 handles those same objects. The
easiest way to explain the difference is to focus on unrestricted horizontal mode
(i.e.\ paragraphs) and hyphenation first. Later on, it will be easy to deal
with the differences that occur in horizontal and math modes.
-In \TEX82, the characters you type are converted into \type {char_node} records
+In \TEX82, the characters you type are converted into \type {char} node records
when they are encountered by the main control loop. \TEX\ attaches and processes
the font information while creating those records, so that the resulting \quote
{horizontal list} contains the final forms of ligatures and implicit kerning.
@@ -21,7 +24,7 @@ This packaging is needed because we may want to get the effective width of for
instance a horizontal box.
When it becomes necessary to hyphenate words in a paragraph, \TEX\ converts (one
-word at time) the \type {char_node} records into a string by replacing ligatures
+word at time) the \type {char} node records into a string by replacing ligatures
with their components and ignoring the kerning. Then it runs the hyphenation
algorithm on this string, and converts the hyphenated result back into a \quote
{horizontal list} that is consecutively spliced back into the paragraph stream.
@@ -29,14 +32,14 @@ Keep in mind that the paragraph may contain unboxed horizontal material, which
then already contains ligatures and kerns and the words therein are part of the
hyphenation process.
-Those \type {char_node} records are somewhat misnamed, as they are glyph
+Those \type {char} node records are somewhat misnamed, as they are glyph
positions in specific fonts, and therefore not really \quote {characters} in the
-linguistic sense. There is no language information inside the \type {char_node}
+linguistic sense. There is no language information inside the \type {char} node
records at all. Instead, language information is passed along using \type
-{language whatsit} records inside the horizontal list.
+{language whatsit} nodes inside the horizontal list.
In \LUATEX, the situation is quite different. The characters you type are always
-converted into \type {glyph_node} records with a special subtype to identify them
+converted into \nod {glyph} node records with a special subtype to identify them
as being intended as linguistic characters. \LUATEX\ stores the needed language
information in those records, but does not do any font|-|related processing at
the time of node creation. It only stores the index of the current font and a
@@ -48,93 +51,83 @@ font information in the whole list (creating ligatures and adjusting kerning),
and finally it adjusts all the subtype identifiers so that the records are \quote
{glyph nodes} from now on.
-\section[charsandglyphs]{Characters and glyphs}
+\stopsection
+
+\startsection[title={Characters, glyphs and discretionaries},reference=charsandglyphs]
+
+\topicindex {characters}
+\topicindex {glyphs}
+\topicindex {hyphenation}
-\TEX82 (including \PDFTEX) differentiates between \type {char_node}s and \type
-{lig_node}s. The former are simple items that contained nothing but a \quote
+\TEX82 (including \PDFTEX) differentiates between \type {char} nodes and \type
+{lig} nodes. The former are simple items that contained nothing but a \quote
{character} and a \quote {font} field, and they lived in the same memory as
tokens did. The latter also contained a list of components, and a subtype
indicating whether this ligature was the result of a word boundary, and it was
stored in the same place as other nodes like boxes and kerns and glues.
In \LUATEX, these two types are merged into one, somewhat larger structure called
-a \type {glyph_node}. Besides having the old character, font, and component
-fields, and the new special fields like \quote {attr} (see~\in {section}
-[glyphnodes]), these nodes also contain:
+a \nod {glyph} node. Besides having the old character, font, and component
+fields there are a few more, like \quote {attr} that we will see in \in {section}
+[glyphnodes], these nodes also contain a subtype, that codes four main types and
+two additional ghost types. For ligatures, multiple bits can be set at the same
+time (in case of a single|-|glyph word).
\startitemize
-
-\startitem A subtype, split into four main types:
-
- \startitemize
- \startitem
- \type {character}, for characters to be hyphenated: the lowest bit
- (bit 0) is set to 1.
- \stopitem
- \startitem
- \type {glyph}, for specific font glyphs: the lowest bit (bit 0) is
- not set.
- \stopitem
- \startitem
- \type {ligature}, for ligatures (bit 1 is set)
- \stopitem
- \startitem
- \type {ghost}, for \quote {ghost objects} (bit 2 is set)
- \stopitem
- \stopitemize
-
- The latter two make further use of two extra fields (bits 3 and 4):
-
- \startitemize
- \startitem
- \type {left}, for ligatures created from a left word boundary and for
- ghosts created from \type {\leftghost}
- \stopitem
- \startitem
- \type {right}, for ligatures created from a right word boundary and
- for ghosts created from \type {\rightghost}
- \stopitem
- \stopitemize
-
- For ligatures, both bits can be set at the same time (in case of a
- single|-|glyph word).
-
-\stopitem
-
-\startitem
- \type {glyph_node}s of type \quote {character} also contain language data,
- split into four items that were current when the node was created: the
- \type {\setlanguage} (15 bits), \type {\lefthyphenmin} (8 bits), \type
- {\righthyphenmin} (8 bits), and \type {\uchyph} (1 bit).
-\stopitem
-
+ \startitem
+ \type {character}, for characters to be hyphenated: the lowest bit
+ (bit 0) is set to 1.
+ \stopitem
+ \startitem
+ \nod {glyph}, for specific font glyphs: the lowest bit (bit 0) is
+ not set.
+ \stopitem
+ \startitem
+ \type {ligature}, for constructed ligatures bit 1 is set.
+ \stopitem
+ \startitem
+ \type {ghost}, for so called \quote {ghost objects} bit 2 is set.
+ \stopitem
+ \startitem
+ \type {left}, for ligatures created from a left word boundary and for
+ ghosts created from \lpr {leftghost} bit 3 gets set.
+ \stopitem
+ \startitem
+ \type {right}, for ligatures created from a right word boundary and
+ for ghosts created from \lpr {rightghost} bit 4 is set.
+ \stopitem
\stopitemize
+The \nod {glyph} nodes also contain language data, split into four items that
+were current when the node was created: the \prm {setlanguage} (15~bits), \prm
+{lefthyphenmin} (8~bits), \prm {righthyphenmin} (8~bits), and \prm {uchyph}
+(1~bit).
+
Incidentally, \LUATEX\ allows 16383 separate languages, and words can be 256
characters long. The language is stored with each character. You can set
-\type {\firstvalidlanguage} to for instance~1 and make thereby language~0
+\prm {firstvalidlanguage} to for instance~1 and make thereby language~0
an ignored hyphenation language.
-The new primitive \type {\hyphenationmin} can be used to signal the minimal length
-of a word. This value stored with the (current) language.
+The new primitive \lpr {hyphenationmin} can be used to signal the minimal length
+of a word. This value is stored with the (current) language.
-Because the \type {\uchyph} value is saved in the actual nodes, its handling is
-subtly different from \TEX82: changes to \type {\uchyph} become effective
+Because the \prm {uchyph} value is saved in the actual nodes, its handling is
+subtly different from \TEX82: changes to \prm {uchyph} become effective
immediately, not at the end of the current partial paragraph.
Typeset boxes now always have their language information embedded in the nodes
themselves, so there is no longer a possible dependency on the surrounding
-language settings. In \TEX82, a mid-paragraph statement like \type {\unhbox0} would
-process the box using the current paragraph language unless there was a
-\type {\setlanguage} issued inside the box. In \LUATEX, all language variables are
-already frozen.
+language settings. In \TEX82, a mid|-|paragraph statement like \type {\unhbox0}
+would process the box using the current paragraph language unless there was a
+\prm {setlanguage} issued inside the box. In \LUATEX, all language variables
+are already frozen.
In traditional \TEX\ the process of hyphenation is driven by \type {lccode}s. In
\LUATEX\ we made this dependency less strong. There are several strategies
possible. When you do nothing, the currently used \type {lccode}s are used, when
loading patterns, setting exceptions or hyphenating a list.
-When you set \type {\savinghyphcodes} to a value larger than zero the current set
+When you set \prm {savinghyphcodes} to a value greater than zero the current set
of \type {lccode}s will be saved with the language. In that case changing a \type
{lccode} afterwards has no effect. However, you can adapt the set with:
@@ -144,96 +137,88 @@ of \type {lccode}s will be saved with the language. In that case changing a \typ
This change is global which makes sense if you keep in mind that the moment that
hyphenation happens is (normally) when the paragraph or a horizontal box is
-constructed. When \type {\savinghyphcodes} was zero when the language got
+constructed. When \prm {savinghyphcodes} was zero when the language got
initialized you start out with nothing, otherwise you already have a set.
-When a \type {\hjcode} is larger than $0$ but smaller than $32$ is indicates the
+When a \lpr {hjcode} is greater than 0 but less than 32 is indicates the
to be used length. In the following example we map a character (\type {x}) onto
another one in the patterns and tell the engine that \type {œ} counts as one
character. Because traditionally zero itself is reserved for inhibiting
-hyphenation, a value of $32$ counts as zero.
-
-\starttyping
-% assuming french patterns:
-foobar % foo-bar
-
-\hjcode`x=`o
-
-fxxbar % fxx-bar
-
-\lefthyphenmin3
-
-œdipus % œdi-pus
-
-\lefthyphenmin4
-
-œdipus % œdipus
-
-\hjcode`œ=2
-
-œdipus % œdi-pus
-
-\hjcode`i=32
-\hjcode`d=32
-
-œdipus % œdipus
-\stoptyping
+hyphenation, a value of 32 counts as zero.
+
+Here are some examples (we assume that French patterns are used):
+
+\starttabulate[||||]
+\NC \NC \type{foobar} \NC \type{foo-bar} \NC \NR
+\NC \type{\hjcode`x=`o} \NC \type{fxxbar} \NC \type{fxx-bar} \NC \NR
+\NC \type{\lefthyphenmin3} \NC \type{œdipus} \NC \type{œdi-pus} \NC \NR
+\NC \type{\lefthyphenmin4} \NC \type{œdipus} \NC \type{œdipus} \NC \NR
+\NC \type{\hjcode`œ=2} \NC \type{œdipus} \NC \type{œdi-pus} \NC \NR
+\NC \type{\hjcode`i=32 \hjcode`d=32} \NC \type{œdipus} \NC \type{œdipus} \NC \NR
+\NC
+\stoptabulate
Carrying all this information with each glyph would give too much overhead and
-also make the process of setting up thee codes more complex. A solution with
+also make the process of setting up these codes more complex. A solution with
\type {hjcode} sets was considered but rejected because in practice the current
approach is sufficient and it would not be compatible anyway.
Beware: the values are always saved in the format, independent of the setting
-of \type {\savinghyphcodes} at the moment the format is dumped.
+of \prm {savinghyphcodes} at the moment the format is dumped.
A boundary node normally would mark the end of a word which interferes with for
-instance discretionary injection. For this you can use the \type {\wordboundary}
-as trigger. Here are a few examples of usage:
+instance discretionary injection. For this you can use the \prm {wordboundary}
+as a trigger. Here are a few examples of usage:
\startbuffer
discrete---discrete
\stopbuffer
-\typebuffer \start \dontcomplain \hsize 1pt \getbuffer \par \stop
+\typebuffer \startnarrower \dontcomplain \hsize 1pt \getbuffer \par \stopnarrower
\startbuffer
discrete\discretionary{}{}{---}discrete
\stopbuffer
-\typebuffer \start \dontcomplain \hsize 1pt \getbuffer \par \stop
+\typebuffer \startnarrower \dontcomplain \hsize 1pt \getbuffer \par \stopnarrower
\startbuffer
discrete\wordboundary\discretionary{}{}{---}discrete
\stopbuffer
-\typebuffer \start \dontcomplain \hsize 1pt \getbuffer \par \stop
+\typebuffer \startnarrower \dontcomplain \hsize 1pt \getbuffer \par \stopnarrower
\startbuffer
discrete\wordboundary\discretionary{}{}{---}\wordboundary discrete
\stopbuffer
-\typebuffer \start \dontcomplain \hsize 1pt \getbuffer \par \stop
+\typebuffer \startnarrower \dontcomplain \hsize 1pt \getbuffer \par \stopnarrower
\startbuffer
discrete\wordboundary\discretionary{---}{}{}\wordboundary discrete
\stopbuffer
-\typebuffer \start \dontcomplain \hsize 1pt \getbuffer \par \stop
+\typebuffer \startnarrower \dontcomplain \hsize 1pt \getbuffer \par \stopnarrower
We only accept an explicit hyphen when there is a preceding glyph and we skip a
-sequence of explicit hyphens as that normally indicates a \type {--} or \type
+sequence of explicit hyphens since that normally indicates a \type {--} or \type
{---} ligature in which case we can in a worse case usage get bad node lists
later on due to messed up ligature building as these dashes are ligatures in base
-fonts. This is a side effect of the separating the hyphenation, ligaturing and
+fonts. This is a side effect of separating the hyphenation, ligaturing and
kerning steps.
-The start and end of a characters is signalled by a glue, penalty, kern or boundary
-node. But by default also a hlist, vlist, rule, dir, whatsit, ins, and adjust node
-indicate a start or end. You can omit the last set from the test by setting
-\type {\hyphenationbounds} to a non|-|zero value:
+The start and end of a sequence of characters is signalled by a \nod {glue}, \nod
+{penalty}, \nod {kern} or \nod {boundary} node. But by default also a \nod
+{hlist}, \nod {vlist}, \nod {rule}, \nod {dir}, \nod {whatsit}, \nod {ins}, and
+\nod {adjust} node indicate a start or end. You can omit the last set from the
+test by setting \lpr {hyphenationbounds} to a non|-|zero value:
-\starttabulate[|l|l|]
+\starttabulate[|c|l|]
+\DB value \BC behaviour \NC \NR
+\TB
\NC \type{0} \NC not strict \NC \NR
\NC \type{1} \NC strict start \NC \NR
\NC \type{2} \NC strict end \NC \NR
\NC \type{3} \NC strict start and strict end \NC \NR
+\LL
\stoptabulate
The word start is determined as follows:
\starttabulate[|l|l|]
+\DB node \BC behaviour \NC \NR
+\TB
\BC boundary \NC yes when wordboundary \NC \NR
\BC hlist \NC when hyphenationbounds 1 or 3 \NC \NR
\BC vlist \NC when hyphenationbounds 1 or 3 \NC \NR
@@ -244,11 +229,14 @@ The word start is determined as follows:
\BC math \NC skipped \NC \NR
\BC glyph \NC exhyphenchar (one only) : yes (so no -- ---) \NC \NR
\BC otherwise \NC yes \NC \NR
+\LL
\stoptabulate
The word end is determined as follows:
\starttabulate[|l|l|]
+\DB node \BC behaviour \NC \NR
+\TB
\BC boundary \NC yes \NC \NR
\BC glyph \NC yes when different language \NC \NR
\BC glue \NC yes \NC \NR
@@ -261,10 +249,11 @@ The word end is determined as follows:
\BC whatsit \NC when hyphenationbounds 2 or 3 \NC \NR
\BC ins \NC when hyphenationbounds 2 or 3 \NC \NR
\BC adjust \NC when hyphenationbounds 2 or 3 \NC \NR
+\LL
\stoptabulate
-\in{Figures}[hb:1] upto \in[hb:5] show some examples. In all cases we set the min
-values to 1 and make sure that the words hyphenate at each character.
+\in {Figures} [hb:1] upto \in [hb:5] show some examples. In all cases we set the
+min values to 1 and make sure that the words hyphenate at each character.
\hyphenation{o-n-e t-w-o}
@@ -283,12 +272,13 @@ values to 1 and make sure that the words hyphenate at each character.
\startplacefigure[reference=hb:1,title={\type{one}}]
\startcombination[4*1]
- {\SomeTest{0}{one}} {\type{0}}
- {\SomeTest{1}{one}} {\type{1}}
- {\SomeTest{2}{one}} {\type{2}}
- {\SomeTest{3}{one}} {\type{3}}
+ {\SomeTest{0}{one}} {\type{0}}
+ {\SomeTest{1}{one}} {\type{1}}
+ {\SomeTest{2}{one}} {\type{2}}
+ {\SomeTest{3}{one}} {\type{3}}
\stopcombination
\stopplacefigure
+
\startplacefigure[reference=hb:2,title={\type{one\null two}}]
\startcombination[4*1]
{\SomeTest{0}{one\null two}} {\type{0}}
@@ -297,6 +287,7 @@ values to 1 and make sure that the words hyphenate at each character.
{\SomeTest{3}{one\null two}} {\type{3}}
\stopcombination
\stopplacefigure
+
\startplacefigure[reference=hb:3,title={\type{\null one\null two}}]
\startcombination[4*1]
{\SomeTest{0}{\null one\null two}} {\type{0}}
@@ -305,6 +296,7 @@ values to 1 and make sure that the words hyphenate at each character.
{\SomeTest{3}{\null one\null two}} {\type{3}}
\stopcombination
\stopplacefigure
+
\startplacefigure[reference=hb:4,title={\type{one\null two\null}}]
\startcombination[4*1]
{\SomeTest{0}{one\null two\null}} {\type{0}}
@@ -313,6 +305,7 @@ values to 1 and make sure that the words hyphenate at each character.
{\SomeTest{3}{one\null two\null}} {\type{3}}
\stopcombination
\stopplacefigure
+
\startplacefigure[reference=hb:5,title={\type{\null one\null two\null}}]
\startcombination[4*1]
{\SomeTest{0}{\null one\null two\null}} {\type{0}}
@@ -330,7 +323,7 @@ deal differently with (a sequence of) explicit hyphens. We already have added
some control over aspects of the hyphenation and yet another one concerns
automatic hyphens (e.g.\ \type {-} characters in the input).
-When \type {\automatichyphenmode} has a value of 0, a hyphen will be turned into
+When \lpr {automatichyphenmode} has a value of 0, a hyphen will be turned into
an automatic discretionary. The snippets before and after it will not be
hyphenated. A side effect is that a leading hyphen can lead to a split but one
will seldom run into that situation. Setting a pre and post character makes this
@@ -359,12 +352,6 @@ before--after \par
before---after \par
\stopbuffer
-We show three samples:
-
-Input A: \typebuffer[a]
-Input B: \typebuffer[b]
-Input C: \typebuffer[c]
-
\startbuffer[demo]
\startcombination[nx=4,ny=3,location=top]
{\framed[align=normal,strut=no,top=\vskip.5ex,bottom=\vskip.5ex]{\automatichyphenmode\zerocount \hsize6em \getbuffer[a]}} {A~0~6em}
@@ -382,104 +369,139 @@ Input C: \typebuffer[c]
\stopcombination
\stopbuffer
-\startplacefigure[reference=automatic:1,title={The automatic modes \type {0} (default), \type {1} and \type {2}, with a \type {\hsize}
+\startplacefigure[locationreference=automatichyphenmode:1,title={The automatic modes \type {0} (default), \type {1} and \type {2}, with a \prm {hsize}
of 6em and 2pt (which triggers a linebreak).}]
\dontcomplain \tt \getbuffer[demo]
\stopplacefigure
-\startplacefigure[reference=automatic:2,title={The automatic modes \type {0} (default), \type {1} and \type {2}, with \type
-{\preexhyphenchar} and \type {\postexhyphenchar} set to characters \type {A} and \type {B}.}]
+\startplacefigure[reference=automatichyphenmode:2,title={The automatic modes \type {0} (default), \type {1} and \type {2}, with \lpr {preexhyphenchar} and \lpr {postexhyphenchar} set to characters \type {A} and \type {B}.}]
\postexhyphenchar`A\relax
\preexhyphenchar `B\relax
\dontcomplain \tt \getbuffer[demo]
\stopplacefigure
-As with primitive companions of other single character commands, the \type {\-}
-command has a more verbose primitive version in \type {\explicitdiscretionary}
+In \in {figure} [automatichyphenmode:1] \in {and} [automatichyphenmode:2] we show
+what happens with three samples:
+
+Input A: \typebuffer[a]
+Input B: \typebuffer[b]
+Input C: \typebuffer[c]
+
+As with primitive companions of other single character commands, the \prm {-}
+command has a more verbose primitive version in \lpr {explicitdiscretionary}
and the normally intercepted in the hyphenator character \type {-} (or whatever
-is configured) is available as \type {\automaticdiscretionary}.
+is configured) is available as \lpr {automaticdiscretionary}.
-\section{The main control loop}
+\stopsection
+
+\startsection[title={The main control loop}]
+
+\topicindex {main loop}
+\topicindex {hyphenation}
In \LUATEX's main loop, almost all input characters that are to be typeset are
-converted into \type {glyph} node records with subtype \quote {character}, but
+converted into \nod {glyph} node records with subtype \quote {character}, but
there are a few exceptions.
-First, the \type {\accent} primitives creates nodes with subtype \quote {glyph}
-instead of \quote {character}: one for the actual accent and one for the
-accentee. The primary reason for this is that \type {\accent} in \TEX82 is
-explicitly dependent on the current font encoding, so it would not make much
-sense to attach a new meaning to the primitive's name, as that would invalidate
-many old documents and macro packages. \footnote {Of course, modern packages will
-not use the \type {\accent} primitive at all but try to map directly on composed
-characters.} A secondary reason is that in \TEX82, \type {\accent} prohibits
-hyphenation of the current word. Since in \LUATEX\ hyphenation only takes place
-on \quote {character} nodes, it is possible to achieve the same effect.
-
-This change of meaning did happen with \type {\char}, that now generates \quote
-{glyph} nodes with a character subtype. In traditional \TEX\ there was a strong
-relationship between the 8|-|bit input encoding, hyphenation and glyphs taken
-from a font. In \LUATEX\ we have \UTF\ input, and in most cases this maps
-directly to a character in a font, apart from glyph replacement in the font
-engine. If you want to access arbitrary glyphs in a font directly you can always
-use \LUA\ to do so, because fonts are available as \LUA\ table.
-
-Second, all the results of processing in math mode eventually become nodes with
-\quote {glyph} subtypes.
-
-Third, the \ALEPH|-|derived commands \type {\leftghost} and \type {\rightghost}
-create nodes of a third subtype: \quote {ghost}. These nodes are ignored
-completely by all further processing until the stage where inter|-|glyph kerning
-is added.
-
-Fourth, automatic discretionaries are handled differently. \TEX82 inserts an
-empty discretionary after sensing an input character that matches the \type
-{\hyphenchar} in the current font. This test is wrong in our opinion: whether or
-not hyphenation takes place should not depend on the current font, it is a
-language property. \footnote {When \TEX\ showed up we didn't have \UNICODE\ yet
-and being limited to eight bits meant that one sometimes had to compromise
-between supporting character input, glyph rendering, hyphenation.}
-
-In \LUATEX, it works like this: if \LUATEX\ senses a string of input characters
-that matches the value of the new integer parameter \type {\exhyphenchar}, it will
-insert an explicit discretionary after that series of nodes. Initex sets the \type
-{\exhyphenchar=`\-}. Incidentally, this is a global parameter instead of a
-language-specific one because it may be useful to change the value depending on
-the document structure instead of the text language.
-
-The insertion of discretionaries after a sequence of explicit hyphens happens at
-the same time as the other hyphenation processing, {\it not\/} inside the main
-control loop.
-
-The only use \LUATEX\ has for \type {\hyphenchar} is at the check whether a word
-should be considered for hyphenation at all. If the \type {\hyphenchar} of the
-font attached to the first character node in a word is negative, then hyphenation
-of that word is abandoned immediately. This behaviour is added for backward
-compatibility only, and the use of \type {\hyphenchar=-1} as a means of
-preventing hyphenation should not be used in new \LUATEX\ documents.
-
-Fifth, \type {\setlanguage} no longer creates whatsits. The meaning of \type
-{\setlanguage} is changed so that it is now an integer parameter like all others.
-That integer parameter is used in \type {\glyph_node} creation to add language
-information to the glyph nodes. In conjunction, the \type {\language} primitive is
-extended so that it always also updates the value of \type {\setlanguage}.
-
-Sixth, the \type {\noboundary} command (that prohibits word boundary processing
-where that would normally take place) now does create nodes. These nodes are
-needed because the exact place of the \type {\noboundary} command in the input
-stream has to be retained until after the ligature and font processing stages.
-
-Finally, there is no longer a \type {main_loop} label in the code. Remember that
-\TEX82 did quite a lot of processing while adding \type {char_nodes} to the
-horizontal list? For speed reasons, it handled that processing code outside of
-the \quote {main control} loop, and only the first character of any \quote {word}
-was handled by that \quote {main control} loop. In \LUATEX, there is no longer a
-need for that (all hard work is done later), and the (now very small) bits of
-character|-|handling code have been moved back inline. When \type
-{\tracingcommands} is on, this is visible because the full word is reported,
-instead of just the initial character.
-
-Because we tend to make hard codes behaviour configurable a few new primitives
+\startitemize[n]
+
+\startitem
+ The \prm {accent} primitive creates nodes with subtype \quote {glyph}
+ instead of \quote {character}: one for the actual accent and one for the
+ accentee. The primary reason for this is that \prm {accent} in \TEX82 is
+ explicitly dependent on the current font encoding, so it would not make much
+ sense to attach a new meaning to the primitive's name, as that would
+ invalidate many old documents and macro packages. A secondary reason is that
+ in \TEX82, \prm {accent} prohibits hyphenation of the current word. Since
+ in \LUATEX\ hyphenation only takes place on \quote {character} nodes, it is
+ possible to achieve the same effect. Of course, modern \UNICODE\ aware macro
+ packages will not use the \prm {accent} primitive at all but try to map
+ directly on composed characters.
+
+ This change of meaning did happen with \prm {char}, that now generates
+ \quote {glyph} nodes with a character subtype. In traditional \TEX\ there was
+ a strong relationship between the 8|-|bit input encoding, hyphenation and
+ glyphs taken from a font. In \LUATEX\ we have \UTF\ input, and in most cases
+ this maps directly to a character in a font, apart from glyph replacement in
+ the font engine. If you want to access arbitrary glyphs in a font directly
+ you can always use \LUA\ to do so, because fonts are available as \LUA\
+ table.
+\stopitem
+
+\startitem
+ All the results of processing in math mode eventually become nodes with
+ \quote {glyph} subtypes. In fact, the result of processing math is just
+ a regular list of glyphs, kerns, glue, penalties, boxes etc.
+\stopitem
+
+\startitem
+ The \ALEPH|-|derived commands \lpr {leftghost} and \lpr {rightghost}
+ create nodes of a third subtype: \quote {ghost}. These nodes are ignored
+ completely by all further processing until the stage where inter|-|glyph
+ kerning is added.
+\stopitem
+
+\startitem
+ Automatic discretionaries are handled differently. \TEX82 inserts an empty
+ discretionary after sensing an input character that matches the \prm
+ {hyphenchar} in the current font. This test is wrong in our opinion: whether
+ or not hyphenation takes place should not depend on the current font, it is a
+ language property. \footnote {When \TEX\ showed up we didn't have \UNICODE\
+ yet and being limited to eight bits meant that one sometimes had to
+ compromise between supporting character input, glyph rendering, hyphenation.}
+
+ In \LUATEX, it works like this: if \LUATEX\ senses a string of input
+ characters that matches the value of the new integer parameter \prm
+ {exhyphenchar}, it will insert an explicit discretionary after that series of
+ nodes. Initially \TEX\ sets the \type {\exhyphenchar=`\-}. Incidentally, this
+ is a global parameter instead of a language-specific one because it may be
+ useful to change the value depending on the document structure instead of the
+ text language.
+
+ The insertion of discretionaries after a sequence of explicit hyphens happens
+ at the same time as the other hyphenation processing, {\it not\/} inside the
+ main control loop.
+
+ The only use \LUATEX\ has for \prm {hyphenchar} is at the check whether a
+ word should be considered for hyphenation at all. If the \prm {hyphenchar}
+ of the font attached to the first character node in a word is negative, then
+ hyphenation of that word is abandoned immediately. This behaviour is added
+ for backward compatibility only, and the use of \type {\hyphenchar=-1} as a
+ means of preventing hyphenation should not be used in new \LUATEX\ documents.
+\stopitem
+
+\startitem
+ The \prm {setlanguage} command no longer creates whatsits. The meaning of
+ \prm {setlanguage} is changed so that it is now an integer parameter like all
+ others. That integer parameter is used in \type {\glyph_node} creation to add
+ language information to the glyph nodes. In conjunction, the \prm {language}
+ primitive is extended so that it always also updates the value of \prm
+ {setlanguage}.
+\stopitem
+
+\startitem
+ The \prm {noboundary} command (that prohibits word boundary processing
+ where that would normally take place) now does create nodes. These nodes are
+ needed because the exact place of the \prm {noboundary} command in the
+ input stream has to be retained until after the ligature and font processing
+ stages.
+\stopitem
+
+\startitem
+ There is no longer a \type {main_loop} label in the code. Remember that
+ \TEX82 did quite a lot of processing while adding \type {char_nodes} to the
+ horizontal list? For speed reasons, it handled that processing code outside
+ of the \quote {main control} loop, and only the first character of any \quote
+ {word} was handled by that \quote {main control} loop. In \LUATEX, there is
+ no longer a need for that (all hard work is done later), and the (now very
+ small) bits of character|-|handling code have been moved back inline. When
+ \prm {tracingcommands} is on, this is visible because the full word is
+ reported, instead of just the initial character.
+\stopitem
+
+\stopitemize
+
+Because we tend to make hard coded behaviour configurable a few new primitives
have been added:
\starttyping
@@ -489,50 +511,59 @@ have been added:
\stoptyping
The first parameter has the following consequences for automatic discs (the ones
-resulting from an \type {\exhyphenchar}:
+resulting from an \prm {exhyphenchar}:
\starttabulate[|c|l|l|]
-\BC mode \BC automatic disc \type{-} \BC explicit disc \type{\-} \NC \NR
-\HL
-\NC \type{0} \NC \type {\exhyphenpenalty} \NC \type {\exhyphenpenalty} \NC \NR
-\NC \type{1} \NC \type {\hyphenpenalty} \NC \type {\hyphenpenalty} \NC \NR
-\NC \type{2} \NC \type {\exhyphenpenalty} \NC \type {\hyphenpenalty} \NC \NR
-\NC \type{3} \NC \type {\hyphenpenalty} \NC \type {\exhyphenpenalty} \NC \NR
-\NC \type{4} \NC \type {\automatichyphenpenalty} \NC \type {\explicithyphenpenalty} \NC \NR
-\NC \type{5} \NC \type {\exhyphenpenalty} \NC \type {\explicithyphenpenalty} \NC \NR
-\NC \type{6} \NC \type {\hyphenpenalty} \NC \type {\explicithyphenpenalty} \NC \NR
-\NC \type{7} \NC \type {\automatichyphenpenalty} \NC \type {\exhyphenpenalty} \NC \NR
-\NC \type{8} \NC \type {\automatichyphenpenalty} \NC \type {\hyphenpenalty} \NC \NR
+\DB mode \BC automatic disc \type {-} \BC explicit disc \prm{-} \NC \NR
+\TB
+\NC \type{0} \NC \prm {exhyphenpenalty} \NC \prm {exhyphenpenalty} \NC \NR
+\NC \type{1} \NC \prm {hyphenpenalty} \NC \prm {hyphenpenalty} \NC \NR
+\NC \type{2} \NC \prm {exhyphenpenalty} \NC \prm {hyphenpenalty} \NC \NR
+\NC \type{3} \NC \prm {hyphenpenalty} \NC \prm {exhyphenpenalty} \NC \NR
+\NC \type{4} \NC \lpr {automatichyphenpenalty} \NC \lpr {explicithyphenpenalty} \NC \NR
+\NC \type{5} \NC \prm {exhyphenpenalty} \NC \lpr {explicithyphenpenalty} \NC \NR
+\NC \type{6} \NC \prm {hyphenpenalty} \NC \lpr {explicithyphenpenalty} \NC \NR
+\NC \type{7} \NC \lpr {automatichyphenpenalty} \NC \prm {exhyphenpenalty} \NC \NR
+\NC \type{8} \NC \lpr {automatichyphenpenalty} \NC \prm {hyphenpenalty} \NC \NR
+\LL
\stoptabulate
-other values do what we always did in \LUATEX: insert \type {\exhyphenpenalty}.
+other values do what we always did in \LUATEX: insert \prm {exhyphenpenalty}.
-\section[patternsexceptions]{Loading patterns and exceptions}
+\stopsection
-The hyphenation algorithm in \LUATEX\ is quite different from the one in \TEX82,
-although it uses essentially the same user input.
+\startsection[title={Loading patterns and exceptions},reference=patternsexceptions]
-After expansion, the argument for \type {\patterns} has to be proper \UTF8 with
-individual patterns separated by spaces, no \type {\char} or \type {\chardef}d
-commands are allowed. The current implementation quite strict and will reject all
-non|-|\UNICODE\ characters.
+\topicindex {hyphenation}
+\topicindex {hyphenation+patterns}
+\topicindex {hyphenation+exceptions}
+\topicindex {patterns}
+\topicindex {exceptions}
-Likewise, the expanded argument for \type {\hyphenation} also has to be proper
-\UTF8, but here a bit of extra syntax is provided:
+Although we keep the traditional approach towards hyphenation (which is still
+superior) the implementation of the hyphenation algorithm in \LUATEX\ is quite
+different from the one in \TEX82.
+
+After expansion, the argument for \prm {patterns} has to be proper \UTF8 with
+individual patterns separated by spaces, no \prm {char} or \prm {chardef}d
+commands are allowed. The current implementation is quite strict and will reject
+all non|-|\UNICODE\ characters. Likewise, the expanded argument for \prm
+{hyphenation} also has to be proper \UTF8, but here a bit of extra syntax is
+provided:
\startitemize[n]
\startitem
- Three sets of arguments in curly braces (\type {{}{}{}}) indicates a desired
- complex discretionary, with arguments as in \type {\discretionary}'s command in
+ Three sets of arguments in curly braces (\type {{}{}{}}) indicate a desired
+ complex discretionary, with arguments as in \prm {discretionary}'s command in
normal document input.
\stopitem
\startitem
- A \type {-} indicates a desired simple discretionary, cf.\ \type {\-} and \type
- {\discretionary{-}{}{}} in normal document input.
+ A \type {-} indicates a desired simple discretionary, cf.\ \type {\-} and
+ \type {\discretionary{-}{}{}} in normal document input.
\stopitem
\startitem
- Internal command names are ignored. This rule is provided especially for \type
- {\discretionary}, but it also helps to deal with \type {\relax} commands that
+ Internal command names are ignored. This rule is provided especially for \prm
+ {discretionary}, but it also helps to deal with \prm {relax} commands that
may sneak in.
\stopitem
\startitem
@@ -540,22 +571,24 @@ Likewise, the expanded argument for \type {\hyphenation} also has to be proper
\stopitem
\stopitemize
-The expanded argument is first converted back to a space-separated string while
+The expanded argument is first converted back to a space|-|separated string while
dropping the internal command names. This string is then converted into a
dictionary by a routine that creates key|-|value pairs by converting the other
listed items. It is important to note that the keys in an exception dictionary
can always be generated from the values. Here are a few examples:
\starttabulate[|l|l|l|]
-\BC value \BC implied key (input) \NC effect \NC\NR
+\DB value \BC implied key (input) \BC effect \NC\NR
+\TB
\NC \type {ta-ble} \NC table \NC \type {ta\-ble} ($=$ \type {ta\discretionary{-}{}{}ble}) \NC\NR
\NC \type {ba{k-}{}{c}ken} \NC backen \NC \type {ba\discretionary{k-}{}{c}ken} \NC\NR
+\LL
\stoptabulate
The resultant patterns and exception dictionary will be stored under the language
-code that is the present value of \type {\language}.
+code that is the present value of \prm {language}.
-In the last line of the table, you see there is no \type {\discretionary} command
+In the last line of the table, you see there is no \prm {discretionary} command
in the value: the command is optional in the \TEX-based input syntax. The
underlying reason for that is that it is conceivable that a whole dictionary of
words is stored as a plain text file and loaded into \LUATEX\ using one of the
@@ -573,20 +606,64 @@ actual explicit hyphen character if needed). For example, this matches the word
\hyphenation{multi{-}{}{-}word{-}{}{-}boun-daries}
\stoptyping
-The motivation behind the \ETEX\ extension \type {\savinghyphcodes} was that
+The motivation behind the \ETEX\ extension \prm {savinghyphcodes} was that
hyphenation heavily depended on font encodings. This is no longer true in
\LUATEX, and the corresponding primitive is basically ignored. Because we now
-have \type {hjcode}, the case relate codes can be used exclusively for \type
-{\uppercase} and \type {\lowercase}.
-
-\section{Applying hyphenation}
+have \lpr {hjcode}, the case relate codes can be used exclusively for \prm
+{uppercase} and \prm {lowercase}.
+
+The three curly brace pair pattern in an exception can be somewhat unexpected so
+we will try to explain it by example. The pattern \type {foo{}{}{x}bar} pattern
+creates a lookup \type {fooxbar} and the pattern \type {foo{}{}{}bar} creates
+\type {foobar}. Then, when a hit happens there is a replacement text (\type {x})
+or none. Because we introduced penalties in discretionary nodes, the exception
+syntax now also can take a penalty specification. The value between square brackets
+is a multiplier for \lpr {exceptionpenalty}. Here we have set it to 10000 so
+effectively we get 30000 in the example.
+
+\def\ShowSample#1#2%
+ {\startlinecorrection[blank]
+ \hyphenation{#1}%
+ \exceptionpenalty=10000
+ \bTABLE[foregroundstyle=type]
+ \bTR
+ \bTD[align=middle,nx=4] \type{#1} \eTD
+ \eTR
+ \bTR
+ \bTD[align=middle] \type{10em} \eTD
+ \bTD[align=middle] \type {3em} \eTD
+ \bTD[align=middle] \type {0em} \eTD
+ \bTD[align=middle] \type {6em} \eTD
+ \eTR
+ \bTR
+ \bTD[width=10em]\vtop{\hsize 10em 123 #2 123\par}\eTD
+ \bTD[width=10em]\vtop{\hsize 3em 123 #2 123\par}\eTD
+ \bTD[width=10em]\vtop{\hsize 0em 123 #2 123\par}\eTD
+ \bTD[width=10em]\vtop{\setupalign[verytolerant,stretch]\rmtf\hsize 6em 123 #2 #2 #2 #2 123\par}\eTD
+ \eTR
+ \eTABLE
+ \stoplinecorrection}
+
+\ShowSample{x{a-}{-b}{}x{a-}{-b}{}x{a-}{-b}{}x{a-}{-b}{}xx}{xxxxxx}
+\ShowSample{x{a-}{-b}{}x{a-}{-b}{}[3]x{a-}{-b}{}[1]x{a-}{-b}{}xx}{xxxxxx}
+
+\ShowSample{z{a-}{-b}{z}{a-}{-b}{z}{a-}{-b}{z}{a-}{-b}{z}z}{zzzzzz}
+\ShowSample{z{a-}{-b}{z}{a-}{-b}{z}[3]{a-}{-b}{z}[1]{a-}{-b}{z}z}{zzzzzz}
+
+\stopsection
+
+\startsection[title={Applying hyphenation}]
+
+\topicindex {hyphenation+how it works}
+\topicindex {hyphenation+discretionaries}
+\topicindex {discretionaries}
The internal structures \LUATEX\ uses for the insertion of discretionaries in
words is very different from the ones in \TEX82, and that means there are some
noticeable differences in handling as well.
First and foremost, there is no \quote {compressed trie} involved in hyphenation.
-The algorithm still reads \PATGEN-generated pattern files, but \LUATEX\ uses a
+The algorithm still reads pattern files generated by \PATGEN, but \LUATEX\ uses a
finite state hash to match the patterns against the word to be hyphenated. This
algorithm is based on the \quote {libhnj} library used by \OPENOFFICE, which in
turn is inspired by \TEX.
@@ -605,12 +682,12 @@ of the implementation:
\stopitem
\startitem
Because there is no \quote {trie preparation} stage, language patterns never
- become frozen. This means that the primitive \type {\patterns} (and its \LUA\
+ become frozen. This means that the primitive \prm {patterns} (and its \LUA\
counterpart \type {lang.patterns}) can be used at any time, not only in
ini\TEX.
\stopitem
\startitem
- Only the string representation of \type {\patterns} and \type {\hyphenation} is
+ Only the string representation of \prm {patterns} and \prm {hyphenation} is
stored in the format file. At format load time, they are simply
re|-|evaluated. It follows that there is no real reason to preload languages
in the format file. In fact, it is usually not a good idea to do so. It is
@@ -618,23 +695,27 @@ of the implementation:
needed.
\stopitem
\startitem
- \LUATEX\ uses the language-specific variables \type {\prehyphenchar} and \type
- {\posthyphenchar} in the creation of implicit discretionaries, instead of
- \TEX82's \type {\hyphenchar}, and the values of the language|-|specific variables
- \type {\preexhyphenchar} and \type {\postexhyphenchar} for explicit
+ \LUATEX\ uses the language-specific variables \lpr {prehyphenchar} and \lpr
+ {posthyphenchar} in the creation of implicit discretionaries, instead of
+ \TEX82's \prm {hyphenchar}, and the values of the language|-|specific
+ variables \lpr {preexhyphenchar} and \lpr {postexhyphenchar} for explicit
discretionaries (instead of \TEX82's empty discretionary).
\stopitem
\startitem
- The value of the two counters related to hyphenation, \type {\hyphenpenalty}
- and \type {\exhyphenpenalty}, are now stored in the discretionary nodes. This
- permits a local overload for explicit \type {\discretionary} commands. The
+ The value of the two counters related to hyphenation, \prm {hyphenpenalty}
+ and \prm {exhyphenpenalty}, are now stored in the discretionary nodes. This
+ permits a local overload for explicit \prm {discretionary} commands. The
value current when the hyphenation pass is applied is used. When no callbacks
are used this is compatible with traditional \TEX. When you apply the \LUA\
\type {lang.hyphenate} function the current values are used.
\stopitem
+\startitem
+ The hyphenation exception dictionary is maintained as key|-|value hash, and
+ that is also dynamic, so the \type {hyph_size} setting is not used either.
+\stopitem
\stopitemize
-Because we store penalties in the disc node the \type {\discretionary} command has
+Because we store penalties in the disc node the \prm {discretionary} command has
been extended to accept an optional penalty specification, so you can do the
following:
@@ -657,18 +738,18 @@ inserted at the left-hand side of a word).
Word boundaries are no longer implied by font switches, but by language switches.
One word can have two separate fonts and still be hyphenated correctly (but it
-can not have two different languages, the \type {\setlanguage} command forces a
+can not have two different languages, the \prm {setlanguage} command forces a
word boundary).
All languages start out with \type {\prehyphenchar=`\-}, \type {\posthyphenchar=0},
\type {\preexhyphenchar=0} and \type {\postexhyphenchar=0}. When you assign the
values of one of these four parameters, you are actually changing the settings
-for the current \type {\language}, this behaviour is compatible with \type {\patterns}
-and \type {\hyphenation}.
+for the current \prm {language}, this behaviour is compatible with \prm {patterns}
+and \prm {hyphenation}.
\LUATEX\ also hyphenates the first word in a paragraph. Words can be up to 256
-characters long (up from 64 in \TEX82). Longer words generate an error right now,
-but eventually either the limitation will be removed or perhaps it will become
+characters long (up from 64 in \TEX82). Longer words are ignored right now, but
+eventually either the limitation will be removed or perhaps it will become
possible to silently ignore the excess characters (this is what happens in
\TEX82, but there the behaviour cannot be controlled).
@@ -677,10 +758,12 @@ that this function expects to receive a list of \quote {character} nodes. It wil
not operate properly in the presence of \quote {glyph}, \quote {ligature}, or
\quote {ghost} nodes, nor does it know how to deal with kerning.
-The hyphenation exception dictionary is maintained as key|-|value hash, and that
-is also dynamic, so the \type {hyph_size} setting is not used either.
+\stopsection
-\section{Applying ligatures and kerning}
+\startsection[title={Applying ligatures and kerning}]
+
+\topicindex {ligatures}
+\topicindex {kerning}
After all possible hyphenation points have been inserted in the list, \LUATEX\
will process the list to convert the \quote {character} nodes into \quote {glyph}
@@ -689,24 +772,28 @@ ligatures are processed, then all kerning information is applied to the result
list. But those two stages are somewhat dependent on each other: If the used font
makes it possible to do so, the ligaturing stage adds virtual \quote {character}
nodes to the word boundaries in the list. While doing so, it removes and
-interprets \type {\noboundary} nodes. The kerning stage deletes those word
+interprets \prm {noboundary} nodes. The kerning stage deletes those word
boundary items after it is done with them, and it does the same for \quote
{ghost} nodes. Finally, at the end of the kerning stage, all remaining \quote
{character} nodes are converted to \quote {glyph} nodes.
-This work separation is worth mentioning because, if you overrule from \LUA\ only
+This word separation is worth mentioning because, if you overrule from \LUA\ only
one of the two callbacks related to font handling, then you have to make sure you
perform the tasks normally done by \LUATEX\ itself in order to make sure that the
other, non|-|overruled, routine continues to function properly.
-Work in this area is not yet complete, but most of the possible cases are handled
-by our rewritten ligaturing engine. At some point all of the possible inputs will
-become supported. \footnote {Not all of this makes sense because we nowadays have
-\OPENTYPE\ fonts and ligature building can happen in ,any different ways there.}
+Although we could improve the situation the reality is that in modern \OPENTYPE\
+fonts ligatures can be constructed in many ways: by replacing a sequence of
+characters by one glyph, or by selectively replacing individual glyphs, or by
+kerning, or any combination of this. Add to that contextual analysis and it will
+be clear that we have to let \LUA\ do that job instead. The generic font handler
+that we provide (which is part of \CONTEXT) distinguishes between base mode
+(which essentially is what we describe here and which delegates the task to \TEX)
+and node mode (which deals with more complex fonts.
-For example, take the word \type {office}, hyphenated \type {of-fice}, using a
-\quote {normal} font with all the \type {f}-\type {f} and \type {f}-\type {i}
-type ligatures:
+Let's look at an example. Take the word \type {office}, hyphenated \type
+{of-fice}, using a \quote {normal} font with all the \type {f}-\type {f} and
+\type {f}-\type {i} type ligatures:
\starttabulate[|l|l|]
\NC initial \NC \type {{o}{f}{f}{i}{c}{e}} \NC\NR
@@ -734,11 +821,15 @@ the top-level discretionary that resulted from the first hyphenation point.
Here is that nested solution again, in a different representation:
+\testpage[4]
+
\starttabulate[|l|c|c|c|c|c|c|]
-\NC \BC pre \BC \BC post \BC \BC replace \BC \NC \NR
+\DB \BC pre \BC \BC post \BC \BC replace \BC \NC \NR
+\TB
\NC topdisc \NC \type {f-} \NC (1) \NC \NC sub 1 \NC \NC sub 2 \NC \NR
\NC sub 1 \NC \type {f-} \NC (2) \NC \type {i} \NC (3) \NC \type {<fi>} \NC (4) \NC \NR
\NC sub 2 \NC \type {<ff>-} \NC (5) \NC \type {i} \NC (6) \NC \type {<ffi>} \NC (7) \NC \NR
+\LL
\stoptabulate
When line breaking is choosing its breakpoints, the following fields will
@@ -763,21 +854,23 @@ the first node).
One can observe that the \type {of-f-ice} and \type {off-ice} cases both end with
the same actual post replacement list (\type {i}), and that this would be the
-case even if that \type {i} was the first item of a potential following ligature
-like \type {ic}. This allows \LUATEX\ to do away with one of the fields, and thus
-make the whole stuff fit into just two discretionary nodes.
+case even if \type {i} was the first item of a potential following ligature like
+\type {ic}. This allows \LUATEX\ to do away with one of the fields, and thus make
+the whole stuff fit into just two discretionary nodes.
The mapping of the seven list fields to the six fields in this discretionary node
pair is as follows:
\starttabulate[|l|c|c|]
-\BC field \BC description \NC \NC \NR
+\DB field \BC description \NC \NC \NR
+\TB
\NC \type {disc1.pre} \NC \type {f-} \NC (1) \NC \NR
\NC \type {disc1.post} \NC \type {<fi>} \NC (4) \NC \NR
\NC \type {disc1.replace} \NC \type {<ffi>} \NC (7) \NC \NR
\NC \type {disc2.pre} \NC \type {f-} \NC (2) \NC \NR
\NC \type {disc2.post} \NC \type {i} \NC (3,6) \NC \NR
\NC \type {disc2.replace} \NC \type {<ff>-} \NC (5) \NC \NR
+\LL
\stoptabulate
What is actually generated after ligaturing has been applied is therefore:
@@ -806,13 +899,21 @@ mapping a sequence of glyphs onto one glyph, but also by selective replacement a
kerning. This means that the above examples are just representing the traditional
approach.
-\section{Breaking paragraphs into lines}
+\stopsection
+
+\startsection[title={Breaking paragraphs into lines}]
-This code is still almost unchanged, but because of the above|-|mentioned changes
+\topicindex {linebreaks}
+\topicindex {paragraphs}
+\topicindex {discretionaries}
+
+This code is almost unchanged, but because of the above|-|mentioned changes
with respect to discretionaries and ligatures, line breaking will potentially be
different from traditional \TEX. The actual line breaking code is still based on
the \TEX82 algorithms, and it does not expect there to be discretionaries inside
-of discretionaries.
+of discretionaries. But, as patterns evolve and font handling can influence
+discretionaries, you need to be aware of the fact that long term consistency is not
+an engine matter only.
But that situation is now fairly common in \LUATEX, due to the changes to the
ligaturing mechanism. And also, the \LUATEX\ discretionary nodes are implemented
@@ -826,10 +927,19 @@ The combined effect of these two differences is that \LUATEX\ does not always us
all of the potential breakpoints in a paragraph, especially when fonts with many
ligatures are used. Of course kerning also complicates matters here.
-\section{The \type {lang} library}
+\stopsection
+
+\startsection[title={The \type {lang} library}][library=lang]
+
+\subsection {\type {new} and \type {id}}
-This library provides the interface to \LUATEX's structure
-representing a language, and the associated functions.
+\topicindex {languages+library}
+
+\libindex {new}
+\libindex {id}
+
+This library provides the interface to \LUATEX's structure representing a
+language, and the associated functions.
\startfunctioncall
<language> l = lang.new()
@@ -837,106 +947,141 @@ representing a language, and the associated functions.
\stopfunctioncall
This function creates a new userdata object. An object of type \type {<language>}
-is the first argument to most of the other functions in the \type {lang}
-library. These functions can also be used as if they were object methods, using
-the colon syntax.
-
-Without an argument, the next available internal id number will be assigned to
-this object. With argument, an object will be created that links to the internal
-language with that id number.
+is the first argument to most of the other functions in the \type {lang} library.
+These functions can also be used as if they were object methods, using the colon
+syntax. Without an argument, the next available internal id number will be
+assigned to this object. With argument, an object will be created that links to
+the internal language with that id number.
\startfunctioncall
<number> n = lang.id(<language> l)
\stopfunctioncall
-returns the internal \type {\language} id number this object refers to.
+The number returned is the internal \prm {language} id number this object refers to.
+
+\subsection {\type {hyphenation}}
+
+\libindex {hyphenation}
+
+You can hyphenate a string directly with:
\startfunctioncall
<string> n = lang.hyphenation(<language> l)
lang.hyphenation(<language> l, <string> n)
\stopfunctioncall
-Either returns the current hyphenation exceptions for this language, or adds new
-ones. The syntax of the string is explained in~\in {section}
+\subsection {\type {clear_hyphenation} and \type {clean}}
+
+\libindex {clear_hyphenation}
+\libindex {clean}
+
+This either returns the current hyphenation exceptions for this language, or adds
+new ones. The syntax of the string is explained in~\in {section}
[patternsexceptions].
\startfunctioncall
lang.clear_hyphenation(<language> l)
\stopfunctioncall
-Clears the exception dictionary (string) for this language.
+This call clears the exception dictionary (string) for this language.
\startfunctioncall
<string> n = lang.clean(<language> l, <string> o)
<string> n = lang.clean(<string> o)
\stopfunctioncall
-Creates a hyphenation key from the supplied hyphenation value. The syntax of the
-argument string is explained in~\in {section} [patternsexceptions]. This function
-is useful if you want to do something else based on the words in a dictionary
-file, like spell|-|checking.
+This function creates a hyphenation key from the supplied hyphenation value. The
+syntax of the argument string is explained in \in {section} [patternsexceptions].
+This function is useful if you want to do something else based on the words in a
+dictionary file, like spell|-|checking.
+
+\subsection {\type {patterns} and \type {clear_patterns}}
+
+\libindex {patterns}
+\libindex {clear_patterns}
\startfunctioncall
<string> n = lang.patterns(<language> l)
lang.patterns(<language> l, <string> n)
\stopfunctioncall
-Adds additional patterns for this language object, or returns the current set.
-The syntax of this string is explained in~\in {section} [patternsexceptions].
+This adds additional patterns for this language object, or returns the current
+set. The syntax of this string is explained in \in {section}
+[patternsexceptions].
\startfunctioncall
lang.clear_patterns(<language> l)
\stopfunctioncall
-Clears the pattern dictionary for this language.
+This can be used to clear the pattern dictionary for a language.
+
+\subsection {\type {hyphenationmin}}
+
+\libindex {hyphenationmin}
+
+This function sets (or gets) the value of the \TEX\ parameter
+\type {\hyphenationmin}.
\startfunctioncall
-<number> n = lang.prehyphenchar(<language> l)
-lang.prehyphenchar(<language> l, <number> n)
+n = lang.hyphenationmin(<language> l)
+lang.hyphenationmin(<language> l, <number> n)
\stopfunctioncall
-Gets or sets the \quote {pre|-|break} hyphen character for implicit hyphenation
-in this language (initially the hyphen, decimal 45).
+\subsection {\type {[pre|post][ex|]hyphenchar}}
+
+\libindex {prehyphenchar}
+\libindex {posthyphenchar}
+\libindex {preexhyphenchar}
+\libindex {postexhyphenchar}
\startfunctioncall
+<number> n = lang.prehyphenchar(<language> l)
+lang.prehyphenchar(<language> l, <number> n)
+
<number> n = lang.posthyphenchar(<language> l)
lang.posthyphenchar(<language> l, <number> n)
\stopfunctioncall
-Gets or sets the \quote {post|-|break} hyphen character for implicit hyphenation
-in this language (initially null, decimal~0, indicating emptiness).
+These two are used to get or set the \quote {pre|-|break} and \quote
+{post|-|break} hyphen characters for implicit hyphenation in this language. The
+intial values are decimal 45 (hyphen) and decimal~0 (indicating emptiness).
\startfunctioncall
<number> n = lang.preexhyphenchar(<language> l)
lang.preexhyphenchar(<language> l, <number> n)
-\stopfunctioncall
-Gets or sets the \quote {pre|-|break} hyphen character for explicit hyphenation
-in this language (initially null, decimal~0, indicating emptiness).
-
-\startfunctioncall
<number> n = lang.postexhyphenchar(<language> l)
lang.postexhyphenchar(<language> l, <number> n)
\stopfunctioncall
-Gets or sets the \quote {post|-|break} hyphen character for explicit hyphenation
-in this language (initially null, decimal~0, indicating emptiness).
+These gets or set the \quote {pre|-|break} and \quote {post|-|break} hyphen
+characters for explicit hyphenation in this language. Both are initially
+decimal~0 (indicating emptiness).
+
+\subsection {\type {hyphenate}}
+
+\libindex {hyphenate}
+
+The next call inserts hyphenation points (discretionary nodes) in a node list. If
+\type {tail} is given as argument, processing stops on that node. Currently,
+\type {success} is always true if \type {head} (and \type {tail}, if specified)
+are proper nodes, regardless of possible other errors.
\startfunctioncall
<boolean> success = lang.hyphenate(<node> head)
<boolean> success = lang.hyphenate(<node> head, <node> tail)
\stopfunctioncall
-Inserts hyphenation points (discretionary nodes) in a node list. If \type {tail}
-is given as argument, processing stops on that node. Currently, \type {success}
-is always true if \type {head} (and \type {tail}, if specified) are proper nodes,
-regardless of possible other errors.
-
Hyphenation works only on \quote {characters}, a special subtype of all the glyph
nodes with the node subtype having the value \type {1}. Glyph modes with
-different subtypes are not processed. See \in {section~} [charsandglyphs] for
+different subtypes are not processed. See \in {section} [charsandglyphs] for
more details.
+\subsection {\type {[set|get]hjcode}}
+
+\libindex {sethjcode}
+\libindex {gethjcode}
+
The following two commands can be used to set or query hj codes:
\startfunctioncall
@@ -945,7 +1090,9 @@ lang.sethjcode(<language> l, <number> char, <number> usedchar)
\stopfunctioncall
When you set a hjcode the current sets get initialized unless the set was already
-initialized due to \type {\savinghyphcodes} being larger than zero.
+initialized due to \prm {savinghyphcodes} being larger than zero.
+
+\stopsection
\stopchapter
diff --git a/doc/context/sources/general/manuals/luatex/luatex-logos.tex b/doc/context/sources/general/manuals/luatex/luatex-logos.tex
index 7406dd602..3172336ec 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-logos.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-logos.tex
@@ -1,5 +1,7 @@
\startenvironment luatex-logos
+\usemodule[abr-02]
+
\logo[DFONT] {dfont}
\logo[CFF] {cff}
\logo[CMAP] {CMap}
diff --git a/doc/context/sources/general/manuals/luatex/luatex-lua.tex b/doc/context/sources/general/manuals/luatex/luatex-lua.tex
index 82b060440..f9107fa1f 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-lua.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-lua.tex
@@ -1,15 +1,17 @@
% language=uk
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-lua
-\startchapter[reference=lua,title={\LUA\ general}]
+\startchapter[reference=lua,title={Using \LUATEX}]
-\section[init]{Initialization}
+\startsection[title={Initialization},reference=init]
-\subsection{\LUATEX\ as a \LUA\ interpreter}
+\startsubsection[title={\LUATEX\ as a \LUA\ interpreter}]
+
+\topicindex {initialization}
+\topicindex {\LUA+interpreter}
There are some situations that make \LUATEX\ behave like a standalone \LUA\
interpreter:
@@ -35,7 +37,11 @@ positive values, just like the \LUA\ interpreter.
in effect, a somewhat bulky stand alone \LUA\ interpreter with a bunch of extra
preloaded libraries.
-\subsection{\LUATEX\ as a \LUA\ byte compiler}
+\stopsubsection
+
+\startsubsection[title={\LUATEX\ as a \LUA\ byte compiler}]
+
+\topicindex {\LUA+byte code}
There are two situations that make \LUATEX\ behave like the \LUA\ byte compiler:
@@ -46,9 +52,15 @@ There are two situations that make \LUATEX\ behave like the \LUA\ byte compiler:
In this mode, \LUATEX\ is exactly like \type {luac} from the stand alone \LUA\
distribution, except that it does not have the \type {-l} switch, and that it
-accepts (but ignores) the \type {--luaconly} switch.
+accepts (but ignores) the \type {--luaconly} switch. The current version of \LUA\
+can dump bytecode using \type {string.dump} so we might decide to drop this
+version of \LUATEX.
-\subsection{Other commandline processing}
+\stopsubsection
+
+\startsubsection[title={Other commandline processing}]
+
+\topicindex {command line}
When the \LUATEX\ executable starts, it looks for the \type {--lua} command line
option. If there is no \type {--lua} option, the command line is interpreted in a
@@ -56,6 +68,8 @@ similar fashion as the other \TEX\ engines. Some options are accepted but have n
consequence. The following command|-|line options are understood:
\starttabulate[|l|p|]
+\DB commandline argument \BC explanation \NC \NR
+\TB
\NC \type{--credits} \NC display credits and exit \NC \NR
\NC \type{--debug-format} \NC enable format debugging \NC \NR
\NC \type{--draftmode} \NC switch on draft mode i.e.\ generate no output in \PDF\ mode \NC \NR
@@ -65,112 +79,137 @@ consequence. The following command|-|line options are understood:
\NC \type{--halt-on-error} \NC stop processing at the first error\NC \NR
\NC \type{--help} \NC display help and exit \NC\NR
\NC \type{--ini} \NC be \type {iniluatex}, for dumping formats \NC\NR
-\NC \type{--interaction=STRING} \NC set interaction mode: \type {batchmode}, \type {nonstopmode}, \type {scrollmode} or \type {errorstopmode} \NC \NR
+\NC \type{--interaction=STRING} \NC set interaction mode: \type {batchmode}, \type {nonstopmode},
+ \type {scrollmode} or \type {errorstopmode} \NC \NR
\NC \type{--jobname=STRING} \NC set the job name to \type {STRING} \NC \NR
-\NC \type{--kpathsea-debug=NUMBER} \NC set path searching debugging flags according to the bits of \type {NUMBER} \NC \NR
+\NC \type{--kpathsea-debug=NUMBER} \NC set path searching debugging flags according to the bits of
+ \type {NUMBER} \NC \NR
\NC \type{--lua=FILE} \NC load and execute a \LUA\ initialization script \NC\NR
-\NC \type{--[no-]mktex=FMT} \NC disable/enable \type {mktexFMT} generation with \type {FMT} is \type {tex} or \type {tfm} \NC \NR
+\NC \type{--[no-]mktex=FMT} \NC disable/enable \type {mktexFMT} generation with \type {FMT} is
+ \type {tex} or \type {tfm} \NC \NR
\NC \type{--nosocket} \NC disable the \LUA\ socket library \NC\NR
-\NC \type{--output-comment=STRING} \NC use \type {STRING} for \DVI\ file comment instead of date (no effect for \PDF) \NC \NR
+\NC \type{--output-comment=STRING} \NC use \type {STRING} for \DVI\ file comment instead of date (no
+ effect for \PDF) \NC \NR
\NC \type{--output-directory=DIR} \NC use \type {DIR} as the directory to write files to \NC \NR
-\NC \type{--output-format=FORMAT} \NC use \type {FORMAT} for job output; \type {FORMAT} is \type {dvi} or \type {pdf} \NC \NR
+\NC \type{--output-format=FORMAT} \NC use \type {FORMAT} for job output; \type {FORMAT} is \type {dvi}
+ or \type {pdf} \NC \NR
\NC \type{--progname=STRING} \NC set the program name to \type {STRING} \NC \NR
\NC \type{--recorder} \NC enable filename recorder \NC \NR
\NC \type{--safer} \NC disable easily exploitable \LUA\ commands \NC\NR
\NC \type{--[no-]shell-escape} \NC disable/enable system calls \NC \NR
-\NC \type{--shell-restricted} \NC restrict system calls to a list of commands given in \type {texmf.cnf} \NC \NR
+\NC \type{--shell-restricted} \NC restrict system calls to a list of commands given in \type
+ {texmf.cnf} \NC \NR
\NC \type{--synctex=NUMBER} \NC enable \type {synctex} \NC \NR
\NC \type{--utc} \NC use utc times when applicable \NC \NR
\NC \type{--version} \NC display version and exit \NC \NR
+\LL
\stoptabulate
-Some of the traditional flags are just ignored: \type {--etex}, \type
-{--translate-file}, \type {--8bit}. \type {--[no-]parse-first-line}, \type
-{--default-translate-file}. Also, we no longer support write18 because \type
-{os.execute} can do the same.
+We don't support \prm {write} 18 because \type {os.execute} can do the same. It
+simplifies the code and makes more write targets possible.
-The value to use for \type {\jobname} is decided as follows:
+The value to use for \prm {jobname} is decided as follows:
\startitemize
\startitem
If \type {--jobname} is given on the command line, its argument will be the
- value for \type {\jobname}, without any changes. The argument will not be
+ value for \prm {jobname}, without any changes. The argument will not be
used for actual input so it need not exist. The \type {--jobname} switch only
- controls the \type {\jobname} setting.
+ controls the \prm {jobname} setting.
\stopitem
\startitem
- Otherwise, \type {\jobname} will be the name of the first file that is read
+ Otherwise, \prm {jobname} will be the name of the first file that is read
from the file system, with any path components and the last extension (the
part following the last \type {.}) stripped off.
\stopitem
\startitem
- An exception to the previous point: if the command line goes into interactive
- mode (by starting with a command) and there are no files input via \type
- {\everyjob} either, then the \type {\jobname} is set to \type {texput} as a
- last resort.
+ There is an exception to the previous point: if the command line goes into
+ interactive mode (by starting with a command) and there are no files input
+ via \prm {everyjob} either, then the \prm {jobname} is set to \type
+ {texput} as a last resort.
\stopitem
\stopitemize
The file names for output files that are generated automatically are created by
attaching the proper extension (\type {log}, \type {pdf}, etc.) to the found
-\type {\jobname}. These files are created in the directory pointed to by \type
+\prm {jobname}. These files are created in the directory pointed to by \type
{--output-directory}, or in the current directory, if that switch is not present.
-\blank
-
Without the \type {--lua} option, command line processing works like it does in
-any other web2c-based typesetting engine, except that \LUATEX\ has a few extra
-switches.
-
-If the \type {--lua} option is present, \LUATEX\ will enter an alternative mode
-of command line processing in comparison to the standard web2c programs.
-
-In this mode, a small series of actions is taken in order. First, it will parse
-the command line as usual, but it will only interpret a small subset of the
-options immediately: \type {--safer}, \type {--nosocket}, \type
-{--[no-]shell-escape}, \type {--enable-write18}, \type {--disable-write18}, \type
-{--shell-restricted}, \type {--help}, \type {--version}, and \type {--credits}.
-
-Next \LUATEX\ searches for the requested \LUA\ initialization script. If it
-cannot be found using the actual name given on the command line, a second attempt
-is made by prepending the value of the environment variable \type {LUATEXDIR}, if
-that variable is defined in the environment.
-
-Then it checks the various safety switches. You can use those to disable some
-\LUA\ commands that can easily be abused by a malicious document. At the moment,
-\type {--safer} \type {nil}s the following functions:
-
-\starttabulate[|l|l|]
-\BC library \BC functions \NC \NR
-\NC \type {os} \NC \type {execute} \type {exec} \type {spawn} \type {setenv} \type {rename} \type {remove} \type {tmpdir} \NC \NR
-\NC \type {io} \NC \type {popen} \type {output} \type {tmpfile} \NC \NR
-\NC \type {lfs} \NC \type {rmdir} \type {mkdir} \type {chdir} \type {lock} \type {touch} \NC \NR
-\stoptabulate
+any other \WEBC|-|based typesetting engine, except that \LUATEX\ has a few extra
+switches and lacks some others. Also, if the \type {--lua} option is present,
+\LUATEX\ will enter an alternative mode of command line processing in comparison
+to the standard \WEBC\ programs. In this mode, a small series of actions is taken
+in the following order:
-Furthermore, it disables loading of compiled \LUA\ libraries and it makes \type
-{io.open()} fail on files that are opened for anything besides reading.
+\startitemize[n]
-When \LUATEX\ starts it set the locale to a neutral value. If for some reason you
-use \type {os.locale}, you need to make sure you \type {nil} it afterwards
-because otherwise it can interfere with code that for instance generates dates.
-You can nil the locale with
+\startitem
+ First, it will parse the command line as usual, but it will only interpret a
+ small subset of the options immediately: \type {--safer}, \type {--nosocket},
+ \type {--[no-]shell-escape}, \type {--enable-write18}, \type
+ {--disable-write18}, \type {--shell-restricted}, \type {--help}, \type
+ {--version}, and \type {--credits}.
+\stopitem
-\starttyping
-os.setlocale(nil.nil)
-\stoptyping
+\startitem
+ Next \LUATEX\ searches for the requested \LUA\ initialization script. If it
+ cannot be found using the actual name given on the command line, a second
+ attempt is made by prepending the value of the environment variable \type
+ {LUATEXDIR}, if that variable is defined in the environment.
+\stopitem
+
+\startitem
+ Then it checks the various safety switches. You can use those to disable some
+ \LUA\ commands that can easily be abused by a malicious document. At the
+ moment, \type {--safer} \type {nil}s the following functions:
+
+ \blank
+
+ \starttabulate[|c|l|]
+ \DB library \BC functions \NC \NR
+ \TB
+ \NC \type {os} \NC \type {execute} \type {exec} \type {spawn} \type {setenv}
+ \type {rename} \type {remove} \type {tmpdir} \NC \NR
+ \NC \type {io} \NC \type {popen} \type {output} \type {tmpfile} \NC \NR
+ \NC \type {lfs} \NC \type {rmdir} \type {mkdir} \type {chdir} \type {lock}
+ \type {touch} \NC \NR
+ \LL
+ \stoptabulate
-The \type {--nosocket} option makes the socket library unavailable, so that \LUA\
-cannot use networking.
+ \blank
-The switches \type {--[no-]shell-escape}, \type {--[enable|disable]-write18}, and
-\type {--shell-restricted} have the same effects as in \PDFTEX, and additionally
-make \type {io.popen()}, \type {os.execute}, \type {os.exec} and \type {os.spawn}
-adhere to the requested option.
+ Furthermore, it disables loading of compiled \LUA\ libraries and it makes
+ \type {io.open()} fail on files that are opened for anything besides reading.
+\stopitem
+
+\startitem
+ When \LUATEX\ starts it sets the \type {locale} to a neutral value. If for
+ some reason you use \type {os.locale}, you need to make sure you \type {nil}
+ it afterwards because otherwise it can interfere with code that for instance
+ generates dates. You can ignore the \type {locale} with:
-Next the initialization script is loaded and executed. From within the script,
-the entire command line is available in the \LUA\ table \type {arg}, beginning with
-\type {arg[0]}, containing the name of the executable. As consequence warnings
-about unrecognized options are suppressed.
+ \starttyping
+ os.setlocale(nil,nil)
+ \stoptyping
+
+ The \type {--nosocket} option makes the socket library unavailable, so that \LUA\
+ cannot use networking.
+
+ The switches \type {--[no-]shell-escape}, \type {--[enable|disable]-write18}, and
+ \type {--shell-restricted} have the same effects as in \PDFTEX, and additionally
+ make \type {io.popen()}, \type {os.execute}, \type {os.exec} and \type {os.spawn}
+ adhere to the requested option.
+\stopitem
+
+\startitem
+ Next the initialization script is loaded and executed. From within the
+ script, the entire command line is available in the \LUA\ table \type {arg},
+ beginning with \type {arg[0]}, containing the name of the executable. As
+ consequence warnings about unrecognized options are suppressed.
+\stopitem
+
+\stopitemize
Command line processing happens very early on. So early, in fact, that none of
\TEX's initializations have taken place yet. For that reason, the tables that
@@ -179,7 +218,7 @@ deal with typesetting, like \type {tex}, \type {token}, \type {node} and
are \type {nil}'d). Special care is taken that \type {texio.write} and \type
{texio.write_nl} function properly, so that you can at least report your actions
to the log file when (and if) it eventually becomes opened (note that \TEX\ does
-not even know its \type {\jobname} yet at this point).
+not even know its \prm {jobname} yet at this point).
Everything you do in the \LUA\ initialization script will remain visible during
the rest of the run, with the exception of the \TEX\ specific libraries like
@@ -205,17 +244,34 @@ finished: in order to initialize the built|-|in \KPATHSEA\ library properly,
check \type {--progname}, or \type {--ini} and \type {--fmt}, if \type
{--progname} is missing.
-\section{\LUA\ behaviour}
+\stopsubsection
+
+\stopsection
+
+\startsection[title={\LUA\ behaviour}]
+
+\startsubsection[title={The \LUA\ version}]
+
+\topicindex {\LUA+libraries}
+\topicindex {\LUA+extensions}
+
+We currently use \LUA\ 5.3 and will follow developments of the language but
+normally with some delay. Therefore the user needs to keep an eye on (subtle)
+differences in successive versions of the language. Also, \LUAJITTEX\ lags behind
+in the sense that \LUAJIT\ is not in sync with regular \LUA\ development. Here is
+an example of one aspect.
\LUA s \type {tostring} function (and \type {string.format} may return values in
scientific notation, thereby confusing the \TEX\ end of things when it is used as
-the right|-|hand side of an assignment to a \type {\dimen} or \type {\count}.
+the right|-|hand side of an assignment to a \prm {dimen} or \prm {count}. The
+output of these serializers also depend on the \LUA\ version, so in \LUA\ 5.3 you
+can get different output than from 5.2.
-Loading dynamic \LUA\ libraries will fail if there are two \LUA\ libraries loaded
-at the same time (which will typically happen on \type {win32}, because there is
-one \LUA\ 5.3 inside \LUATEX, and another will likely be linked to the \DLL\ file
-of the module itself).
+\stopsubsection
+
+\startsubsection[title={Integration in the \TDS\ ecosystem}]
+The main \TEX\ distributions follow the \TEX\ directory structure (\TDS).
\LUATEX\ is able to use the kpathsea library to find \type {require()}d modules.
For this purpose, \type {package.searchers[2]} is replaced by a different loader
function, that decides at runtime whether to use kpathsea or the built|-|in core
@@ -226,6 +282,10 @@ Initialization of \KPATHSEA\ can happen either implicitly (when \LUATEX\ starts
up and the startup script has not set \type {texconfig.kpse_init} to false), or
explicitly by calling the \LUA\ function \type {kpse.set_program_name()}.
+\stopsubsection
+
+\startsubsection[title={Loading libraries}]
+
\LUATEX\ is able to use dynamically loadable \LUA\ libraries, unless
\type {--safer} was given as an option on the command line. For this purpose,
\type {package.searchers[3]} is replaced by a different loader function, that
@@ -233,12 +293,10 @@ decides at runtime whether to use \KPATHSEA\ or the built|-|in core \LUA\
function. It uses \KPATHSEA\ when that is already initialized at that point in
time, otherwise it reverts to using the normal \type {package.cpath} loader.
-This functionality required an extension to kpathsea:
-
-\startnarrower
-There is a new kpathsea file format: \type {kpse_clua_format} that searches for
-files with extension \type {.dll} and \type {.so}. The \type {texmf.cnf} setting
-for this variable is \type {CLUAINPUTS}, and by default it has this value:
+This functionality required an extension to kpathsea. There is a new kpathsea
+file format: \type {kpse_clua_format} that searches for files with extension
+\type {.dll} and \type {.so}. The \type {texmf.cnf} setting for this variable is
+\type {CLUAINPUTS}, and by default it has this value:
\starttyping
CLUAINPUTS=.:$SELFAUTOLOC/lib/{$progname,$engine,}/lua//
@@ -248,12 +306,18 @@ This path is imperfect (it requires a \TDS\ subtree below the binaries
directory), but the architecture has to be in the path somewhere, and the
currently simplest way to do that is to search below the binaries directory only.
Of course it no big deal to write an alternative loader and use that in a macro
-package.
+package. One level up (a \type {lib} directory parallel to \type {bin}) would
+have been nicer, but that is not doable because \TEXLIVE\ uses a \type
+{bin/<arch>} structure.
+
+Loading dynamic \LUA\ libraries will fail if there are two \LUA\ libraries loaded
+at the same time (which will typically happen on \type {win32}, because there is
+one \LUA\ 5.3 inside \LUATEX, and another will likely be linked to the \DLL\ file
+of the module itself).
-One level up (a \type {lib} directory parallel to \type {bin}) would have been
-nicer, but that is not doable because \TEXLIVE\ uses a \type {bin/<arch>}
-structure.
-\stopnarrower
+\stopsubsection
+
+\startsubsection[title={Executing programs}]
In keeping with the other \TEX|-|like programs in \TEXLIVE, the two \LUA\ functions
\type {os.execute} and \type {io.popen}, as well as the two new functions \type
@@ -265,26 +329,29 @@ the command line option \type {--luaonly} was not given), it will only run the
four functions above if the matching \type {texmf.cnf} variable(s) or their \type
{texconfig} (see \in {section} [texconfig]) counterparts allow execution of the
requested system command. In \quote {script interpreter} runs of \LUATEX, these
-settings have no effect, and all four functions function as normal.
-
-The \type {f:read("*line")} and \type {f:lines()} functions from the io library
-have been adjusted so that they are line|-|ending neutral: any of \type {LF},
-\type {CR} or \type {CR+LF} are acceptable line endings.
-
-\type {luafilesystem} has been extended: there are two extra boolean functions
-(\type {lfs.isdir(filename)} and \type {lfs.isfile(filename)}) and one extra
-string field in its attributes table (\type {permissions}). There is an
-additional function \type {lfs.shortname()} which takes a file name and returns
-its short name on \type {win32} platforms. On other platforms, it just returns
-the given argument. The file name is not tested for existence. Finally, for
-non|-|\type {win32} platforms only, there is the new function \type
-{lfs.readlink()} hat takes an existing symbolic link as argument and returns its
-content. It returns an error on \type {win32}.
-
-The \type {string} library has an extra function: \type {string.explode(s[,m])}.
-This function returns an array containing the string argument \type {s} split
-into sub-strings based on the value of the string argument \type {m}. The second
-argument is a string that is either empty (this splits the string into
+settings have no effect, and all four functions have their original meaning.
+
+Some libraries have a few more functions, either coded in \CCODE\ or in \LUA. For
+instance, when we started with \LUATEX\ we added some helpers to the \type
+{luafilesystem} namespace \type {lfs}. The two boolean functions \type
+{lfs.isdir} and \type {lfs.isfile} were speedy and better variants of what could
+be done with \type {lfs.attributes}. The additional function \type
+{lfs.shortname} takes a file name and returns its short name on \type {win32}
+platforms. Finally, for non|-|\type {win32} platforms only, we provided \type
+{lfs.readlink} that takes an existing symbolic link as argument and returns its
+name. However, the \type library evolved so we have dropped these in favour of
+pure \LUA\ variants. The \type {shortname} helper is obsolete and now just
+returns the name.
+
+\stopsubsection
+
+\startsubsection[title={Multibyte \type {string} functions}]
+
+The \type {string} library has a few extra functions, for example \libidx
+{string} {explode}. This function takes upto two arguments: \type
+{string.explode(s[,m])} and returns an array containing the string argument \type
+{s} split into sub-strings based on the value of the string argument \type {m}.
+The second argument is a string that is either empty (this splits the string into
characters), a single character (this splits on each occurrence of that
character, possibly introducing empty strings), or a single character followed by
the plus sign \type {+} (this special version does not create empty sub-strings).
@@ -293,7 +360,9 @@ The default value for \type {m} is \quote {\type { +}} (multiple spaces). Note:
written in \TEX\ macros.
The \type {string} library also has six extra iterators that return strings
-piecemeal:
+piecemeal: \libidx {string} {utfvalues}, \libidx {string} {utfcharacters},
+\libidx {string} {characters}, \libidx {string} {characterpairs}, \libidx
+{string} {bytes} and \libidx {string} {bytepairs}.
\startitemize
\startitem
@@ -303,7 +372,7 @@ piecemeal:
\type {string.utfcharacters(s)}: a string with a single \UTF-8 token in it
\stopitem
\startitem
- \type {string.characters(s)}: a string containing one byte
+ \type {string.cWharacters(s)}: a string containing one byte
\stopitem
\startitem
\type {string.characterpairs(s)}: two strings each containing one byte or an
@@ -323,7 +392,8 @@ are useful especially in the conversion of \UTF16 encoded data into \UTF8.
There is also a two|-|argument form of \type {string.dump()}. The second argument
is a boolean which, if true, strips the symbols from the dumped data. This
-matches an extension made in \type {luajit}.
+matches an extension made in \type {luajit}. This is typically a function that
+gets adapted as \LUA\ itself progresses.
The \type {string} library functions \type {len}, \type {lower}, \type {sub}
etc.\ are not \UNICODE|-|aware. For strings in the \UTF8 encoding, i.e., strings
@@ -338,7 +408,8 @@ interpretation of character classes in \type {unicode.utf8} functions refer to
the library sources at \hyphenatedurl {http://luaforge.net/projects/sln}.
Version 5.3 of \LUA\ provides some native \UTF8 support but we have added a few
-similar helpers too:
+similar helpers too: \libidx {string} {utfvalue}, \libidx {string} {utfcharacter}
+and \libidx {string} {utflength}.
\startitemize
\startitem
@@ -354,13 +425,18 @@ similar helpers too:
\stopitem
\stopitemize
-These three functions are relative fast and don't do much checking. They can be used
-as building blocks for other helpers.
+These three functions are relative fast and don't do much checking. They can be
+used as building blocks for other helpers.
+\stopsubsection
-\blank
+\startsubsection[title={Extra \type {os} library functions}]
-The \type {os} library has a few extra functions and variables:
+The \type {os} library has a few extra functions and variables: \libidx {os}
+{selfdir}, \libidx {os} {exec}, \libidx {os} {spawn}, \libidx {os} {setenv},
+\libidx {os} {env}, \libidx {os} {gettimeofday}, \libidx {os} {times}, \libidx
+{os} {tmpdir}, \libidx {os} {type}, \libidx {os} {name} and \libidx {os} {uname},
+that we will discuss here.
\startitemize
@@ -373,25 +449,37 @@ The \type {os} library has a few extra functions and variables:
\type {os.exec(commandline)} is a variation on \type {os.execute}. Here
\type {commandline} can be either a single string or a single table.
- If the argument is a table \LUATEX\ first checks if there is a value at
- integer index zero. If there is, this is the command to be executed.
- Otherwise, it will use the value at integer index one. If neither are
- present, nothing at all happens.
-
- The set of consecutive values starting at integer~1 in the table are the
- arguments that are passed on to the command (the value at index~1 becomes
- \type {arg[0]}). The command is searched for in the execution path, so there
- is normally no need to pass on a fully qualified path name.
-
- If the argument is a string, then it is automatically converted into a table
- by splitting on whitespace. In this case, it is impossible for the command
- and first argument to differ from each other.
-
- In the string argument format, whitespace can be protected by putting (part
- of) an argument inside single or double quotes. One layer of quotes is
- interpreted by \LUATEX, and all occurrences of \type {\"}, \type {\'} or \type
- {\\} within the quoted text are unescaped. In the table format, there is no
- string handling taking place.
+ \startitemize
+
+ \startitem
+ If the argument is a table \LUATEX\ first checks if there is a value at
+ integer index zero. If there is, this is the command to be executed.
+ Otherwise, it will use the value at integer index one. If neither are
+ present, nothing at all happens.
+ \stopitem
+
+ \startitem
+ The set of consecutive values starting at integer~1 in the table are the
+ arguments that are passed on to the command (the value at index~1 becomes
+ \type {arg[0]}). The command is searched for in the execution path, so
+ there is normally no need to pass on a fully qualified path name.
+ \stopitem
+
+ \startitem
+ If the argument is a string, then it is automatically converted into a
+ table by splitting on whitespace. In this case, it is impossible for the
+ command and first argument to differ from each other.
+ \stopitem
+
+ \startitem
+ In the string argument format, whitespace can be protected by putting
+ (part of) an argument inside single or double quotes. One layer of quotes
+ is interpreted by \LUATEX, and all occurrences of \type {\"}, \type {\'}
+ or \type {\\} within the quoted text are unescaped. In the table format,
+ there is no string handling taking place.
+ \stopitem
+
+ \stopitemize
This function normally does not return control back to the \LUA\ script: the
command will replace the current process. However, it will return the two
@@ -470,14 +558,86 @@ The \type {os} library has a few extra functions and variables:
\stopitem
\startitem
- \type {os.uname()} returns a table with specific operating system
+ \type {os.uname} returns a table with specific operating system
information acquired at runtime. The keys in the returned table are all
- string valued, and their names are: \type {sysname}, \type {machine}, \type
+ string values, and their names are: \type {sysname}, \type {machine}, \type
{release}, \type {version}, and \type {nodename}.
\stopitem
\stopitemize
+\stopsubsection
+
+\startsubsection[title={Binary input from files with \type {fio}}]
+
+There is a whole set of helpers for reading numbers and strings from a file:
+\libidx {fio} {readcardinal1}, \libidx {fio} {readcardinal2}, \libidx {fio}
+{readcardinal3}, \libidx {fio} {readcardinal4}, \libidx {fio}
+{readcardinaltable}, \libidx {fio} {readinteger1}, \libidx {fio} {readinteger2},
+\libidx {fio} {readinteger3}, \libidx {fio} {readinteger4}, \libidx {fio}
+{readintegertable}, \libidx {fio} {readfixed2}, \libidx {fio} {readfixed4},
+\libidx {fio} {read2dot14}, \libidx {fio} {setposition}, \libidx {fio}
+{getposition}, \libidx {fio} {skipposition}, \libidx {fio} {readbytes}, \libidx
+{fio} {readbytetable}. They work on normal \LUA\ file handles.
+
+%libidx{fio}{readline}
+%libidx{fio}{recordfilename}
+%libidx{fio}{checkpermission}
+
+This library provides a set of functions for reading numbers from a file and
+in addition to the regular \type {io} library functions.
+
+\starttabulate
+\NC \type{readcardinal1(f)} \NC a 1 byte unsigned integer \NC \NR
+\NC \type{readcardinal2(f)} \NC a 2 byte unsigned integer \NC \NR
+\NC \type{readcardinal3(f)} \NC a 3 byte unsigned integer \NC \NR
+\NC \type{readcardinal4(f)} \NC a 4 byte unsigned integer \NC \NR
+\NC \type{readcardinaltable(f,n,b)} \NC \type {n} cardinals of \type {b} bytes \NC \NR
+\NC \type{readinteger1(f)} \NC a 1 byte signed integer \NC \NR
+\NC \type{readinteger2(f)} \NC a 2 byte signed integer \NC \NR
+\NC \type{readinteger3(f)} \NC a 3 byte signed integer \NC \NR
+\NC \type{readinteger4(f)} \NC a 4 byte signed integer \NC \NR
+\NC \type{readintegertable(f,n,b)} \NC \type {n} integers of \type {b} bytes \NC \NR
+\NC \type{readfixed2(f)} \NC a 2 byte float (used in font files) \NC \NR
+\NC \type{readfixed4(f)} \NC a 4 byte float (used in font files) \NC \NR
+\NC \type{read2dot14(f)} \NC a 2 byte float (used in font files) \NC \NR
+\NC \type{setposition(f,p)} \NC goto position \type {p} \NC \NR
+\NC \type{getposition(f)} \NC get the current position \NC \NR
+\NC \type{skipposition(f,n)} \NC skip \type {n} positions \NC \NR
+\NC \type{readbytes(f,n)} \NC \type {n} bytes \NC \NR
+\NC \type{readbytetable(f,n)} \NC \type {n} bytes\NC \NR
+\stoptabulate
+
+\stopsubsection
+
+\startsubsection[title={Binary input from strings with \type {sio}}]
+
+A similar set of function as in the \type {fio} library is available in the \type
+{sio} library: \libidx {sio} {readcardinal1}, \libidx {sio} {readcardinal2},
+\libidx {sio} {readcardinal3}, \libidx {sio} {readcardinal4}, \libidx {sio}
+{readcardinaltable}, \libidx {sio} {readinteger1}, \libidx {sio} {readinteger2},
+\libidx {sio} {readinteger3}, \libidx {sio} {readinteger4}, \libidx {sio}
+{readintegertable}, \libidx {sio} {readfixed2}, \libidx {sio} {readfixed4},
+\libidx {sio} {read2dot14}, \libidx {sio} {setposition}, \libidx {sio}
+{getposition}, \libidx {sio} {skipposition}, \libidx {sio} {readbytes} and
+\libidx {sio} {readbytetable}. Here the first argument is a string instead of a
+file handle. More details can be found in the previous section.
+
+\stopsubsection
+
+\startsubsection[title={Hashes conform \type {sha2}}]
+
+This library is a side effect of the \type {pdfe} library that needs such
+helpers. The \libidx{sha2}{digest256}, \libidx{sha2}{digest384} and
+\libidx{sha2}{digest512} functions accept a string and return a string with the
+hash.
+
+\stopsubsection
+
+\startsubsection[title={Locales}]
+
+\index {locales}
+
In stock \LUA, many things depend on the current locale. In \LUATEX, we can't do
that, because it makes documents unportable. While \LUATEX\ is running if
forces the following locale settings:
@@ -488,7 +648,14 @@ LC_COLLATE=C
LC_NUMERIC=C
\stoptyping
-\section {\LUA\ modules}
+\stopsubsection
+
+\stopsection
+
+\startsection[title={\LUA\ modules}]
+
+\topicindex {\LUA+libraries}
+\topicindex {\LUA+modules}
Some modules that are normally external to \LUA\ are statically linked in with
\LUATEX, because they offer useful functionality:
@@ -496,11 +663,27 @@ Some modules that are normally external to \LUA\ are statically linked in with
\startitemize
\startitem
+ \type {lpeg}, by Roberto Ierusalimschy, \hyphenatedurl
+ {http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html}. This library is not
+ \UNICODE|-|aware, but interprets strings on a byte|-|per|-|byte basis. This
+ mainly means that \type {lpeg.S} cannot be used with \UTF8 characters encoded
+ in more than two bytes, and thus \type {lpeg.S} will look for one of those
+ two bytes when matching, not the combination of the two. The same is true for
+ \type {lpeg.R}, although the latter will display an error message if used
+ with multibyte characters. Therefore \type {lpeg.R('aä')} results in the
+ message \type {bad argument #1 to 'R' (range must have two characters)},
+ since to \type {lpeg}, \type {ä} is two 'characters' (bytes), so \type {aä}
+ totals three. In practice this is no real issue and with some care you can
+ deal with \UNICODE\ just fine.
+\stopitem
+
+\startitem
\type {slnunicode}, from the \type {selene} libraries, \hyphenatedurl
{http://luaforge.net/projects/sln}. This library has been slightly extended
so that the \type {unicode.utf8.*} functions also accept the first 256 values
of plane~18. This is the range \LUATEX\ uses for raw binary output, as
- explained above.
+ explained above. We have no plans to provide more like this because you can
+ basically do all that you want in \LUA.
\stopitem
\startitem
@@ -514,20 +697,6 @@ Some modules that are normally external to \LUA\ are statically linked in with
\stopitem
\startitem
- \type {lpeg}, by Roberto Ierusalimschy, \hyphenatedurl
- {http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html}. This library is not
- \UNICODE|-|aware, but interprets strings on a byte|-|per|-|byte basis. This
- mainly means that \type {lpeg.S} cannot be used with \UTF8 characters encoded
- in more than two bytes, and thus \type {lpeg.S} will look for one of those
- two bytes when matching, not the combination of the two. The same is true for
- \type {lpeg.R}, although the latter will display an error message if used
- with multibyte characters. Therefore \type {lpeg.R('aä')} results in the
- message \type {bad argument #1 to 'R' (range must have two characters)},
- since to \type {lpeg}, \type {ä} is two 'characters' (bytes), so \type {aä}
- totals three. In practice this is no real issue.
-\stopitem
-
-\startitem
\type {lzlib}, by Tiago Dionizio, \hyphenatedurl
{http://luaforge.net/projects/lzlib/}.
\stopitem
@@ -546,11 +715,12 @@ Some modules that are normally external to \LUA\ are statically linked in with
\stopitemize
-At some point (this also depends on distributions) \LUATEX\ might have these
-libraries loaded on demand. For this reason you can best use \type {require} to
-make sure they are loaded.
+\stopsection
-\section{Testing}
+\startsection[title={Testing}]
+
+\topicindex {testing}
+\topicindex {\PDF+date}
For development reasons you can influence the used startup date and time. This can
be done in two ways.
@@ -579,17 +749,11 @@ When Universal Time is needed, you can pass the flag \type {utc} to the engine.
property also works when the date and time are set by \LUATEX\ itself. It has a
complementary entry \type {use_utc_time} in the \type {texconfig} table.
-\startnotabene
- To some extend a cleaner solution would be to have a flag that disables all
- variable data in one go (like filenames and so) but we just follow the method
- implemented in \PDFTEX\ where primitives are used to influence other
- properties.
-\stopnotabene
-
-\startnotabene
- In \CONTEXT\ we provide the command line argument \type {--nodates} that does
- bit more disabling of dates.
-\stopnotabene
+There is some control possible, for instance prevent filename to be written to
+the \PDF\ file. This is discussed elsewhere. In \CONTEXT\ we provide the command
+line argument \type {--nodates} that does a bit more disabling of dates.
+
+\stopsection
\stopchapter
diff --git a/doc/context/sources/general/manuals/luatex/luatex-math.tex b/doc/context/sources/general/manuals/luatex/luatex-math.tex
index 8ccae83f3..4623ce706 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-math.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-math.tex
@@ -1,12 +1,15 @@
% language=uk
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-math
\startchapter[reference=math,title={Math}]
+\startsection[title={Traditional alongside \OPENTYPE}]
+
+\topicindex {math}
+
The handling of mathematics in \LUATEX\ differs quite a bit from how \TEX82 (and
therefore \PDFTEX) handles math. First, \LUATEX\ adds primitives and extends some
others so that \UNICODE\ input can be used easily. Second, all of \TEX82's
@@ -16,18 +19,133 @@ make it easier to use \OPENTYPE\ math fonts. And finally, there are some
extensions that have been proposed or considered in the past that are now added
to the engine.
-\section{The current math style}
+\stopsection
+
+\startsection[title={Unicode math characters}]
+
+\topicindex {math+\UNICODE}
+\topicindex {\UNICODE+math}
+
+Character handling is now extended up to the full \UNICODE\ range (the \type {\U}
+prefix), which is compatible with \XETEX.
+
+The math primitives from \TEX\ are kept as they are, except for the ones that
+convert from input to math commands: \type {mathcode}, and \type {delcode}. These
+two now allow for a 21-bit character argument on the left hand side of the equals
+sign.
+
+Some of the new \LUATEX\ primitives read more than one separate value. This is
+shown in the tables below by a plus sign.
+
+The input for such primitives would look like this:
+
+\starttyping
+\def\overbrace{\Umathaccent 0 1 "23DE }
+\stoptyping
+
+The altered \TEX82 primitives are:
+
+\starttabulate[|l|l|r|c|l|r|]
+\DB primitive \BC min \BC max \BC \kern 2em \BC min \BC max \NC \NR
+\TB
+\NC \prm {mathcode} \NC 0 \NC 10FFFF \NC = \NC 0 \NC 8000 \NC \NR
+\NC \prm {delcode} \NC 0 \NC 10FFFF \NC = \NC 0 \NC FFFFFF \NC \NR
+\LL
+\stoptabulate
+
+The unaltered ones are:
+
+\starttabulate[|l|l|r|]
+\DB primitive \BC min \BC max \NC \NR
+\TB
+\NC \prm {mathchardef} \NC 0 \NC 8000 \NC \NR
+\NC \prm {mathchar} \NC 0 \NC 7FFF \NC \NR
+\NC \prm {mathaccent} \NC 0 \NC 7FFF \NC \NR
+\NC \prm {delimiter} \NC 0 \NC 7FFFFFF \NC \NR
+\NC \prm {radical} \NC 0 \NC 7FFFFFF \NC \NR
+\LL
+\stoptabulate
+
+For practical reasons \prm {mathchardef} will silently accept values larger
+that \type {0x8000} and interpret it as \lpr {Umathcharnumdef}. This is needed
+to satisfy older macro packages.
+
+The following new primitives are compatible with \XETEX:
+
+% somewhat fuzzy:
+
+\starttabulate[|l|l|r|c|l|r|]
+\DB primitive \BC min \BC max \BC \kern 2em \BC min \BC max \NC \NR
+\TB
+\NC \lpr {Umathchardef} \NC 0+0+0 \NC 7+FF+10FFFF \NC \NC \NC \NC \NR
+\NC \lpr {Umathcharnumdef}\rlap{\high{5}} \NC -80000000 \NC 7FFFFFFF \NC \NC \NC \NC \NR
+\NC \lpr {Umathcode} \NC 0 \NC 10FFFF \NC = \NC 0+0+0 \NC 7+FF+10FFFF \NC \NR
+\NC \lpr {Udelcode} \NC 0 \NC 10FFFF \NC = \NC 0+0 \NC FF+10FFFF \NC \NR
+\NC \lpr {Umathchar} \NC 0+0+0 \NC 7+FF+10FFFF \NC \NC \NC \NC \NR
+\NC \lpr {Umathaccent} \NC 0+0+0 \NC 7+FF+10FFFF \NC \NC \NC \NC \NR
+\NC \lpr {Udelimiter} \NC 0+0+0 \NC 7+FF+10FFFF \NC \NC \NC \NC \NR
+\NC \lpr {Uradical} \NC 0+0 \NC FF+10FFFF \NC \NC \NC \NC \NR
+\NC \lpr {Umathcharnum} \NC -80000000 \NC 7FFFFFFF \NC \NC \NC \NC \NR
+\NC \lpr {Umathcodenum} \NC 0 \NC 10FFFF \NC = \NC -80000000 \NC 7FFFFFFF \NC \NR
+\NC \lpr {Udelcodenum} \NC 0 \NC 10FFFF \NC = \NC -80000000 \NC 7FFFFFFF \NC \NR
+\LL
+\stoptabulate
+
+Specifications typically look like:
+
+\starttyping
+\Umathchardef\xx="1"0"456
+\Umathcode 123="1"0"789
+\stoptyping
+
+The new primitives that deal with delimiter|-|style objects do not set up a
+\quote {large family}. Selecting a suitable size for display purposes is expected
+to be dealt with by the font via the \lpr {Umathoperatorsize} parameter.
+
+For some of these primitives, all information is packed into a single signed
+integer. For the first two (\lpr {Umathcharnum} and \lpr {Umathcodenum}), the
+lowest 21 bits are the character code, the 3 bits above that represent the math
+class, and the family data is kept in the topmost bits. This means that the values
+for math families 128--255 are actually negative. For \lpr {Udelcodenum} there
+is no math class. The math family information is stored in the bits directly on
+top of the character code. Using these three commands is not as natural as using
+the two- and three|-|value commands, so unless you know exactly what you are
+doing and absolutely require the speedup resulting from the faster input
+scanning, it is better to use the verbose commands instead.
+
+The \lpr {Umathaccent} command accepts optional keywords to control various
+details regarding math accents. See \in {section} [mathacc] below for details.
+
+There are more new primitives and all of these will be explained in following
+sections:
+
+\starttabulate[|l|l|]
+\DB primitive \BC value range (in hex) \NC \NR
+\TB
+\NC \lpr {Uroot} \NC 0 + 0--FF + 10FFFF \NC \NR
+\NC \lpr {Uoverdelimiter} \NC 0 + 0--FF + 10FFFF \NC \NR
+\NC \lpr {Uunderdelimiter} \NC 0 + 0--FF + 10FFFF \NC \NR
+\NC \lpr {Udelimiterover} \NC 0 + 0--FF + 10FFFF \NC \NR
+\NC \lpr {Udelimiterunder} \NC 0 + 0--FF + 10FFFF \NC \NR
+\LL
+\stoptabulate
+
+\stopsection
+
+\startsection[title={Math styles}]
+
+\subsection{\lpr {mathstyle}}
+
+\topicindex {math+styles}
It is possible to discover the math style that will be used for a formula in an
expandable fashion (while the math list is still being read). To make this
-possible, \LUATEX\ adds the new primitive: \type {\mathstyle}. This is a \quote
-{convert command} like e.g. \type {\romannumeral}: its value can only be read,
+possible, \LUATEX\ adds the new primitive: \lpr {mathstyle}. This is a \quote
+{convert command} like e.g. \prm {romannumeral}: its value can only be read,
not set.
-\subsection{\type {\mathstyle}}
-
The returned value is between 0 and 7 (in math mode), or $-1$ (all other modes).
-For easy testing, the eight math style commands have been altered so that the can
+For easy testing, the eight math style commands have been altered so that they can
be used as numeric values, so you can write code like this:
\starttyping
@@ -48,16 +166,15 @@ thereby reusing numbers) because the number that got used is stored and used in
the second pass (so changing \type {\fam 12} mid|-|formula spoils over to
preceding use of that family).
-The style switching primitives like \type {\textstyle} are turned into nodes so
-the styles set there are frozen. The \type {\mathchoice} primitive results in
-four lists being constructed of which one is used in the second pass. The fact
-that some automatic styles are not yet known also means that the \type
-{\mathstyle} primitive expands to the current style which can of course be
-different from the one really used. It's a snapshot of the first pass state. As a
-consequence in the following example you get a style number (first pass) typeset
-that can actually differ from the used style (second pass). In the case of a math
-choice used ungrouped, the chosen style is used after the choice too, unless you
-group.
+The style switching primitives like \prm {textstyle} are turned into nodes so the
+styles set there are frozen. The \prm {mathchoice} primitive results in four
+lists being constructed of which one is used in the second pass. The fact that
+some automatic styles are not yet known also means that the \lpr {mathstyle}
+primitive expands to the current style which can of course be different from the
+one really used. It's a snapshot of the first pass state. As a consequence in the
+following example you get a style number (first pass) typeset that can actually
+differ from the used style (second pass). In the case of a math choice used
+ungrouped, the chosen style is used after the choice too, unless you group.
\startbuffer[1]
[a:\mathstyle]\quad
@@ -120,134 +237,39 @@ This gives:
\blank $\displaystyle \getbuffer[1]$ \blank
\blank $\textstyle \getbuffer[1]$ \blank
-Using \type {\begingroup} \unknown\ \type {\endgroup} instead gives:
+Using \prm {begingroup} \unknown\ \prm {endgroup} instead gives:
\blank $\displaystyle \getbuffer[2]$ \blank
\blank $\textstyle \getbuffer[2]$ \blank
-This might look wrong but it's just a side effect of \type {\mathstyle} expanding
+This might look wrong but it's just a side effect of \lpr {mathstyle} expanding
to the current (first pass) style and the number being injected in the list that
gets converted in the second pass. It all makes sense and it illustrates the
importance of grouping. In fact, the math choice style being effective afterwards
has advantages. It would be hard to get it otherwise.
-\subsection{\type {\Ustack}}
+\subsection{\lpr {Ustack}}
+
+\topicindex {math+stacks}
There are a few math commands in \TEX\ where the style that will be used is not
-known straight from the start. These commands (\type {\over}, \type {\atop},
-\type {\overwithdelims}, \type {\atopwithdelims}) would therefore normally return
-wrong values for \type {\mathstyle}. To fix this, \LUATEX\ introduces a special
-prefix command: \type {\Ustack}:
+known straight from the start. These commands (\prm {over}, \prm {atop},
+\prm {overwithdelims}, \prm {atopwithdelims}) would therefore normally return
+wrong values for \lpr {mathstyle}. To fix this, \LUATEX\ introduces a special
+prefix command: \lpr {Ustack}:
\starttyping
$\Ustack {a \over b}$
\stoptyping
-The \type {\Ustack} command will scan the next brace and start a new math group
+The \lpr {Ustack} command will scan the next brace and start a new math group
with the correct (numerator) math style.
-\section{Unicode math characters}
-
-Character handling is now extended up to the full \UNICODE\ range (the \type {\U}
-prefix), which is compatible with \XETEX.
-
-The math primitives from \TEX\ are kept as they are, except for the ones that
-convert from input to math commands: \type {mathcode}, and \type {delcode}. These
-two now allow for a 21-bit character argument on the left hand side of the equals
-sign.
-
-Some of the new \LUATEX\ primitives read more than one separate value. This is
-shown in the tables below by a plus sign in the second column.
-
-The input for such primitives would look like this:
-
-\starttyping
-\def\overbrace{\Umathaccent 0 1 "23DE }
-\stoptyping
-
-The altered \TEX82 primitives are:
-
-\starttabulate[|l|l|r|c|l|r|]
-\BC primitive \BC min \BC max \BC \kern 2em \BC min \BC max \NC \NR
-\NC \type {\mathcode} \NC 0 \NC 10FFFF \NC = \NC 0 \NC 8000 \NC \NR
-\NC \type {\delcode} \NC 0 \NC 10FFFF \NC = \NC 0 \NC FFFFFF \NC \NR
-\stoptabulate
-
-The unaltered ones are:
-
-\starttabulate[|l|l|r|]
-\BC primitive \BC min \BC max \NC \NR
-\NC \type {\mathchardef} \NC 0 \NC 8000 \NC \NR
-\NC \type {\mathchar} \NC 0 \NC 7FFF \NC \NR
-\NC \type {\mathaccent} \NC 0 \NC 7FFF \NC \NR
-\NC \type {\delimiter} \NC 0 \NC 7FFFFFF \NC \NR
-\NC \type {\radical} \NC 0 \NC 7FFFFFF \NC \NR
-\stoptabulate
+\subsection{Cramped math styles}
-For practical reasons \type {\mathchardef} will silently accept values larger
-that \type {0x8000} and interpret it as \type {\Umathcharnumdef}. This is needed
-to satisfy older macro packages.
-
-The following new primitives are compatible with \XETEX:
-
-% somewhat fuzzy:
-
-\starttabulate[|l|l|r|c|l|r|]
-\BC primitive \BC min \BC max \BC \kern 2em \BC min \BC max \NC \NR
-\NC \type {\Umathchardef} \NC 0+0+0 \NC 7+FF+10FFFF\rlap{\high{1}} \NC \NC \NC \NC \NR
-\NC \type {\Umathcharnumdef}\rlap{\high{5}} \NC -80000000 \NC 7FFFFFFF\rlap{\high{3}} \NC \NC \NC \NC \NR
-\NC \type {\Umathcode} \NC 0 \NC 10FFFF \NC = \NC 0+0+0 \NC 7+FF+10FFFF\rlap{\high{1}} \NC \NR
-\NC \type {\Udelcode} \NC 0 \NC 10FFFF \NC = \NC 0+0 \NC FF+10FFFF\rlap{\high{2}} \NC \NR
-\NC \type {\Umathchar} \NC 0+0+0 \NC 7+FF+10FFFF \NC \NC \NC \NC \NR
-\NC \type {\Umathaccent} \NC 0+0+0 \NC 7+FF+10FFFF\rlap{\high{2,4}} \NC \NC \NC \NC \NR
-\NC \type {\Udelimiter} \NC 0+0+0 \NC 7+FF+10FFFF\rlap{\high{2}} \NC \NC \NC \NC \NR
-\NC \type {\Uradical} \NC 0+0 \NC FF+10FFFF\rlap{\high{2}} \NC \NC \NC \NC \NR
-\NC \type {\Umathcharnum} \NC -80000000 \NC 7FFFFFFF\rlap{\high{3}} \NC \NC \NC \NC \NR
-\NC \type {\Umathcodenum} \NC 0 \NC 10FFFF \NC = \NC -80000000 \NC 7FFFFFFF\rlap{\high{3}} \NC \NR
-\NC \type {\Udelcodenum} \NC 0 \NC 10FFFF \NC = \NC -80000000 \NC 7FFFFFFF\rlap{\high{3}} \NC \NR
-\stoptabulate
-
-Specifications typically look like:
-
-\starttyping
-\Umathchardef\xx="1"0"456
-\Umathcode 123="1"0"789
-\stoptyping
-
-Note 1: The new primitives that deal with delimiter|-|style objects do not set up a
-\quote {large family}. Selecting a suitable size for display purposes is expected
-to be dealt with by the font via the \type {\Umathoperatorsize} parameter (more
-information can be found in a following section).
-
-Note 2: For these three primitives, all information is packed into a single
-signed integer. For the first two (\type {\Umathcharnum} and \type
-{\Umathcodenum}), the lowest 21 bits are the character code, the 3 bits above
-that represent the math class, and the family data is kept in the topmost bits
-(This means that the values for math families 128--255 are actually negative).
-For \type {\Udelcodenum} there is no math class. The math family information is
-stored in the bits directly on top of the character code. Using these three
-commands is not as natural as using the two- and three|-|value commands, so
-unless you know exactly what you are doing and absolutely require the speedup
-resulting from the faster input scanning, it is better to use the verbose
-commands instead.
-
-Note 3: The \type {\Umathaccent} command accepts optional keywords to control
-various details regarding math accents. See \in {section} [mathacc] below for
-details.
-
-New primitives that exist in \LUATEX\ only (all of these will be explained
-in following sections):
-
-\starttabulate[|l|l|]
-\BC primitive \BC value range (in hex) \NC \NR
-\NC \type {\Uroot} \NC 0+0--FF+10FFFF$^2$ \NC \NR
-\NC \type {\Uoverdelimiter} \NC 0+0--FF+10FFFF$^2$ \NC \NR
-\NC \type {\Uunderdelimiter} \NC 0+0--FF+10FFFF$^2$ \NC \NR
-\NC \type {\Udelimiterover} \NC 0+0--FF+10FFFF$^2$ \NC \NR
-\NC \type {\Udelimiterunder} \NC 0+0--FF+10FFFF$^2$ \NC \NR
-\stoptabulate
-
-\section{Cramped math styles}
+\topicindex {math+styles}
+\topicindex {math+spacing}
+\topicindex {math+cramped}
\LUATEX\ has four new primitives to set the cramped math styles directly:
@@ -282,20 +304,23 @@ are described as follows:
style if the original style was cramped.
\stopitem
\startitem
- Formulas under a \type {\sqrt} or \type {\overline} are in cramped style.
+ Formulas under a \type {\sqrt} or \prm {overline} are in cramped style.
\stopitem
\stopitemize
In \LUATEX\ one can set the styles in more detail which means that you sometimes
-have to set both normal and cramped styles to get the effect you want. If we
-force styles in the script using \type {\scriptstyle} and \type {\crampedscriptstyle}
-we get this:
+have to set both normal and cramped styles to get the effect you want. (Even) if
+we force styles in the script using \prm {scriptstyle} and \lpr
+{crampedscriptstyle} we get this:
\startbuffer[demo]
\starttabulate
+\DB style \BC example \NC \NR
+\TB
\NC default \NC $b_{x=xx}^{x=xx}$ \NC \NR
\NC script \NC $b_{\scriptstyle x=xx}^{\scriptstyle x=xx}$ \NC \NR
\NC crampedscript \NC $b_{\crampedscriptstyle x=xx}^{\crampedscriptstyle x=xx}$ \NC \NR
+\LL
\stoptabulate
\stopbuffer
@@ -310,7 +335,7 @@ Now we set the following parameters
\typebuffer[setup]
-This gives:
+This gives a different result:
\start\getbuffer[setup,demo]\stop
@@ -329,69 +354,77 @@ Now we get:
\start\getbuffer[setup,demo]\stop
-\section{Math parameter settings}
+\stopsection
+
+\startsection[title={Math parameter settings}]
+
+\subsection {Many new \lpr {Umath*} primitives}
+
+\topicindex {math+parameters}
In \LUATEX, the font dimension parameters that \TEX\ used in math typesetting are
now accessible via primitive commands. In fact, refactoring of the math engine
-has resulted in many more parameters than were accessible before.
+has resulted in many more parameters than were not accessible before.
\starttabulate
-\BC primitive name \BC description \NC \NR
-\NC \type {\Umathquad} \NC the width of 18 mu's \NC \NR
-\NC \type {\Umathaxis} \NC height of the vertical center axis of
+\DB primitive name \BC description \NC \NR
+\TB
+\NC \lpr {Umathquad} \NC the width of 18 mu's \NC \NR
+\NC \lpr {Umathaxis} \NC height of the vertical center axis of
the math formula above the baseline \NC \NR
-\NC \type {\Umathoperatorsize} \NC minimum size of large operators in display mode \NC \NR
-\NC \type {\Umathoverbarkern} \NC vertical clearance above the rule \NC \NR
-\NC \type {\Umathoverbarrule} \NC the width of the rule \NC \NR
-\NC \type {\Umathoverbarvgap} \NC vertical clearance below the rule \NC \NR
-\NC \type {\Umathunderbarkern} \NC vertical clearance below the rule \NC \NR
-\NC \type {\Umathunderbarrule} \NC the width of the rule \NC \NR
-\NC \type {\Umathunderbarvgap} \NC vertical clearance above the rule \NC \NR
-\NC \type {\Umathradicalkern} \NC vertical clearance above the rule \NC \NR
-\NC \type {\Umathradicalrule} \NC the width of the rule \NC \NR
-\NC \type {\Umathradicalvgap} \NC vertical clearance below the rule \NC \NR
-\NC \type {\Umathradicaldegreebefore}\NC the forward kern that takes place before placement of
- the radical degree \NC \NR
-\NC \type {\Umathradicaldegreeafter} \NC the backward kern that takes place after placement of
- the radical degree \NC \NR
-\NC \type {\Umathradicaldegreeraise} \NC this is the percentage of the total height and depth of
- the radical sign that the degree is raised by; it is
- expressed in \type {percents}, so 60\% is expressed as the
- integer $60$ \NC \NR
-\NC \type {\Umathstackvgap} \NC vertical clearance between the two
- elements in a \type {\atop} stack \NC \NR
-\NC \type {\Umathstacknumup} \NC numerator shift upward in \type {\atop} stack \NC \NR
-\NC \type {\Umathstackdenomdown} \NC denominator shift downward in \type {\atop} stack \NC \NR
-\NC \type {\Umathfractionrule} \NC the width of the rule in a \type {\over} \NC \NR
-\NC \type {\Umathfractionnumvgap} \NC vertical clearance between the numerator and the rule \NC \NR
-\NC \type {\Umathfractionnumup} \NC numerator shift upward in \type {\over} \NC \NR
-\NC \type {\Umathfractiondenomvgap} \NC vertical clearance between the denominator and the rule \NC \NR
-\NC \type {\Umathfractiondenomdown} \NC denominator shift downward in \type {\over} \NC \NR
-\NC \type {\Umathfractiondelsize} \NC minimum delimiter size for \type {\...withdelims} \NC \NR
-\NC \type {\Umathlimitabovevgap} \NC vertical clearance for limits above operators \NC \NR
-\NC \type {\Umathlimitabovebgap} \NC vertical baseline clearance for limits above operators \NC \NR
-\NC \type {\Umathlimitabovekern} \NC space reserved at the top of the limit \NC \NR
-\NC \type {\Umathlimitbelowvgap} \NC vertical clearance for limits below operators \NC \NR
-\NC \type {\Umathlimitbelowbgap} \NC vertical baseline clearance for limits below operators \NC \NR
-\NC \type {\Umathlimitbelowkern} \NC space reserved at the bottom of the limit \NC \NR
-\NC \type {\Umathoverdelimitervgap} \NC vertical clearance for limits above delimiters \NC \NR
-\NC \type {\Umathoverdelimiterbgap} \NC vertical baseline clearance for limits above delimiters \NC \NR
-\NC \type {\Umathunderdelimitervgap} \NC vertical clearance for limits below delimiters \NC \NR
-\NC \type {\Umathunderdelimiterbgap} \NC vertical baseline clearance for limits below delimiters \NC \NR
-\NC \type {\Umathsubshiftdrop} \NC subscript drop for boxes and subformulas \NC \NR
-\NC \type {\Umathsubshiftdown} \NC subscript drop for characters \NC \NR
-\NC \type {\Umathsupshiftdrop} \NC superscript drop (raise, actually) for boxes and subformulas \NC \NR
-\NC \type {\Umathsupshiftup} \NC superscript raise for characters \NC \NR
-\NC \type {\Umathsubsupshiftdown} \NC subscript drop in the presence of a superscript \NC \NR
-\NC \type {\Umathsubtopmax} \NC the top of standalone subscripts cannot be higher than this
- above the baseline \NC \NR
-\NC \type {\Umathsupbottommin} \NC the bottom of standalone superscripts cannot be less than
- this above the baseline \NC \NR
-\NC \type {\Umathsupsubbottommax} \NC the bottom of the superscript of a combined super- and subscript
- be at least as high as this above the baseline \NC \NR
-\NC \type {\Umathsubsupvgap} \NC vertical clearance between super- and subscript \NC \NR
-\NC \type {\Umathspaceafterscript} \NC additional space added after a super- or subscript \NC \NR
-\NC \type {\Umathconnectoroverlapmin}\NC minimum overlap between parts in an extensible recipe \NC \NR
+\NC \lpr {Umathoperatorsize} \NC minimum size of large operators in display mode \NC \NR
+\NC \lpr {Umathoverbarkern} \NC vertical clearance above the rule \NC \NR
+\NC \lpr {Umathoverbarrule} \NC the width of the rule \NC \NR
+\NC \lpr {Umathoverbarvgap} \NC vertical clearance below the rule \NC \NR
+\NC \lpr {Umathunderbarkern} \NC vertical clearance below the rule \NC \NR
+\NC \lpr {Umathunderbarrule} \NC the width of the rule \NC \NR
+\NC \lpr {Umathunderbarvgap} \NC vertical clearance above the rule \NC \NR
+\NC \lpr {Umathradicalkern} \NC vertical clearance above the rule \NC \NR
+\NC \lpr {Umathradicalrule} \NC the width of the rule \NC \NR
+\NC \lpr {Umathradicalvgap} \NC vertical clearance below the rule \NC \NR
+\NC \lpr {Umathradicaldegreebefore}\NC the forward kern that takes place before placement of
+ the radical degree \NC \NR
+\NC \lpr {Umathradicaldegreeafter} \NC the backward kern that takes place after placement of
+ the radical degree \NC \NR
+\NC \lpr {Umathradicaldegreeraise} \NC this is the percentage of the total height and depth of
+ the radical sign that the degree is raised by; it is
+ expressed in \type {percents}, so 60\% is expressed as the
+ integer $60$ \NC \NR
+\NC \lpr {Umathstackvgap} \NC vertical clearance between the two
+ elements in a \prm {atop} stack \NC \NR
+\NC \lpr {Umathstacknumup} \NC numerator shift upward in \prm {atop} stack \NC \NR
+\NC \lpr {Umathstackdenomdown} \NC denominator shift downward in \prm {atop} stack \NC \NR
+\NC \lpr {Umathfractionrule} \NC the width of the rule in a \prm {over} \NC \NR
+\NC \lpr {Umathfractionnumvgap} \NC vertical clearance between the numerator and the rule \NC \NR
+\NC \lpr {Umathfractionnumup} \NC numerator shift upward in \prm {over} \NC \NR
+\NC \lpr {Umathfractiondenomvgap} \NC vertical clearance between the denominator and the rule \NC \NR
+\NC \lpr {Umathfractiondenomdown} \NC denominator shift downward in \prm {over} \NC \NR
+\NC \lpr {Umathfractiondelsize} \NC minimum delimiter size for \type {\...withdelims} \NC \NR
+\NC \lpr {Umathlimitabovevgap} \NC vertical clearance for limits above operators \NC \NR
+\NC \lpr {Umathlimitabovebgap} \NC vertical baseline clearance for limits above operators \NC \NR
+\NC \lpr {Umathlimitabovekern} \NC space reserved at the top of the limit \NC \NR
+\NC \lpr {Umathlimitbelowvgap} \NC vertical clearance for limits below operators \NC \NR
+\NC \lpr {Umathlimitbelowbgap} \NC vertical baseline clearance for limits below operators \NC \NR
+\NC \lpr {Umathlimitbelowkern} \NC space reserved at the bottom of the limit \NC \NR
+\NC \lpr {Umathoverdelimitervgap} \NC vertical clearance for limits above delimiters \NC \NR
+\NC \lpr {Umathoverdelimiterbgap} \NC vertical baseline clearance for limits above delimiters \NC \NR
+\NC \lpr {Umathunderdelimitervgap} \NC vertical clearance for limits below delimiters \NC \NR
+\NC \lpr {Umathunderdelimiterbgap} \NC vertical baseline clearance for limits below delimiters \NC \NR
+\NC \lpr {Umathsubshiftdrop} \NC subscript drop for boxes and subformulas \NC \NR
+\NC \lpr {Umathsubshiftdown} \NC subscript drop for characters \NC \NR
+\NC \lpr {Umathsupshiftdrop} \NC superscript drop (raise, actually) for boxes and subformulas \NC \NR
+\NC \lpr {Umathsupshiftup} \NC superscript raise for characters \NC \NR
+\NC \lpr {Umathsubsupshiftdown} \NC subscript drop in the presence of a superscript \NC \NR
+\NC \lpr {Umathsubtopmax} \NC the top of standalone subscripts cannot be higher than this
+ above the baseline \NC \NR
+\NC \lpr {Umathsupbottommin} \NC the bottom of standalone superscripts cannot be less than
+ this above the baseline \NC \NR
+\NC \lpr {Umathsupsubbottommax} \NC the bottom of the superscript of a combined super- and subscript
+ be at least as high as this above the baseline \NC \NR
+\NC \lpr {Umathsubsupvgap} \NC vertical clearance between super- and subscript \NC \NR
+\NC \lpr {Umathspaceafterscript} \NC additional space added after a super- or subscript \NC \NR
+\NC \lpr {Umathconnectoroverlapmin}\NC minimum overlap between parts in an extensible recipe \NC \NR
+\LL
\stoptabulate
Each of the parameters in this section can be set by a command like this:
@@ -403,22 +436,9 @@ Each of the parameters in this section can be set by a command like this:
they obey grouping, and you can use \type {\the\Umathquad\displaystyle} if
needed.
-\section{Skips around display math}
+\subsection{Font|-|based math parameters}
-The injection of \type {\abovedisplayskip} and \type {\belowdisplayskip} is not
-symmetrical. An above one is always inserted, also when zero, but the below is
-only inserted when larger than zero. Especially the later makes it sometimes hard
-to fully control spacing. Therefore \LUATEX\ comes with a new directive: \type
-{\mathdisplayskipmode}. The following values apply:
-
-\starttabulate
-\NC 0 \NC normal \TEX\ behaviour \NC \NR
-\NC 1 \NC always (same as 0) \NC \NR
-\NC 2 \NC only when not zero \NC \NR
-\NC 3 \NC never, not even when not zero \NC \NR
-\stoptabulate
-
-\section{Font-based Math Parameters}
+\topicindex {math+parameters}
While it is nice to have these math parameters available for tweaking, it would
be tedious to have to set each of them by hand. For this reason, \LUATEX\
@@ -432,121 +452,118 @@ case no attention is paid to which family is being assigned to: the \type
{MathConstants} tables in the last assigned family sets all parameters.
In the table below, the one|-|letter style abbreviations and symbolic tfm font
-dimension names match those using in the \TeX book. Assignments to \type
-{\textfont} set the values for the cramped and uncramped display and text styles,
-\type {\scriptfont} sets the script styles, and \type {\scriptscriptfont} sets
-the scriptscript styles, so we have eight parameters for three font sizes. In the
+dimension names match those used in the \TeX book. Assignments to \prm
+{textfont} set the values for the cramped and uncramped display and text styles,
+\prm {scriptfont} sets the script styles, and \prm {scriptscriptfont} sets the
+scriptscript styles, so we have eight parameters for three font sizes. In the
\TFM\ case, assignments only happen in family~2 and family~3 (and of course only
for the parameters for which there are font dimensions).
Besides the parameters below, \LUATEX\ also looks at the \quote {space} font
dimension parameter. For math fonts, this should be set to zero.
-\start
+\def\MathLine#1#2#3#4#5%
+ {\TB
+ \NC \llap{\high{\tx #2\enspace}}\ttbf \string #1 \NC \tt #5 \NC \NR
+ \NC \tx #3 \NC \tt #4 \NC \NR}
-\switchtobodyfont[8pt]
-
-\starttabulate[|l|l|l|p|]
-\BC variable \BC style \BC default value opentype \BC default value tfm \NC \NR
-\NC \type {\Umathaxis} \NC -- \NC AxisHeight \NC axis_height \NC \NR
-\NC \type {\Umathoperatorsize} \NC D, D' \NC DisplayOperatorMinHeight \NC $^6$ \NC \NR
-\NC \type {\Umathfractiondelsize} \NC D, D' \NC FractionDelimiterDisplayStyleSize$^9$ \NC delim1 \NC \NR
-\NC \NC T, T', S, S', SS, SS' \NC FractionDelimiterSize$^9$ \NC delim2 \NC \NR
-\NC \type {\Umathfractiondenomdown} \NC D, D' \NC FractionDenominatorDisplayStyleShiftDown \NC denom1 \NC \NR
-\NC \NC T, T', S, S', SS, SS' \NC FractionDenominatorShiftDown \NC denom2 \NC \NR
-\NC \type {\Umathfractiondenomvgap} \NC D, D' \NC FractionDenominatorDisplayStyleGapMin \NC 3*default_rule_thickness \NC \NR
-\NC \NC T, T', S, S', SS, SS' \NC FractionDenominatorGapMin \NC default_rule_thickness \NC \NR
-\NC \type {\Umathfractionnumup} \NC D, D' \NC FractionNumeratorDisplayStyleShiftUp \NC num1 \NC \NR
-\NC \NC T, T', S, S', SS, SS' \NC FractionNumeratorShiftUp \NC num2 \NC \NR
-\NC \type {\Umathfractionnumvgap} \NC D, D' \NC FractionNumeratorDisplayStyleGapMin \NC 3*default_rule_thickness \NC \NR
-\NC \NC T, T', S, S', SS, SS' \NC FractionNumeratorGapMin \NC default_rule_thickness \NC \NR
-\NC \type {\Umathfractionrule} \NC -- \NC FractionRuleThickness \NC default_rule_thickness \NC \NR
-\NC \type {\Umathskewedfractionhgap} \NC -- \NC SkewedFractionHorizontalGap \NC math_quad/2 \NC \NR
-\NC \type {\Umathskewedfractionvgap} \NC -- \NC SkewedFractionVerticalGap \NC math_x_height \NC \NR
-\NC \type {\Umathlimitabovebgap} \NC -- \NC UpperLimitBaselineRiseMin \NC big_op_spacing3 \NC \NR
-\NC \type {\Umathlimitabovekern} \NC -- \NC 0$^1$ \NC big_op_spacing5 \NC \NR
-\NC \type {\Umathlimitabovevgap} \NC -- \NC UpperLimitGapMin \NC big_op_spacing1 \NC \NR
-\NC \type {\Umathlimitbelowbgap} \NC -- \NC LowerLimitBaselineDropMin \NC big_op_spacing4 \NC \NR
-\NC \type {\Umathlimitbelowkern} \NC -- \NC 0$^1$ \NC big_op_spacing5 \NC \NR
-\NC \type {\Umathlimitbelowvgap} \NC -- \NC LowerLimitGapMin \NC big_op_spacing2 \NC \NR
-\NC \type {\Umathoverdelimitervgap} \NC -- \NC StretchStackGapBelowMin \NC big_op_spacing1 \NC \NR
-\NC \type {\Umathoverdelimiterbgap} \NC -- \NC StretchStackTopShiftUp \NC big_op_spacing3 \NC \NR
-\NC \type {\Umathunderdelimitervgap} \NC-- \NC StretchStackGapAboveMin \NC big_op_spacing2 \NC \NR
-\NC \type {\Umathunderdelimiterbgap} \NC-- \NC StretchStackBottomShiftDown \NC big_op_spacing4 \NC \NR
-\NC \type {\Umathoverbarkern} \NC -- \NC OverbarExtraAscender \NC default_rule_thickness \NC \NR
-\NC \type {\Umathoverbarrule} \NC -- \NC OverbarRuleThickness \NC default_rule_thickness \NC \NR
-\NC \type {\Umathoverbarvgap} \NC -- \NC OverbarVerticalGap \NC 3*default_rule_thickness \NC \NR
-\NC \type {\Umathquad} \NC -- \NC <font_size(f)>$^1$ \NC math_quad \NC \NR
-\NC \type {\Umathradicalkern} \NC -- \NC RadicalExtraAscender \NC default_rule_thickness \NC \NR
-\NC \type {\Umathradicalrule} \NC -- \NC RadicalRuleThickness \NC <not set>$^2$ \NC \NR
-\NC \type {\Umathradicalvgap} \NC D, D' \NC RadicalDisplayStyleVerticalGap \NC (default_rule_thickness+\crlf
- (abs(math_x_height)/4))$^3$ \NC \NR
-\NC \NC T, T', S, S', SS, SS' \NC RadicalVerticalGap \NC (default_rule_thickness+\crlf
- (abs(default_rule_thickness)/4))$^3$ \NC \NR
-\NC \type {\Umathradicaldegreebefore} \NC -- \NC RadicalKernBeforeDegree \NC <not set>$^2$ \NC \NR
-\NC \type {\Umathradicaldegreeafter} \NC -- \NC RadicalKernAfterDegree \NC <not set>$^2$ \NC \NR
-\NC \type {\Umathradicaldegreeraise} \NC -- \NC RadicalDegreeBottomRaisePercent \NC <not set>$^{2,7}$ \NC \NR
-\NC \type {\Umathspaceafterscript} \NC -- \NC SpaceAfterScript \NC script_space$^4$ \NC \NR
-\NC \type {\Umathstackdenomdown} \NC D, D' \NC StackBottomDisplayStyleShiftDown \NC denom1 \NC \NR
-\NC \NC T, T', S, S', SS, SS' \NC StackBottomShiftDown \NC denom2 \NC \NR
-\NC \type {\Umathstacknumup} \NC D, D' \NC StackTopDisplayStyleShiftUp \NC num1 \NC \NR
-\NC \NC T, T', S, S', SS, SS' \NC StackTopShiftUp \NC num3 \NC \NR
-\NC \type {\Umathstackvgap} \NC D, D' \NC StackDisplayStyleGapMin \NC 7*default_rule_thickness \NC \NR
-\NC \NC T, T', S, S', SS, SS' \NC StackGapMin \NC 3*default_rule_thickness \NC \NR
-\NC \type {\Umathsubshiftdown} \NC -- \NC SubscriptShiftDown \NC sub1 \NC \NR
-\NC \type {\Umathsubshiftdrop} \NC -- \NC SubscriptBaselineDropMin \NC sub_drop \NC \NR
-\NC \type {\Umathsubsupshiftdown} \NC -- \NC SubscriptShiftDownWithSuperscript$^8$ \NC \NC \NR
-\NC \NC \NC \quad\ or SubscriptShiftDown \NC sub2 \NC \NR
-\NC \type {\Umathsubtopmax} \NC -- \NC SubscriptTopMax \NC (abs(math_x_height * 4) / 5) \NC \NR
-\NC \type {\Umathsubsupvgap} \NC -- \NC SubSuperscriptGapMin \NC 4*default_rule_thickness \NC \NR
-\NC \type {\Umathsupbottommin} \NC -- \NC SuperscriptBottomMin \NC (abs(math_x_height) / 4) \NC \NR
-\NC \type {\Umathsupshiftdrop} \NC -- \NC SuperscriptBaselineDropMax \NC sup_drop \NC \NR
-\NC \type {\Umathsupshiftup} \NC D \NC SuperscriptShiftUp \NC sup1 \NC \NR
-\NC \NC T, S, SS, \NC SuperscriptShiftUp \NC sup2 \NC \NR
-\NC \NC D', T', S', SS' \NC SuperscriptShiftUpCramped \NC sup3 \NC \NR
-\NC \type {\Umathsupsubbottommax} \NC -- \NC SuperscriptBottomMaxWithSubscript \NC (abs(math_x_height * 4) / 5) \NC \NR
-\NC \type {\Umathunderbarkern} \NC -- \NC UnderbarExtraDescender \NC default_rule_thickness \NC \NR
-\NC \type {\Umathunderbarrule} \NC -- \NC UnderbarRuleThickness \NC default_rule_thickness \NC \NR
-\NC \type {\Umathunderbarvgap} \NC -- \NC UnderbarVerticalGap \NC 3*default_rule_thickness \NC \NR
-\NC \type {\Umathconnectoroverlapmin} \NC -- \NC MinConnectorOverlap \NC 0$^5$ \NC \NR
+\starttabulate[|l|l|]
+\DB variable / style \BC tfm / opentype \NC \NR
+\MathLine{\Umathaxis} {} {} {AxisHeight} {axis_height}
+\MathLine{\Umathoperatorsize} {6} {D, D'} {DisplayOperatorMinHeight} {\emdash}
+\MathLine{\Umathfractiondelsize} {9} {D, D'} {FractionDelimiterDisplayStyleSize} {delim1}
+\MathLine{\Umathfractiondelsize} {9} {T, T', S, S', SS, SS'}{FractionDelimiterSize} {delim2}
+\MathLine{\Umathfractiondenomdown} {} {D, D'} {FractionDenominatorDisplayStyleShiftDown}{denom1}
+\MathLine{\Umathfractiondenomdown} {} {T, T', S, S', SS, SS'}{FractionDenominatorShiftDown} {denom2}
+\MathLine{\Umathfractiondenomvgap} {} {D, D'} {FractionDenominatorDisplayStyleGapMin} {3*default_rule_thickness}
+\MathLine{\Umathfractiondenomvgap} {} {T, T', S, S', SS, SS'}{FractionDenominatorGapMin} {default_rule_thickness}
+\MathLine{\Umathfractionnumup} {} {D, D'} {FractionNumeratorDisplayStyleShiftUp} {num1}
+\MathLine{\Umathfractionnumup} {} {T, T', S, S', SS, SS'}{FractionNumeratorShiftUp} {num2}
+\MathLine{\Umathfractionnumvgap} {} {D, D'} {FractionNumeratorDisplayStyleGapMin} {3*default_rule_thickness}
+\MathLine{\Umathfractionnumvgap} {} {T, T', S, S', SS, SS'}{FractionNumeratorGapMin} {default_rule_thickness}
+\MathLine{\Umathfractionrule} {} {} {FractionRuleThickness} {default_rule_thickness}
+\MathLine{\Umathskewedfractionhgap} {} {} {SkewedFractionHorizontalGap} {math_quad/2}
+\MathLine{\Umathskewedfractionvgap} {} {} {SkewedFractionVerticalGap} {math_x_height}
+\MathLine{\Umathlimitabovebgap} {} {} {UpperLimitBaselineRiseMin} {big_op_spacing3}
+\MathLine{\Umathlimitabovekern} {1} {} {0} {big_op_spacing5}
+\MathLine{\Umathlimitabovevgap} {} {} {UpperLimitGapMin} {big_op_spacing1}
+\MathLine{\Umathlimitbelowbgap} {} {} {LowerLimitBaselineDropMin} {big_op_spacing4}
+\MathLine{\Umathlimitbelowkern} {1} {} {0} {big_op_spacing5}
+\MathLine{\Umathlimitbelowvgap} {} {} {LowerLimitGapMin} {big_op_spacing2}
+\MathLine{\Umathoverdelimitervgap} {} {} {StretchStackGapBelowMin} {big_op_spacing1}
+\MathLine{\Umathoverdelimiterbgap} {} {} {StretchStackTopShiftUp} {big_op_spacing3}
+\MathLine{\Umathunderdelimitervgap} {} {} {StretchStackGapAboveMin} {big_op_spacing2}
+\MathLine{\Umathunderdelimiterbgap} {} {} {StretchStackBottomShiftDown} {big_op_spacing4}
+\MathLine{\Umathoverbarkern} {} {} {OverbarExtraAscender} {default_rule_thickness}
+\MathLine{\Umathoverbarrule} {} {} {OverbarRuleThickness} {default_rule_thickness}
+\MathLine{\Umathoverbarvgap} {} {} {OverbarVerticalGap} {3*default_rule_thickness}
+\MathLine{\Umathquad} {1} {} {<font_size(f)>} {math_quad}
+\MathLine{\Umathradicalkern} {} {} {RadicalExtraAscender} {default_rule_thickness}
+\MathLine{\Umathradicalrule} {2} {} {RadicalRuleThickness} {<not set>}
+\MathLine{\Umathradicalvgap} {3} {D, D'} {RadicalDisplayStyleVerticalGap} {default_rule_thickness+abs(math_x_height)/4}
+\MathLine{\Umathradicalvgap} {3} {T, T', S, S', SS, SS'}{RadicalVerticalGap} {default_rule_thickness+abs(default_rule_thickness)/4}
+\MathLine{\Umathradicaldegreebefore}{2} {} {RadicalKernBeforeDegree} {<not set>}
+\MathLine{\Umathradicaldegreeafter} {2} {} {RadicalKernAfterDegree} {<not set>}
+\MathLine{\Umathradicaldegreeraise} {2,7}{} {RadicalDegreeBottomRaisePercent} {<not set>}
+\MathLine{\Umathspaceafterscript} {4} {} {SpaceAfterScript} {script_space}
+\MathLine{\Umathstackdenomdown} {} {D, D'} {StackBottomDisplayStyleShiftDown} {denom1}
+\MathLine{\Umathstackdenomdown} {} {T, T', S, S', SS, SS'}{StackBottomShiftDown} {denom2}
+\MathLine{\Umathstacknumup} {} {D, D'} {StackTopDisplayStyleShiftUp} {num1}
+\MathLine{\Umathstacknumup} {} {T, T', S, S', SS, SS'}{StackTopShiftUp} {num3}
+\MathLine{\Umathstackvgap} {} {D, D'} {StackDisplayStyleGapMin} {7*default_rule_thickness}
+\MathLine{\Umathstackvgap} {} {T, T', S, S', SS, SS'}{StackGapMin} {3*default_rule_thickness}
+\MathLine{\Umathsubshiftdown} {} {} {SubscriptShiftDown} {sub1}
+\MathLine{\Umathsubshiftdrop} {} {} {SubscriptBaselineDropMin} {sub_drop}
+\MathLine{\Umathsubsupshiftdown} {8} {} {SubscriptShiftDownWithSuperscript} {\emdash}
+\MathLine{\Umathsubtopmax} {} {} {SubscriptTopMax} {abs(math_x_height*4)/5}
+\MathLine{\Umathsubsupvgap} {} {} {SubSuperscriptGapMin} {4*default_rule_thickness}
+\MathLine{\Umathsupbottommin} {} {} {SuperscriptBottomMin} {abs(math_x_height/4)}
+\MathLine{\Umathsupshiftdrop} {} {} {SuperscriptBaselineDropMax} {sup_drop}
+\MathLine{\Umathsupshiftup} {} {D} {SuperscriptShiftUp} {sup1}
+\MathLine{\Umathsupshiftup} {} {T, S, SS,} {SuperscriptShiftUp} {sup2}
+\MathLine{\Umathsupshiftup} {} {D', T', S', SS'} {SuperscriptShiftUpCramped} {sup3}
+\MathLine{\Umathsupsubbottommax} {} {} {SuperscriptBottomMaxWithSubscript} {abs(math_x_height*4)/5}
+\MathLine{\Umathunderbarkern} {} {} {UnderbarExtraDescender} {default_rule_thickness}
+\MathLine{\Umathunderbarrule} {} {} {UnderbarRuleThickness} {default_rule_thickness}
+\MathLine{\Umathunderbarvgap} {} {} {UnderbarVerticalGap} {3*default_rule_thickness}
+\MathLine{\Umathconnectoroverlapmin}{5} {} {MinConnectorOverlap} {0}
+\LL
\stoptabulate
-\stop
-
-Note 1: \OPENTYPE\ fonts set \type {\Umathlimitabovekern} and \type
-{\Umathlimitbelowkern} to zero and set \type {\Umathquad} to the font size of the
+Note 1: \OPENTYPE\ fonts set \lpr {Umathlimitabovekern} and \lpr
+{Umathlimitbelowkern} to zero and set \lpr {Umathquad} to the font size of the
used font, because these are not supported in the \type {MATH} table,
-Note 2: Traditional \TFM\ fonts do not set \type {\Umathradicalrule} because
+Note 2: Traditional \TFM\ fonts do not set \lpr {Umathradicalrule} because
\TEX82\ uses the height of the radical instead. When this parameter is indeed not
set when \LUATEX\ has to typeset a radical, a backward compatibility mode will
kick in that assumes that an oldstyle \TEX\ font is used. Also, they do not set
-\type {\Umathradicaldegreebefore}, \type {\Umathradicaldegreeafter}, and \type
-{\Umathradicaldegreeraise}. These are then automatically initialized to
+\lpr {Umathradicaldegreebefore}, \lpr {Umathradicaldegreeafter}, and \lpr
+{Umathradicaldegreeraise}. These are then automatically initialized to
$5/18$quad, $-10/18$quad, and 60.
-Note 3: If \TFM\ fonts are used, then the \type {\Umathradicalvgap} is not set
+Note 3: If \TFM\ fonts are used, then the \lpr {Umathradicalvgap} is not set
until the first time \LUATEX\ has to typeset a formula because this needs
parameters from both family~2 and family~3. This provides a partial backward
-compatibility with \TEX82, but that compatibility is only partial: once the \type
-{\Umathradicalvgap} is set, it will not be recalculated any more.
+compatibility with \TEX82, but that compatibility is only partial: once the \lpr
+{Umathradicalvgap} is set, it will not be recalculated any more.
-Note 4: When \TFM\ fonts are used a similar situation arises with respect to
-\type {\Umathspaceafterscript}: it is not set until the first time \LUATEX\ has
-to typeset a formula. This provides some backward compatibility with \TEX82. But
-once the \type {\Umathspaceafterscript} is set, \type {\scriptspace} will never
-be looked at again.
+Note 4: When \TFM\ fonts are used a similar situation arises with respect to \lpr
+{Umathspaceafterscript}: it is not set until the first time \LUATEX\ has to
+typeset a formula. This provides some backward compatibility with \TEX82. But
+once the \lpr {Umathspaceafterscript} is set, \prm {scriptspace} will never be
+looked at again.
-Note 5: Traditional \TFM\ fonts set \type {\Umathconnectoroverlapmin} to zero
+Note 5: Traditional \TFM\ fonts set \lpr {Umathconnectoroverlapmin} to zero
because \TEX82\ always stacks extensibles without any overlap.
-Note 6: The \type {\Umathoperatorsize} is only used in \type {\displaystyle}, and
-is only set in \OPENTYPE\ fonts. In \TFM\ font mode, it is artificially set to
-one scaled point more than the initial attempt's size, so that always the \quote
+Note 6: The \lpr {Umathoperatorsize} is only used in \prm {displaystyle}, and is
+only set in \OPENTYPE\ fonts. In \TFM\ font mode, it is artificially set to one
+scaled point more than the initial attempt's size, so that always the \quote
{first next} will be tried, just like in \TEX82.
-Note 7: The \type {\Umathradicaldegreeraise} is a special case because it is the
-only parameter that is expressed in a percentage instead of as a number of scaled
+Note 7: The \lpr {Umathradicaldegreeraise} is a special case because it is the
+only parameter that is expressed in a percentage instead of a number of scaled
points.
Note 8: \type {SubscriptShiftDownWithSuperscript} does not actually exist in the
@@ -557,16 +574,198 @@ Note 9: \type {FractionDelimiterDisplayStyleSize} and \type
{FractionDelimiterSize} do not actually exist in the \quote {standard} \OPENTYPE\
math font Cambria, but were useful enough to be added.
-\section{Nolimit correction}
+\stopsection
+
+\startsection[title={Math spacing}]
+
+\subsection{Inline surrounding space}
+
+\topicindex {math+spacing}
+
+Inline math is surrounded by (optional) \prm {mathsurround} spacing but that is a fixed
+dimension. There is now an additional parameter \lpr {mathsurroundskip}. When set to a
+non|-|zero value (or zero with some stretch or shrink) this parameter will replace
+\prm {mathsurround}. By using an additional parameter instead of changing the nature
+of \prm {mathsurround}, we can remain compatible. In the meantime a bit more
+control has been added via \lpr {mathsurroundmode}. This directive can take 6 values
+with zero being the default behaviour.
+
+\start
+
+\def\OneLiner#1#2%
+ {\NC \type{#1}
+ \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\mathsurroundmode#1\relax\hsize 100pt x$x$x}
+ \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\mathsurroundmode#1\relax\hsize 100pt x $x$ x}
+ \NC #2
+ \NC \NR}
+
+\startbuffer
+\mathsurround 10pt
+\mathsurroundskip20pt
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\starttabulate[|c|c|c|pl|]
+\DB mode \BC x\$x\$x \BC x \$x\$ x \BC effect \NC \NR
+\TB
+\OneLiner{0}{obey \prm {mathsurround} when \lpr {mathsurroundskip} is 0pt}
+\OneLiner{1}{only add skip to the left}
+\OneLiner{2}{only add skip to the right}
+\OneLiner{3}{add skip to the left and right}
+\OneLiner{4}{ignore the skip setting, obey \prm {mathsurround}}
+\OneLiner{5}{disable all spacing around math}
+\OneLiner{6}{only apply \lpr {mathsurroundskip} when also spacing}
+\OneLiner{7}{only apply \lpr {mathsurroundskip} when no spacing}
+\LL
+\stoptabulate
+
+\stop
+
+Method six omits the surround glue when there is (x)spacing glue present while
+method seven does the opposite, the glue is only applied when there is (x)space
+glue present too. Anything more fancy, like checking the begining or end of a
+paragraph (or edges of a box) would not be robust anyway. If you want that you
+can write a callback that runs over a list and analyzes a paragraph. Actually, in
+that case you could also inject glue (or set the properties of a math node)
+explicitly. So, these modes are in practice mostly useful for special purposes
+and experiments (they originate in a tracker item). Keep in mind that this glue
+is part of the math node and not always treated as normal glue: it travels with
+the begin and end math nodes. Also, method 6 and 7 will zero the skip related
+fields in a node when applicable in the first occasion that checks them
+(linebreaking or packaging).
+
+\subsection{Pairwise spacing}
+
+\topicindex {math+spacing}
+
+Besides the parameters mentioned in the previous sections, there are also 64 new
+primitives to control the math spacing table (as explained in Chapter~18 of the
+\TEX book). The primitive names are a simple matter of combining two math atom
+types, but for completeness' sake, here is the whole list:
+
+\starttwocolumns
+\startlines
+\lpr {Umathordordspacing}
+\lpr {Umathordopspacing}
+\lpr {Umathordbinspacing}
+\lpr {Umathordrelspacing}
+\lpr {Umathordopenspacing}
+\lpr {Umathordclosespacing}
+\lpr {Umathordpunctspacing}
+\lpr {Umathordinnerspacing}
+\lpr {Umathopordspacing}
+\lpr {Umathopopspacing}
+\lpr {Umathopbinspacing}
+\lpr {Umathoprelspacing}
+\lpr {Umathopopenspacing}
+\lpr {Umathopclosespacing}
+\lpr {Umathoppunctspacing}
+\lpr {Umathopinnerspacing}
+\lpr {Umathbinordspacing}
+\lpr {Umathbinopspacing}
+\lpr {Umathbinbinspacing}
+\lpr {Umathbinrelspacing}
+\lpr {Umathbinopenspacing}
+\lpr {Umathbinclosespacing}
+\lpr {Umathbinpunctspacing}
+\lpr {Umathbininnerspacing}
+\lpr {Umathrelordspacing}
+\lpr {Umathrelopspacing}
+\lpr {Umathrelbinspacing}
+\lpr {Umathrelrelspacing}
+\lpr {Umathrelopenspacing}
+\lpr {Umathrelclosespacing}
+\lpr {Umathrelpunctspacing}
+\lpr {Umathrelinnerspacing}
+\lpr {Umathopenordspacing}
+\lpr {Umathopenopspacing}
+\lpr {Umathopenbinspacing}
+\lpr {Umathopenrelspacing}
+\lpr {Umathopenopenspacing}
+\lpr {Umathopenclosespacing}
+\lpr {Umathopenpunctspacing}
+\lpr {Umathopeninnerspacing}
+\lpr {Umathcloseordspacing}
+\lpr {Umathcloseopspacing}
+\lpr {Umathclosebinspacing}
+\lpr {Umathcloserelspacing}
+\lpr {Umathcloseopenspacing}
+\lpr {Umathcloseclosespacing}
+\lpr {Umathclosepunctspacing}
+\lpr {Umathcloseinnerspacing}
+\lpr {Umathpunctordspacing}
+\lpr {Umathpunctopspacing}
+\lpr {Umathpunctbinspacing}
+\lpr {Umathpunctrelspacing}
+\lpr {Umathpunctopenspacing}
+\lpr {Umathpunctclosespacing}
+\lpr {Umathpunctpunctspacing}
+\lpr {Umathpunctinnerspacing}
+\lpr {Umathinnerordspacing}
+\lpr {Umathinneropspacing}
+\lpr {Umathinnerbinspacing}
+\lpr {Umathinnerrelspacing}
+\lpr {Umathinneropenspacing}
+\lpr {Umathinnerclosespacing}
+\lpr {Umathinnerpunctspacing}
+\lpr {Umathinnerinnerspacing}
+\stoplines
+\stoptwocolumns
+
+These parameters are of type \prm {muskip}, so setting a parameter can be done
+like this:
+
+\starttyping
+\Umathopordspacing\displaystyle=4mu plus 2mu
+\stoptyping
+
+They are all initialized by \type {initex} to the values mentioned in the table
+in Chapter~18 of the \TEX book.
+
+Note 1: for ease of use as well as for backward compatibility, \prm {thinmuskip},
+\prm {medmuskip} and \prm {thickmuskip} are treated specially. In their case a
+pointer to the corresponding internal parameter is saved, not the actual \prm
+{muskip} value. This means that any later changes to one of these three
+parameters will be taken into account.
+
+Note 2: Careful readers will realise that there are also primitives for the items
+marked \type {*} in the \TEX book. These will not actually be used as those
+combinations of atoms cannot actually happen, but it seemed better not to break
+orthogonality. They are initialized to zero.
+
+\subsection{Skips around display math}
+
+\topicindex {math+spacing}
+
+The injection of \prm {abovedisplayskip} and \prm {belowdisplayskip} is not
+symmetrical. An above one is always inserted, also when zero, but the below is
+only inserted when larger than zero. Especially the latter makes it sometimes hard
+to fully control spacing. Therefore \LUATEX\ comes with a new directive: \lpr
+{mathdisplayskipmode}. The following values apply:
+
+\starttabulate[|c|l|]
+\DB value \BC meaning \NC \NR
+\TB
+\NC 0 \NC normal \TEX\ behaviour \NC \NR
+\NC 1 \NC always (same as 0) \NC \NR
+\NC 2 \NC only when not zero \NC \NR
+\NC 3 \NC never, not even when not zero \NC \NR
+\LL
+\stoptabulate
+
+\subsection {Nolimit correction}
-There are two extra math parameters \type {\Umathnolimitsupfactor} and \type
-{\Umathnolimitsubfactor} that were added to provide some control over how limits
+\topicindex {math+limits}
+
+There are two extra math parameters \lpr {Umathnolimitsupfactor} and \lpr
+{Umathnolimitsubfactor} that were added to provide some control over how limits
are spaced (for example the position of super and subscripts after integral
-operators). They relate to an extra parameter \type {\mathnolimitsmode}. The half
-corrections are what happens when scripts are placed on above and below. The
+operators). They relate to an extra parameter \lpr {mathnolimitsmode}. The half
+corrections are what happens when scripts are placed above and below. The
problem with italic corrections is that officially that correction italic is used
for above|/|below placement while advanced kerns are used for placement at the
-right end. The question is: how often is this implemented, and if so, does the
+right end. The question is: how often is this implemented, and if so, do the
kerns assume correction too. Anyway, with this parameter one can control it.
\starttabulate[|l|ck1|ck1|ck1|ck1|ck1|ck1|]
@@ -609,13 +808,15 @@ When the mode is set to one, the math parameters are used. This way a macro
package writer can decide what looks best. Given the current state of fonts in
\CONTEXT\ we currently use mode 1 with factor 0 for the superscript and 750 for
the subscripts. Positive values are used for both parameters but the subscript
-shifts to the left. A \type {\mathnolimitsmode} larger that 15 is considered to
+shifts to the left. A \lpr {mathnolimitsmode} larger that 15 is considered to
be a factor for the subscript correction. This feature can be handy when
experimenting.
-\section{Math italic mess}
+\subsection {Math italic mess}
+
+\topicindex {math+italics}
-The \type {\mathitalicsmode} parameter can be set to~1 to force italic correction
+The \lpr {mathitalicsmode} parameter can be set to~1 to force italic correction
before noads that represent some more complex structure (read: everything
that is not an ord, bin, rel, open, close, punct or inner). We show a Cambria
example.
@@ -641,20 +842,26 @@ example.
This kind of parameters relate to the fact that italic correction in \OPENTYPE\
math is bound to fuzzy rules. So, control is the solution.
-\section{Script boxes}
+\subsection {Script and kerning}
-If you want typeset text in math macro packages often provide something \type
-{\text} which obeys the script sizes. As the definition can be anything there is
-a good change that the kerning doesn't come out well when used in a script. Given
-that the first glyph ends up in an \type {\hbox} we have some control over this.
-And, as a bonus we also added control over the normal sublist kerning. The \type
-{\mathscriptboxmode} parameter defaults to~1.
+\topicindex {math+kerning}
+\topicindex {math+scripts}
-\starttabulate[|l|l|]
+If you want to typeset text in math macro packages often provide something \type
+{\text} which obeys the script sizes. As the definition can be anything there is
+a good chance that the kerning doesn't come out well when used in a script. Given
+that the first glyph ends up in a \prm {hbox} we have some control over this.
+And, as a bonus we also added control over the normal sublist kerning. The \lpr
+{mathscriptboxmode} parameter defaults to~1.
+
+\starttabulate[|c|l|]
+\DB value \BC meaning \NC \NR
+\TB
\NC \type {0} \NC forget about kerning \NC \NR
\NC \type {1} \NC kern math sub lists with a valid glyph \NC \NR
\NC \type {2} \NC also kern math sub boxes that have a valid glyph \NC \NR
\NC \type {2} \NC only kern math sub boxes with a boundary node present\NC \NR
+\LL
\stoptabulate
Here we show some examples. Of course this doesn't solve all our problems, if
@@ -675,12 +882,12 @@ italics, while other fonts can lack kerns.
\unexpanded\def\Show#1#2#3%
{\doifelsenothing{#3}
- {\small\typeinlinebuffer[#1]}
+ {\small\tx\typeinlinebuffer[#1]}
{\doifelse{#3}{-}
- {\small\type{mode #2}}
+ {\small\bf\tt mode #2}
{\switchtobodyfont[#3]\showfontkerns\showglyphs\mathscriptboxmode#2\relax\inlinebuffer[#1]}}}
-\starttabulate[|lT|c|c|c|c|c|]
+\starttabulate[|lBT|c|c|c|c|c|]
\NC \NC \Show{1}{0}{} \NC\Show{1}{1}{} \NC \Show{2}{1}{} \NC \Show{2}{2}{} \NC \Show{3}{3}{} \NC \NR
\NC \NC \Show{1}{0}{-} \NC\Show{1}{1}{-} \NC \Show{2}{1}{-} \NC \Show{2}{2}{-} \NC \Show{3}{3}{-} \NC \NR
\NC modern \NC \Show{1}{0}{modern} \NC\Show{1}{1}{modern} \NC \Show{2}{1}{modern} \NC \Show{2}{2}{modern} \NC \Show{3}{3}{modern} \NC \NR
@@ -690,15 +897,129 @@ italics, while other fonts can lack kerns.
\NC dejavu \NC \Show{1}{0}{dejavu} \NC\Show{1}{1}{dejavu} \NC \Show{2}{1}{dejavu} \NC \Show{2}{2}{dejavu} \NC \Show{3}{3}{dejavu} \NC \NR
\stoptabulate
-\section{Unscaled fences}
+Kerning between a character subscript is controlled by \lpr {mathscriptcharmode}
+which also defaults to~1.
+
+Here is another example. Internally we tag kerns as italic kerns or font kerns
+where font kerns result from the staircase kern tables. In 2018 fonts like Latin
+Modern and Pagella rely on cheats with the boundingbox, Cambria uses staircase
+kerns and Lucida a mixture. Depending on how fonts evolve we might add some more
+control over what one can turn on and off.
+
+\def\MathSample#1#2#3%
+ {\NC
+ #1 \NC
+ #2 \NC
+ \showglyphdata \switchtobodyfont[#2,17.3pt]$#3T_{f}$ \NC
+ \showglyphdata \switchtobodyfont[#2,17.3pt]$#3\gamma_{e}$ \NC
+ \showglyphdata \switchtobodyfont[#2,17.3pt]$#3\gamma_{ee}$ \NC
+ \showglyphdata \switchtobodyfont[#2,17.3pt]$#3T_{\tf fluff}$ \NC
+ \NR}
+
+\starttabulate[|Tl|Tl|l|l|l|l|]
+ \FL
+ \MathSample{normal}{modern} {\mr}
+ \MathSample{} {pagella} {\mr}
+ \MathSample{} {cambria} {\mr}
+ \MathSample{} {lucidaot}{\mr}
+ \ML
+ \MathSample{bold} {modern} {\mb}
+ \MathSample{} {pagella} {\mb}
+ \MathSample{} {cambria} {\mb}
+ \MathSample{} {lucidaot}{\mb}
+ \LL
+\stoptabulate
+
+\subsection{Fixed scripts}
+
+We have three parameters that are used for this fixed anchoring:
+
+\starttabulate[|c|l|]
+\DB parameter \BC register \NC \NR
+\NC $d$ \NC \lpr {Umathsubshiftdown} \NC \NR
+\NC $u$ \NC \lpr {Umathsupshiftup} \NC \NR
+\NC $s$ \NC \lpr {Umathsubsupshiftdown} \NC \NR
+\LL
+\stoptabulate
+
+When we set \lpr {mathscriptsmode} to a value other than zero these are used
+for calculating fixed positions. This is something that is needed for instance
+for chemistry. You can manipulate the mentioned variables to achieve different
+effects.
+
+\def\SampleMath#1%
+ {$\mathscriptsmode#1\mathupright CH_2 + CH^+_2 + CH^2_2$}
+
+\starttabulate[|c|c|c|p|]
+\DB mode \BC down \BC up \BC example \NC \NR
+\TB
+\NC 0 \NC dynamic \NC dynamic \NC \SampleMath{0} \NC \NR
+\NC 1 \NC $d$ \NC $u$ \NC \SampleMath{1} \NC \NR
+\NC 2 \NC $s$ \NC $u$ \NC \SampleMath{2} \NC \NR
+\NC 3 \NC $s$ \NC $u + s - d$ \NC \SampleMath{3} \NC \NR
+\NC 4 \NC $d + (s-d)/2$ \NC $u + (s-d)/2$ \NC \SampleMath{4} \NC \NR
+\NC 5 \NC $d$ \NC $u + s - d$ \NC \SampleMath{5} \NC \NR
+\LL
+\stoptabulate
+
+The value of this parameter obeys grouping but applies to the whole current
+formula.
+
+% if needed we can put the value in stylenodes but maybe more should go there
-The \type {\mathdelimitersmode} primitive is experimental and deals with the
-following (potential) problems. Three bits can be set. The first bit prevents
-an unwanted shift when the fence symbol is not scaled (a cambria side effect). The
-second bit forces italic correction between a preceding character ordinal and
-the fenced subformula, while the third bit turns that subformula into a ordinary
-so that the same spacing applies as with unfenced variants. Here we show Cambria
-(with \type {\mathitalicsmode} enabled).
+\subsection{Penalties: \lpr {mathpenaltiesmode}}
+
+\topicindex {math+penalties}
+
+Only in inline math penalties will be added in a math list. You can force
+penalties (also in display math) by setting:
+
+\starttyping
+\mathpenaltiesmode = 1
+\stoptyping
+
+This primnitive is not really needed in \LUATEX\ because you can use the callback
+\cbk {mlist_to_hlist} to force penalties by just calling the regular routine
+with forced penalties. However, as part of opening up and control this primitive
+makes sense. As a bonus we also provide two extra penalties:
+
+\starttyping
+\prebinoppenalty = -100 % example value
+\prerelpenalty = 900 % example value
+\stoptyping
+
+They default to inifinite which signals that they don't need to be inserted. When
+set they are injected before a binop or rel noad. This is an experimental feature.
+
+\subsection{Equation spacing: \lpr {matheqnogapstep}}
+
+By default \TEX\ will add one quad between the equation and the number. This is
+hard coded. A new primitive can control this:
+
+\startsyntax
+\matheqnogapstep = 1000
+\stopsyntax
+
+Because a math quad from the math text font is used instead of a dimension, we
+use a step to control the size. A value of zero will suppress the gap. The step
+is divided by 1000 which is the usual way to mimmick floating point factors in
+\TEX.
+
+\stopsection
+
+\startsection[title={Math constructs}]
+
+\subsection {Unscaled fences}
+
+\topicindex {math+fences}
+
+The \lpr {mathdelimitersmode} primitive is experimental and deals with the
+following (potential) problems. Three bits can be set. The first bit prevents an
+unwanted shift when the fence symbol is not scaled (a cambria side effect). The
+second bit forces italic correction between a preceding character ordinal and the
+fenced subformula, while the third bit turns that subformula into an ordinary so
+that the same spacing applies as with unfenced variants. Here we show Cambria
+(with \lpr {mathitalicsmode} enabled).
\starttexdefinition Whatever #1
\NC \type{\mathdelimitersmode = #1}
@@ -716,127 +1037,34 @@ so that the same spacing applies as with unfenced variants. Here we show Cambria
\stop
So, when set to 7 fenced subformulas with unscaled delimiters come out the same
-as unfenced ones. This can be handy for cases where one is forced to use \type
-{\left} and \type {\right} always because of unpredictable content. As said, it's
-an experimental features (which somehow fits in the exceptional way fences are
-dealt with in the engine). The full list of flags is given in the next table:
-
-\starttabulate[|T|l|]
-\NC "01 \NC don't apply the usual shift \NC \NR
-\NC "02 \NC apply italic correction when possible \NC \NR
-\NC "04 \NC force a ordinary subformula \NC \NR
-\NC "08 \NC no shift when a base character \NC \NR
-\NC "10 \NC only shift when an extensible \NC \NR
+as unfenced ones. This can be handy for cases where one is forced to use \prm
+{left} and \prm {right} always because of unpredictable content. As said, it's an
+experimental feature (which somehow fits in the exceptional way fences are dealt
+with in the engine). The full list of flags is given in the next table:
+
+\starttabulate[|c|l|]
+\DB value \BC meaning \NC \NR
+\TB
+\NC \type{"01} \NC don't apply the usual shift \NC \NR
+\NC \type{"02} \NC apply italic correction when possible \NC \NR
+\NC \type{"04} \NC force an ordinary subformula \NC \NR
+\NC \type{"08} \NC no shift when a base character \NC \NR
+\NC \type{"10} \NC only shift when an extensible \NC \NR
+\LL
\stoptabulate
-The effect can depend on the font (and for Cambria one can use for instance \type
-{"16}).
+The effect can depend on the font (and for Cambria one can use for instance \type {"16}).
-\section{Math spacing setting}
+\subsection[mathacc]{Accent handling}
-Besides the parameters mentioned in the previous sections, there are also 64 new
-primitives to control the math spacing table (as explained in Chapter~18 of the
-\TEX book). The primitive names are a simple matter of combining two math atom
-types, but for completeness' sake, here is the whole list:
-
-\starttwocolumns
-\starttyping
-\Umathordordspacing
-\Umathordopspacing
-\Umathordbinspacing
-\Umathordrelspacing
-\Umathordopenspacing
-\Umathordclosespacing
-\Umathordpunctspacing
-\Umathordinnerspacing
-\Umathopordspacing
-\Umathopopspacing
-\Umathopbinspacing
-\Umathoprelspacing
-\Umathopopenspacing
-\Umathopclosespacing
-\Umathoppunctspacing
-\Umathopinnerspacing
-\Umathbinordspacing
-\Umathbinopspacing
-\Umathbinbinspacing
-\Umathbinrelspacing
-\Umathbinopenspacing
-\Umathbinclosespacing
-\Umathbinpunctspacing
-\Umathbininnerspacing
-\Umathrelordspacing
-\Umathrelopspacing
-\Umathrelbinspacing
-\Umathrelrelspacing
-\Umathrelopenspacing
-\Umathrelclosespacing
-\Umathrelpunctspacing
-\Umathrelinnerspacing
-\Umathopenordspacing
-\Umathopenopspacing
-\Umathopenbinspacing
-\Umathopenrelspacing
-\Umathopenopenspacing
-\Umathopenclosespacing
-\Umathopenpunctspacing
-\Umathopeninnerspacing
-\Umathcloseordspacing
-\Umathcloseopspacing
-\Umathclosebinspacing
-\Umathcloserelspacing
-\Umathcloseopenspacing
-\Umathcloseclosespacing
-\Umathclosepunctspacing
-\Umathcloseinnerspacing
-\Umathpunctordspacing
-\Umathpunctopspacing
-\Umathpunctbinspacing
-\Umathpunctrelspacing
-\Umathpunctopenspacing
-\Umathpunctclosespacing
-\Umathpunctpunctspacing
-\Umathpunctinnerspacing
-\Umathinnerordspacing
-\Umathinneropspacing
-\Umathinnerbinspacing
-\Umathinnerrelspacing
-\Umathinneropenspacing
-\Umathinnerclosespacing
-\Umathinnerpunctspacing
-\Umathinnerinnerspacing
-\stoptyping
-\stoptwocolumns
-
-These parameters are of type \type {\muskip}, so setting a parameter can be done
-like this:
-
-\starttyping
-\Umathopordspacing\displaystyle=4mu plus 2mu
-\stoptyping
-
-They are all initialized by \type {initex} to the values mentioned in the table
-in Chapter~18 of the \TEX book.
-
-Note 1: for ease of use as well as for backward compatibility, \type
-{\thinmuskip}, \type {\medmuskip} and \type {\thickmuskip} are treated
-especially. In their case a pointer to the corresponding internal parameter is
-saved, not the actual \type {\muskip} value. This means that any later changes to
-one of these three parameters will be taken into account.
-
-Note 2: Careful readers will realise that there are also primitives for the items
-marked \type {*} in the \TEX book. These will not actually be used as those
-combinations of atoms cannot actually happen, but it seemed better not to break
-orthogonality. They are initialized to zero.
-
-\section[mathacc]{Math accent handling}
+\topicindex {math+accents}
\LUATEX\ supports both top accents and bottom accents in math mode, and math
accents stretch automatically (if this is supported by the font the accent comes
from, of course). Bottom and combined accents as well as fixed-width math accents
-are controlled by optional keywords following \type {\Umathaccent}.
+are controlled by optional keywords following \lpr {Umathaccent}.
-The keyword \type {bottom} after \type {\Umathaccent} signals that a bottom accent
+The keyword \type {bottom} after \lpr {Umathaccent} signals that a bottom accent
is needed, and the keyword \type {both} signals that both a top and a bottom
accent are needed (in this case two accents need to be specified, of course).
@@ -852,7 +1080,7 @@ A simple example:
If a math top accent has to be placed and the accentee is a character and has a
non-zero \type {top_accent} value, then this value will be used to place the
-accent instead of the \type {\skewchar} kern used by \TEX82.
+accent instead of the \prm {skewchar} kern used by \TEX82.
The \type {top_accent} value represents a vertical line somewhere in the
accentee. The accent will be shifted horizontally such that its own \type
@@ -861,7 +1089,7 @@ accentee. The accent will be shifted horizontally such that its own \type
followed by its italic correction is used instead.
The vertical placement of a top accent depends on the \type {x_height} of the
-font of the accentee (as explained in the \TEX book), but if value that turns out
+font of the accentee (as explained in the \TEX book), but if a value turns out
to be zero and the font had a \type {MathConstants} table, then \type
{AccentBaseHeight} is used instead.
@@ -870,28 +1098,30 @@ correction takes place.
Possible locations are \type {top}, \type {bottom}, \type {both} and \type
{center}. When no location is given \type {top} is assumed. An additional
-parameter \type {fraction} can be specified followed by a number; a value of for
+parameter \nod {fraction} can be specified followed by a number; a value of for
instance 1200 means that the criterium is 1.2 times the width of the nucleus. The
fraction only applies to the stepwise selected shapes and is mostly meant for the
\type {overlay} location. It also works for the other locations but then it
concerns the width.
-\section{Math root extension}
+\subsection{Radical extensions}
+
+\topicindex {math+radicals}
-The new primitive \type {\Uroot} allows the construction of a radical noad
-including a degree field. Its syntax is an extension of \type {\Uradical}:
+The new primitive \lpr {Uroot} allows the construction of a radical noad
+including a degree field. Its syntax is an extension of \lpr {Uradical}:
\starttyping
\Uradical <fam integer> <char integer> <radicand>
\Uroot <fam integer> <char integer> <degree> <radicand>
\stoptyping
-The placement of the degree is controlled by the math parameters \type
-{\Umathradicaldegreebefore}, \type {\Umathradicaldegreeafter}, and \type
-{\Umathradicaldegreeraise}. The degree will be typeset in \type
-{\scriptscriptstyle}.
+The placement of the degree is controlled by the math parameters \lpr
+{Umathradicaldegreebefore}, \lpr {Umathradicaldegreeafter}, and \lpr
+{Umathradicaldegreeraise}. The degree will be typeset in \prm
+{scriptscriptstyle}.
-\section{Math kerning in super- and subscripts}
+\subsection{Super- and subscripts}
The character fields in a \LUA|-|loaded \OPENTYPE\ math font can have a \quote
{mathkern} table. The format of this table is the same as the \quote {mathkern}
@@ -950,11 +1180,15 @@ next higher height and kern pair, or the highest one in the character (if there
value high enough in the character), or simply zero (if the character has no math kern
pairs at all).
-\section{Scripts on horizontally extensible items like arrows}
+\subsection{Scripts on extensibles}
-The primitives \type {\Uunderdelimiter} and \type {\Uoverdelimiter} allow the
+\topicindex {math+scripts}
+\topicindex {math+delimiters}
+\topicindex {math+extensibles}
+
+The primitives \lpr {Uunderdelimiter} and \lpr {Uoverdelimiter} allow the
placement of a subscript or superscript on an automatically extensible item and
-\type {\Udelimiterunder} and \type {\Udelimiterover} allow the placement of an
+\lpr {Udelimiterunder} and \lpr {Udelimiterover} allow the placement of an
automatically extensible item as a subscript or superscript on a nucleus. The
input:
@@ -972,18 +1206,18 @@ $\Udelimiterunder 0 "2194 {\hbox{\strut delimiterunder}}$
\blank \startnarrower \getbuffer \stopnarrower \blank
-The vertical placements are controlled by \type {\Umathunderdelimiterbgap}, \type
-{\Umathunderdelimitervgap}, \type {\Umathoverdelimiterbgap}, and \type
-{\Umathoverdelimitervgap} in a similar way as limit placements on large operators.
-The superscript in \type {\Uoverdelimiter} is typeset in a suitable scripted style,
-the subscript in \type {\Uunderdelimiter} is cramped as well.
+The vertical placements are controlled by \lpr {Umathunderdelimiterbgap}, \lpr
+{Umathunderdelimitervgap}, \lpr {Umathoverdelimiterbgap}, and \lpr
+{Umathoverdelimitervgap} in a similar way as limit placements on large operators.
+The superscript in \lpr {Uoverdelimiter} is typeset in a suitable scripted style,
+the subscript in \lpr {Uunderdelimiter} is cramped as well.
These primitives accepts an option \type {width} specification. When used the
also optional keywords \type {left}, \type {middle} and \type {right} will
determine what happens when a requested size can't be met (which can happen when
we step to successive larger variants).
-An extra primitive \type {\Uhextensible} is available that can be used like this:
+An extra primitive \lpr {Uhextensible} is available that can be used like this:
\startbuffer
$\Uhextensible width 10cm 0 "2194$
@@ -1008,38 +1242,11 @@ $\Uhextensible width 1pt middle 0 "2194$
font metrics are involved we have a different code path for traditional fonts end
\OPENTYPE\ fonts.
-\section {Extracting values}
-
-You can extract the components of a math character. Say that we have defined:
+\subsection{Fractions}
-\starttyping
-\Umathcode 1 2 3 4
-\stoptyping
-
-then
-
-\starttyping
-[\Umathcharclass1] [\Umathcharfam1] [\Umathcharslot1]
-\stoptyping
+\topicindex {math+fractions}
-will return:
-
-\starttyping
-[2] [3] [4]
-\stoptyping
-
-These commands are provides as convenience. Before they came available you could
-do the following:
-
-\starttyping
-\def\Umathcharclass{\directlua{tex.print(tex.getmathcode(token.scan_int())[1])}}
-\def\Umathcharfam {\directlua{tex.print(tex.getmathcode(token.scan_int())[2])}}
-\def\Umathcharslot {\directlua{tex.print(tex.getmathcode(token.scan_int())[3])}}
-\stoptyping
-
-\section{fractions}
-
-The \type {\abovewithdelims} command accepts a keyword \type {exact}. When issued
+The \prm {abovewithdelims} command accepts a keyword \type {exact}. When issued
the extra space relative to the rule thickness is not added. One can of course
use the \type {\Umathfraction..gap} commands to influence the spacing. Also the
rule is still positioned around the math axis.
@@ -1053,7 +1260,7 @@ vertical gap for skewed fractions. Of course some guessing is needed in order to
implement something that uses them. And so we now provide a primitive similar to the
other fraction related ones but with a few options so that one can influence the
rendering. Of course a user can also mess around a bit with the parameters
-\type {\Umathskewedfractionhgap} and \type {\Umathskewedfractionvgap}.
+\lpr {Umathskewedfractionhgap} and \lpr {Umathskewedfractionvgap}.
The syntax used here is:
@@ -1064,7 +1271,7 @@ The syntax used here is:
where the options can be \type {noaxis} and \type {exact}. By default we add half
the axis to the shifts and by default we zero the width of the middle character.
-For Latin Modern The result looks as follows:
+For Latin Modern the result looks as follows:
\def\ShowA#1#2#3{$x + { {#1} \Uskewed / #3 {#2} } + x$}
\def\ShowB#1#2#3{$x + { {#1} \Uskewedwithdelims / () #3 {#2} } + x$}
@@ -1099,7 +1306,85 @@ For Latin Modern The result looks as follows:
\stoptabulate
\stop
-\section {Last lines}
+\subsection {Delimiters: \type{\Uleft}, \prm {Umiddle} and \prm {Uright}}
+
+\topicindex {math+delimiters}
+
+Normally you will force delimiters to certain sizes by putting an empty box or
+rule next to it. The resulting delimiter will either be a character from the
+stepwise size range or an extensible. The latter can be quite differently
+positioned than the characters as it depends on the fit as well as the fact if
+the used characters in the font have depth or height. Commands like (plain \TEX
+s) \type {\big} need use this feature. In \LUATEX\ we provide a bit more control
+by three variants that support optional parameters \type {height}, \type {depth}
+and \type {axis}. The following example uses this:
+
+\startbuffer
+\Uleft height 30pt depth 10pt \Udelimiter "0 "0 "000028
+\quad x\quad
+\Umiddle height 40pt depth 15pt \Udelimiter "0 "0 "002016
+\quad x\quad
+\Uright height 30pt depth 10pt \Udelimiter "0 "0 "000029
+\quad \quad \quad
+\Uleft height 30pt depth 10pt axis \Udelimiter "0 "0 "000028
+\quad x\quad
+\Umiddle height 40pt depth 15pt axis \Udelimiter "0 "0 "002016
+\quad x\quad
+\Uright height 30pt depth 10pt axis \Udelimiter "0 "0 "000029
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\ruledhbox{\mathematics{\getbuffer}}
+\stoplinecorrection
+
+The keyword \type {exact} can be used as directive that the real dimensions
+should be applied when the criteria can't be met which can happen when we're
+still stepping through the successively larger variants. When no dimensions are
+given the \type {noaxis} command can be used to prevent shifting over the axis.
+
+You can influence the final class with the keyword \type {class} which will
+influence the spacing. The numbers are the same as for character classes.
+
+\stopsection
+
+\startsection[title={Extracting values}]
+
+\subsection{Codes}
+
+\topicindex {math+codes}
+
+You can extract the components of a math character. Say that we have defined:
+
+\starttyping
+\Umathcode 1 2 3 4
+\stoptyping
+
+then
+
+\starttyping
+[\Umathcharclass1] [\Umathcharfam1] [\Umathcharslot1]
+\stoptyping
+
+will return:
+
+\starttyping
+[2] [3] [4]
+\stoptyping
+
+These commands are provides as convenience. Before they come available you could
+do the following:
+
+\starttyping
+\def\Umathcharclass{\directlua{tex.print(tex.getmathcode(token.scan_int())[1])}}
+\def\Umathcharfam {\directlua{tex.print(tex.getmathcode(token.scan_int())[2])}}
+\def\Umathcharslot {\directlua{tex.print(tex.getmathcode(token.scan_int())[3])}}
+\stoptyping
+
+\subsection {Last lines}
+
+\topicindex {math+last line}
There is a new primitive to control the overshoot in the calculation of the
previous line in mid|-|paragraph display math. The default value is 2 times
@@ -1121,32 +1406,41 @@ get the length of the last line, the following will often work too:
\relax}
\stoptyping
-\section {Other Math changes}
+\stopsection
+
+\startsection[title={Math mode}]
+
+\subsection {Verbose versions of single|-|character math commands}
-\subsection {Verbose versions of single-character math commands}
+\topicindex {math+styles}
\LUATEX\ defines six new primitives that have the same function as
\type {^}, \type {_}, \type {$}, and \type {$$}:
\starttabulate[|l|l|]
-\BC primitive \BC explanation \NC \NR
-\NC \type {\Usuperscript} \NC Duplicates the functionality of \type {^} \NC \NR
-\NC \type {\Usubscript} \NC Duplicates the functionality of \type {_} \NC \NR
-\NC \type {\Ustartmath} \NC Duplicates the functionality of \type {$}, % $
+\DB primitive \BC explanation \NC \NR
+\TB
+\NC \lpr {Usuperscript} \NC duplicates the functionality of \type {^} \NC \NR
+\NC \lpr {Usubscript} \NC duplicates the functionality of \type {_} \NC \NR
+\NC \lpr {Ustartmath} \NC duplicates the functionality of \type {$}, % $
when used in non-math mode. \NC \NR
-\NC \type {\Ustopmath} \NC Duplicates the functionality of \type {$}, % $
+\NC \lpr {Ustopmath} \NC duplicates the functionality of \type {$}, % $
when used in inline math mode. \NC \NR
-\NC \type {\Ustartdisplaymath} \NC Duplicates the functionality of \type {$$}, % $$
+\NC \lpr {Ustartdisplaymath} \NC duplicates the functionality of \type {$$}, % $$
when used in non-math mode. \NC \NR
-\NC \type {\Ustopdisplaymath} \NC Duplicates the functionality of \type {$$}, % $$
+\NC \lpr {Ustopdisplaymath} \NC duplicates the functionality of \type {$$}, % $$
when used in display math mode. \NC \NR
+\LL
\stoptabulate
-The \type {\Ustopmath} and \type {\Ustopdisplaymath} primitives check if the current
+The \lpr {Ustopmath} and \lpr {Ustopdisplaymath} primitives check if the current
math mode is the correct one (inline vs.\ displayed), but you can freely intermix
the four mathon|/|mathoff commands with explicit dollar sign(s).
-\subsection{Script commands \type {\Unosuperscript} and \type {\Unosubscript}}
+\subsection{Script commands \lpr {Unosuperscript} and \lpr {Unosubscript}}
+
+\topicindex {math+styles}
+\topicindex {math+scripts}
These two commands result in super- and subscripts but with the current style (at the
time of rendering). So,
@@ -1164,71 +1458,17 @@ $
results in \inlinebuffer[script].
+\subsection{Allowed math commands in non|-|math modes}
-\subsection{Allowed math commands in non-math modes}
-
-The commands \type {\mathchar}, and \type {\Umathchar} and control sequences that
-are the result of \type {\mathchardef} or \type {\Umathchardef} are also
-acceptable in the horizontal and vertical modes. In those cases, the \type
-{\textfont} from the requested math family is used.
-
-\section{Math surrounding skips}
-
-Inline math is surrounded by (optional) \type {\mathsurround} spacing but that is fixed
-dimension. There is now an additional parameter \type {\mathsurroundskip}. When set to a
-non|-|zero value (or zero with some stretch or shrink) this parameter will replace
-\type {\mathsurround}. By using an additional parameter instead of changing the nature
-of \type {\mathsurround}, we can remain compatible. In the meantime a bit more
-control has been added via \type {\mathsurroundmode}. This directive can take 6 values
-with zero being the default behaviour.
-
-\start
+\topicindex {math+text}
+\topicindex {text+math}
-\def\OneLiner#1#2%
- {\NC \type{#1}
- \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\mathsurroundmode#1\relax\hsize 100pt x$x$x}
- \NC \dontleavehmode\inframed[align=normal,offset=0pt,frame=off]{\mathsurroundmode#1\relax\hsize 100pt x $x$ x}
- \NC #2
- \NC \NR}
+The commands \prm {mathchar}, and \lpr {Umathchar} and control sequences that are
+the result of \prm {mathchardef} or \lpr {Umathchardef} are also acceptable in
+the horizontal and vertical modes. In those cases, the \prm {textfont} from the
+requested math family is used.
-\startbuffer
-\mathsurround 10pt
-\mathsurroundskip20pt
-\stopbuffer
-
-\typebuffer \getbuffer
-
-\starttabulate[|c|c|c|pl|]
-\HL
-\BC mode \BC \type {x$x$x} \BC \type {x $x$ x} \BC effect \NC \NR
-\HL
-\OneLiner{0}{obey \type {\mathsurround} when \type {\mathsurroundskip} is 0pt}
-\OneLiner{1}{only add skip to the left}
-\OneLiner{2}{only add skip to the right}
-\OneLiner{3}{add skip to the left and right}
-\OneLiner{4}{ignore the skip setting, obey \type {\mathsurround}}
-\OneLiner{5}{disable all spacing around math}
-\OneLiner{6}{only apply \type {\mathsurroundskip} when also spacing}
-\OneLiner{7}{only apply \type {\mathsurroundskip} when no spacing}
-\HL
-\stoptabulate
-
-\stop
-
-Method six omits the surround glue when there is (x)spacing glue present while
-method seven does the opposite, the glue is only applied when there is (x)space
-glue present too. Anything more fancy, like checking the begining or end of a
-paragraph (or edges of a box) would not be robust anyway. If you want that you
-can write a callback that runs over a list and analyzes a paragraph. Actually, in
-that case you could also inject glue (or set the properties of a math node)
-explicitly. So, these modes are in practice mostly useful for special purposes
-and experiments (they originate in a tracker item). Keep in mind that this glue
-is part of the math node and not always treated as normal glue: it travels with
-the begin and end math nodes. Also, method 6 and 7 will zero the skip related
-fields in a node when applicable in the first occasion that checks them
-(linebreaking or packaging).
-
-% \section{Math todo}
+% \startsection[title={Math todo}]
%
% The following items are still todo.
%
@@ -1249,194 +1489,158 @@ fields in a node when applicable in the first occasion that checks them
% Support for multi|-|line displays using \MATHML\ style alignment points.
% \stopitem
% \stopitemize
+%
+% \stopsection
-\subsection {Delimiters: \type{\Uleft}, \type {\Umiddle} and \type {\Uright}}
-
-Normally you will force delimiters to certain sizes by putting an empty box or
-rule next to it. The resulting delimiter will either be a character from the
-stepwise size range or an extensible. The latter can be quite differently
-positioned that the characters as it depends on the fit as well as the fact if
-the used characters in the font have depth or height. Commands like (plain \TEX
-s) \type {\big} need use this feature. In \LUATEX\ we provide a bit more control
-by three variants that supporting optional parameters \type {height}, \type
-{depth} and \type {axis}. The following example uses this:
-
-\startbuffer
-\Uleft height 30pt depth 10pt \Udelimiter "0 "0 "000028
-\quad x\quad
-\Umiddle height 40pt depth 15pt \Udelimiter "0 "0 "002016
-\quad x\quad
-\Uright height 30pt depth 10pt \Udelimiter "0 "0 "000029
-\quad \quad \quad
-\Uleft height 30pt depth 10pt axis \Udelimiter "0 "0 "000028
-\quad x\quad
-\Umiddle height 40pt depth 15pt axis \Udelimiter "0 "0 "002016
-\quad x\quad
-\Uright height 30pt depth 10pt axis \Udelimiter "0 "0 "000029
-\stopbuffer
-
-\typebuffer
-
-\startlinecorrection
-\ruledhbox{\mathematics{\getbuffer}}
-\stoplinecorrection
-
-The keyword \type {exact} can be used as directive that the real dimensions
-should be applied when the criteria can't be met which can happen when we're
-still stepping through the successively larger variants. When no dimensions are
-given the \type {noaxis} command can be used to prevent shifting over the axis.
+\stopsection
-You can influence the final class with the keyword \type {class} which will
-influence the spacing. The numbers are the same as for character classes.
+\startsection[title={Goodies}]
-\subsection{Fixed scripts}
+\subsection {Flattening: \lpr {mathflattenmode}}
-We have three parameters that are used for this fixed anchoring:
+\topicindex {math+flattening}
-\starttabulate[|l|l|]
-\NC $d$ \NC \type {\Umathsubshiftdown} \NC \NR
-\NC $u$ \NC \type {\Umathsupshiftup} \NC \NR
-\NC $s$ \NC \type {\Umathsubsupshiftdown} \NC \NR
-\stoptabulate
+The \TEX\ math engine collapses \type {ord} noads without sub- and superscripts
+and a character as nucleus. and which has the side effect that in \OPENTYPE\ mode
+italic corrections are applied (given that they are enabled).
-When we set \type {\mathscriptsmode} to a value other than zero these are used
-for calculating fixed positions. This is something that is needed for instance
-for chemistry. You can manipulate the mentioned variables to achive different
-effects.
+\startbuffer[sample]
+\switchtobodyfont[modern]
+$V \mathbin{\mathbin{v}} V$\par
+$V \mathord{\mathord{v}} V$\par
+\stopbuffer
-\def\SampleMath#1%
- {$\mathscriptsmode#1\mathupright CH_2 + CH^+_2 + CH^2_2$}
+\typebuffer[sample]
-\starttabulate[|c|c|c|l|]
-\BC mode \BC down \BC up \BC \NC \NR
-\NC 0 \NC dynamic \NC dynamic \NC \SampleMath{0} \NC \NR
-\NC 1 \NC $d$ \NC $u$ \NC \SampleMath{1} \NC \NR
-\NC 2 \NC $s$ \NC $u$ \NC \SampleMath{2} \NC \NR
-\NC 3 \NC $s$ \NC $u + s - d$ \NC \SampleMath{3} \NC \NR
-\NC 4 \NC $d + (s-d)/2$ \NC $u + (s-d)/2$ \NC \SampleMath{4} \NC \NR
-\NC 5 \NC $d$ \NC $u + s - d$ \NC \SampleMath{5} \NC \NR
-\stoptabulate
+This renders as:
-The value of this parameter obeys grouping but applies to the whole current
-formula.
+\blank \start \mathflattenmode\plusone \getbuffer[sample] \stop \blank
-% if needed we can put the value in stylenodes but maybe more should go there
+When we set \lpr {mathflattenmode} to 31 we get:
-\subsection{Penalties: \type {\mathpenaltiesmode}}
+\blank \start \mathflattenmode\numexpr1+2+4+8+16\relax \getbuffer[sample] \stop \blank
-Only in inline math penalties will be added in a math list. You can force
-penalties (also in display math) by setting:
+When you see no difference, then the font probably has the proper character
+dimensions and no italic correction is needed. For Latin Modern (at least till
+2018) there was a visual difference. In that respect this parameter is not always
+needed unless of course you want efficient math lists anyway.
-\starttyping
-\mathpenaltiesmode = 1
-\stoptyping
-
-This primnitive is not really needed in \LUATEX\ because you can use the callback
-\type {mlist_to_hlist} to force penalties by just calling the regular routine
-with forced penalties. However, as part of opening up and control this primitive
-makes sense. As a bonus we also provide two extra penalties:
+You can influence flattening by adding the appropriate number to the value of the
+mode parameter. The default value is~1.
-\starttyping
-\prebinoppenalty = -100 % example value
-\prerelpenalty = 900 % example value
-\stoptyping
+\starttabulate[|Tc|c|]
+\DB mode \BC class \NC \NR
+\TB
+\NC 1 \NC ord \NC \NR
+\NC 2 \NC bin \NC \NR
+\NC 4 \NC rel \NC \NR
+\NC 8 \NC punct \NC \NR
+\NC 16 \NC inner \NC \NR
+\LL
+\stoptabulate
-They default to inifinite which signals that they don't need to be inserted. When
-set they are injected before a binop or rel noad. This is an experimental feature.
+\subsection {Less Tracing}
-\subsection {Tracing}
+\topicindex {math+tracing}
Because there are quite some math related parameters and values, it is possible
to limit tracing. Only when \type {tracingassigns} and|/|or \type
{tracingrestores} are set to~2 or more they will be traced.
-\subsection {Math options}
+\subsection {Math options with \lpr {mathoption}}
The logic in the math engine is rather complex and there are often no universal
solutions (read: what works out well for one font, fails for another). Therefore
-some variations in the implementation will be driven by options for which a new
-primitive \type {\mathoption} has been introduced (so that we don't end up with
-many new commands). The approach of options also permits us to see what effect a
-specific solution has.
-
-\subsubsection {\type {\mathoption old}}
+some variations in the implementation are driven by parameters (modes). In
+addition there is a new primitive \lpr {mathoption} which will be used for
+testing. Don't rely on any option to be there in a production version as they are
+meant for development.
This option was introduced for testing purposes when the math engine got split
code paths and it forces the engine to treat new fonts as old ones with respect
to italic correction etc. There are no guarantees given with respect to the final
-result and unexpected side effects are not seens as bugs as they relate to font
-properties.
+result and unexpected side effects are not seen as bugs as they relate to font
+properties. Ther eis currently only one option:
\startbuffer
\mathoption old 1
\stopbuffer
The \type {oldmath} boolean flag in the \LUA\ font table is the official way to
-force old treatment as it's bound to fonts.
-
-\subsubsection {\type {\mathoption noitaliccompensation}}
-
-This option compensates placement for characters with a built|-|in italic
-correction.
-
-\startbuffer
-{\showboxes\int}\quad
-{\showboxes\int_{|}^{|}}\quad
-{\showboxes\int\limits_{|}^{|}}
-\stopbuffer
-
-\typebuffer
-
-Gives (with computer modern that has such italics):
-
-\startlinecorrection[blank]
- \switchtobodyfont[modern]
- \startcombination[nx=2,ny=2,distance=5em]
- {\mathoption noitaliccompensation 0\relax \mathematics{\getbuffer}}
- {\nohyphens\type{0:inline}}
- {\mathoption noitaliccompensation 0\relax \mathematics{\displaymath\getbuffer}}
- {\nohyphens\type{0:display}}
- {\mathoption noitaliccompensation 1\relax \mathematics{\getbuffer}}
- {\nohyphens\type{1:inline}}
- {\mathoption noitaliccompensation 1\relax \mathematics{\displaymath\getbuffer}}
- {\nohyphens\type{1:display}}
- \stopcombination
-\stoplinecorrection
-
-\subsubsection {\type {\mathoption nocharitalic}}
+force old treatment as it's bound to fonts. Like with all options we may
+temporarily introduce with this command this feature is not meant for production.
-When two characters follow each other italic correction can interfere. The
-following example shows what this option does:
-
-\startbuffer
-\catcode"1D443=11
-\catcode"1D444=11
-\catcode"1D445=11
-P( PP PQR
-\stopbuffer
-
-\typebuffer
-
-Gives (with computer modern that has such italics):
-
-\startlinecorrection[blank]
- \switchtobodyfont[modern]
- \startcombination[nx=2,ny=2,distance=5em]
- {\mathoption nocharitalic 0\relax \mathematics{\getbuffer}}
- {\nohyphens\type{0:inline}}
- {\mathoption nocharitalic 0\relax \mathematics{\displaymath\getbuffer}}
- {\nohyphens\type{0:display}}
- {\mathoption nocharitalic 1\relax \mathematics{\getbuffer}}
- {\nohyphens\type{1:inline}}
- {\mathoption nocharitalic 1\relax \mathematics{\displaymath\getbuffer}}
- {\nohyphens\type{1:display}}
- \stopcombination
-\stoplinecorrection
-
-\subsubsection {\type {\mathoption useoldfractionscaling}}
+% % obsolete:
+%
+% \subsubsection {\type {\mathoption noitaliccompensation}}
+%
+% This option compensates placement for characters with a built|-|in italic
+% correction.
+%
+% \startbuffer
+% {\showboxes\int}\quad
+% {\showboxes\int_{|}^{|}}\quad
+% {\showboxes\int\limits_{|}^{|}}
+% \stopbuffer
+%
+% \typebuffer
+%
+% Gives (with computer modern that has such italics):
+%
+% \startlinecorrection[blank]
+% \switchtobodyfont[modern]
+% \startcombination[nx=2,ny=2,distance=5em]
+% {\mathoption noitaliccompensation 0\relax \mathematics{\getbuffer}}
+% {\nohyphens\type{0:inline}}
+% {\mathoption noitaliccompensation 0\relax \mathematics{\displaymath\getbuffer}}
+% {\nohyphens\type{0:display}}
+% {\mathoption noitaliccompensation 1\relax \mathematics{\getbuffer}}
+% {\nohyphens\type{1:inline}}
+% {\mathoption noitaliccompensation 1\relax \mathematics{\displaymath\getbuffer}}
+% {\nohyphens\type{1:display}}
+% \stopcombination
+% \stoplinecorrection
+
+% % obsolete:
+%
+% \subsubsection {\type {\mathoption nocharitalic}}
+%
+% When two characters follow each other italic correction can interfere. The
+% following example shows what this option does:
+%
+% \startbuffer
+% \catcode"1D443=11
+% \catcode"1D444=11
+% \catcode"1D445=11
+% P( PP PQR
+% \stopbuffer
+%
+% \typebuffer
+%
+% Gives (with computer modern that has such italics):
+%
+% \startlinecorrection[blank]
+% \switchtobodyfont[modern]
+% \startcombination[nx=2,ny=2,distance=5em]
+% {\mathoption nocharitalic 0\relax \mathematics{\getbuffer}}
+% {\nohyphens\type{0:inline}}
+% {\mathoption nocharitalic 0\relax \mathematics{\displaymath\getbuffer}}
+% {\nohyphens\type{0:display}}
+% {\mathoption nocharitalic 1\relax \mathematics{\getbuffer}}
+% {\nohyphens\type{1:inline}}
+% {\mathoption nocharitalic 1\relax \mathematics{\displaymath\getbuffer}}
+% {\nohyphens\type{1:display}}
+% \stopcombination
+% \stoplinecorrection
+
+% % obsolete:
+%
+% \subsubsection {\type {\mathoption useoldfractionscaling}}
+%
+% This option has been introduced as solution for tracker item 604 for fuzzy cases
+% around either or not present fraction related settings for new fonts.
-This option has been introduced as solution for tracker item 604 for fuzzy cases
-around either or not present fraction related settings for new fonts.
+\stopsection
\stopchapter
diff --git a/doc/context/sources/general/manuals/luatex/luatex-modifications.tex b/doc/context/sources/general/manuals/luatex/luatex-modifications.tex
index b5d8f2750..50d23fb1b 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-modifications.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-modifications.tex
@@ -1,7 +1,6 @@
% language=uk
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-modifications
@@ -11,6 +10,9 @@
\startsubsection[title=The need for change]
+\topicindex {engines}
+\topicindex {history}
+
The first version of \LUATEX\ only had a few extra primitives and it was largely
the same as \PDFTEX. Then we merged substantial parts of \ALEPH\ into the code
and got more primitives. When we got more stable the decision was made to clean
@@ -22,13 +24,15 @@ most of the adapted ones.
Besides the expected changes caused by new functionality, there are a number of
not|-|so|-|expected changes. These are sometimes a side|-|effect of a new
-(conflicting) feature, or, more often than not, a change neccessary to clean up
+(conflicting) feature, or, more often than not, a change necessary to clean up
the internal interfaces. These will also be mentioned.
\stopsubsection
\startsubsection[title=Changes from \TEX\ 3.1415926]
+\topicindex {\TEX}
+
Of course it all starts with traditional \TEX. Even if we started with \PDFTEX,
most still comes from the original. But we divert a bit.
@@ -38,7 +42,7 @@ most still comes from the original. But we divert a bit.
The current code base is written in \CCODE, not \PASCAL. We use \CWEB\ when
possible. As a consequence instead of one large file plus change files, we
now have multiple files organized in categories like \type {tex}, \type
- {pdf}, \type {lang}, \type {font}, \type {lua}, etc. There are some artefacts
+ {pdf}, \type {lang}, \type {font}, \type {lua}, etc. There are some artifacts
of the conversion to \CCODE, but in due time we will clean up the source code
and make sure that the documentation is done right. Many files are in the
\CWEB\ format, but others, like those interfacing to \LUA, are \CCODE\ files.
@@ -63,21 +67,21 @@ most still comes from the original. But we divert a bit.
\stopitem
\startitem
- The upper limit to \type {\endlinechar} and \type {\newlinechar} is 127.
+ The upper limit to \prm {endlinechar} and \prm {newlinechar} is 127.
\stopitem
\startitem
- Magnification (\type {\mag}) is only supported in \DVI\ output mode. You can
+ Magnification (\prm {mag}) is only supported in \DVI\ output mode. You can
set this parameter and it even works with \type {true} units till you switch
to \PDF\ output mode. When you use \PDF\ output you can best not touch the
- \type {\mag} variable. This fuzzy behaviour is not much different from using
+ \prm {mag} variable. This fuzzy behaviour is not much different from using
\PDF\ backend related functionality while eventually \DVI\ output is
required.
After the output mode has been frozen (normally that happens when the first
page is shipped out) or when \PDF\ output is enabled, the \type {true}
specification is ignored. When you preload a plain format adapted to
- \LUATEX\ it can be that the \type {\mag} parameter already has been set.
+ \LUATEX\ it can be that the \prm {mag} parameter already has been set.
\stopitem
\stopitemize
@@ -86,6 +90,8 @@ most still comes from the original. But we divert a bit.
\startsubsection[title=Changes from \ETEX\ 2.2]
+\topicindex {\ETEX}
+
Being the de factor standard extension of course we provide the \ETEX\
functionality, but with a few small adaptations.
@@ -99,18 +105,19 @@ functionality, but with a few small adaptations.
\startitem
The \TEXXET\ extension is not present, so the primitives \type
{\TeXXeTstate}, \type {\beginR}, \type {\beginL}, \type {\endR} and \type
- {\endL} are missing. Instead we use the \OMEGA\ approach to directionality.
+ {\endL} are missing. Instead we used the \OMEGA/\ALEPH\ approach to
+ directionality as starting point.
\stopitem
\startitem
- Some of the tracing information that is output by \ETEX's \type
- {\tracingassigns} and \type {\tracingrestores} is not there.
+ Some of the tracing information that is output by \ETEX's \prm
+ {tracingassigns} and \prm {tracingrestores} is not there.
\stopitem
\startitem
- Register management in \LUATEX\ uses the \ALEPH\ model, so the maximum value
- is 65535 and the implementation uses a flat array instead of the mixed
- flat|\&|sparse model from \ETEX.
+ Register management in \LUATEX\ uses the \OMEGA/\ALEPH\ model, so the maximum
+ value is 65535 and the implementation uses a flat array instead of the mixed
+ flat & sparse model from \ETEX.
\stopitem
\startitem
@@ -127,6 +134,8 @@ functionality, but with a few small adaptations.
\startsubsection[title=Changes from \PDFTEX\ 1.40]
+\topicindex {\PDFTEX}
+
Because we want to produce \PDF\ the most natural starting point was the popular
\PDFTEX\ program. We inherit the stable features, dropped most of the
experimental code and promoted some functionality to core \LUATEX\ functionality
@@ -134,76 +143,73 @@ which in turn triggered renaming primitives.
For compatibility reasons we still refer to \type {\pdf...} commands but \LUATEX\
has a different backend interface. Instead of these primitives there are three
-interfacing primitives: \type {\pdfextension}, \type {\pdfvariable} and
-\type {\pdffeedback} that take keywords and optional further arguments. This way
-we can extend the features when needed but don't need to adapt the core engine.
-The front- and backend are decoupled as much as possible.
+interfacing primitives: \lpr {pdfextension}, \lpr {pdfvariable} and \lpr
+{pdffeedback} that take keywords and optional further arguments (below we will
+still use the \tex {pdf} prefix names as reference). This way we can extend the
+features when needed but don't need to adapt the core engine. The front- and
+backend are decoupled as much as possible.
\startitemize
\startitem
The (experimental) support for snap nodes has been removed, because it is
much more natural to build this functionality on top of node processing and
- attributes. The associated primitives that are now gone are: \type
- {\pdfsnaprefpoint}, \type {\pdfsnapy}, and \type {\pdfsnapycomp}.
+ attributes. The associated primitives that are gone are: \orm
+ {pdfsnaprefpoint}, \orm {pdfsnapy}, and \orm {pdfsnapycomp}.
\stopitem
\startitem
The (experimental) support for specialized spacing around nodes has also been
- removed. The associated primitives that are now gone are: \type
- {\pdfadjustinterwordglue}, \type {\pdfprependkern}, and \type
- {\pdfappendkern}, as well as the five supporting primitives \type
- {\knbscode}, \type {\stbscode}, \type {\shbscode}, \type {\knbccode}, and
- \type {\knaccode}.
+ removed. The associated primitives that are gone are: \orm
+ {pdfadjustinterwordglue}, \orm {pdfprependkern}, and \orm {pdfappendkern}, as
+ well as the five supporting primitives \orm {knbscode}, \orm {stbscode}, \orm
+ {shbscode}, \orm {knbccode}, and \orm {knaccode}.
\stopitem
\startitem
A number of \quote {\PDFTEX\ primitives} have been removed as they can be
- implemented using \LUA:
-
- \start \raggedright
- \type {\pdfelapsedtime}, \type {\pdfescapehex}, \type {\pdfescapename}, \type
- {\pdfescapestring}, \type {\pdffiledump}, \type {\pdffilemoddate}, \type
- {\pdffilesize}, \type {\pdfforcepagebox}, \type {\pdflastmatch}, \type
- {\pdfmatch}, \type {\pdfmdfivesum}, \type {\pdfmovechars}, \type
- {\pdfoptionalwaysusepdfpagebox}, \type {\pdfoptionpdfinclusionerrorlevel},
- \type {\pdfresettimer}, \type {\pdfshellescape}, \type {\pdfstrcmp} and \type
- {\pdfunescapehex}
- \par \stop
+ implemented using \LUA: \orm {pdfelapsedtime}, \orm {pdfescapehex}, \orm
+ {pdfescapename}, \orm {pdfescapestring}, \orm {pdffiledump}, \orm
+ {pdffilemoddate}, \orm {pdffilesize}, \orm {pdfforcepagebox}, \orm
+ {pdflastmatch}, \orm {pdfmatch}, \orm {pdfmdfivesum}, \orm {pdfmovechars},
+ \orm {pdfoptionalwaysusepdfpagebox}, \orm {pdfoptionpdfinclusionerrorlevel},
+ \orm {pdfresettimer}, \orm {pdfshellescape}, \orm {pdfstrcmp} and \orm
+ {pdfunescapehex}.
\stopitem
\startitem
- The version related primitives \type {\pdftexbanner}, \type {\pdftexversion}
- and \type {\pdftexrevision} are no longer present as there is no longer a
+ The version related primitives \orm {pdftexbanner}, \orm {pdftexversion}
+ and \orm {pdftexrevision} are no longer present as there is no longer a
relationship with \PDFTEX\ development.
\stopitem
\startitem
The experimental snapper mechanism has been removed and therefore also the
- primitives:
-
- \start \raggedright
- \type {\pdfignoreddimen}, \type {\pdffirstlineheight}, \type
- {\pdfeachlineheight}, \type {\pdfeachlinedepth} and \type
- {\pdflastlinedepth}
- \par \stop
+ primitives \orm {pdfignoreddimen}, \orm {pdffirstlineheight}, \orm
+ {pdfeachlineheight}, \orm {pdfeachlinedepth} and \orm {pdflastlinedepth}.
\stopitem
\startitem
- The experimental primitives \type {\primitive}, \type {\ifprimitive}, \type
- {\ifabsnum} and \type {\ifabsdim} are promoted to core primitives. The \type
+ The experimental primitives \lpr {primitive}, \lpr {ifprimitive}, \lpr
+ {ifabsnum} and \lpr {ifabsdim} are promoted to core primitives. The \type
{\pdf*} prefixed originals are not available.
\stopitem
\startitem
- The \PNG\ transparency fix from 1.40.6 is not applied as high|-|level support
- is pending. Because \LUATEX\ has a different subsystem for managing images,
- more diversion from its ancestor happened in the meantime.
+ Because \LUATEX\ has a different subsystem for managing images, more
+ diversion from its ancestor happened in the meantime. We don't adapt to
+ changes in \PDFTEX.
+\stopitem
+
+\startitem
+ Two extra token lists are provided, \orm {pdfxformresources} and \orm
+ {pdfxformattr}, as an alternative to \orm {pdfxform} keywords.
\stopitem
\startitem
- Two extra token lists are provides, \type {\pdfxformresources} and \type
- {\pdfxformattr}, as an alternative to \type {\pdfxform} keywords.
+ Image specifications also support \type {visiblefilename}, \type
+ {userpassword} and \type {ownerpassword}. The password options are only
+ relevant for encrypted \PDF\ files.
\stopitem
\startitem
@@ -214,27 +220,27 @@ The front- and backend are decoupled as much as possible.
\stopitem
\startitem
- The primitives \type {\pdfpagewidth} and \type {\pdfpageheight} have been removed
- because \type {\pagewidth} and \type {\pageheight} have that purpose.
+ The primitives \orm {pdfpagewidth} and \orm {pdfpageheight} have been removed
+ because \lpr {pagewidth} and \lpr {pageheight} have that purpose.
\stopitem
\startitem
- The primitives \type {\pdfnormaldeviate}, \type {\pdfuniformdeviate}, \type
- {\pdfsetrandomseed} and \type {\pdfrandomseed} have been promoted to core
+ The primitives \orm {pdfnormaldeviate}, \orm {pdfuniformdeviate}, \orm
+ {pdfsetrandomseed} and \orm {pdfrandomseed} have been promoted to core
primitives without \type {pdf} prefix so the original commands are no longer
recognized.
\stopitem
\startitem
- The primitives \type {\ifincsname}, \type {\expanded} and \type {\quitvmode}
+ The primitives \lpr {ifincsname}, \lpr {expanded} and \lpr {quitvmode}
are now core primitives.
\stopitem
\startitem
As the hz and protrusion mechanism are part of the core the related
- primitives \type {\lpcode}, \type {\rpcode}, \type {\efcode}, \type
- {\leftmarginkern}, \type {\rightmarginkern} are promoted to core primitives. The
- two commands \type {\protrudechars} and \type {\adjustspacing} replace their
+ primitives \lpr {lpcode}, \lpr {rpcode}, \lpr {efcode}, \lpr
+ {leftmarginkern}, \lpr {rightmarginkern} are promoted to core primitives. The
+ two commands \lpr {protrudechars} and \lpr {adjustspacing} replace their
prefixed with \type {\pdf} originals.
\stopitem
@@ -245,36 +251,36 @@ The front- and backend are decoupled as much as possible.
\stopitem
\startitem
- When \type {\adjustspacing} has value~2, hz optimization will be applied to
+ When \lpr {adjustspacing} has value~2, hz optimization will be applied to
glyphs and kerns. When the value is~3, only glyphs will be treated. A value
smaller than~2 disables this feature.
\stopitem
\startitem
- The \type {\tagcode} primitive is promoted to core primitive.
+ The \lpr {tagcode} primitive is promoted to core primitive.
\stopitem
\startitem
- The \type {\letterspacefont} feature is now part of the core but will not be
+ The \lpr {letterspacefont} feature is now part of the core but will not be
changed (improved). We just provide it for legacy use.
\stopitem
\startitem
- The \type {\pdfnoligatures} primitive is now \type {\ignoreligaturesinfont}.
+ The \orm {pdfnoligatures} primitive is now \lpr {ignoreligaturesinfont}.
\stopitem
\startitem
- The \type {\pdfcopyfont} primitive is now \type {\copyfont}.
+ The \orm {pdfcopyfont} primitive is now \lpr {copyfont}.
\stopitem
\startitem
- The \type {\pdffontexpand} primitive is now \type {\expandglyphsinfont}.
+ The \orm {pdffontexpand} primitive is now \lpr {expandglyphsinfont}.
\stopitem
\startitem
- Because position tracking is also available in \DVI\ mode the \type
- {\savepos}, \type {\lastxpos} and \type {\lastypos} commands now replace
- their \type {pdf} prefixed originals.
+ Because position tracking is also available in \DVI\ mode the \lpr {savepos},
+ \lpr {lastxpos} and \lpr {lastypos} commands now replace their \type {pdf}
+ prefixed originals.
\stopitem
\startitem
@@ -284,27 +290,31 @@ The front- and backend are decoupled as much as possible.
\stopitem
\startitem
- The initializers \type {\pdfoutput} has been replaced by \type {\outputmode} and
- \type {\pdfdraftmode} is now \type {\draftmode}.
+ The initializers \orm {pdfoutput} has been replaced by \lpr {outputmode} and
+ \orm {pdfdraftmode} is now \lpr {draftmode}.
\stopitem
\startitem
- The pixel multiplier dimension \type {\pdfpxdimen} lots its prefix and is now calles
- \type {\pxdimen}.
+ The pixel multiplier dimension \orm {pdfpxdimen} lost its prefix and is now
+ called \lpr {pxdimen}.
\stopitem
\startitem
- An extra \type {\pdfimageaddfilename} option has been added that can be used to block
- writing the filename to the \PDF\ file.
+ An extra \orm {pdfimageaddfilename} option has been added that can be used to
+ block writing the filename to the \PDF\ file.
\stopitem
\startitem
- The primitive \type {\pdftracingfonts} is now \type {\tracingfonts} as it
+ The primitive \orm {pdftracingfonts} is now \lpr {tracingfonts} as it
doesn't relate to the backend.
\stopitem
\startitem
- The experimental primitive \type {\pdfinsertht} is kept as \type {\insertht}.
+ The experimental primitive \orm {pdfinsertht} is kept as \lpr {insertht}.
+\stopitem
+
+\startitem
+ There is some more control over what metadata goes into the \PDF\ file.
\stopitem
\startitem
@@ -318,25 +328,28 @@ The front- and backend are decoupled as much as possible.
One change involves the so called xforms and ximages. In \PDFTEX\ these are
implemented as so called whatsits. But contrary to other whatsits they have
dimensions that need to be taken into account when for instance calculating
-optimal line breaks. In \LUATEX\ these are now promoted to normal nodes, which
-simplifies code that needs those dimensions.
+optimal line breaks. In \LUATEX\ these are now promoted to a special type of rule
+nodes, which simplifies code that needs those dimensions.
Another reason for promotion is that these are useful concepts. Backends can
-provide the ability to use content that has been rendered in several places,
-and images are also common. For that reason we also changed the names:
+provide the ability to use content that has been rendered in several places, and
+images are also common. As already mentioned in \in {section}
+[sec:imagedandforms], we now have:
\starttabulate[|l|l|]
-\BC new name \BC old name \NC \NR
-\NC \type {\saveboxresource} \NC \type {\pdfxform} \NC \NR
-\NC \type {\saveimageresource} \NC \type {\pdfximage} \NC \NR
-\NC \type {\useboxresource} \NC \type {\pdfrefxform} \NC \NR
-\NC \type {\useimageresource} \NC \type {\pdfrefximage} \NC \NR
-\NC \type {\lastsavedboxresourceindex} \NC \type {\pdflastxform} \NC \NR
-\NC \type {\lastsavedimageresourceindex} \NC \type {\pdflastximage} \NC \NR
-\NC \type {\lastsavedimageresourcepages} \NC \type {\pdflastximagepages} \NC \NR
+\DB \LUATEX \BC \PDFTEX \NC \NR
+\TB
+\NC \lpr {saveboxresource} \NC \orm {pdfxform} \NC \NR
+\NC \lpr {saveimageresource} \NC \orm {pdfximage} \NC \NR
+\NC \lpr {useboxresource} \NC \orm {pdfrefxform} \NC \NR
+\NC \lpr {useimageresource} \NC \orm {pdfrefximage} \NC \NR
+\NC \lpr {lastsavedboxresourceindex} \NC \orm {pdflastxform} \NC \NR
+\NC \lpr {lastsavedimageresourceindex} \NC \orm {pdflastximage} \NC \NR
+\NC \lpr {lastsavedimageresourcepages} \NC \orm {pdflastximagepages} \NC \NR
+\LL
\stoptabulate
-There are a few \type {\pdffeedback} features that relate to this but these are
+There are a few \lpr {pdffeedback} features that relate to this but these are
typical backend specific ones. The index that gets returned is to be considered
as \quote {just a number} and although it still has the same meaning (object
related) as before, you should not depend on that.
@@ -344,7 +357,7 @@ related) as before, you should not depend on that.
The protrusion detection mechanism is enhanced a bit to enable a bit more complex
situations. When protrusion characters are identified some nodes are skipped:
-\startitemize[packed]
+\startitemize[packed,columns,two]
\startitem zero glue \stopitem
\startitem penalties \stopitem
\startitem empty discretionaries \stopitem
@@ -374,6 +387,8 @@ instance content moved into the margin:
\startsubsection[title=Changes from \ALEPH\ RC4]
+\topicindex {\ALEPH}
+
Because we wanted proper directional typesetting the \ALEPH\ mechanisms looked
most attractive. These are rather close to the ones provided by \OMEGA, so what
we say next applies to both these programs.
@@ -381,46 +396,40 @@ we say next applies to both these programs.
\startitemize
\startitem
- The extended 16-bit math primitives (\type {\omathcode} etc.) have been
+ The extended 16-bit math primitives (\orm {omathcode} etc.) have been
removed.
\stopitem
\startitem
The \OCP\ processing has been removed completely and as a consequence, the
- following primitives have been removed:
-
- \start \raggedright
- \type {\ocp}, \type {\externalocp}, \type {\ocplist}, \type {\pushocplist},
- \type {\popocplist}, \type {\clearocplists}, \type {\addbeforeocplist}, \type
- {\addafterocplist}, \type {\removebeforeocplist}, \type {\removeafterocplist}
- and \type {\ocptracelevel}
- \par \stop
+ following primitives have been removed: \orm {ocp}, \orm {externalocp}, \orm
+ {ocplist}, \orm {pushocplist}, \orm {popocplist}, \orm {clearocplists}, \orm
+ {addbeforeocplist}, \orm {addafterocplist}, \orm {removebeforeocplist}, \orm
+ {removeafterocplist} and \orm {ocptracelevel}.
\stopitem
\startitem
\LUATEX\ only understands 4~of the 16~direction specifiers of \ALEPH: \type
- {TLT} (latin), \type {TRT} (arabic), \type {RTT} (cjk), \type {LTL}
- (mongolian). All other direction specifiers generate an error.
+ {TLT} (latin), \type {TRT} (arabic), \type {RTT} (cjk), \type {LTL} (mongolian).
+ All other direction specifiers generate an error. In addition to a keyword
+ driven model we also provide an integer driven one.
\stopitem
\startitem
The input translations from \ALEPH\ are not implemented, the related
- primitives are not available:
-
- \start \raggedright
- \type {\DefaultInputMode}, \type {\noDefaultInputMode}, \type {\noInputMode},
- \type {\InputMode}, \type {\DefaultOutputMode}, \type {\noDefaultOutputMode},
- \type {\noOutputMode}, \type {\OutputMode}, \type {\DefaultInputTranslation},
- \type {\noDefaultInputTranslation}, \type {\noInputTranslation}, \type
- {\InputTranslation}, \type {\DefaultOutputTranslation}, \type
- {\noDefaultOutputTranslation}, \type {\noOutputTranslation} and \type
- {\OutputTranslation}
- \par \stop
+ primitives are not available: \orm {DefaultInputMode}, \orm
+ {noDefaultInputMode}, \orm {noInputMode}, \orm {InputMode}, \orm
+ {DefaultOutputMode}, \orm {noDefaultOutputMode}, \orm {noOutputMode}, \orm
+ {OutputMode}, \orm {DefaultInputTranslation}, \orm
+ {noDefaultInputTranslation}, \orm {noInputTranslation}, \orm
+ {InputTranslation}, \orm {DefaultOutputTranslation}, \orm
+ {noDefaultOutputTranslation}, \orm {noOutputTranslation} and \orm
+ {OutputTranslation}.
\stopitem
\startitem
- Several bugs have been fixed an confusing implementation details have been sorted
- out.
+ Several bugs have been fixed and confusing implementation details have been
+ sorted out.
\stopitem
\startitem
@@ -429,13 +438,13 @@ we say next applies to both these programs.
\stopitem
\startitem
- The \type {^^} notation has been extended: after \type {^^^^} four hexadecimal
- characters are expected and after \type {^^^^^^} six hexadecimal characters
- have to be given. The original \TEX\ interpretation is still valid for the
- \type {^^} case but the four and six variants do no backtracking, i.e.\ when
- they are not followed by the right number of hexadecimal digits they issue an
- error message. Because \type{^^^} is a normal \TEX\ case, we don't support the
- odd number of \type {^^^^^} either.
+ The \type {^^} notation has been extended: after \type {^^^^} four
+ hexadecimal characters are expected and after \type {^^^^^^} six hexadecimal
+ characters have to be given. The original \TEX\ interpretation is still valid
+ for the \type {^^} case but the four and six variants do no backtracking,
+ i.e.\ when they are not followed by the right number of hexadecimal digits
+ they issue an error message. Because \type{^^^} is a normal \TEX\ case, we
+ don't support the odd number of \type {^^^^^} either.
\stopitem
\startitem
@@ -449,9 +458,9 @@ we say next applies to both these programs.
\stopitem
\startitem
- The page dimension related primitives \type {\pagewidth} and \type
- {\pageheight} have been promoted to core primitives. The \type {\hoffset} and
- \type {\voffset} primitives have been fixed.
+ The page dimension related primitives \lpr {pagewidth} and \lpr {pageheight}
+ have been promoted to core primitives. The \prm {hoffset} and \prm {voffset}
+ primitives have been fixed.
\stopitem
\startitem
@@ -461,30 +470,35 @@ we say next applies to both these programs.
\stopitem
\startitem
- The two dimension registers \type {\pagerightoffset} and \type
- {\pagebottomoffset} are now core primitives.
+ The two dimension registers \lpr {pagerightoffset} and \lpr
+ {pagebottomoffset} are now core primitives.
\stopitem
\startitem
- The direction related primitives \type {\pagedir}, \type {\bodydir}, \type
- {\pardir}, \type {\textdir}, \type {\mathdir} and \type {\boxdir} are now
- core primitives.
+ The direction related primitives \lpr {pagedir}, \lpr {bodydir}, \lpr
+ {pardir}, \lpr {textdir}, \lpr {mathdir} and \lpr {boxdir} are now core
+ primitives.
\stopitem
\startitem
- The promotion of primitives to core primitives as well as the removed of all
- others means that the initialization namespace \type {aleph} is gone.
+ The promotion of primitives to core primitives as well as removing of all
+ others means that the initialization namespace \type {aleph} that early
+ versions of \LUATEX\ provided is gone.
\stopitem
\stopitemize
The above let's itself summarize as: we took the 32 bit aspects and much of the
-directional mechanisms.
+directional mechanisms and merged it into the \PDFTEX\ code base as starting
+point for further development. Then we simplified directionality, fixed it and
+opened it up.
\stopsubsection
\startsubsection[title=Changes from standard \WEBC]
+\topicindex {\WEBC}
+
The compilation framework is \WEBC\ and we keep using that but without the
\PASCAL\ to \CCODE\ step. This framework also provides some common features that
deal with reading bytes from files and locating files in \TDS. This is what we do
@@ -507,7 +521,7 @@ different:
\stopitem
\startitem
- The \type {\openout} whatsits are not written to the log file.
+ The \prm {openout} whatsits are not written to the log file.
\stopitem
\startitem
@@ -515,7 +529,8 @@ different:
mode because \type {texmf.cnf} is not read: \type {shell-escape} is off (but
that is not a problem because of \LUA's \type {os.execute}), and the paranoia
checks on \type {openin} and \type {openout} do not happen. However, it is
- easy for a \LUA\ script to do this itself by overloading \type {io.open}.
+ easy for a \LUA\ script to do this itself by overloading \type {io.open} and
+ alike.
\stopitem
\startitem
@@ -528,17 +543,22 @@ different:
\stopsection
-\startsection[reference=backendprimitives,title=The backend primitives \type {\pdf*}]
+\startsection[reference=backendprimitives,title=The backend primitives]
+
+\startsubsection[title={Less primitives}]
+
+\topicindex {backend}
+\topicindex {\PDF+backend}
In a previous section we mentioned that some \PDFTEX\ primitives were removed and
others promoted to core \LUATEX\ primitives. That is only part of the story. In
order to separate the backend specific primitives in de code these commands are
now replaced by only a few. In traditional \TEX\ we only had the \DVI\ backend
but now we have two: \DVI\ and \PDF. Additional functionality is implemented as
-\quote {extensions} in \TEX speak. By separating more strickly we are able to
-keep the core (fontend) clean and stable. If for some reason an extra backend
-option is needed, it can be implemented without touching the core. The three
-\PDF\ backend related primitives are
+\quote {extensions} in \TEX\ speak. By separating more strickly we are able to
+keep the core (frontend) clean and stable and isolate these extensions. If for
+some reason an extra backend option is needed, it can be implemented without
+touching the core. The three \PDF\ backend related primitives are:
\starttyping
\pdfextension command [specification]
@@ -550,8 +570,12 @@ An extension triggers further parsing, depending on the command given. A variabl
a (kind of) register and can be read and written, while a feedback is reporting
something (as it comes from the backend it's normally a sequence of tokens).
+\stopsubsection
+
+\startsubsection[title={\lpr{pdfextension}, \lpr {pdfvariable} and \lpr {pdffeedback}},reference=sec:pdfextensions]
+
In order for \LUATEX\ to be more than just \TEX\ you need to enable primitives. That
-has already be the case right from the start. If you want the traditional \PDFTEX\
+has already been the case right from the start. If you want the traditional \PDFTEX\
primitives (for as far their functionality is still around) you now can do this:
\starttyping
@@ -604,6 +628,7 @@ The configuration related registers have become:
\starttyping
\edef\pdfcompresslevel {\pdfvariable compresslevel}
\edef\pdfobjcompresslevel {\pdfvariable objcompresslevel}
+\edef\pdfrecompress {\pdfvariable recompress}
\edef\pdfdecimaldigits {\pdfvariable decimaldigits}
\edef\pdfgamma {\pdfvariable gamma}
\edef\pdfimageresolution {\pdfvariable imageresolution}
@@ -618,6 +643,7 @@ The configuration related registers have become:
\edef\pdfignoreunknownimages {\pdfvariable ignoreunknownimages}
\edef\pdfgentounicode {\pdfvariable gentounicode}
\edef\pdfomitcidset {\pdfvariable omitcidset}
+\edef\pdfomitcharset {\pdfvariable omitcharset}
\edef\pdfpagebox {\pdfvariable pagebox}
\edef\pdfminorversion {\pdfvariable minorversion}
\edef\pdfuniqueresname {\pdfvariable uniqueresname}
@@ -657,100 +683,16 @@ macro:->[internal backend integer]
macro:->[internal backend tokenlist]
\stoptyping
-The \type {\edef} can also be an \type {\def} but it's a bit more efficient
-to expand the lookup related register beforehand. After that you can adapt
-the defaults; these are:
-
-\starttyping
-\pdfcompresslevel 9
-\pdfobjcompresslevel 1 % used: (0,9)
-\pdfdecimaldigits 4 % used: (3,6)
-\pdfgamma 1000
-\pdfimageresolution 71
-\pdfimageapplygamma 0
-\pdfimagegamma 2200
-\pdfimagehicolor 1
-\pdfimageaddfilename 1
-\pdfpkresolution 72
-\pdfpkfixeddpi 0
-\pdfinclusioncopyfonts 0
-\pdfinclusionerrorlevel 0
-\pdfignoreunknownimages 0
-\pdfgentounicode 0
-\pdfomitcidset 0
-\pdfpagebox 0
-\pdfminorversion 4
-\pdfuniqueresname 0
-
-\pdfhorigin 1in
-\pdfvorigin 1in
-\pdflinkmargin 0pt
-\pdfdestmargin 0pt
-\pdfthreadmargin 0pt
-\pdfxformmargin 0pt
-\stoptyping
-
-If you also want some backward compatibility, you can add:
-
-\starttyping
-\let\pdfpagewidth \pagewidth
-\let\pdfpageheight \pageheight
-
-\let\pdfadjustspacing \adjustspacing
-\let\pdfprotrudechars \protrudechars
-\let\pdfnoligatures \ignoreligaturesinfont
-\let\pdffontexpand \expandglyphsinfont
-\let\pdfcopyfont \copyfont
-
-\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
-
-\let\pdfoutput \outputmode
-\let\pdfdraftmode \draftmode
-
-\let\pdfpxdimen \pxdimen
-
-\let\pdfinsertht \insertht
-
-\let\pdfnormaldeviate \normaldeviate
-\let\pdfuniformdeviate \uniformdeviate
-\let\pdfsetrandomseed \setrandomseed
-\let\pdfrandomseed \randomseed
-
-\let\pdfprimitive \primitive
-\let\ifpdfprimitive \ifprimitive
-
-\let\ifpdfabsnum \ifabsnum
-\let\ifpdfabsdim \ifabsdim
-\stoptyping
-
-And even:
-
-\starttyping
-\newdimen\pdfeachlineheight
-\newdimen\pdfeachlinedepth
-\newdimen\pdflastlinedepth
-\newdimen\pdffirstlineheight
-\newdimen\pdfignoreddimen
-\stoptyping
+The \prm {edef} can also be a \prm {def} but it's a bit more efficient to expand
+the lookup related register beforehand.
The backend is derived from \PDFTEX\ so the same syntax applies. However, the
\type {outline} command accepts a \type {objnum} followed by a number. No
checking takes place so when this is used it had better be a valid (flushed)
object.
-In order to be (more or less) compatible with \PDFTEX\ we also support the
-option to suppress some info:
+In order to be (more or less) compatible with \PDFTEX\ we also support the option
+to suppress some info but we do so via a bitset:
\starttyping
\pdfvariable suppressoptionalinfo \numexpr
@@ -770,7 +712,7 @@ option to suppress some info:
In addition you can overload the trailer id, but we don't do any checking on
validity, so you have to pass a valid array. The following is like the ones
-normally generated by the engine:
+normally generated by the engine. You even need to include the brackets here!
\starttyping
\pdfvariable trailerid {[
@@ -779,8 +721,6 @@ normally generated by the engine:
]}
\stoptyping
-So, you even need to include the brackets!
-
Although we started from a merge of \PDFTEX\ and \ALEPH, by now the code base as
well as functionality has diverted from those parents. Here we show the options
that can be passed to the extensions.
@@ -928,10 +868,113 @@ that can be passed to the extensions.
{tokens}
\stoptexsyntax
+\stopsubsection
+
+\startsubsection[title={Defaults}]
+
+The engine sets the following defaults.
+
+\starttyping
+\pdfcompresslevel 9
+\pdfobjcompresslevel 1 % used: (0,9)
+\pdfrecompress 0 % mostly for debugging
+\pdfdecimaldigits 4 % used: (3,6)
+\pdfgamma 1000
+\pdfimageresolution 71
+\pdfimageapplygamma 0
+\pdfimagegamma 2200
+\pdfimagehicolor 1
+\pdfimageaddfilename 1
+\pdfpkresolution 72
+\pdfpkfixeddpi 0
+\pdfinclusioncopyfonts 0
+\pdfinclusionerrorlevel 0
+\pdfignoreunknownimages 0
+\pdfgentounicode 0
+\pdfomitcidset 0
+\pdfomitcharset 0
+\pdfpagebox 0
+\pdfminorversion 4
+\pdfuniqueresname 0
+
+\pdfhorigin 1in
+\pdfvorigin 1in
+\pdflinkmargin 0pt
+\pdfdestmargin 0pt
+\pdfthreadmargin 0pt
+\pdfxformmargin 0pt
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title={Backward compatibility}]
+
+If you also want some backward compatibility, you can add:
+
+\starttyping
+\let\pdfpagewidth \pagewidth
+\let\pdfpageheight \pageheight
+
+\let\pdfadjustspacing \adjustspacing
+\let\pdfprotrudechars \protrudechars
+\let\pdfnoligatures \ignoreligaturesinfont
+\let\pdffontexpand \expandglyphsinfont
+\let\pdfcopyfont \copyfont
+
+\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
+
+\let\pdfoutput \outputmode
+\let\pdfdraftmode \draftmode
+
+\let\pdfpxdimen \pxdimen
+
+\let\pdfinsertht \insertht
+
+\let\pdfnormaldeviate \normaldeviate
+\let\pdfuniformdeviate \uniformdeviate
+\let\pdfsetrandomseed \setrandomseed
+\let\pdfrandomseed \randomseed
+
+\let\pdfprimitive \primitive
+\let\ifpdfprimitive \ifprimitive
+
+\let\ifpdfabsnum \ifabsnum
+\let\ifpdfabsdim \ifabsdim
+\stoptyping
+
+And even:
+
+\starttyping
+\newdimen\pdfeachlineheight
+\newdimen\pdfeachlinedepth
+\newdimen\pdflastlinedepth
+\newdimen\pdffirstlineheight
+\newdimen\pdfignoreddimen
+\stoptyping
+
+\stopsubsection
+
\stopsection
\startsection[title=Directions]
+\topicindex {\OMEGA}
+\topicindex {\ALEPH}
+\topicindex {directions}
+
+\startsubsection[title={Four directions}]
+
The directional model in \LUATEX\ is inherited from \OMEGA|/|\ALEPH\ but we tried
to improve it a bit. At some point we played with recovery of modes but that was
disabled later on when we found that it interfered with nested directions. That
@@ -939,14 +982,23 @@ itself had as side effect that the node list was no longer balanced with respect
to directional nodes which in turn can give side effects when a series of dir
changes happens without grouping.
-The current (0.97 onward) approach is that we again make the list balanced but
-try to avoid some side effects. What happens is quite intuitive if we forget
-about spaces (turned into glue) but even there what happens makes sense if you
-look at it in detail. However that logic makes in|-|group switching kind of
-useless when no proper nested grouping is used: switching from right to left
-several times nested, results in spacing ending up after each other due to nested
-mirroring. Of course a sane macro package will manage this for the user but here
-we are discussing the low level dir injection.
+When extending the \PDF\ backend to support directions some inconsistencies were
+found and as a result we decided to support only the four models that make sense
+\type {TLT} (latin), \type {TRT} (arabic), \type {RTT} (cjk) and \type {LTL}
+(mongolian).
+
+\stopsubsection
+
+\startsubsection[title={How it works}]
+
+The approach is that we again make the list balanced but try to avoid some side
+effects. What happens is quite intuitive if we forget about spaces (turned into
+glue) but even there what happens makes sense if you look at it in detail.
+However that logic makes in|-|group switching kind of useless when no proper
+nested grouping is used: switching from right to left several times nested,
+results in spacing ending up after each other due to nested mirroring. Of course
+a sane macro package will manage this for the user but here we are discussing the
+low level dir injection.
This is what happens:
@@ -1031,7 +1083,7 @@ It gets typeset as:
We could define the two helpers to look back, pick up a skip, remove it and
inject it after the dir node. But that way we loose the subtype information that
for some applications can be handy to be kept as|-|is. This is why we now have a
-variant of \type {\textdir} which injects the balanced node before the skip.
+variant of \lpr {textdir} which injects the balanced node before the skip.
Instead of the previous definition we can use:
\startbuffer[def]
@@ -1060,64 +1112,64 @@ comes out as a properly spaced:
Anything more complex that this, like combination of skips and penalties, or
kerns, should be handled in the input or macro package because there is no way we
-can predict the expected behaviour. In fact, the \type {\linedir} is just a
+can predict the expected behaviour. In fact, the \lpr {linedir} is just a
convenience extra which could also have been implemented using node list parsing.
+\stopsubsection
+
+\startsubsection[title={Controlling glue with \lpr {breakafterdirmode}}]
+
Glue after a dir node is ignored in the linebreak decision but you can bypass that
-by setting \type {\breakafterdirmode} to~\type {1}. The following table shows the
+by setting \lpr {breakafterdirmode} to~\type {1}. The following table shows the
difference. Watch your spaces.
\def\ShowSome#1{%
- \BC
- \type{#1}
- \NC
- \breakafterdirmode = 0
- \hsize 0pt
- #1
+ \BC \type{#1}
+ \NC \breakafterdirmode\zerocount\hsize\zeropoint#1
\NC
+ \NC \breakafterdirmode\plusone\hsize\zeropoint#1
\NC
- \breakafterdirmode = 1
- \hsize 0pt
- #1
- \NC
- \NC \NR \HL
+ \NC \NR
}
-\starttabulate[|l|Tp(0pt)|w(5em)|Tp(0pt)|p|]
- \HL
- \BC \type{\breakafterdirmode}
+\starttabulate[|l|Tp(1pt)|w(5em)|Tp(1pt)|w(5em)|]
+ \DB
\BC \type{0}
\NC
\BC \type{1}
\NC
\NC \NR
- \HL
+ \TB
\ShowSome{pre {\textdir TLT xxx} post}
\ShowSome{pre {\textdir TLT xxx }post}
\ShowSome{pre{ \textdir TLT xxx} post}
\ShowSome{pre{ \textdir TLT xxx }post}
\ShowSome{pre { \textdir TLT xxx } post}
\ShowSome{pre {\textdir TLT\relax\space xxx} post}
+ \LL
\stoptabulate
+\stopsubsection
+
+\startsubsection[title={Controling parshapes with \lpr {shapemode}}]
Another adaptation to the \ALEPH\ directional model is control over shapes driven
-by \type {\hangindent} and \type {\parshape}. This is controlled by a new parameter
-\type {\shapemode}:
+by \prm {hangindent} and \prm {parshape}. This is controlled by a new parameter
+\lpr {shapemode}:
-\starttabulate[|c|c|c|]
-\BC \BC \type {\hangindent} \BC \type {\parshape} \NC \NR
+\starttabulate[|c|l|l|]
+\DB value \BC \prm {hangindent} \BC \prm {parshape} \NC \NR
+\TB
\BC \type{0} \NC normal \NC normal \NC \NR
\BC \type{1} \NC mirrored \NC normal \NC \NR
\BC \type{2} \NC normal \NC mirrored \NC \NR
\BC \type{3} \NC mirrored \NC mirrored \NC \NR
+\LL
\stoptabulate
-The value is reset to zero (like \type {\hangindent} and \type {\parshape})
+The value is reset to zero (like \prm {hangindent} and \prm {parshape})
after the paragraph is done with. You can use negative values to prevent
-this.
-
-In \in {figure} [fig:shapemode] a few examples are given.
+this. In \in {figure} [fig:shapemode] a few examples are given.
\startplacefigure[reference=fig:shapemode,title={The effect of \type {shapemode}.}]
\startcombination[2*3]
@@ -1162,12 +1214,46 @@ In \in {figure} [fig:shapemode] a few examples are given.
\stopcombination
\stopplacefigure
+\stopsubsection
+
+\startsubsection[title={Symbols or numbers}]
+
+Internally the implementation is different from \ALEPH. First of all we use no
+whatsits but dedicated nodes, but also we have only 4 directions that are mapped
+onto 4 numbers. A text direction node can mark the start or end of a sequence of
+nodes, and therefore has two states. At the \TEX\ end we don't see these states
+because \TEX\ itself will add proper end state nodes if needed.
+
+The symbolic names \type {TLT}, \type {TRT}, etc.\ originate in \OMEGA. In
+\LUATEX\ we also have a number based model which sometimes makes more sense.
+
+\starttabulate[|c|l|l|]
+\DB value \BC equivalent \NC \NR
+\TB
+\BC \type {0} \NC TLT \NC \NR
+\BC \type {1} \NC TRT \NC \NR
+\BC \type {2} \NC LTL \NC \NR
+\BC \type {3} \NC RTT \NC \NR
+\LL
+\stoptabulate
+
+We support the \OMEGA\ primitives \orm {textdir}, \orm {pardir}, \orm {pagedir},
+\orm {pardir} and \orm {mathdir}. These accept three character keywords. The
+primitives that set the direction by number are: \lpr {textdirection}, \lpr
+{pardirection}, \lpr {pagedirection} and \lpr {bodydirection} and \lpr
+{mathdirection}. When specifying a direction for a box you can use \type {bdir}
+instead of \type {dir}.
+
+\stopsubsection
+
\stopsection
\startsection[title=Implementation notes]
\startsubsection[title=Memory allocation]
+\topicindex {memory}
+
The single internal memory heap that traditional \TEX\ used for tokens and nodes
is split into two separate arrays. Each of these will grow dynamically when
needed.
@@ -1189,14 +1275,9 @@ structures, some of the macros have been duplicated. For instance, there are now
{token_info}. All access to the variable memory array is now hidden behind a
macro called \type {vmem}. We mention this because using the \TEX book as
reference is still quite valid but not for memory related details. Another
-significate detail is that we have double linked node lists and that some nodes
+significant detail is that we have double linked node lists and that most nodes
carry more data.
-The implementation of the growth of two arrays (via reallocation) introduces a
-potential pitfall: the memory arrays should never be used as the left hand side
-of a statement that can modify the array in question. Details like this are
-of no concern to users.
-
The input line buffer and pool size are now also reallocated when needed, and the
\type {texmf.cnf} settings \type {buf_size} and \type {pool_size} are silently
ignored.
@@ -1205,25 +1286,31 @@ ignored.
\startsubsection[title=Sparse arrays]
-The \type {\mathcode}, \type {\delcode}, \type {\catcode}, \type {\sfcode}, \type
-{\lccode} and \type {\uccode} (and the new \type {\hjcode}) tables are now sparse
-arrays that are implemented in~\CCODE. They are no longer part of the \TEX\
-\quote {equivalence table} and because each had 1.1 million entries with a few
-memory words each, this makes a major difference in memory usage.
+The \prm {mathcode}, \prm {delcode}, \prm {catcode}, \prm {sfcode}, \prm {lccode}
+and \prm {uccode} (and the new \lpr {hjcode}) tables are now sparse arrays that
+are implemented in~\CCODE. They are no longer part of the \TEX\ \quote
+{equivalence table} and because each had 1.1 million entries with a few memory
+words each, this makes a major difference in memory usage. Performance is not
+really hurt by this.
-The \type {\catcode}, \type {\sfcode}, \type {\lccode}, \type {\uccode} and \type
-{\hjcode} assignments do not yet show up when using the \ETEX\ tracing routines
-\type {\tracingassigns} and \type {\tracingrestores}.
+The \prm {catcode}, \prm {sfcode}, \prm {lccode}, \prm {uccode} and \lpr {hjcode}
+assignments don't show up when using the \ETEX\ tracing routines \prm
+{tracingassigns} and \prm {tracingrestores} but we don't see that as a real
+limitation.
-A side|-|effect of the current implementation is that \type {\global} is now more
-expensive in terms of processing than non|-|global assignments.
+A side|-|effect of the current implementation is that \prm {global} is now more
+expensive in terms of processing than non|-|global assignments but not many users
+will notice that.
The glyph ids within a font are also managed by means of a sparse array as glyph
-ids can go up to index $2^{21}-1$.
+ids can go up to index $2^{21}-1$ but these are never accessed directly so again
+users will not notice this.
\stopsubsection
-\startsubsection[title=Simple single-character csnames]
+\startsubsection[title=Simple single|-|character csnames]
+
+\topicindex {csnames}
Single|-|character commands are no longer treated specially in the internals,
they are stored in the hash just like the multiletter csnames.
@@ -1236,16 +1323,22 @@ control sequences that uses a prefix that is otherwise impossible to obtain.
\stopsubsection
-\startsubsection[title=Compressed format]
+\startsubsection[title=The compressed format file]
+
+\topicindex {format}
The format is passed through \type {zlib}, allowing it to shrink to roughly half
of the size it would have had in uncompressed form. This takes a bit more \CPU\
-cycles but much less disk \IO, so it should still be faster.
+cycles but much less disk \IO, so it should still be faster. We use a level~3
+compression which we found to be the optimal trade|-|off between filesize and
+decompression speed.
\stopsubsection
\startsubsection[title=Binary file reading]
+\topicindex {files+binary}
+
All of the internal code is changed in such a way that if one of the \type
{read_xxx_file} callbacks is not set, then the file is read by a \CCODE\ function
using basically the same convention as the callback: a single read into a buffer
@@ -1257,6 +1350,9 @@ previous code (that mostly used \type {getc} calls), it can be quite a bit faste
\startsubsection[title=Tabs and spaces]
+\topicindex {space}
+\topicindex {newline}
+
We conform to the way other \TEX\ engines handle trailing tabs and spaces. For
decades trailing tabs and spaces (before a newline) were removed from the input
but this behaviour was changed in September 2017 to only handle spaces. We are
@@ -1273,7 +1369,7 @@ to be kept. We are aware of the fact that this contradicts some of our other
choices but consistency with other engines and the fact that in \KPSE\ mode a
common file \IO\ layer is used can have a side effect of breaking compatibility.
We still stick to our view that at the log level we can (and might be) more
-incompatible.
+incompatible. We already expose some more details.
\stopsubsection
diff --git a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
index 517d9b6c8..34a2aebe8 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-nodes.tex
@@ -1,16 +1,21 @@
% language=uk
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-nodes
\startchapter[reference=nodes,title={Nodes}]
-\section{\LUA\ node representation}
+\startsection[title={\LUA\ node representation}][library=node]
-\TEX's nodes are represented in \LUA\ as userdata object with a variable set of
-fields. In the following syntax tables, such the type of such a userdata object
+\topicindex {nodes}
+
+\libindex {fields}
+\libindex {subtypes}
+\libindex {values}
+
+\TEX's nodes are represented in \LUA\ as userdata objects with a variable set of
+fields. In the following syntax tables, such as the type of such a userdata object
is represented as \syntax {<node>}.
The current return value of \type {node.types()} is:
@@ -24,76 +29,43 @@ The current return value of \type {node.types()} is:
\stopluacode
. % period
-The \type {\lastnodetype} primitive is \ETEX\ compliant. The valid range is still
+The \prm {lastnodetype} primitive is \ETEX\ compliant. The valid range is still
$[-1,15]$ and glyph nodes (formerly known as char nodes) have number~0 while
ligature nodes are mapped to~7. That way macro packages can use the same symbolic
names as in traditional \ETEX. Keep in mind that these \ETEX\ node numbers are
different from the real internal ones and that there are more \ETEX\ node types
than~15.
-You can ask for a list of fields with the \type {node.fields} (which takes an id)
-and for valid subtypes with \type {node.subtypes} (which takes a string because
-eventually we might support more used enumerations).
-
-The \type {node.values} function reports some used values. Valid arguments are
-\type {dir}, \type {direction}, \type {glue}, \type {pdf_literal}, \type
-{pdf_action}, \type {pdf_window} and \type {color_stack}. Keep in mind that the
-setters normally expect a number, but this helper gives you a list of what
-numbers matter. For practical reason the \type {pagestate} values are also
-reported with this helper.
-
-\subsection{Attributes}
-
-The newly introduced attribute registers are non|-|trivial, because the value
-that is attached to a node is essentially a sparse array of key|-|value pairs. It
-is generally easiest to deal with attribute lists and attributes by using the
-dedicated functions in the \type {node} library, but for completeness, here is
-the low|-|level interface.
-
-\subsubsection{attribute_list nodes}
-
-An \type {attribute_list} item is used as a head pointer for a list of attribute
-items. It has only one user-visible field:
-
-\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
-\NC \type{next} \NC node \NC pointer to the first attribute \NC \NR
-\stoptabulate
-
-\subsubsection{attribute nodes}
-
-A normal node's attribute field will point to an item of type \type
-{attribute_list}, and the \type {next} field in that item will point to the first
-defined \quote {attribute} item, whose \type {next} will point to the second
-\quote {attribute} item, etc.
+You can ask for a list of fields with \type {node.fields} and for valid subtypes
+with \type {node.subtypes}. The \type {node.values} function reports some used
+values. Valid arguments are \nod {dir}, \type {direction}, \nod {glue}, \whs
+{pdf_literal}, \whs {pdf_action}, \whs {pdf_window} and \whs {color_stack}. Keep
+in mind that the setters normally expect a number, but this helper gives you a
+list of what numbers matter. For practical reason the \type {pagestate} values
+are also reported with this helper.
-\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
-\NC \type{next} \NC node \NC pointer to the next attribute \NC \NR
-\NC \type{number} \NC number \NC the attribute type id \NC \NR
-\NC \type{value} \NC number \NC the attribute value \NC \NR
-\stoptabulate
+\stopsection
-As mentioned it's better to use the official helpers rather than edit these
-fields directly. For instance the \type {prev} field is used for other purposes
-and there is no double linked list.
+\startsection[title={Main text nodes}]
-\subsection{Main text nodes}
+\topicindex {nodes+text}
These are the nodes that comprise actual typesetting commands. A few fields are
present in all nodes regardless of their type, these are:
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{next} \NC node \NC the next node in a list, or nil \NC \NR
\NC \type{id} \NC number \NC the node's type (\type {id}) number \NC \NR
\NC \type{subtype} \NC number \NC the node \type {subtype} identifier \NC \NR
+\LL
\stoptabulate
-The \type {subtype} is sometimes just a stub entry. Not all nodes actually use
-the \type {subtype}, but this way you can be sure that all nodes accept it as a
-valid field name, and that is often handy in node list traversal. In the
-following tables \type {next} and \type {id} are not explicitly mentioned.
+The \type {subtype} is sometimes just a dummy entry because not all nodes
+actually use the \type {subtype}, but this way you can be sure that all nodes
+accept it as a valid field name, and that is often handy in node list traversal.
+In the following tables \type {next} and \type {id} are not explicitly mentioned.
Besides these three fields, almost all nodes also have an \type {attr} field, and
there is a also a field called \type {prev}. That last field is always present,
@@ -101,25 +73,33 @@ but only initialized on explicit request: when the function \type {node.slide()}
is called, it will set up the \type {prev} fields to be a backwards pointer in
the argument node list. By now most of \TEX's node processing makes sure that the
\type {prev} nodes are valid but there can be exceptions, especially when the
-internal magic uses a leading \type {temp} nodes to temporarily store a state.
+internal magic uses a leading \nod {temp} nodes to temporarily store a state.
-\subsubsection{hlist nodes}
+\subsection{\nod {hlist} nodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{list} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{width} \NC number \NC the width of the box \NC \NR
\NC \type{height} \NC number \NC the height of the box \NC \NR
\NC \type{depth} \NC number \NC the depth of the box \NC \NR
-\NC \type{shift} \NC number \NC a displacement perpendicular to the character progression direction \NC \NR
-\NC \type{glue_order} \NC number \NC a number in the range $[0,4]$, indicating the glue order \NC \NR
+\NC \type{shift} \NC number \NC a displacement perpendicular to the character
+ progression direction \NC \NR
+\NC \type{glue_order} \NC number \NC a number in the range $[0,4]$, indicating the
+ glue order \NC \NR
\NC \type{glue_set} \NC number \NC the calculated glue ratio \NC \NR
-\NC \type{glue_sign} \NC number \NC 0 = \type {normal}, 1 = \type {stretching}, 2 = \type {shrinking} \NC \NR
+\NC \type{glue_sign} \NC number \NC 0 = \type {normal}, 1 = \type {stretching}, 2 =
+ \type {shrinking} \NC \NR
\NC \type{head/list} \NC node \NC the first node of the body of this list \NC \NR
-\NC \type{dir} \NC string \NC the direction of this box, see~\in[dirnodes] \NC \NR
+\NC \type{dir} \NC string \NC the direction of this box, see~\in [dirnodes] \NC \NR
+\LL
\stoptabulate
+\topicindex {nodes+lists}
+\topicindex {lists}
+
A warning: never assign a node list to the \type {head} field unless you are sure
its internal link structure is correct, otherwise an error may result.
@@ -127,39 +107,72 @@ Note: the field name \type {head} and \type {list} are both valid. Sometimes it
makes more sense to refer to a list by \type {head}, sometimes \type {list} makes
more sense.
-\subsubsection{vlist nodes}
+\subsection{\nod {vlist} nodes}
+
+\topicindex {nodes+lists}
+\topicindex {lists}
-This node is similar to \type {hlist}, except that \quote {shift} is a displacement
+This node is similar to \nod {hlist}, except that \quote {shift} is a displacement
perpendicular to the line progression direction, and \quote {subtype} only has
the values 0, 4, and~5.
-\subsubsection{rule nodes}
+\subsection{\nod {rule} nodes}
-Contrary to traditional \TEX, \LUATEX\ has more subtypes because we also use
-rules to store reuseable objects and images. User nodes are invisible and can be
-intercepted by a callback.
+\topicindex {nodes+rules}
+\topicindex {rules}
+
+Contrary to traditional \TEX, \LUATEX\ has more \prm {rule} subtypes because we
+also use rules to store reuseable objects and images. User nodes are invisible
+and can be intercepted by a callback.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
-\NC \type{subtype} \NC number \NC \showsubtypes{rule} \NC \NR
-\NC \type{attr} \NC node \NC list of attributes \NC \NR
-\NC \type{width} \NC number \NC the width of the rule where the special value $-1073741824$ is used for \quote {running} glue dimensions \NC \NR
-\NC \type{height} \NC number \NC the height of the rule (can be negative) \NC \NR
-\NC \type{depth} \NC number \NC the depth of the rule (can be negative) \NC \NR
-\NC \type{dir} \NC string \NC the direction of this rule, see~\in[dirnodes] \NC \NR
-\NC \type{index} \NC number \NC an optional index that can be referred to \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
+\NC \type{subtype} \NC number \NC \showsubtypes {rule} \NC \NR
+\NC \type{attr} \NC node \NC list of attributes \NC \NR
+\NC \type{width} \NC number \NC the width of the rule where the special value
+ $-1073741824$ is used for \quote {running} glue dimensions \NC \NR
+\NC \type{height} \NC number \NC the height of the rule (can be negative) \NC \NR
+\NC \type{depth} \NC number \NC the depth of the rule (can be negative) \NC \NR
+\NC \type{left} \NC number \NC shift at the left end (also subtracted from width) \NC \NR
+\NC \type{right} \NC number \NC (subtracted from width) \NC \NR
+\NC \type{dir} \NC string \NC the direction of this rule, see~\in[dirnodes] \NC \NR
+\NC \type{index} \NC number \NC an optional index that can be referred to \NC \NR
+\NC \type{transform} \NC number \NC an private variable (also used to specify outline width) \NC \NR
+\LL
\stoptabulate
-\subsubsection{ins nodes}
+The \type {left} and type {right} keys are somewhat special (and experimental).
+When rules are auto adapting to the surrounding box width you can enforce a shift
+to the right by setting \type {left}. The value is also subtracted from the width
+which can be a value set by the engine itself and is not entirely under user
+control. The \type {right} is also subtracted from the width. It all happens in
+the backend so these are not affecting the calculations in the frontend (actually
+the auto settings also happen in the backend). For a vertical rule \type {left}
+affects the height and \type {right} affects the depth. There is no matching
+interface at the \TEX\ end (although we can have more keywords for rules it would
+complicate matters and introduce a speed penalty.) However, you can just
+construct a rule node with \LUA\ and write it to the \TEX\ input. The \type
+{outline} subtype is just a convenient variant and the \type {transform} field
+specifies the width of the outline.
+
+\subsection{\nod {ins} nodes}
+
+\topicindex {nodes+insertions}
+\topicindex {insertions}
+
+This node relates to the \prm {insert} primitive.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC the insertion class \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{cost} \NC number \NC the penalty associated with this insert \NC \NR
\NC \type{height} \NC number \NC height of the insert \NC \NR
\NC \type{depth} \NC number \NC depth of the insert \NC \NR
\NC \type{head/list} \NC node \NC the first node of the body of this insert \NC \NR
+\LL
\stoptabulate
There is a set of extra fields that concern the associated glue: \type {width},
@@ -167,53 +180,76 @@ There is a set of extra fields that concern the associated glue: \type {width},
These are all numbers.
A warning: never assign a node list to the \type {head} field unless you are sure
-its internal link structure is correct, otherwise an error may be result. You can use
-\type {list} instead (often in functions you want to use local variable swith similar
+its internal link structure is correct, otherwise an error may result. You can use
+\type {list} instead (often in functions you want to use local variable with similar
names and both names are equally sensible).
-\subsubsection{mark nodes}
+\subsection{\nod {mark} nodes}
+
+\topicindex {nodes+marks}
+\topicindex {marks}
+
+This one relates to the \prm {mark} primitive.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC unused \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{class} \NC number \NC the mark class \NC \NR
\NC \type{mark} \NC table \NC a table representing a token list \NC \NR
+\LL
\stoptabulate
-\subsubsection{adjust nodes}
+\subsection{\nod {adjust} nodes}
+
+\topicindex {nodes+adjust}
+\topicindex {adjust}
+
+This node comes from \prm {vadjust} primitive.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{adjust} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{head/list} \NC node \NC adjusted material \NC \NR
+\LL
\stoptabulate
A warning: never assign a node list to the \type {head} field unless you are sure
-its internal link structure is correct, otherwise an error may be result.
+its internal link structure is correct, otherwise an error may be the result.
+
+\subsection{\nod {disc} nodes}
+
+\topicindex {nodes+discretionaries}
+\topicindex {discretionaries}
-\subsubsection{disc nodes}
+The \prm {discretionary} and \prm {-}, the \type {-} character but also the
+hyphenation mechanism produces these nodes.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{disc} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{pre} \NC node \NC pointer to the pre|-|break text \NC \NR
\NC \type{post} \NC node \NC pointer to the post|-|break text \NC \NR
\NC \type{replace} \NC node \NC pointer to the no|-|break text \NC \NR
-\NC \type{penalty} \NC number \NC the penalty associated with the break, normally \type {\hyphenpenalty} or \type {\exhyphenpenalty} \NC \NR
+\NC \type{penalty} \NC number \NC the penalty associated with the break, normally
+ \prm {hyphenpenalty} or \prm {exhyphenpenalty} \NC \NR
+\LL
\stoptabulate
The subtype numbers~4 and~5 belong to the \quote {of-f-ice} explanation given
-elsewhere.
+elsewhere. These disc nodes are kind of special as at some point they also keep
+information about breakpoints and nested ligatures.
-These disc nodes are kind of special as at some point they also keep information
-about breakpoints and nested ligatures. The \type {pre}, \type {post} and \type
-{replace} fields at the \LUA\ end are in fact indirectly accessed and have a
-\type {prev} pointer that is not \type {nil}. This means that when you mess
-around with the head of these (three) lists, you also need to reassign them
-because that will restore the proper \type {prev} pointer, so:
+The \type {pre}, \type {post} and \type {replace} fields at the \LUA\ end are in
+fact indirectly accessed and have a \type {prev} pointer that is not \type {nil}.
+This means that when you mess around with the head of these (three) lists, you
+also need to reassign them because that will restore the proper \type {prev}
+pointer, so:
\starttyping
pre = d.pre
@@ -225,48 +261,64 @@ Otherwise you can end up with an invalid internal perception of reality and
\LUATEX\ might even decide to crash on you. It also means that running forward
over for instance \type {pre} is ok but backward you need to stop at \type {pre}.
And you definitely must not mess with the node that \type {prev} points to, if
-only because it is not really an node but part of the disc data structure (so
+only because it is not really a node but part of the disc data structure (so
freeing it again might crash \LUATEX).
-\subsubsection{math nodes}
+\subsection{\nod {math} nodes}
+
+\topicindex {nodes+math}
+\topicindex {math+nodes}
+
+Math nodes represent the boundaries of a math formula, normally wrapped into
+\type {$} signs.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{math} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
-\NC \type{surround} \NC number \NC width of the \type {\mathsurround} kern \NC \NR
+\NC \type{surround} \NC number \NC width of the \prm {mathsurround} kern \NC \NR
+\LL
\stoptabulate
There is a set of extra fields that concern the associated glue: \type {width},
\type {stretch}, \type {stretch_order}, \type {shrink} and \type {shrink_order}.
These are all numbers.
-\subsubsection{glue nodes}
+\subsection{\nod {glue} nodes}
+
+\topicindex {nodes+glue}
+\topicindex {glue}
Skips are about the only type of data objects in traditional \TEX\ that are not a
-simple value. The structure that represents the glue components of a skip is
-called a \type {glue_spec}, and it has the following accessible fields:
+simple value. They are inserted when \TEX\ sees a space in the text flow but also
+by \prm {hskip} and \prm {vskip}. The structure that represents the glue
+components of a skip is called a \nod {glue_spec}, and it has the following
+accessible fields:
\starttabulate[|l|l|p|]
-\BC key \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{width} \NC number \NC the horizontal or vertical displacement \NC \NR
\NC \type{stretch} \NC number \NC extra (positive) displacement or stretch amount \NC \NR
\NC \type{stretch_order} \NC number \NC factor applied to stretch amount \NC \NR
\NC \type{shrink} \NC number \NC extra (negative) displacement or shrink amount\NC \NR
\NC \type{shrink_order} \NC number \NC factor applied to shrink amount \NC \NR
+\LL
\stoptabulate
The effective width of some glue subtypes depends on the stretch or shrink needed
to make the encapsulating box fit its dimensions. For instance, in a paragraph
-lines normally have glue representing spaces and these stretch of shrink to make
+lines normally have glue representing spaces and these stretch or shrink to make
the content fit in the available space. The \type {effective_glue} function that
takes a glue node and a parent (hlist or vlist) returns the effective width of
-that glue item.
+that glue item. When you pass \type {true} as third argument the value will be
+rounded.
-A gluespec node is a special kind of node that is used for storing a set of glue
-values in registers. Originally they were also used to store properties of glue
-nodes (using a system of reference counts) but we now keep these properties in
-the glue nodes themselves, which gives a cleaner interface to \LUA.
+A \nod {glue_spec} node is a special kind of node that is used for storing a set
+of glue values in registers. Originally they were also used to store properties
+of glue nodes (using a system of reference counts) but we now keep these
+properties in the glue nodes themselves, which gives a cleaner interface to \LUA.
The indirect spec approach was in fact an optimization in the original \TEX\
code. First of all it can save quite some memory because all these spaces that
@@ -281,10 +333,12 @@ not that high (and nowadays memory is less an issue, also given that a glue node
is only a few memory words larger than a spec).
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{glue} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{leader} \NC node \NC pointer to a box or rule for leaders \NC \NR
+\LL
\stoptabulate
In addition there are the \type {width}, \type {stretch} \type {stretch_order},
@@ -295,64 +349,90 @@ so we decided to stick to that naming.
A regular word space also results in a \type {spaceskip} subtype (this used to be
a \type {userskip} with subtype zero).
-\subsubsection{kern nodes}
+\subsection{\nod {kern} nodes}
+
+\topicindex {nodes+kerns}
+\topicindex {kerns}
+
+The \prm {kern} command creates such nodes but for instance the font and math
+machinery can also add them.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{kern} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{kern} \NC number \NC fixed horizontal or vertical advance \NC \NR
+\LL
\stoptabulate
-\subsubsection{penalty nodes}
+\subsection{\nod {penalty} nodes}
+
+\topicindex {nodes+penalty}
+\topicindex {penalty}
+
+The \prm {penalty} command is one that generates these nodes.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{penalty} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{penalty} \NC number \NC the penalty value \NC \NR
+\LL
\stoptabulate
The subtypes are just informative and \TEX\ itself doesn't use them. When you
run into an \type {linebreakpenalty} you need to keep in mind that it's a
accumulation of \type {club}, \type{widow} and other relevant penalties.
-\subsubsection[glyphnodes]{glyph nodes}
+\subsection[glyphnodes]{\nod {glyph} nodes}
+
+\topicindex {nodes+glyph}
+\topicindex {glyphs}
+
+These are probably the mostly used nodes and although you can push them in the
+current list with for instance \prm {char} \TEX\ will normally do it for you when
+it considers some input to be text.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
-\NC \type{subtype} \NC number \NC bitfield \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
+\NC \type{subtype} \NC number \NC bit field \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
-\NC \type{char} \NC number \NC the chatacter index in the font \NC \NR
+\NC \type{char} \NC number \NC the character index in the font \NC \NR
\NC \type{font} \NC number \NC the font identifier \NC \NR
\NC \type{lang} \NC number \NC the language identifier \NC \NR
\NC \type{left} \NC number \NC the frozen \type {\lefthyphenmnin} value \NC \NR
\NC \type{right} \NC number \NC the frozen \type {\righthyphenmnin} value \NC \NR
-\NC \type{uchyph} \NC boolean \NC the frozen \type {\uchyph} value \NC \NR
+\NC \type{uchyph} \NC boolean \NC the frozen \prm {uchyph} value \NC \NR
\NC \type{components} \NC node \NC pointer to ligature components \NC \NR
\NC \type{xoffset} \NC number \NC a virtual displacement in horizontal direction \NC \NR
\NC \type{yoffset} \NC number \NC a virtual displacement in vertical direction \NC \NR
-%NC \type{xadvance} \NC number \NC an additional advance after the glyph (experimental) \NC \NR
\NC \type{width} \NC number \NC the (original) width of the character \NC \NR
\NC \type{height} \NC number \NC the (original) height of the character\NC \NR
\NC \type{depth} \NC number \NC the (original) depth of the character\NC \NR
\NC \type{expansion_factor} \NC number \NC the to be applied expansion_factor \NC \NR
+\NC \type{data} \NC number \NC a general purpose field for users (we had room for it) \NC \NR
+\LL
\stoptabulate
The \type {width}, \type {height} and \type {depth} values are read|-|only. The
-\type {expansion_factor} is assigned in the parbuilder and used in the backend.
+\type {expansion_factor} is assigned in the par builder and used in the backend.
A warning: never assign a node list to the components field unless you are sure
its internal link structure is correct, otherwise an error may be result. Valid
bits for the \type {subtype} field are:
\starttabulate[|c|l|]
-\BC bit \BC meaning \NC \NR
+\DB bit \BC meaning \NC \NR
+\TB
\NC 0 \NC character \NC \NR
\NC 1 \NC ligature \NC \NR
\NC 2 \NC ghost \NC \NR
\NC 3 \NC left \NC \NR
\NC 4 \NC right \NC \NR
+\LL
\stoptabulate
See \in {section} [charsandglyphs] for a detailed description of the \type
@@ -378,87 +458,117 @@ helpers are not always faster than separate calls but they sometimes permit
making more readable tests. The \type {uses_font} helpers takes a node
and font id and returns true when a glyph or disc node references that font.
-\subsubsection{boundary nodes}
+\subsection{\nod {boundary} nodes}
+
+\topicindex {nodes+boundary}
+\topicindex {boundary}
+
+This node relates to the \prm {noboundary}, \prm {boundary}, \prm
+{protrusionboundary} and \prm {wordboundary} primitives.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{boundary} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{value} \NC number \NC values 0--255 are reserved \NC \NR
+\LL
\stoptabulate
-This node relates to the \type {\noboundary}, \type {\boundary}, \type
-{\protrusionboundary} and \type {\wordboundary} primitives.
+\subsection{\nod {local_par} nodes}
+
+\topicindex {nodes+paragraphs}
+\topicindex {paragraphs}
-\subsubsection{local_par nodes}
+This node is inserted at the start of a paragraph. You should not mess
+too much with this one.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
-\NC \type{pen_inter} \NC number \NC local interline penalty (from \type {\localinterlinepenalty}) \NC \NR
-\NC \type{pen_broken} \NC number \NC local broken penalty (from \type {\localbrokenpenalty}) \NC \NR
+\NC \type{pen_inter} \NC number \NC local interline penalty (from \lpr {localinterlinepenalty}) \NC \NR
+\NC \type{pen_broken} \NC number \NC local broken penalty (from \lpr {localbrokenpenalty}) \NC \NR
\NC \type{dir} \NC string \NC the direction of this par. see~\in [dirnodes] \NC \NR
-\NC \type{box_left} \NC node \NC the \type {\localleftbox} \NC \NR
-\NC \type{box_left_width} \NC number \NC width of the \type {\localleftbox} \NC \NR
-\NC \type{box_right} \NC node \NC the \type {\localrightbox} \NC \NR
-\NC \type{box_right_width} \NC number \NC width of the \type {\localrightbox} \NC \NR
+\NC \type{box_left} \NC node \NC the \lpr {localleftbox} \NC \NR
+\NC \type{box_left_width} \NC number \NC width of the \lpr {localleftbox} \NC \NR
+\NC \type{box_right} \NC node \NC the \lpr {localrightbox} \NC \NR
+\NC \type{box_right_width} \NC number \NC width of the \lpr {localrightbox} \NC \NR
+\LL
\stoptabulate
A warning: never assign a node list to the \type {box_left} or \type {box_right}
field unless you are sure its internal link structure is correct, otherwise an
-error may be result.
+error may result.
+
+\subsection[dirnodes]{\nod {dir} nodes}
-\subsubsection[dirnodes]{dir nodes}
+\topicindex {nodes+direction}
+\topicindex {directions}
+
+Direction nodes mark parts of the running text that need a change of direction and \
+the \prm {textdir} command generates them.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{dir} \NC string \NC the direction (but see below) \NC \NR
\NC \type{level} \NC number \NC nesting level of this direction whatsit \NC \NR
+\LL
\stoptabulate
-A note on \type {dir} strings. Direction specifiers are three|-|letter
-combinations of \type {T}, \type {B}, \type {R}, and \type {L}.
-
-These are built up out of three separate items:
+Direction specifiers are three|-|letter combinations of \type {T}, \type {B},
+\type {R}, and \type {L}. These are built up out of three separate items:
\startitemize[packed]
\startitem
- the first is the direction of the \quote{top} of paragraphs.
+ the first is the direction of the \quote{top} of paragraphs
\stopitem
\startitem
- the second is the direction of the \quote{start} of lines.
+ the second is the direction of the \quote{start} of lines
\stopitem
\startitem
- the third is the direction of the \quote{top} of glyphs.
+ the third is the direction of the \quote{top} of glyphs
\stopitem
\stopitemize
However, only four combinations are accepted: \type {TLT}, \type {TRT}, \type
-{RTT}, and \type {LTL}.
+{RTT}, and \type {LTL}. Inside actual \nod {dir} nodes, the representation of
+\nod {dir} is not a three|-|letter but a combination of numbers. When printed the
+direction is indicated by a \type {+} or \type {-}, indicating whether the value
+is pushed or popped from the direction stack.
-Inside actual \type {dir} whatsit nodes, the representation of \type {dir} is not
-a three-letter but a four|-|letter combination. The first character in this case
-is always either \type {+} or \type {-}, indicating whether the value is pushed
-or popped from the direction stack.
+\subsection{\nod {marginkern} nodes}
-\subsubsection{margin_kern nodes}
+\topicindex {nodes+paragraphs}
+\topicindex {paragraphs}
+\topicindex {protrusion}
+
+Margin kerns result from protrusion.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
-\NC \type{subtype} \NC number \NC \showsubtypes{margin_kern} \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
+\NC \type{subtype} \NC number \NC \showsubtypes{marginkern} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{width} \NC number \NC the advance of the kern \NC \NR
\NC \type{glyph} \NC node \NC the glyph to be used \NC \NR
+\LL
\stoptabulate
-\subsection{Math nodes}
+\stopsection
+
+\startsection[title={Math noads}]
+
+\topicindex {nodes+math}
+\topicindex {math+nodes}
These are the so||called \quote {noad}s and the nodes that are specifically
associated with math processing. Most of these nodes contain subnodes so that the
list of possible fields is actually quite small. First, the subnodes:
-\subsubsection{Math kernel subnodes}
+\subsection{Math kernel subnodes}
Many object fields in math mode are either simple characters in a specific family
or math lists or node lists. There are four associated subnodes that represent
@@ -467,58 +577,62 @@ these cases (in the following node descriptions these are indicated by the word
The \type {next} and \type {prev} fields for these subnodes are unused.
-\subsubsubsection{math_char and math_text_char subnodes}
+\subsection{\nod {math_char} and \nod {math_text_char} subnodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{char} \NC number \NC the character index \NC \NR
\NC \type{fam} \NC number \NC the family number \NC \NR
+\LL
\stoptabulate
-The \type {math_char} is the simplest subnode field, it contains the character
-and family for a single glyph object. The \type {math_text_char} is a special
+The \nod {math_char} is the simplest subnode field, it contains the character
+and family for a single glyph object. The \nod {math_text_char} is a special
case that you will not normally encounter, it arises temporarily during math list
conversion (its sole function is to suppress a following italic correction).
-\subsubsubsection{sub_box and sub_mlist subnodes}
+\subsection{\nod {sub_box} and \nod {sub_mlist} subnodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{head/list} \NC node \NC list of nodes \NC \NR
+\LL
\stoptabulate
-These two subnode types are used for subsidiary list items. For \type {sub_box},
-the \type {head} points to a \quote {normal} vbox or hbox. For \type {sub_mlist},
+These two subnode types are used for subsidiary list items. For \nod {sub_box},
+the \type {head} points to a \quote {normal} vbox or hbox. For \nod {sub_mlist},
the \type {head} points to a math list that is yet to be converted.
A warning: never assign a node list to the \type {head} field unless you are sure
-its internal link structure is correct, otherwise an error may be result.
+its internal link structure is correct, otherwise an error is triggered.
-\subsubsection{Math delimiter subnode}
+\subsection{\nod {delim} subnodes}
There is a fifth subnode type that is used exclusively for delimiter fields. As
before, the \type {next} and \type {prev} fields are unused.
-\subsubsubsection{delim subnodes}
-
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{small_char} \NC number \NC character index of base character \NC \NR
\NC \type{small_fam} \NC number \NC family number of base character \NC \NR
\NC \type{large_char} \NC number \NC character index of next larger character \NC \NR
\NC \type{large_fam} \NC number \NC family number of next larger character \NC \NR
+\LL
\stoptabulate
The fields \type {large_char} and \type {large_fam} can be zero, in that case the
-font that is sed for the \type {small_fam} is expected to provide the large
+font that is set for the \type {small_fam} is expected to provide the large
version as an extension to the \type {small_char}.
-\subsubsection{Math core nodes}
+\subsection{Math core nodes}
-First, there are the objects (the \TEX book calls then \quote {atoms}) that are
+First, there are the objects (the \TEX book calls them \quote {atoms}) that are
associated with the simple math objects: ord, op, bin, rel, open, close, punct,
inner, over, under, vcent. These all have the same fields, and they are combined
into a single node type with separate subtypes for differentiation.
@@ -526,6 +640,8 @@ into a single node type with separate subtypes for differentiation.
Some noads have an option field. The values in this bitset are common:
\starttabulate[|l|r|]
+\DB meaning \BC bits \NC \NR
+\TB
\NC set \NC \type{0x08} \NC \NR
\NC internal \NC \type{0x00} + \type{0x08} \NC \NR
\NC internal \NC \type{0x01} + \type{0x08} \NC \NR
@@ -538,24 +654,28 @@ Some noads have an option field. The values in this bitset are common:
\NC no sub script \NC \type{0x21} + \type{0x08} \NC \NR
\NC no super script \NC \type{0x22} + \type{0x08} \NC \NR
\NC no script \NC \type{0x23} + \type{0x08} \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{simple nodes}
+\subsection{simple \nod {noad} nodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{noad} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{nucleus} \NC kernel node \NC base \NC \NR
\NC \type{sub} \NC kernel node \NC subscript \NC \NR
\NC \type{sup} \NC kernel node \NC superscript \NC \NR
\NC \type{options} \NC number \NC bitset of rendering options \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{accent nodes}
+\subsection{\nod {accent} nodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{accent} \NC \NR
\NC \type{nucleus} \NC kernel node \NC base \NC \NR
\NC \type{sub} \NC kernel node \NC subscript \NC \NR
@@ -563,57 +683,65 @@ Some noads have an option field. The values in this bitset are common:
\NC \type{accent} \NC kernel node \NC top accent \NC \NR
\NC \type{bot_accent} \NC kernel node \NC bottom accent \NC \NR
\NC \type{fraction} \NC number \NC larger step criterium (divided by 1000) \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{style nodes}
+\subsection{\nod {style} nodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{style} \NC string \NC contains the style \NC \NR
+\LL
\stoptabulate
There are eight possibilities for the string value: one of \type {display},
\type {text}, \type {script}, or \type {scriptscript}. Each of these can have
be prefixed by \type {cramped}.
-\subsubsubsection{choice nodes}
+\subsection{\nod {choice} nodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{display} \NC node \NC list of display size alternatives \NC \NR
\NC \type{text} \NC node \NC list of text size alternatives \NC \NR
\NC \type{script} \NC node \NC list of scriptsize alternatives \NC \NR
\NC \type{scriptscript} \NC node \NC list of scriptscriptsize alternatives \NC \NR
+\LL
\stoptabulate
Warning: never assign a node list to the \type {display}, \type {text}, \type
{script}, or \type {scriptscript} field unless you are sure its internal link
-structure is correct, otherwise an error may be result.
+structure is correct, otherwise an error can occur.
-\subsubsubsection{radical nodes}
+\subsection{\nod {radical} nodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{radical} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{nucleus} \NC kernel node \NC base \NC \NR
\NC \type{sub} \NC kernel node \NC subscript \NC \NR
\NC \type{sup} \NC kernel node \NC superscript \NC \NR
\NC \type{left} \NC delimiter node \NC \NC \NR
-\NC \type{degree} \NC kernel node \NC only set by \type {\Uroot} \NC \NR
+\NC \type{degree} \NC kernel node \NC only set by \lpr {Uroot} \NC \NR
\NC \type{width} \NC number \NC required width \NC \NR
\NC \type{options} \NC number \NC bitset of rendering options \NC \NR
+\LL
\stoptabulate
Warning: never assign a node list to the \type {nucleus}, \type {sub}, \type
{sup}, \type {left}, or \type {degree} field unless you are sure its internal
-link structure is correct, otherwise an error may be result.
+link structure is correct, otherwise an error can be triggered.
-\subsubsubsection{fraction nodes}
+\subsection{\nod {fraction} nodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{width} \NC number \NC (optional) width of the fraction \NC \NR
\NC \type{num} \NC kernel node \NC numerator \NC \NR
@@ -622,16 +750,18 @@ link structure is correct, otherwise an error may be result.
\NC \type{right} \NC delimiter node \NC right side symbol \NC \NR
\NC \type{middle} \NC delimiter node \NC middle symbol \NC \NR
\NC \type{options} \NC number \NC bitset of rendering options \NC \NR
+\LL
\stoptabulate
Warning: never assign a node list to the \type {num}, or \type {denom} field
unless you are sure its internal link structure is correct, otherwise an error
-may be result.
+can result.
-\subsubsubsection{fence nodes}
+\subsection{\nod {fence} nodes}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{subtype} \NC number \NC \showsubtypes{fence} \NC \NR
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{delim} \NC delimiter node \NC delimiter specification \NC \NR
@@ -640,15 +770,18 @@ may be result.
\NC \type{depth} \NC number \NC required depth \NC \NR
\NC \type{options} \NC number \NC bitset of rendering options \NC \NR
\NC \type{class} \NC number \NC spacing related class \NC \NR
+\LL
\stoptabulate
Warning: some of these fields are used by the renderer and might get adapted in
the process.
-\subsection{whatsit nodes}
+\stopsection
+
+\startsection[title={Front|-|end whatsits}]
-Whatsit nodes come in many subtypes that you can ask for by running
-\type {node.whatsits()}:
+Whatsit nodes come in many subtypes that you can ask for them by running
+\type {node.whatsits}:
\startluacode
for id, name in table.sortedpairs(node.whatsits()) do
context.type(name)
@@ -659,44 +792,53 @@ Whatsit nodes come in many subtypes that you can ask for by running
\stopluacode
. % period
-\subsubsection{front|-|end whatsits}
+Some of them are generic and independent of the output mode and others are
+specific to the chosen backend: \DVI\ or \PDF. Here we discuss the generic
+font|-|end nodes nodes.
-\subsubsubsection{open whatsits}
+\subsection{\whs {open}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{stream} \NC number \NC \TEX's stream id number \NC \NR
\NC \type{name} \NC string \NC file name \NC \NR
\NC \type{ext} \NC string \NC file extension \NC \NR
\NC \type{area} \NC string \NC file area (this may become obsolete) \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{write whatsits}
+\subsection{\whs {write}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{stream} \NC number \NC \TEX's stream id number \NC \NR
\NC \type{data} \NC table \NC a table representing the token list to be written \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{close whatsits}
+\subsection{\whs {close}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{stream} \NC number \NC \TEX's stream id number \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{user_defined whatsits}
+\subsection{\whs {user_defined}}
User|-|defined whatsit nodes can only be created and handled from \LUA\ code. In
effect, they are an extension to the extension mechanism. The \LUATEX\ engine
will simply step over such whatsits without ever looking at the contents.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{user_id} \NC number \NC id number \NC \NR
\NC \type{type} \NC number \NC type of the value \NC \NR
@@ -704,103 +846,129 @@ will simply step over such whatsits without ever looking at the contents.
\NC \NC node \NC a node list \NC \NR
\NC \NC string \NC a \LUA\ string \NC \NR
\NC \NC table \NC a \LUA\ table \NC \NR
+\LL
\stoptabulate
The \type {type} can have one of six distinct values. The number is the \ASCII\
-value if the first character if the type name (so you can use string.byte("l")
+value if the first character of the type name (so you can use string.byte("l")
instead of \type {108}).
\starttabulate[|r|c|p|]
-\BC value \BC meaning \BC explanation \NC \NR
+\DB value \BC meaning \BC explanation \NC \NR
+\TB
\NC 97 \NC a \NC list of attributes (a node list) \NC \NR
\NC 100 \NC d \NC a \LUA\ number \NC \NR
\NC 108 \NC l \NC a \LUA\ value (table, number, boolean, etc) \NC \NR
\NC 110 \NC n \NC a node list \NC \NR
\NC 115 \NC s \NC a \LUA\ string \NC \NR
\NC 116 \NC t \NC a \LUA\ token list in \LUA\ table form (a list of triplets) \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{save_pos whatsits}
+\subsection{\whs {save_pos}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{late_lua whatsits}
+\subsection{\whs {late_lua}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
-\NC \type{attr} \NC node \NC list of attributes \NC \NR
-\NC \type{data} \NC string \NC data to execute \NC \NR
-\NC \type{string} \NC string \NC data to execute \NC \NR
-\NC \type{name} \NC string \NC the name to use for \LUA\ error reporting \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
+\NC \type{attr} \NC node \NC list of attributes \NC \NR
+\NC \type{data} \NC string or function \NC the to be written information stored as \LUA\ value \NC \NR
+\NC \type{token} \NC string \NC the to be written information stored as token list \NC \NR
+\NC \type{name} \NC string \NC the name to use for \LUA\ error reporting \NC \NR
+\LL
\stoptabulate
The difference between \type {data} and \type {string} is that on assignment, the
-\type {data} field is converted to a token list, cf. use as \type {\latelua}. The
+\type {data} field is converted to a token list, cf.\ use as \lpr {latelua}. The
\type {string} version is treated as a literal string.
-\subsubsection{\DVI\ backend whatsits}
+\stopsection
-\subsubsection{special whatsits}
+\startsection[title={\DVI\ backend whatsits}]
+
+\subsection{\whs {special}}
+
+There is only one \DVI\ backend whatsit, and it just flushes its content to the
+output file.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
-\NC \type{data} \NC string \NC the \type {\special} information \NC \NR
+\NC \type{data} \NC string \NC the \prm {special} information \NC \NR
+\LL
\stoptabulate
-\subsubsection{\PDF\ backend whatsits}
+\stopsection
+
+\startsection[title={\PDF\ backend whatsits}]
-\subsubsubsection{pdf_literal whatsits}
+\subsection{\whs {pdf_literal}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
-\NC \type{attr} \NC node \NC list of attributes \NC \NR
-\NC \type{mode} \NC number \NC the \quote {mode} setting of this literal \NC \NR
-\NC \type{data} \NC string \NC the \type {\pdfliteral} information \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
+\NC \type{attr} \NC node \NC list of attributes \NC \NR
+\NC \type{mode} \NC number \NC the \quote {mode} setting of this literal \NC \NR
+\NC \type{data} \NC string \NC the to be written information stored as \LUA\ string \NC \NR
+\NC \type{token} \NC string \NC the to be written information stored as token list \NC \NR
+\LL
\stoptabulate
Possible mode values are:
-\starttabulate[|l|p|]
-\BC value \BC keyword \NC \NR
+\starttabulate[|c|p|]
+\DB value \BC keyword \NC \NR
+\TB
\NC 0 \NC \type{origin} \NC \NR
\NC 1 \NC \type{page} \NC \NR
\NC 2 \NC \type{direct} \NC \NR
\NC 3 \NC \type{raw} \NC \NR
\NC 4 \NC \type{text} \NC \NR
+\LL
\stoptabulate
-The higher the number, the less checking and the more you can run into troubles.
+The higher the number, the less checking and the more you can run into trouble.
Especially the \type {raw} variant can produce bad \PDF\ so you can best check
what you generate.
-\subsubsubsection{pdf_refobj whatsits}
+\subsection{\whs {pdf_refobj}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{objnum} \NC number \NC the referenced \PDF\ object number \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_annot whatsits}
+\subsection{\whs {pdf_annot}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{width} \NC number \NC the width (not used in calculations) \NC \NR
\NC \type{height} \NC number \NC the height (not used in calculations) \NC \NR
\NC \type{depth} \NC number \NC the depth (not used in calculations) \NC \NR
\NC \type{objnum} \NC number \NC the referenced \PDF\ object number \NC \NR
\NC \type{data} \NC string \NC the annotation data \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_start_link whatsits}
+\subsection{\whs {pdf_start_link}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{width} \NC number \NC the width (not used in calculations) \NC \NR
\NC \type{height} \NC number \NC the height (not used in calculations) \NC \NR
@@ -808,19 +976,23 @@ what you generate.
\NC \type{objnum} \NC number \NC the referenced \PDF\ object number \NC \NR
\NC \type{link_attr} \NC table \NC the link attribute token list \NC \NR
\NC \type{action} \NC node \NC the action to perform \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_end_link whatsits}
+\subsection{\whs {pdf_end_link}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_dest whatsits}
+\subsection{\whs {pdf_dest}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{width} \NC number \NC the width (not used in calculations) \NC \NR
\NC \type{height} \NC number \NC the height (not used in calculations) \NC \NR
@@ -831,45 +1003,54 @@ what you generate.
\NC \type{dest_type} \NC number \NC type of destination \NC \NR
\NC \type{xyz_zoom} \NC number \NC the zoom factor (times 1000) \NC \NR
\NC \type{objnum} \NC number \NC the \PDF\ object number \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_action whatsits}
+\subsection{\whs {pdf_action}}
-These are a special kind of item that only appears inside \PDF\ start link
+These are a special kind of items that only appear inside \PDF\ start link
objects.
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{action_type} \NC number \NC the kind of action involved \NC \NR
\NC \type{action_id} \NC number or string \NC token list reference or string \NC \NR
\NC \type{named_id} \NC number \NC the index of the destination \NC \NR
\NC \type{file} \NC string \NC the target filename \NC \NR
\NC \type{new_window} \NC number \NC the window state of the target \NC \NR
\NC \type{data} \NC string \NC the name of the destination \NC \NR
+\LL
\stoptabulate
Valid action types are:
\starttabulate[|l|l|]
-\NC 0 \NC \type{page} \NC \NR
-\NC 1 \NC \type{goto} \NC \NR
-\NC 2 \NC \type{thread} \NC \NR
-\NC 3 \NC \type{user} \NC \NR
+\DB value \BC meaning \NC \NR
+\TB
+\NC 0 \NC \type{page} \NC \NR
+\NC 1 \NC \type{goto} \NC \NR
+\NC 2 \NC \type{thread} \NC \NR
+\NC 3 \NC \type{user} \NC \NR
+\LL
\stoptabulate
Valid window types are:
\starttabulate[|l|l|]
-\NC 0 \NC \type{notset} \NC \NR
-\NC 1 \NC \type{new} \NC \NR
-\NC 2 \NC \type{nonew} \NC \NR
+\DB value \BC meaning \NC \NR
+\TB
+\NC 0 \NC \type{notset} \NC \NR
+\NC 1 \NC \type{new} \NC \NR
+\NC 2 \NC \type{nonew} \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_thread whatsits}
+\subsection{\whs {pdf_thread}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{width} \NC number \NC the width (not used in calculations) \NC \NR
\NC \type{height} \NC number \NC the height (not used in calculations) \NC \NR
@@ -878,12 +1059,14 @@ Valid window types are:
\NC \type{tread_id} \NC number \NC the thread id \NC \NR
\NC \NC string \NC the thread name \NC \NR
\NC \type{thread_attr} \NC number \NC extra thread information \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_start_thread whatsits}
+\subsection{\whs {pdf_start_thread}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{width} \NC number \NC the width (not used in calculations) \NC \NR
\NC \type{height} \NC number \NC the height (not used in calculations) \NC \NR
@@ -892,48 +1075,63 @@ Valid window types are:
\NC \type{tread_id} \NC number \NC the thread id \NC \NR
\NC \NC string \NC the thread name \NC \NR
\NC \type{thread_attr} \NC number \NC extra thread information \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_end_thread whatsits}
+\subsection{\whs {pdf_end_thread}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_colorstack whatsits}
+\subsection{\whs {pdf_colorstack}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{stack} \NC number \NC colorstack id number \NC \NR
\NC \type{command} \NC number \NC command to execute \NC \NR
\NC \type{data} \NC string \NC data \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_setmatrix whatsits}
+\subsection{\whs {pdf_setmatrix}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
\NC \type{data} \NC string \NC data \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_save whatsits}
+\subsection{\whs {pdf_save}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
+\LL
\stoptabulate
-\subsubsubsection{pdf_restore whatsits}
+\subsection{\whs {pdf_restore}}
\starttabulate[|l|l|p|]
-\BC field \BC type \BC explanation \NC \NR
+\DB field \BC type \BC explanation \NC \NR
+\TB
\NC \type{attr} \NC node \NC list of attributes \NC \NR
+\LL
\stoptabulate
-\section{The \type {node} library}
+\stopsection
+
+\startsection[title={The \type {node} library}][library=node]
+
+\subsection {Introduction}
The \type {node} library contains functions that facilitate dealing with (lists
of) nodes and their values. They allow you to create, alter, copy, delete, and
@@ -943,8 +1141,7 @@ insert \LUATEX\ node objects, the core objects within the typesetter.
\type {luatex.node}. The various parts within a node can be accessed using
named fields.
-Each node has at least the three fields \type {next}, \type {id}, and \type
-{subtype}:
+Each node has at least the three fields \type {next}, \type {id}, and \type {subtype}:
\startitemize[intro]
@@ -969,10 +1166,9 @@ Each node has at least the three fields \type {next}, \type {id}, and \type
\stopitemize
The other available fields depend on the \type {id} (and for \quote {whatsits},
-the \type {subtype}) of the node. Further details on the various fields and their
-meanings are given in~\in{chapter}[nodes].
+the \type {subtype}) of the node.
-Support for \type {unset} (alignment) nodes is partial: they can be queried and
+Support for \nod {unset} (alignment) nodes is partial: they can be queried and
modified from \LUA\ code, but not created.
Nodes can be compared to each other, but: you are actually comparing indices into
@@ -987,76 +1183,90 @@ call the node freeing functions yourself when you are no longer in need of a nod
(list). Nodes form linked lists without reference counting, so you have to be
careful that when control returns back to \LUATEX\ itself, you have not deleted
nodes that are still referenced from a \type {next} pointer elsewhere, and that
-you did not create nodes that are referenced more than once.
+you did not create nodes that are referenced more than once. Normally the setters
+and getters handle this for you.
There are statistics available with regards to the allocated node memory, which
can be handy for tracing.
-\subsection{Node handling functions}
+\subsection{\type {is_node}}
-\subsubsection{\type {node.is_node}}
+\topicindex {nodes+functions}
+
+\libindex {is_node}
\startfunctioncall
-<boolean> t =
+<boolean|integer> t =
node.is_node(<any> item)
\stopfunctioncall
-This function returns true if the argument is a userdata object of
-type \type {<node>}.
+This function returns a number (the internal index of the node) if the argument
+is a userdata object of type \type {<node>} and false when no node is passed.
-\subsubsection{\type {node.types}}
+\subsection{\type {types} and \type {whatsits}}
+
+\libindex {types}
+\libindex {whatsits}
+
+This function returns an array that maps node id numbers to node type strings,
+providing an overview of the possible top|-|level \type {id} types.
\startfunctioncall
<table> t =
node.types()
\stopfunctioncall
-This function returns an array that maps node id numbers to node type strings,
-providing an overview of the possible top|-|level \type {id} types.
-
-\subsubsection{\type {node.whatsits}}
+\TEX's \quote {whatsits} all have the same \type {id}. The various subtypes are
+defined by their \type {subtype} fields. The function is much like \type {types},
+except that it provides an array of \type {subtype} mappings.
\startfunctioncall
<table> t =
node.whatsits()
\stopfunctioncall
-\TEX's \quote{whatsits} all have the same \type {id}. The various subtypes are
-defined by their \type {subtype} fields. The function is much like \type
-{node.types}, except that it provides an array of \type {subtype} mappings.
+\subsection{\type {id}}
-\subsubsection{\type {node.id}}
+\libindex{id}
+
+This converts a single type name to its internal numeric representation.
\startfunctioncall
<number> id =
node.id(<string> type)
\stopfunctioncall
-This converts a single type name to its internal numeric representation.
+\subsection{\type {type} and \type {subtype}}
-\subsubsection{\type {node.subtype}}
+\libindex {type}
+\libindex {subtype}
+
+In the argument is a number, then the next function converts an internal numeric
+representation to an external string representation. Otherwise, it will return
+the string \type {node} if the object represents a node, and \type {nil}
+otherwise.
\startfunctioncall
-<number> subtype =
- node.subtype(<string> type)
+<string> type =
+ node.type(<any> n)
\stopfunctioncall
-This converts a single whatsit name to its internal numeric representation (\type
-{subtype}).
-
-\subsubsection{\type {node.type}}
+This next one converts a single whatsit name to its internal numeric
+representation (\type {subtype}).
\startfunctioncall
-<string> type =
- node.type(<any> n)
+<number> subtype =
+ node.subtype(<string> type)
\stopfunctioncall
-In the argument is a number, then this function converts an internal numeric
-representation to an external string representation. Otherwise, it will return
-the string \type {node} if the object represents a node, and \type {nil}
-otherwise.
+\subsection{\type {fields}}
+
+\libindex {fields}
-\subsubsection{\type {node.fields}}
+This function returns an array of valid field names for a particular type of
+node. If you want to get the valid fields for a \quote {whatsit}, you have to
+supply the second argument also. In other cases, any given second argument will
+be silently ignored.
\startfunctioncall
<table> t =
@@ -1065,24 +1275,29 @@ otherwise.
node.fields(<number> id, <number> subtype)
\stopfunctioncall
-This function returns an array of valid field names for a particular type of
-node. If you want to get the valid fields for a \quote {whatsit}, you have to
-supply the second argument also. In other cases, any given second argument will
-be silently ignored.
+The function accepts string \type {id} and \type {subtype} values as well.
-This function accepts string \type {id} and \type {subtype} values as well.
+\subsection{\type {has_field}}
-\subsubsection{\type {node.has_field}}
+\libindex {has_field}
+
+This function returns a boolean that is only true if \type {n} is
+actually a node, and it has the field.
\startfunctioncall
<boolean> t =
node.has_field(<node> n, <string> field)
\stopfunctioncall
-This function returns a boolean that is only true if \type {n} is
-actually a node, and it has the field.
+\subsection{\type {new}}
-\subsubsection{\type {node.new}}
+\libindex{new}
+
+The \type {new} function creates a new node. All its fields are initialized to
+either zero or \type {nil} except for \type {id} and \type {subtype}. Instead of
+numbers you can also use strings (names). If you create a new \nod {whatsit} node
+the second argument is required. As with all node functions, this function
+creates a node at the \TEX\ level.
\startfunctioncall
<node> n =
@@ -1091,15 +1306,16 @@ actually a node, and it has the field.
node.new(<number> id, <number> subtype)
\stopfunctioncall
-Creates a new node. All of the new node's fields are initialized to either zero
-or \type {nil} except for \type {id} and \type {subtype} (if supplied). If you
-want to create a new whatsit, then the second argument is required, otherwise it
-need not be present. As with all node functions, this function creates a node on
-the \TEX\ level.
+\subsection{\type {free}, \type {flush_node} and \type {flush_list}}
-This function accepts string \type {id} and \type {subtype} values as well.
+\libindex{free}
+\libindex{flush_node}
+\libindex{flush_list}
-\subsubsection{\type {node.free} and \type {node.flush_node}}
+The next one the node \type {n} from \TEX's memory. Be careful: no checks are
+done on whether this node is still pointed to from a register or some \type
+{next} field: it is up to you to make sure that the internal data structures
+remain correct.
\startfunctioncall
<node> next =
@@ -1107,35 +1323,33 @@ This function accepts string \type {id} and \type {subtype} values as well.
flush_node(<node> n)
\stopfunctioncall
-Removes the node \type {n} from \TEX's memory. Be careful: no checks are done on
-whether this node is still pointed to from a register or some \type {next} field:
-it is up to you to make sure that the internal data structures remain correct.
-
The \type {free} function returns the next field of the freed node, while the
\type {flush_node} alternative returns nothing.
-\subsubsection{\type {node.flush_list}}
+A list starting with node \type {n} can be flushed from \TEX's memory too. Be
+careful: no checks are done on whether any of these nodes is still pointed to
+from a register or some \type {next} field: it is up to you to make sure that the
+internal data structures remain correct.
\startfunctioncall
node.flush_list(<node> n)
\stopfunctioncall
-Removes the node list \type {n} and the complete node list following \type {n}
-from \TEX's memory. Be careful: no checks are done on whether any of these nodes
-is still pointed to from a register or some \type {next} field: it is up to you
-to make sure that the internal data structures remain correct.
+\subsection{\type {copy} and \type {copy_list}}
-\subsubsection{\type {node.copy}}
+\libindex{copy}
+\libindex{copy_list}
+
+This creates a deep copy of node \type {n}, including all nested lists as in the case
+of a hlist or vlist node. Only the \type {next} field is not copied.
\startfunctioncall
<node> m =
node.copy(<node> n)
\stopfunctioncall
-Creates a deep copy of node \type {n}, including all nested lists as in the case
-of a hlist or vlist node. Only the \type {next} field is not copied.
-
-\subsubsection{\type {node.copy_list}}
+A deep copy of the node list that starts at \type {n} can be created too. If
+\type {m} is also given, the copy stops just before node \type {m}.
\startfunctioncall
<node> m =
@@ -1144,42 +1358,37 @@ of a hlist or vlist node. Only the \type {next} field is not copied.
node.copy_list(<node> n, <node> m)
\stopfunctioncall
-Creates a deep copy of the node list that starts at \type {n}. If \type {m} is
-also given, the copy stops just before node \type {m}.
+Note that you cannot copy attribute lists this way. However, there is normally no
+need to copy attribute lists as when you do assignments to the \type {attr} field
+or make changes to specific attributes, the needed copying and freeing takes
+place automatically.
+
+\subsection{\type {prev} and \type{next}}
-Note that you cannot copy attribute lists this way, specialized functions for
-dealing with attribute lists will be provided later but are not there yet.
-However, there is normally no need to copy attribute lists as when you do
-assignments to the \type {attr} field or make changes to specific attributes, the
-needed copying and freeing takes place automatically.
+\libindex{prev}
+\libindex{next}
-\subsubsection{\type {node.next}}
+These returns the node preceding or following the given node, or \type {nil} if
+there is no such node.
\startfunctioncall
<node> m =
node.next(<node> n)
-\stopfunctioncall
-
-Returns the node following this node, or \type {nil} if there is no such node.
-
-\subsubsection{\type {node.prev}}
-
-\startfunctioncall
<node> m =
node.prev(<node> n)
\stopfunctioncall
-Returns the node preceding this node, or \type {nil} if there is no such node.
+\subsection{\type {current_attr}}
+
+\libindex{current_attr}
-\subsubsection{\type {node.current_attr}}
+This returns the currently active list of attributes, if there is one.
\startfunctioncall
<node> m =
node.current_attr()
\stopfunctioncall
-Returns the currently active list of attributes, if there is one.
-
The intended usage of \type {current_attr} is as follows:
\starttyping
@@ -1209,7 +1418,16 @@ attribute list, not a copy thereof. Therefore, changing any of the attributes in
the list will change these values for all nodes that have the current attribute
list assigned to them.
-\subsubsection{\type {node.hpack}}
+\subsection{\type {hpack}}
+
+\libindex {hpack}
+
+This function creates a new hlist by packaging the list that begins at node \type
+{n} into a horizontal box. With only a single argument, this box is created using
+the natural width of its components. In the three argument form, \type {info}
+must be either \type {additional} or \type {exactly}, and \type {w} is the
+additional (\type {\hbox spread}) or exact (\type {\hbox to}) width to be used.
+The second return value is the badness of the generated box.
\startfunctioncall
<node> h, <number> b =
@@ -1220,21 +1438,22 @@ list assigned to them.
node.hpack(<node> n, <number> w, <string> info, <string> dir)
\stopfunctioncall
-This function creates a new hlist by packaging the list that begins at node \type
-{n} into a horizontal box. With only a single argument, this box is created using
-the natural width of its components. In the three argument form, \type {info}
-must be either \type {additional} or \type {exactly}, and \type {w} is the
-additional (\type {\hbox spread}) or exact (\type {\hbox to}) width to be used. The
-second return value is the badness of the generated box.
+Caveat: there can be unexpected side|-|effects to this function, like updating
+some of the \prm {marks} and \type {\inserts}. Also note that the content of
+\type {h} is the original node list \type {n}: if you call \type {node.free(h)}
+you will also free the node list itself, unless you explicitly set the \type
+{list} field to \type {nil} beforehand. And in a similar way, calling \type
+{node.free(n)} will invalidate \type {h} as well!
-Caveat: at this moment, there can be unexpected side|-|effects to this function,
-like updating some of the \type {\marks} and \type {\inserts}. Also note that the
-content of \type {h} is the original node list \type {n}: if you call \type
-{node.free(h)} you will also free the node list itself, unless you explicitly set
-the \type {list} field to \type {nil} beforehand. And in a similar way, calling
-\type {node.free(n)} will invalidate \type {h} as well!
+\subsection{\type {vpack}}
-\subsubsection{\type {node.vpack}}
+\libindex {vpack}
+
+This function creates a new vlist by packaging the list that begins at node \type
+{n} into a vertical box. With only a single argument, this box is created using
+the natural height of its components. In the three argument form, \type {info}
+must be either \type {additional} or \type {exactly}, and \type {w} is the
+additional (\type {\vbox spread}) or exact (\type {\vbox to}) height to be used.
\startfunctioncall
<node> h, <number> b =
@@ -1245,17 +1464,26 @@ the \type {list} field to \type {nil} beforehand. And in a similar way, calling
node.vpack(<node> n, <number> w, <string> info, <string> dir)
\stopfunctioncall
-This function creates a new vlist by packaging the list that begins at node \type
-{n} into a vertical box. With only a single argument, this box is created using
-the natural height of its components. In the three argument form, \type {info}
-must be either \type {additional} or \type {exactly}, and \type {w} is the
-additional (\type {\vbox spread}) or exact (\type {\vbox to}) height to be used.
+The second return value is the badness of the generated box. See the description
+of \type {hpack} for a few memory allocation caveats.
-The second return value is the badness of the generated box.
+\subsection{\type {prepend_prevdepth}}
-See the description of \type {node.hpack()} for a few memory allocation caveats.
+\libindex {prepend_prevdepth}
-\subsubsection{\type {node.dimensions}, \type {node.rangedimensions}}
+This function is somewhat special in the sense that it is an experimental helper
+that adds the interlinespace to a line keeping the baselineskip and lineskip into
+account.
+
+\startfunctioncall
+<node> n, <number> delta =
+ node.prepend_prevdepth(<node> n,<number> prevdepth)
+\stopfunctioncall
+
+\subsection{\type {dimensions} and \type {rangedimensions}}
+
+\libindex{dimensions}
+\libindex{rangedimensions}
\startfunctioncall
<number> w, <number> h, <number> d =
@@ -1320,7 +1548,9 @@ cases:
node.rangedimensions(<node> parent, <node> first, <node> last)
\stopfunctioncall
-\subsubsection{\type {node.mlist_to_hlist}}
+\subsection{\type {mlist_to_hlist}}
+
+\libindex {mlist_to_hlist}
\startfunctioncall
<node> h =
@@ -1329,9 +1559,9 @@ cases:
This runs the internal mlist to hlist conversion, converting the math list in
\type {n} into the horizontal list \type {h}. The interface is exactly the same
-as for the callback \type {mlist_to_hlist}.
+as for the callback \cbk {mlist_to_hlist}.
-\subsubsection{\type {node.slide}}
+\subsection{\type {slide}}
\startfunctioncall
<node> m =
@@ -1342,7 +1572,9 @@ Returns the last node of the node list that starts at \type {n}. As a
side|-|effect, it also creates a reverse chain of \type {prev} pointers between
nodes.
-\subsubsection{\type {node.tail}}
+\subsection{\type {tail}}
+
+\libindex {tail}
\startfunctioncall
<node> m =
@@ -1351,7 +1583,10 @@ nodes.
Returns the last node of the node list that starts at \type {n}.
-\subsubsection{\type {node.length}}
+\subsection{\type {length} and type {count}}
+
+\libindex {length}
+\libindex {count}
\startfunctioncall
<number> i =
@@ -1364,8 +1599,6 @@ Returns the number of nodes contained in the node list that starts at \type {n}.
If \type {m} is also supplied it stops at \type {m} instead of at the end of the
list. The node \type {m} is not counted.
-\subsubsection{\type {node.count}}
-
\startfunctioncall
<number> i =
node.count(<number> id, <node> n)
@@ -1376,14 +1609,29 @@ list. The node \type {m} is not counted.
Returns the number of nodes contained in the node list that starts at \type {n}
that have a matching \type {id} field. If \type {m} is also supplied, counting
stops at \type {m} instead of at the end of the list. The node \type {m} is not
-counted.
+counted. This function also accept string \type {id}'s.
+
+\subsection{\type {is_char} and \type {is_glyph}}
-This function also accept string \type {id}'s.
+\libindex {is_char}
+\libindex {is_glyph}
-\subsubsection{\type {node.traverse}}
+The subtype of a glyph node signals if the glyph is already turned into a character reference
+or not.
\startfunctioncall
-<node> t =
+<boolean> b =
+ node.is_char(<node> n)
+<boolean> b =
+ node.is_glyph(<node> n)
+\stopfunctioncall
+
+\subsection{\type {traverse}}
+
+\libindex {traverse}
+
+\startfunctioncall
+<node> t, id, subtype =
node.traverse(<node> n)
\stopfunctioncall
@@ -1426,10 +1674,12 @@ pointers remain valid.
If the above is unclear to you, see the section \quote {For Statement} in the
\LUA\ Reference Manual.
-\subsubsection{\type {node.traverse_id}}
+\subsection{\type {traverse_id}}
+
+\libindex {traverse_id}
\startfunctioncall
-<node> t =
+<node> t, subtype =
node.traverse_id(<number> id, <node> n)
\stopfunctioncall
@@ -1454,17 +1704,45 @@ See the previous section for details. The change is in the local function \type
end
\stoptyping
-\subsubsection{\type {node.traverse_char}}
+\subsection{\type {traverse_char} and \type {traverse_glyph}}
+
+\libindex {traverse_char}
+\libindex {traverse_glyph}
-This iterators loops over the glyph nodes in a list. Only nodes with a subtype
-less than 256 are seen.
+The \type{traverse_char} iterator loops over the \nod {glyph} nodes in a list.
+Only nodes with a subtype less than 256 are seen.
\startfunctioncall
-<node> n =
+<node> n, font, char =
node.traverse_char(<node> n)
\stopfunctioncall
-\subsubsection{\type {node.has_glyph}}
+The \type{traverse_glyph} iterator loops over a list and returns the list and
+filters all glyphs:
+
+\startfunctioncall
+<node> n, font, char =
+ node.traverse_glyph(<node> n)
+\stopfunctioncall
+
+\subsection{\type {traverse_list}}
+
+\libindex {traverse_list}
+
+This iterator loops over the \nod {hlist} and \nod {vlist} nodes in a list.
+
+\startfunctioncall
+<node> n, id, subtype, list =
+ node.traverse_list(<node> n)
+\stopfunctioncall
+
+The four return values can save some time compared to fetching these fields but
+in practice you seldom need them all. So consider it a (side effect of
+experimental) convenience.
+
+\subsection{\type {has_glyph}}
+
+\libindex {has_glyph}
This function returns the first glyph or disc node in the given list:
@@ -1473,7 +1751,9 @@ This function returns the first glyph or disc node in the given list:
node.has_glyph(<node> n)
\stopfunctioncall
-\subsubsection{\type {node.end_of_math}}
+\subsection{\type {end_of_math}}
+
+\libindex {end_of_math}
\startfunctioncall
<node> t =
@@ -1481,11 +1761,13 @@ This function returns the first glyph or disc node in the given list:
\stopfunctioncall
Looks for and returns the next \type {math_node} following the \type {start}. If
-the given node is a math endnode this helper return that node, else it follows
-the list and return the next math endnote. If no such node is found nil is
+the given node is a math end node this helper returns that node, else it follows
+the list and returns the next math endnote. If no such node is found nil is
returned.
-\subsubsection{\type {node.remove}}
+\subsection{\type {remove}}
+
+\libindex {remove}
\startfunctioncall
<node> head, current =
@@ -1501,7 +1783,9 @@ no such node). The returned \type {head} is more important, because if the
function is called with \type {current} equal to \type {head}, it will be
changed.
-\subsubsection{\type {node.insert_before}}
+\subsection{\type {insert_before}}
+
+\libindex {insert_before}
\startfunctioncall
<node> head, new =
@@ -1515,7 +1799,9 @@ mutated) \type {head} and the node \type {new}, set up to be part of the list
(with correct \type {next} field). If \type {head} is initially \type {nil}, it
will become \type {new}.
-\subsubsection{\type {node.insert_after}}
+\subsection{\type {insert_after}}
+
+\libindex {insert_after}
\startfunctioncall
<node> head, new =
@@ -1528,7 +1814,9 @@ following \type {head}. It is your responsibility to make sure that \type
the node \type {new}, set up to be part of the list (with correct \type {next}
field). If \type {head} is initially \type {nil}, it will become \type {new}.
-\subsubsection{\type {node.first_glyph}}
+\subsection{\type {first_glyph}}
+
+\libindex {first_glyph}
\startfunctioncall
<node> n =
@@ -1542,7 +1830,9 @@ with a subtype indicating it is a glyph, or \type {nil}. If \type {m} is given,
processing stops at (but including) that node, otherwise processing stops at the
end of the list.
-\subsubsection{\type {node.ligaturing}}
+\subsection{\type {ligaturing}}
+
+\libindex {ligaturing}
\startfunctioncall
<node> h, <node> t, <boolean> success =
@@ -1555,7 +1845,9 @@ Apply \TEX-style ligaturing to the specified nodelist. The tail node \type {m} i
optional. The two returned nodes \type {h} and \type {t} are the new head and
tail (both \type {n} and \type {m} can change into a new ligature).
-\subsubsection{\type {node.kerning}}
+\subsection{\type {kerning}}
+
+\libindex {kerning}
\startfunctioncall
<node> h, <node> t, <boolean> success =
@@ -1569,7 +1861,10 @@ optional. The two returned nodes \type {h} and \type {t} are the head and tail
(either one of these can be an inserted kern node, because special kernings with
word boundaries are possible).
-\subsubsection{\type {node.unprotect_glyphs} and \type {node.unprotect_glyph}}
+\subsection{\type {unprotect_glyph[s]}}
+
+\libindex {unprotect_glyphs}
+\libindex {unprotect_glyph}
\startfunctioncall
node.unprotect_glyph(<node> n)
@@ -1578,9 +1873,12 @@ node.unprotect_glyphs(<node> n,[<node> n])
Subtracts 256 from all glyph node subtypes. This and the next function are
helpers to convert from \type {characters} to \type {glyphs} during node
-processing. The second argument is option and indicates the end of a range.
+processing. The second argument is optional and indicates the end of a range.
-\subsubsection{\type {node.protect_glyphs} and \type {node.protect_glyph}}
+\subsection{\type {protect_glyph[s]}}
+
+\libindex {protect_glyphs}
+\libindex {protect_glyph}
\startfunctioncall
node.protect_glyph(<node> n)
@@ -1591,9 +1889,11 @@ Adds 256 to all glyph node subtypes in the node list starting at \type {n},
except that if the value is 1, it adds only 255. The special handling of 1 means
that \type {characters} will become \type {glyphs} after subtraction of 256. A
single character can be marked by the singular call. The second argument is
-option and indicates the end of a range.
+optional and indicates the end of a range.
+
+\subsection{\type {last_node}}
-\subsubsection{\type {node.last_node}}
+\libindex {last_node}
\startfunctioncall
<node> n =
@@ -1603,17 +1903,21 @@ option and indicates the end of a range.
This function pops the last node from \TEX's \quote{current list}. It returns
that node, or \type {nil} if the current list is empty.
-\subsubsection{\type {node.write}}
+\subsection{\type {write}}
+
+\libindex {write}
\startfunctioncall
node.write(<node> n)
\stopfunctioncall
-This is an experimental function that will append a node list to \TEX's \quote
-{current list} The node list is not deep|-|copied! There is no error checking
-either!
+This function that will append a node list to \TEX's \quote {current list}. The
+node list is not deep|-|copied! There is no error checking either! You mignt need
+to enforce horizontal mode in order for this to work as expected.
+
+\subsection{\type {protrusion_skippable}}
-\subsubsection{\type {node.protrusion_skippable}}
+\libindex {protrusion_skippable}
\startfunctioncall
<boolean> skippable =
@@ -1623,9 +1927,13 @@ either!
Returns \type {true} if, for the purpose of line boundary discovery when
character protrusion is active, this node can be skipped.
-\subsection{Glue handling}
+\stopsection
+
+\startsection[title={Glue handling}][library=node]
-\subsubsection{\type {node.setglue}}
+\subsection{\type {setglue}}
+
+\libindex {setglue}
You can set the properties of a glue in one go. If you pass no values, the glue
will become a zero glue.
@@ -1645,9 +1953,11 @@ will only adapt the width and shrink.
When a list node is passed, you set the glue, order and sign instead.
-\subsubsection{\type {node.getglue}}
+\subsection{\type {getglue}}
+
+\libindex {getglue}
-The next call will return 5 values (or northing when no glue is passed).
+The next call will return 5 values or nothing when no glue is passed.
\startfunctioncall
<integer> width, <integer> stretch, <integer> shrink, <integer> stretch_order,
@@ -1660,7 +1970,9 @@ with \type {tex.get}).
When a list node is passed, you get back the glue that is set, the order of that
glue and the sign.
-\subsubsection{\type {node.is_zero_glue}}
+\subsection{\type {is_zero_glue}}
+
+\libindex {is_zero_glue}
This function returns \type {true} when the width, stretch and shrink properties
are zero.
@@ -1670,13 +1982,61 @@ are zero.
node.is_zero_glue(<node> n)
\stopfunctioncall
-\subsection{Attribute handling}
+\stopsection
+
+\startsection[title={Attribute handling}][library=node]
+
+\subsection{Attributes}
+
+\topicindex {attributes}
+
+The newly introduced attribute registers are non|-|trivial, because the value
+that is attached to a node is essentially a sparse array of key|-|value pairs. It
+is generally easiest to deal with attribute lists and attributes by using the
+dedicated functions in the \type {node} library, but for completeness, here is
+the low|-|level interface.
Attributes appear as linked list of userdata objects in the \type {attr} field of
individual nodes. They can be handled individually, but it is much safer and more
efficient to use the dedicated functions associated with them.
-\subsubsection{\type {node.has_attribute}}
+\subsection{\nod {attribute_list} nodes}
+
+\topicindex {nodes+attributes}
+
+An \nod {attribute_list} item is used as a head pointer for a list of attribute
+items. It has only one user-visible field:
+
+\starttabulate[|l|l|p|]
+\DB field \BC type \BC explanation \NC \NR
+\TB
+\NC \type{next} \NC node \NC pointer to the first attribute \NC \NR
+\LL
+\stoptabulate
+
+\subsection{\nod {attr} nodes}
+
+A normal node's attribute field will point to an item of type \nod
+{attribute_list}, and the \type {next} field in that item will point to the first
+defined \quote {attribute} item, whose \type {next} will point to the second
+\quote {attribute} item, etc.
+
+\starttabulate[|l|l|p|]
+\DB field \BC type \BC explanation \NC \NR
+\TB
+\NC \type{next} \NC node \NC pointer to the next attribute \NC \NR
+\NC \type{number} \NC number \NC the attribute type id \NC \NR
+\NC \type{value} \NC number \NC the attribute value \NC \NR
+\LL
+\stoptabulate
+
+As mentioned it's better to use the official helpers rather than edit these
+fields directly. For instance the \type {prev} field is used for other purposes
+and there is no double linked list.
+
+\subsection{\type {has_attribute}}
+
+\libindex {has_attribute}
\startfunctioncall
<number> v =
@@ -1689,7 +2049,9 @@ Tests if a node has the attribute with number \type {id} set. If \type {val} is
also supplied, also tests if the value matches \type {val}. It returns the value,
or, if no match is found, \type {nil}.
-\subsubsection{\type {node.get_attribute}}
+\subsection{\type {get_attribute}}
+
+\libindex {get_attribute}
\startfunctioncall
<number> v =
@@ -1697,9 +2059,12 @@ or, if no match is found, \type {nil}.
\stopfunctioncall
Tests if a node has an attribute with number \type {id} set. It returns the
-value, or, if no match is found, \type {nil}.
+value, or, if no match is found, \type {nil}. If no \type {id} is given then the
+zero attributes is assumed.
+
+\subsection{\type {find_attribute}}
-\subsubsection{\type {node.find_attribute}}
+\libindex {find_attribute}
\startfunctioncall
<number> v, <node> n =
@@ -1709,7 +2074,9 @@ value, or, if no match is found, \type {nil}.
Finds the first node that has attribute with number \type {id} set. It returns
the value and the node if there is a match and otherwise nothing.
-\subsubsection{\type {node.set_attribute}}
+\subsection{\type {set_attribute}}
+
+\libindex {set_attribute}
\startfunctioncall
node.set_attribute(<node> n, <number> id, <number> val)
@@ -1718,7 +2085,9 @@ node.set_attribute(<node> n, <number> id, <number> val)
Sets the attribute with number \type {id} to the value \type {val}. Duplicate
assignments are ignored.
-\subsubsection{\type {node.unset_attribute}}
+\subsection{\type {unset_attribute}}
+
+\libindex {unset_attribute}
\startfunctioncall
<number> v =
@@ -1734,7 +2103,9 @@ attributes or attribute|-|value pairs are ignored.
If the attribute was actually deleted, returns its old value. Otherwise, returns
\type {nil}.
-\subsubsection{\type {node.slide}}
+\subsection{\type {slide}}
+
+\libindex {slide}
This helper makes sure that the node lists is double linked and returns the found
tail node.
@@ -1751,13 +2122,16 @@ pointers but your other callbacks might expect proper \type {prev} pointers too.
Future versions of \LUATEX\ can add more checking but this will not influence
usage.
-\subsubsection{\type {node.check_discretionary} and \type {node.check_discretionaries}}
+\subsection{\type {check_discretionary}, \type {check_discretionaries}}
+
+\libindex{check_discretionary}
+\libindex{check_discretionaries}
When you fool around with disc nodes you need to be aware of the fact that they
have a special internal data structure. As long as you reassign the fields when
you have extended the lists it's ok because then the tail pointers get updated,
-but when you add to list without reassigning you might end up in troubles when
-the linebreak routien kicks in. You can call this function to check the list for
+but when you add to list without reassigning you might end up in trouble when
+the linebreak routine kicks in. You can call this function to check the list for
issues with disc nodes.
\startfunctioncall
@@ -1768,7 +2142,9 @@ node.check_discretionaries(<node> head)
The plural variant runs over all disc nodes in a list, the singular variant
checks one node only (it also checks if the node is a disc node).
-\subsubsection{\type {node.flatten_discretionaries}}
+\subsection{\type {flatten_discretionaries}}
+
+\libindex {flatten_discretionaries}
This function will remove the discretionaries in the list and inject the replace
field when set.
@@ -1777,45 +2153,51 @@ field when set.
<node> head, count = node.flatten_discretionaries(<node> n)
\stopfunctioncall
-\subsubsection{\type {node.family_font}}
+\subsection{\type {family_font}}
+
+\libindex {family_font}
-When you pass it a proper family identifier the next helper will return the font
-currently associated with it. You can normally also access the font with the normal
-font field or getter because it will resolve the family automatically for noads.
+When you pass a proper family identifier the next helper will return the font
+currently associated with it. You can normally also access the font with the
+normal font field or getter because it will resolve the family automatically for
+noads.
\startfunctioncall
<integer> id =
node.family_font(<integer> fam)
\stopfunctioncall
-\subsubsection{\type {node.set_synctex_fields} and \type {node.get_synctex_fields}}
-
-You can set and query the synctex fields, a file number aka tag and a line
-number, for a glue, kern, hlist, vlist, rule and math nodes as well as glyph
-nodes (although this last one are not used in native synctex).
+\stopsection
-\startfunctioncall
-node.set_synctex_fields(<integer> f, <integer> l)
-<integer> f, <integer> l =
- node.get_synctex_fields(<node> n)
-\stopfunctioncall
+\startsection[title={Two access models}][library=node]
-Of course you need to know what you're doing as no checking on sane values takes
-place. Also, the synctex interpreter used in editors is rather peculiar and has
-some assumptions (heuristics).
+\topicindex{nodes+direct}
+\topicindex{direct nodes}
-\section{Two access models}
+\libindex {todirect}
+\libindex {tonode}
+\libindex {tostring}
-Deep down in \TEX\ a node has a number which is an numeric entry in a memory
+Deep down in \TEX\ a node has a number which is a numeric entry in a memory
table. In fact, this model, where \TEX\ manages memory is real fast and one of
the reasons why plugging in callbacks that operate on nodes is quite fast too.
Each node gets a number that is in fact an index in the memory table and that
-number often gets reported when you print node related information.
+number often is reported when you print node related information. You go from
+userdata nodes and there numeric references and back with:
+
+\startfunctioncall
+<integer> d = node.todirect(<node> n))
+<node> n = node.tonode(<integer> d))
+\stopfunctioncall
+
+The userdata model is rather robust as it is a virtual interface with some
+additional checking while the more direct access which uses the node numbers
+directly. However, even with userdata you can get into troubles when you free
+nodes that are no longer allocated or mess up lists. if you apply \type
+{tostring} to a node you see its internal (direct) number and id.
-There are two access models, a robust one using a so called user data object that
-provides a virtual interface to the internal nodes, and a more direct access which
-uses the node numbers directly. The first model provide key based access while
-the second always accesses fields via functions:
+The first model provides key based access while the second always accesses fields
+via functions:
\starttyping
nodeobject.char
@@ -1823,19 +2205,19 @@ getfield(nodenumber,"char")
\stoptyping
If you use the direct model, even if you know that you deal with numbers, you
-should not depend on that property but treat it an abstraction just like
+should not depend on that property but treat it as an abstraction just like
traditional nodes. In fact, the fact that we use a simple basic datatype has the
penalty that less checking can be done, but less checking is also the reason why
it's somewhat faster. An important aspect is that one cannot mix both methods,
but you can cast both models. So, multiplying a node number makes no sense.
So our advice is: use the indexed (table) approach when possible and investigate
-the direct one when speed might be an real issue. For that reason we also provide
-the \type {get*} and \type {set*} functions in the top level node namespace.
-There is a limited set of getters. When implementing this direct approach the
-regular index by key variant was also optimized, so direct access only makes
-sense when we're accessing nodes millions of times (which happens in some font
-processing for instance).
+the direct one when speed might be a real issue. For that reason \LUATEX\ also
+provide the \type {get*} and \type {set*} functions in the top level node
+namespace. There is a limited set of getters. When implementing this direct
+approach the regular index by key variant was also optimized, so direct access
+only makes sense when nodes are accessed millions of times (which happens in some
+font processing for instance).
We're talking mostly of getters because setters are less important. Documents
have not that many content related nodes and setting many thousands of properties
@@ -1873,8 +2255,10 @@ end
Some accessors are used frequently and for these we provide more efficient helpers:
\starttabulate[|l|p|]
+\DB function \BC explanation \NC \NR
+\TB
\NC \type{getnext} \NC parsing nodelist always involves this one \NC \NR
-\NC \type{getprev} \NC used less but is logical companion to \type {getnext} \NC \NR
+\NC \type{getprev} \NC used less but a logical companion to \type {getnext} \NC \NR
\NC \type{getboth} \NC returns the next and prev pointer of a node \NC \NR
\NC \type{getid} \NC consulted a lot \NC \NR
\NC \type{getsubtype} \NC consulted less but also a topper \NC \NR
@@ -1883,13 +2267,16 @@ Some accessors are used frequently and for these we provide more efficient helpe
\NC \type{getwhd} \NC returns the \type {width}, \type {height} and \type {depth} of a list, rule or
(unexpanded) glyph as well as glue (its spec is looked at) and unset nodes\NC \NR
\NC \type{getdisc} \NC returns the \type {pre}, \type {post} and \type {replace} fields and
- optionally when true is passed also the tail fields. \NC \NR
+ optionally when true is passed also the tail fields \NC \NR
\NC \type{getlist} \NC we often parse nested lists so this is a convenient one too \NC \NR
\NC \type{getleader} \NC comparable to list, seldom used in \TEX\ (but needs frequent consulting
like lists; leaders could have been made a dedicated node type) \NC \NR
\NC \type{getfield} \NC generic getter, sufficient for the rest (other field names are
often shared so a specific getter makes no sense then) \NC \NR
\NC \type{getbox} \NC gets the given box (a list node) \NC \NR
+\NC \type{getoffsets} \NC gets the \type {xoffset} and \type {yoffset} of a glyph or
+ \type {left} and \type {right} values of a rule \NC \NR
+\LL
\stoptabulate
In the direct namespace there are more such helpers and most of them are
@@ -1910,145 +2297,157 @@ directmode setter \type {setlink} takes a list of nodes and will link them,
thereby ignoring \type {nil} entries. The first valid node is returned (beware:
for good reason it assumes single nodes). For rarely used fields no helpers are
provided and there are a few that probably are used seldom too but were added for
-consistency. You can of course always define additional accessor using \type
-{getfield} and \type {setfield} with little overhead.
-
-% \startcolumns[balance=yes]
+consistency. You can of course always define additional accessors using \type
+{getfield} and \type {setfield} with little overhead. When the second argument of
+\type {setattributelist} is \type {true} the current attribute list is assumed.
\def\yes{$+$} \def\nop{$-$}
+\def\supported#1#2#3%
+ {\NC \type{#1}
+ \NC \ifx#2\yes\libidx{node} {#1}\fi #2
+ \NC \ifx#3\yes\libidx{node.direct}{#1}\fi #3 \NC
+ \NR}
+
\starttabulate[|l|c|c|]
-\HL
-\BC function \BC node \BC direct \NC \NR
-\HL
-%NC \type {do_ligature_n} \NC \yes \NC \yes \NC \NR % was never documented and experimental
-\NC \type {check_discretionaries}\NC \yes \NC \yes \NC \NR
-\NC \type {copy_list} \NC \yes \NC \yes \NC \NR
-\NC \type {copy} \NC \yes \NC \yes \NC \NR
-\NC \type {count} \NC \yes \NC \yes \NC \NR
-\NC \type {current_attr} \NC \yes \NC \yes \NC \NR
-\NC \type {dimensions} \NC \yes \NC \yes \NC \NR
-\NC \type {effective_glue} \NC \yes \NC \yes \NC \NR
-\NC \type {end_of_math} \NC \yes \NC \yes \NC \NR
-\NC \type {family_font} \NC \yes \NC \nop \NC \NR
-\NC \type {fields} \NC \yes \NC \nop \NC \NR
-\NC \type {find_attribute} \NC \yes \NC \yes \NC \NR
-\NC \type {first_glyph} \NC \yes \NC \yes \NC \NR
-\NC \type {flush_list} \NC \yes \NC \yes \NC \NR
-\NC \type {flush_node} \NC \yes \NC \yes \NC \NR
-\NC \type {free} \NC \yes \NC \yes \NC \NR
-\NC \type {get_attribute} \NC \yes \NC \yes \NC \NR
-\NC \type {getattributelist} \NC \nop \NC \yes \NC \NR
-\NC \type {getboth} \NC \yes \NC \yes \NC \NR
-\NC \type {getbox} \NC \nop \NC \yes \NC \NR
-\NC \type {getchar} \NC \yes \NC \yes \NC \NR
-\NC \type {getcomponents} \NC \nop \NC \yes \NC \NR
-\NC \type {getdepth} \NC \nop \NC \yes \NC \NR
-\NC \type {getdir} \NC \nop \NC \yes \NC \NR
-\NC \type {getdisc} \NC \yes \NC \yes \NC \NR
-\NC \type {getfam} \NC \nop \NC \yes \NC \NR
-\NC \type {getfield} \NC \yes \NC \yes \NC \NR
-\NC \type {getfont} \NC \yes \NC \yes \NC \NR
-\NC \type {getglue} \NC \yes \NC \yes \NC \NR
-\NC \type {getheight} \NC \nop \NC \yes \NC \NR
-\NC \type {getid} \NC \yes \NC \yes \NC \NR
-\NC \type {getkern} \NC \nop \NC \yes \NC \NR
-\NC \type {getlang} \NC \nop \NC \yes \NC \NR
-\NC \type {getleader} \NC \yes \NC \yes \NC \NR
-\NC \type {getlist} \NC \yes \NC \yes \NC \NR
-\NC \type {getnext} \NC \yes \NC \yes \NC \NR
-\NC \type {getnucleus} \NC \nop \NC \yes \NC \NR
-\NC \type {getoffsets} \NC \nop \NC \yes \NC \NR
-\NC \type {getpenalty} \NC \nop \NC \yes \NC \NR
-\NC \type {getprev} \NC \yes \NC \yes \NC \NR
-\NC \type {getproperty} \NC \yes \NC \yes \NC \NR
-\NC \type {getshift} \NC \nop \NC \yes \NC \NR
-\NC \type {getwidth} \NC \nop \NC \yes \NC \NR
-\NC \type {getwhd} \NC \nop \NC \yes \NC \NR
-\NC \type {getsub} \NC \nop \NC \yes \NC \NR
-\NC \type {getsubtype} \NC \yes \NC \yes \NC \NR
-\NC \type {getsup} \NC \nop \NC \yes \NC \NR
-\NC \type {has_attribute} \NC \yes \NC \yes \NC \NR
-\NC \type {has_field} \NC \yes \NC \yes \NC \NR
-\NC \type {has_glyph} \NC \yes \NC \yes \NC \NR
-\NC \type {hpack} \NC \yes \NC \yes \NC \NR
-\NC \type {id} \NC \yes \NC \nop \NC \NR
-\NC \type {insert_after} \NC \yes \NC \yes \NC \NR
-\NC \type {insert_before} \NC \yes \NC \yes \NC \NR
-\NC \type {is_char} \NC \yes \NC \yes \NC \NR
-\NC \type {is_direct} \NC \nop \NC \yes \NC \NR
-\NC \type {is_glue_zero} \NC \yes \NC \yes \NC \NR
-\NC \type {is_glyph} \NC \yes \NC \yes \NC \NR
-\NC \type {is_node} \NC \yes \NC \yes \NC \NR
-\NC \type {kerning} \NC \yes \NC \yes \NC \NR
-\NC \type {last_node} \NC \yes \NC \yes \NC \NR
-\NC \type {length} \NC \yes \NC \yes \NC \NR
-\NC \type {ligaturing} \NC \yes \NC \yes \NC \NR
-\NC \type {mlist_to_hlist} \NC \yes \NC \nop \NC \NR
-\NC \type {new} \NC \yes \NC \yes \NC \NR
-\NC \type {next} \NC \yes \NC \nop \NC \NR
-\NC \type {prev} \NC \yes \NC \nop \NC \NR
-\NC \type {protect_glyphs} \NC \yes \NC \yes \NC \NR
-\NC \type {protect_glyph} \NC \yes \NC \yes \NC \NR
-\NC \type {protrusion_skippable} \NC \yes \NC \yes \NC \NR
-\NC \type {rangedimensions} \NC \yes \NC \yes \NC \NR
-\NC \type {remove} \NC \yes \NC \yes \NC \NR
-\NC \type {set_attribute} \NC \nop \NC \yes \NC \NR
-\NC \type {setattributelist} \NC \nop \NC \yes \NC \NR
-\NC \type {setboth} \NC \nop \NC \yes \NC \NR
-\NC \type {setbox} \NC \nop \NC \yes \NC \NR
-\NC \type {setchar} \NC \nop \NC \yes \NC \NR
-\NC \type {setcomponents} \NC \nop \NC \yes \NC \NR
-\NC \type {setdepth} \NC \nop \NC \yes \NC \NR
-\NC \type {setdir} \NC \nop \NC \yes \NC \NR
-\NC \type {setdisc} \NC \nop \NC \yes \NC \NR
-\NC \type {setfield} \NC \yes \NC \yes \NC \NR
-\NC \type {setfont} \NC \nop \NC \yes \NC \NR
-\NC \type {setglue} \NC \yes \NC \yes \NC \NR
-\NC \type {setheight} \NC \nop \NC \yes \NC \NR
-\NC \type {setid} \NC \nop \NC \yes \NC \NR
-\NC \type {setkern} \NC \nop \NC \yes \NC \NR
-\NC \type {setlang} \NC \nop \NC \yes \NC \NR
-\NC \type {setleader} \NC \nop \NC \yes \NC \NR
-\NC \type {setlist} \NC \nop \NC \yes \NC \NR
-\NC \type {setnext} \NC \nop \NC \yes \NC \NR
-\NC \type {setnucleus} \NC \nop \NC \yes \NC \NR
-\NC \type {setoffsets} \NC \nop \NC \yes \NC \NR
-\NC \type {setpenalty} \NC \nop \NC \yes \NC \NR
-\NC \type {setprev} \NC \nop \NC \yes \NC \NR
-\NC \type {setproperty} \NC \nop \NC \yes \NC \NR
-\NC \type {setshift} \NC \nop \NC \yes \NC \NR
-\NC \type {setwidth} \NC \nop \NC \yes \NC \NR
-\NC \type {setwhd} \NC \nop \NC \yes \NC \NR
-\NC \type {setsub} \NC \nop \NC \yes \NC \NR
-\NC \type {setsubtype} \NC \nop \NC \yes \NC \NR
-\NC \type {setsup} \NC \nop \NC \yes \NC \NR
-\NC \type {slide} \NC \yes \NC \yes \NC \NR
-\NC \type {subtypes} \NC \yes \NC \nop \NC \NR
-\NC \type {subtype} \NC \yes \NC \nop \NC \NR
-\NC \type {tail} \NC \yes \NC \yes \NC \NR
-\NC \type {todirect} \NC \yes \NC \yes \NC \NR
-\NC \type {tonode} \NC \yes \NC \yes \NC \NR
-\NC \type {tostring} \NC \yes \NC \yes \NC \NR
-\NC \type {traverse_char} \NC \yes \NC \yes \NC \NR
-\NC \type {traverse_id} \NC \yes \NC \yes \NC \NR
-\NC \type {traverse} \NC \yes \NC \yes \NC \NR
-\NC \type {types} \NC \yes \NC \nop \NC \NR
-\NC \type {type} \NC \yes \NC \nop \NC \NR
-\NC \type {unprotect_glyphs} \NC \yes \NC \yes \NC \NR
-\NC \type {unset_attribute} \NC \yes \NC \yes \NC \NR
-\NC \type {usedlist} \NC \yes \NC \yes \NC \NR
-\NC \type {uses_font} \NC \yes \NC \yes \NC \NR
-\NC \type {vpack} \NC \yes \NC \yes \NC \NR
-\NC \type {whatsitsubtypes} \NC \yes \NC \nop \NC \NR
-\NC \type {whatsits} \NC \yes \NC \nop \NC \NR
-\NC \type {write} \NC \yes \NC \yes \NC \NR
-\NC \type {set_synctex_fields} \NC \yes \NC \yes \NC \NR
-\NC \type {get_synctex_fields} \NC \yes \NC \yes \NC \NR
+\DB function \BC node \BC direct \NC \NR
+\TB
+\supported {check_discretionaries} \yes \yes
+\supported {check_discretionary} \yes \yes
+\supported {copy_list} \yes \yes
+\supported {copy} \yes \yes
+\supported {count} \yes \yes
+\supported {current_attr} \yes \yes
+\supported {dimensions} \yes \yes
+\supported {effective_glue} \yes \yes
+\supported {end_of_math} \yes \yes
+\supported {family_font} \yes \nop
+\supported {fields} \yes \nop
+\supported {find_attribute} \yes \yes
+\supported {first_glyph} \yes \yes
+\supported {flatten_discretionaries} \yes \yes
+\supported {flush_list} \yes \yes
+\supported {flush_node} \yes \yes
+\supported {free} \yes \yes
+\supported {get_attribute} \yes \yes
+\supported {get_synctex_fields} \nop \yes
+\supported {getattributelist} \nop \yes
+\supported {getboth} \yes \yes
+\supported {getbox} \nop \yes
+\supported {getchar} \yes \yes
+\supported {getcomponents} \nop \yes
+\supported {getdepth} \nop \yes
+\supported {getdirection} \nop \yes
+\supported {getdir} \nop \yes
+\supported {getdisc} \yes \yes
+\supported {getfam} \nop \yes
+\supported {getfield} \yes \yes
+\supported {getfont} \yes \yes
+\supported {getglue} \yes \yes
+\supported {getheight} \nop \yes
+\supported {getid} \yes \yes
+\supported {getkern} \nop \yes
+\supported {getlang} \nop \yes
+\supported {getleader} \yes \yes
+\supported {getlist} \yes \yes
+\supported {getnext} \yes \yes
+\supported {getnucleus} \nop \yes
+\supported {getoffsets} \nop \yes
+\supported {getpenalty} \nop \yes
+\supported {getprev} \yes \yes
+\supported {getproperty} \yes \yes
+\supported {getshift} \nop \yes
+\supported {getsubtype} \yes \yes
+\supported {getsub} \nop \yes
+\supported {getsup} \nop \yes
+\supported {getdata} \nop \yes
+\supported {getwhd} \yes \yes
+\supported {getwidth} \nop \yes
+\supported {has_attribute} \yes \yes
+\supported {has_field} \yes \yes
+\supported {has_glyph} \yes \yes
+\supported {hpack} \yes \yes
+\supported {id} \yes \nop
+\supported {insert_after} \yes \yes
+\supported {insert_before} \yes \yes
+\supported {is_char} \yes \yes
+\supported {is_direct} \nop \yes
+\supported {is_glyph} \yes \yes
+\supported {is_node} \yes \yes
+\supported {is_zero_glue} \yes \yes
+\supported {kerning} \yes \yes
+\supported {last_node} \yes \yes
+\supported {length} \yes \yes
+\supported {ligaturing} \yes \yes
+\supported {mlist_to_hlist} \yes \nop
+\supported {new} \yes \yes
+\supported {next} \yes \nop
+\supported {prepend_prevdepth} \nop \yes
+\supported {prev} \yes \nop
+\supported {protect_glyphs} \yes \yes
+\supported {protect_glyph} \yes \yes
+\supported {protrusion_skippable} \yes \yes
+\supported {rangedimensions} \yes \yes
+\supported {remove} \yes \yes
+\supported {set_attribute} \yes \yes
+\supported {set_synctex_fields} \nop \yes
+\supported {setattributelist} \nop \yes
+\supported {setboth} \nop \yes
+\supported {setbox} \nop \yes
+\supported {setchar} \nop \yes
+\supported {setcomponents} \nop \yes
+\supported {setdepth} \nop \yes
+\supported {setdirection} \nop \yes
+\supported {setdir} \nop \yes
+\supported {setdisc} \nop \yes
+\supported {setfam} \nop \yes
+\supported {setfield} \yes \yes
+\supported {setfont} \nop \yes
+\supported {setexpansion} \nop \yes
+\supported {setglue} \yes \yes
+\supported {setheight} \nop \yes
+\supported {setkern} \nop \yes
+\supported {setlang} \nop \yes
+\supported {setleader} \nop \yes
+\supported {setlink} \nop \yes
+\supported {setlist} \nop \yes
+\supported {setnext} \nop \yes
+\supported {setnucleus} \nop \yes
+\supported {setoffsets} \nop \yes
+\supported {setpenalty} \nop \yes
+\supported {setprev} \nop \yes
+\supported {setproperty} \yes \yes
+\supported {setshift} \nop \yes
+\supported {setsplit} \nop \yes
+\supported {setsubtype} \nop \yes
+\supported {setsub} \nop \yes
+\supported {setsup} \nop \yes
+\supported {setwhd} \nop \yes
+\supported {setwidth} \nop \yes
+\supported {slide} \yes \yes
+\supported {subtypes} \yes \nop
+\supported {subtype} \yes \nop
+\supported {tail} \yes \yes
+\supported {todirect} \yes \yes
+\supported {tonode} \yes \yes
+\supported {tostring} \yes \yes
+\supported {traverse_char} \yes \yes
+\supported {traverse_glyph} \yes \yes
+\supported {traverse_id} \yes \yes
+\supported {traverse} \yes \yes
+\supported {types} \yes \nop
+\supported {type} \yes \nop
+\supported {unprotect_glyphs} \yes \yes
+\supported {unprotect_glyph} \yes \yes
+\supported {unset_attribute} \yes \yes
+\supported {usedlist} \yes \yes
+\supported {uses_font} \yes \yes
+\supported {vpack} \yes \yes
+\supported {whatsits} \yes \nop
+\supported {write} \yes \yes
+\LL
\stoptabulate
-% \stopcolumns
-
The \type {node.next} and \type {node.prev} functions will stay but for
consistency there are variants called \type {getnext} and \type {getprev}. We had
to use \type {get} because \type {node.id} and \type {node.subtype} are already
@@ -2056,6 +2455,13 @@ taken for providing meta information about nodes. Note: The getters do only basi
checking for valid keys. You should just stick to the keys mentioned in the
sections that describe node properties.
+Some of the getters and setters handle multiple node types, given that the field
+is relevant. In that case, some field names are considered similar (like \type
+{kern} and \type {width}, or \type {data} and \type {value}. In retrospect we
+could have normalized field names better but we decided to stick to the original
+(internal) names as much as possible. After all, at the \LUA\ end one can easily
+create synonyms.
+
Some nodes have indirect references. For instance a math character refers to a
family instead of a font. In that case we provide a virtual font field as
accessor. So, \type {getfont} and \type {.font} can be used on them. The same is
@@ -2063,6 +2469,196 @@ true for the \type {width}, \type {height} and \type {depth} of glue nodes. Thes
actually access the spec node properties, and here we can set as well as get the
values.
+In some places \LUATEX\ can do a bit of extra checking for valid node lists and
+you can enable that with:
+
+\startfunctioncall
+node.fix_node_lists(<boolean> b)
+\stopfunctioncall
+
+You can set and query the \SYNCTEX\ fields, a file number aka tag and a line
+number, for a glue, kern, hlist, vlist, rule and math nodes as well as glyph
+nodes (although this last one is not used in native \SYNCTEX).
+
+\startfunctioncall
+node.set_synctex_fields(<integer> f, <integer> l)
+<integer> f, <integer> l =
+ node.get_synctex_fields(<node> n)
+\stopfunctioncall
+
+Of course you need to know what you're doing as no checking on sane values takes
+place. Also, the synctex interpreter used in editors is rather peculiar and has
+some assumptions (heuristics).
+
+\stopsection
+
+\startsection[title={Properties}][library=node]
+
+\topicindex {nodes+properties}
+\topicindex {properties}
+
+\libindex{flush_properties_table}
+\libindex{get_properties_table}
+\libindex{set_properties_mode}
+
+Attributes are a convenient way to relate extra information to a node. You can
+assign them at the \TEX\ end as well as at the \LUA\ end and and consult them at
+the \LUA\ end. One big advantage is that they obey grouping. They are linked
+lists and normally checking for them is pretty efficient, even if you use a lot
+of them. A macro package has to provide some way to manage these attributes at the
+\TEX\ end because otherwise clashes in their usage can occur.
+
+Each node also can have a properties table and you can assign values to this
+table using the \type {setproperty} function and get properties using the \type
+{getproperty} function. Managing properties is way more demanding than managing
+attributes.
+
+Take the following example:
+
+\starttyping
+\directlua {
+ local n = node.new("glyph")
+
+ node.setproperty(n,"foo")
+ print(node.getproperty(n))
+
+ node.setproperty(n,"bar")
+ print(node.getproperty(n))
+
+ node.free(n)
+}
+\stoptyping
+
+This will print \type {foo} and \type {bar} which in itself is not that useful
+when multiple mechanisms want to use this feature. A variant is:
+
+\starttyping
+\directlua {
+ local n = node.new("glyph")
+
+ node.setproperty(n,{ one = "foo", two = "bar" })
+ print(node.getproperty(n).one)
+ print(node.getproperty(n).two)
+
+ node.free(n)
+}
+\stoptyping
+
+This time we store two properties with the node. It really makes sense to have a
+table as property because that way we can store more. But in order for that to
+work well you need to do it this way:
+
+\starttyping
+\directlua {
+ local n = node.new("glyph")
+
+ local t = node.getproperty(n)
+
+ if not t then
+ t = { }
+ node.setproperty(n,t)
+ end
+ t.one = "foo"
+ t.two = "bar"
+
+ print(node.getproperty(n).one)
+ print(node.getproperty(n).two)
+
+ node.free(n)
+}
+\stoptyping
+
+Here our own properties will not overwrite other users properties unless of
+course they use the same keys. So, eventually you will end up with something:
+
+\starttyping
+\directlua {
+ local n = node.new("glyph")
+
+ local t = node.getproperty(n)
+
+ if not t then
+ t = { }
+ node.setproperty(n,t)
+ end
+ t.myself = { one = "foo", two = "bar" }
+
+ print(node.getproperty(n).myself.one)
+ print(node.getproperty(n).myself.two)
+
+ node.free(n)
+}
+\stoptyping
+
+This assumes that only you use \type {myself} as subtable. The possibilities are
+endless but care is needed. For instance, the generic font handler that ships
+with \CONTEXT\ uses the \type {injections} subtable and you should not mess with
+that one!
+
+There are a few helper functions that you normally should not touch as user: \typ
+{flush_properties_table} will wipe the table (normally a bad idea), \typ
+{get_properties_table} and will give the table that stores properties (using
+direct entries) and you can best not mess too much with that one either because
+\LUATEX\ itself will make sure that entries related to nodes will get wiped when
+nodes get freed, so that the \LUA\ garbage collector can do its job. In fact, the
+main reason why we have this mechanism is that it saves the user (or macro
+package) some work. One can easily write a property mechanism in \LUA\ where
+after a shipout properties gets cleaned up but it's not entirely trivial to make
+sure that with each freed node also its properties get freed, due to the fact
+that there can be nodes left over for a next page. And having a callback bound to
+the node deallocator would add way to much overhead.
+
+Managing properties in the node (de)allocator functions is disabled by default
+and is enabled by:
+
+\starttyping
+node.set_properties_mode(true)
+\stoptyping
+
+When we copy a node list that has a table as property, there are several possibilities: we do the same as
+a new node, we copy the entry to the table in properties (a reference), we do
+a deep copy of a table in the properties, we create a new table and give it
+the original one as a metatable. After some experiments (that also included
+timing) with these scenarios we decided that a deep copy made no sense, nor
+did nilling. In the end both the shallow copy and the metatable variant were
+both ok, although the second one is slower. The most important aspect to keep
+in mind is that references to other nodes in properties no longer can be
+valid for that copy. We could use two tables (one unique and one shared) or
+metatables but that only complicates matters.
+
+When defining a new node, we could already allocate a table but it is rather easy
+to do that at the lua end e.g.\ using a metatable \type {__index} method. That
+way it is under macro package control. When deleting a node, we could keep the
+slot (e.g. setting it to false) but it could make memory consumption raise
+unneeded when we have temporary large node lists and after that only small lists.
+Both are not done.
+
+So in the end this is what happens now: when a node is copied, and it has a table
+as property, the new node will share that table. If the second argument of \typ
+{set_properties_mode} is \type {true} then a metatable approach is chosen: the
+copy gets its own table with the original table as metatable. If you use the
+generic font loader the mode is enabled that way.
+
+A few more xperiments were done. For instance: copy attributes to the properties
+so that we have fast access at the \LUA\ end. In the end the overhead is not
+compensated by speed and convenience, in fact, attributes are not that slow when
+it comes to accessing them. So this was rejected.
+
+Another experiment concerned a bitset in the node but again the gain compared to
+attributes was neglectable and given the small amount of available bits it also
+demands a pretty strong agreement over what bit represents what, and this is
+unlikely to succeed in the \TEX\ community. It doesn't pay off.
+
+Just in case one wonders why properties make sense: it is not so much speed that
+we gain, but more convenience: storing all kind of (temporary) data in attributes
+is no fun and this mechanism makes sure that properties are cleaned up when a
+node is freed. Also, the advantage of a more or less global properties table is
+that we stay at the \LUA\ end. An alternative is to store a reference in the node
+itself but that is complicated by the fact that the register has some limitations
+(no numeric keys) and we also don't want to mess with it too much.
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/luatex/luatex-preamble.tex b/doc/context/sources/general/manuals/luatex/luatex-preamble.tex
new file mode 100644
index 000000000..829317977
--- /dev/null
+++ b/doc/context/sources/general/manuals/luatex/luatex-preamble.tex
@@ -0,0 +1,110 @@
+% language=uk
+
+\environment luatex-style
+
+\startcomponent luatex-preamble
+
+\startchapter[reference=preamble,title={Preamble}]
+
+\topicindex{nodes}
+\topicindex{boxes}
+\topicindex{\LUA}
+
+This is a reference manual, not a tutorial. This means that we discuss changes
+relative to traditonal \TEX\ and also present new functionality. As a consequence
+we will refer to concepts that we assume to be known or that might be explained
+later.
+
+The average user doesn't need to know much about what is in this manual. For
+instance fonts and languages are normally dealt with in the macro package that
+you use. Messing around with node lists is also often not really needed at the
+user level. If you do mess around, you'd better know what you're dealing with.
+Reading \quotation {The \TEX\ Book} by Donald Knuth is a good investment of time
+then also because it's good to know where it all started. A more summarizing
+overview is given by \quotation {\TEX\ by Topic} by Victor Eijkhout. You might
+want to peek in \quotation {The \ETEX\ manual} and documentation about \PDFTEX.
+
+But \unknown\ if you're here because of \LUA, then all you need to know is that
+you can call it from within a run. The macro package that you use probably will
+provide a few wrapper mechanisms but the basic \lpr {directlua} command that
+does the job is:
+
+\starttyping
+\directlua{tex.print("Hi there")}
+\stoptyping
+
+You can put code between curly braces but if it's a lot you can also put it in a
+file and load that file with the usual \LUA\ commands.
+
+If you still decide to read on, then it's good to know what nodes are, so we do a
+quick introduction here. If you input this text:
+
+\starttyping
+Hi There
+\stoptyping
+
+eventually we will get a linked lists of nodes, which in \ASCII\ art looks like:
+
+\starttyping
+H <=> i <=> [glue] <=> T <=> h <=> e <=> r <=> e
+\stoptyping
+
+When we have a paragraph, we actually get something:
+
+\starttyping
+[localpar] <=> H <=> i <=> [glue] <=> T <=> h <=> e <=> r <=> e <=> [glue]
+\stoptyping
+
+Each character becomes a so called glyph node, a record with properties like the
+current font, the character code and the current language. Spaces become glue
+nodes. There are many node types that we will discuss later. Each node points
+back to a previous node or next node, given that these exist.
+
+It's also good to know beforehand that \TEX\ is basically centered around
+creating paragraphs and pages. The par builder takes a list and breaks it into
+lines. We turn horizontal material into vertical. Lines are so called boxes and
+can be separated by glue, penalties and more. The page builder accumulates lines
+and when feasible triggers an output routine that will take the list so far.
+Constructing the actual page is not part of \TEX\ but done using primitives that
+permit manipulation of boxes. The result is handled back to \TEX\ and flushed to
+a (often \PDF) file.
+
+The \LUATEX\ engine provides hooks for \LUA\ code at nearly every reasonable
+point in the process: collecting content, hyphenating, applying font features,
+breaking into lines, etc. This means that you can overload \TEX's natural
+behaviour, which still is the benchmark. When we refer to \quote {callbacks} we
+means these hooks.
+
+Where plain \TEX\ is basically a basic framework for writing a specific style,
+macro packages like \CONTEXT\ and \LATEX\ provide the user a whole lot of
+additional tools to make documents look good. They hide the dirty details of font
+management, language demands, turning structure into typeset results, wrapping
+pages, including images, and so on. You should be aware of the fact that when you
+hook in your own code to manipulate lists, this can interfere with the macro
+package that you use.
+
+When you read about nodes in the following chapters it's good to keep in mind their
+commands that relate to then. Here are a few:
+
+\starttabulate[|l|l|p|]
+\DB command \BC node \BC explanation \NC \NR
+\TB
+\NC \prm {hbox} \NC \nod {hlist} \NC horizontal box \NC \NR
+\NC \prm {vbox} \NC \nod {vlist} \NC vertical box with the baseline at the bottom \NC \NR
+\NC \prm {vtop} \NC \nod {vlist} \NC vertical box with the baseline at the top \NC \NR
+\NC \prm {hskip} \NC \nod {glue} \NC horizontal skip with optional stretch and shrink \NC \NR
+\NC \prm {vskip} \NC \nod {glue} \NC vertical skip with optional stretch and shrink \NC \NR
+\NC \prm {kern} \NC \nod {kern} \NC horizontal or vertical fixed skip \NC \NR
+\NC \prm {discretionary} \NC \nod {disc} \NC hyphenation point (pre, post, replace) \NC \NR
+\NC \prm {char} \NC \nod {glyph} \NC a character \NC \NR
+\NC \prm {hrule} \NC \nod {rule} \NC a horizontal rule \NC \NR
+\NC \prm {vrule} \NC \nod {rule} \NC a vertical rule \NC \NR
+\NC \prm {textdir(ection)} \NC \nod {dir} \NC a change in text direction \NC \NR
+\LL
+\stoptabulate
+
+For now this should be enough to enable you to understand the next chapters.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luatex/luatex-registers.tex b/doc/context/sources/general/manuals/luatex/luatex-registers.tex
new file mode 100644
index 000000000..36b1ec051
--- /dev/null
+++ b/doc/context/sources/general/manuals/luatex/luatex-registers.tex
@@ -0,0 +1,47 @@
+\environment luatex-style
+
+\startcomponent luatex-registers
+
+\startchapter[title=Topics]
+
+ \placeregister[topicindex]
+
+\stopchapter
+
+\startchapter[title=Primitives]
+
+ This register contains the primitives that are mentioned in the manual. There
+ are of course many more primitives. The \LUATEX\ primitives are typeset in
+ bold. The primitives from \PDFTEX\ are not supported that way but mentioned
+ anyway.
+
+ \placeregister[primitiveindex][indicator=no]
+
+\stopchapter
+
+\startchapter[title=Callbacks]
+
+ \placeregister[callbackindex]
+
+\stopchapter
+
+\startchapter[title=Nodes]
+
+ This register contains the nodes that are known to \LUATEX. The primary nodes
+ are in bold, whatsits that are determined by their subtype are normal. The
+ names prefixed by \type {pdf_} are backend specific.
+
+ \placeregister[nodeindex]
+
+\stopchapter
+
+\startchapter[title=Libraries]
+
+ This register contains the functions available in libraries. Not all functions
+ are documented, for instance because they can be experimental or obsolete.
+
+ \placeregister[libraryindex]
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luatex/luatex-statistics.tex b/doc/context/sources/general/manuals/luatex/luatex-statistics.tex
new file mode 100644
index 000000000..efd7f1c75
--- /dev/null
+++ b/doc/context/sources/general/manuals/luatex/luatex-statistics.tex
@@ -0,0 +1,17 @@
+% language=uk
+
+\environment luatex-style
+
+\startcomponent luatex-statistics
+
+\startchapter[title={Statistics}]
+
+ \topicindex{fonts+used}
+
+ The following fonts are used in this document:
+
+ \showfontusage
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/luatex/luatex-style.tex b/doc/context/sources/general/manuals/luatex/luatex-style.tex
index a277a1178..708f83ed6 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-style.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-style.tex
@@ -2,7 +2,9 @@
% todo: use \useMPlibrary[lua]
-\usemodule[abr-02]
+\enabletrackers[fonts.usage]
+
+\usemodule[fonts-statistics]
\setuplayout
[height=middle,
@@ -31,9 +33,31 @@
[each]
[packed]
+\definesymbol[1][\Uchar"2023]
+\definesymbol[2][\endash]
+\definesymbol[3][\wait] % we want to catch it
+
+\setupitemize
+ [each]
+ [headcolor=maincolor,
+ symbolcolor=maincolor,
+ color=maincolor]
+
\setupwhitespace
[medium]
+\setuptabulate
+ [blank={small,samepage},
+ headstyle=bold,
+ rulecolor=maincolor,
+ rulethickness=1pt,
+ foregroundcolor=white,
+ foregroundstyle=\ss\bfx\WORD,
+ backgroundcolor=maincolor]
+
+\setupcaptions
+ [headcolor=darkblue]
+
\startluacode
local skipped = table.tohash { 'id', 'subtype', 'next', 'prev' }
@@ -89,51 +113,13 @@
\definecolor[keptcolor] [b=.5]
\definecolor[othercolor][r=.5,g=.5]
-\usebodyfont[lucidaot]
-\usebodyfont[pagella]
-\usebodyfont[cambria]
-%usebodyfont[dejavu]
-\usebodyfont[modern] % we need this in examples so we predefine
-
-% \doifmodeelse {atpragma} {
-%
-% % \setupbodyfont
-% % [lucidaot,10pt]
-%
-% \setupbodyfont
-% [dejavu,10pt]
-%
-% \setuphead [chapter] [style=\bfd]
-% \setuphead [section] [style=\bfb]
-% \setuphead [subsection] [style=\bfa]
-% \setuphead [subsubsection][style=\bf]
-%
-% } {
-%
-% \definetypeface[mainfacenormal] [ss][sans] [iwona] [default]
-% \definetypeface[mainfacenormal] [rm][serif][palatino] [default]
-% \definetypeface[mainfacenormal] [tt][mono] [modern] [default][rscale=1.1]
-% \definetypeface[mainfacenormal] [mm][math] [iwona] [default]
-%
-% \definetypeface[mainfacemedium] [ss][sans] [iwona-medium][default]
-% \definetypeface[mainfacemedium] [rm][serif][palatino] [default]
-% \definetypeface[mainfacemedium] [tt][mono] [modern] [default][rscale=1.1]
-% \definetypeface[mainfacemedium] [mm][math] [iwona-medium][default]
-%
-% \setupbodyfont
-% [mainfacenormal,10pt]
-%
-% \setuphead [chapter] [style=\mainfacemedium\bfd]
-% \setuphead [section] [style=\mainfacemedium\bfb]
-% \setuphead [subsection] [style=\mainfacemedium\bfa]
-% \setuphead [subsubsection][style=\mainfacemedium\bf]
-%
-% }
-
-\writestatus{luatex manual}{we assume that dejavu math is available}
-
-\setupbodyfont % assumes dejavu-math
- [dejavu,10pt]
+\writestatus{luatex manual}{}
+\writestatus{luatex manual}{defining lucodaot} \usebodyfont [lucidaot]
+\writestatus{luatex manual}{defining pagella} \usebodyfont [pagella]
+\writestatus{luatex manual}{defining cambria} \usebodyfont [cambria]
+\writestatus{luatex manual}{defining modern} \usebodyfont [modern]
+\writestatus{luatex manual}{defining dejavu} \setupbodyfont[dejavu,10pt]
+\writestatus{luatex manual}{}
\setuphead [chapter] [align={flushleft,broad},style=\bfd]
\setuphead [section] [align={flushleft,broad},style=\bfb]
@@ -145,6 +131,9 @@
\setuphead [subsection] [color=maincolor]
\setuphead [subsubsection][color=maincolor]
+\setupfloats
+ [ntop=4]
+
\definehead
[remark]
[subsubsubject]
@@ -152,6 +141,10 @@
\setupheadertexts
[]
+% \setuplayout
+% [style=bold,
+% color=maincolor]
+
\definemixedcolumns
[twocolumns]
[n=2,
@@ -207,7 +200,7 @@
fill fullcircle scaled r shifted (d-1/8,d-1/8)
withcolor luaholecolor ;
luaorbitfactor := .25 ;
- ) enddef ;
+ ) enddef ;
\stopMPdefinitions
@@ -217,8 +210,15 @@
fill Page withcolor \MPcolor{othercolor} ;
luaorbitfactor := 1 ;
- picture p ; p := lualogo xsized (3PaperWidth/5) ;
- draw p shifted center Page shifted (0,-.85ypart center ulcorner p) ;
+
+ picture p ; p := lualogo ysized (5*\measure{paperheight}/10) ;
+ draw p
+ shifted - center p
+ shifted (
+ \measure{spreadwidth} - .5*\measure{paperwidth} + \measure{spinewidth},
+ .375*\measure{paperheight}
+ )
+ ;
StopPage ;
\stopuseMPgraphic
@@ -232,7 +232,7 @@
\startuseMPgraphic{luanumber}
% luaextraangle := \luaextraangle;
- luaextraangle := if (LastPageNumber == 0) : 0 else : (RealPageNumber / LastPageNumber) * 360 fi;
+ luaextraangle := if (LastPageNumber < 10) : 10 else : (RealPageNumber / LastPageNumber) * 360 fi;
luaorbitfactor := 0.25 ;
picture p ; p := lualogo ;
setbounds p to boundingbox fullcircle ;
@@ -252,40 +252,46 @@
[rightpage]
[background=page]
+\definemeasure[banneroffset][\bottomspace-\footerheight-\footerdistance+2cm]
+
\startsetups pagenumber:right
\setlayerframed
[page]
- [preset=rightbottom,offset=1cm]
+ [preset=rightbottom,x=1.0cm,y=\measure{banneroffset}]
[frame=off,height=1cm,offset=overlay]
- {\useMPgraphic{luanumber}}
+ {\strut\useMPgraphic{luanumber}}
\setlayerframed
[page]
- [preset=rightbottom,offset=1cm,x=1.5cm]
- [frame=off,height=1cm,width=1cm,offset=overlay]
- {\pagenumber}
+ [preset=rightbottom,x=2.5cm,y=\measure{banneroffset}]
+ [frame=off,height=1cm,width=1cm,offset=overlay,
+ foregroundstyle=bold,foregroundcolor=maincolor]
+ {\strut\pagenumber}
\setlayerframed
[page]
- [preset=rightbottom,offset=1cm,x=2.5cm]
- [frame=off,height=1cm,offset=overlay]
- {\getmarking[chapter]}
+ [preset=rightbottom,x=3.5cm,y=\measure{banneroffset}]
+ [frame=off,height=1cm,offset=overlay,
+ foregroundstyle=bold,foregroundcolor=maincolor]
+ {\strut\getmarking[chapter]}
\stopsetups
\startsetups pagenumber:left
\setlayerframed
[page]
- [preset=leftbottom,offset=1cm,x=2.5cm]
- [frame=off,height=1cm,offset=overlay]
- {\getmarking[chapter]}
+ [preset=leftbottom,x=3.5cm,y=\measure{banneroffset}]
+ [frame=off,height=1cm,offset=overlay,
+ foregroundstyle=bold,foregroundcolor=maincolor]
+ {\strut\getmarking[chapter]}
\setlayerframed
[page]
- [preset=leftbottom,offset=1cm,x=1.5cm]
- [frame=off,height=1cm,width=1cm,offset=overlay]
- {\pagenumber}
+ [preset=leftbottom,x=2.5cm,y=\measure{banneroffset}]
+ [frame=off,height=1cm,width=1cm,offset=overlay,
+ foregroundstyle=bold,foregroundcolor=maincolor]
+ {\strut\pagenumber}
\setlayerframed
[page]
- [preset=leftbottom,offset=1cm]
+ [preset=leftbottom,x=1.0cm,y=\measure{banneroffset}]
[frame=off,height=1cm,offset=overlay]
- {\useMPgraphic{luanumber}}
+ {\strut\useMPgraphic{luanumber}}
\stopsetups
\unexpanded\def\nonterminal#1>{\mathematics{\langle\hbox{\rm #1}\rangle}}
@@ -311,13 +317,15 @@
{\par
\tt
\startnarrower
- \maincolor #1
+ % \maincolor
+ #1
\stopnarrower
\par}
\unexpanded\def\syntaxbody#1%
{\begingroup
- \maincolor \tt #1%
+ % \maincolor
+ \tt #1%
\endgroup}
\bgroup \catcodetable\syntaxcodetable
@@ -329,7 +337,7 @@
\definetyping
[texsyntax]
- [color=maincolor]
+% [color=maincolor]
% end of wave
@@ -351,9 +359,14 @@
\setuplist
[chapter]
[style=bold,
+ before={\testpage[4]\blank},
color=keptcolor]
\setuplist
+ [section]
+ [before={\testpage[3]}]
+
+\setuplist
[subsection,subsubsection]
[margin=3em,
width=5em]
@@ -373,4 +386,57 @@
% \setupinteractionscreen
% [option=bookmark]
+\startbuffer[stylecalculations]
+
+ \normalexpanded{\definemeasure[spinewidth] [0pt]}
+ \normalexpanded{\definemeasure[paperwidth] [\the\paperwidth ]}
+ \normalexpanded{\definemeasure[paperheight][\the\paperheight]}
+ \normalexpanded{\definemeasure[spreadwidth][\measure{paperwidth}]}
+
+\stopbuffer
+
+\getbuffer[stylecalculations]
+
+\dontcomplain
+
+\environment luatex-logos
+
+\defineregister[topicindex]
+\defineregister[primitiveindex]
+\defineregister[callbackindex]
+\defineregister[nodeindex]
+\defineregister[libraryindex]
+
+\unexpanded\def\lpr#1{\doifmode{*bodypart}{\primitiveindex[#1]{\bf\tex {#1}}}\tex {#1}}
+\unexpanded\def\prm#1{\doifmode{*bodypart}{\primitiveindex[#1]{\tex {#1}}}\tex {#1}}
+\unexpanded\def\orm#1{\doifmode{*bodypart}{\primitiveindex[#1]{\tex {#1}}}\tex {#1}}
+\unexpanded\def\cbk#1{\doifmode{*bodypart}{\callbackindex [#1]{\type {#1}}}\type{#1}}
+\unexpanded\def\nod#1{\doifmode{*bodypart}{\nodeindex [#1]{\bf\type{#1}}}\type{#1}}
+\unexpanded\def\whs#1{\doifmode{*bodypart}{\nodeindex [#1]{\type {#1}}}\type{#1}}
+\unexpanded\def\noa#1{\doifmode{*bodypart}{\nodeindex [#1]{\type {#1}}}\type{#1}}
+
+\hyphenation{sub-nodes}
+
+\def\currentlibraryindex{\namedstructureuservariable{section}{library}}
+
+\setupregister
+ [libraryindex]
+ [indicator=no,before=]
+
+\setupregister
+ [libraryindex]
+ [1]
+ [textstyle=\ttbf]
+
+\setupregister
+ [libraryindex]
+ [2]
+ [textstyle=\tttf]
+
+\unexpanded\def\lib #1{\doifmode{*bodypart}{\expanded{\libraryindex{\currentlibraryindex+#1}}\type{\currentlibraryindex.#1}}}
+\unexpanded\def\libindex#1{\doifmode{*bodypart}{\expanded{\libraryindex{\currentlibraryindex+#1}}}}
+\unexpanded\def\libidx#1#2{\doifmode{*bodypart}{\expanded{\libraryindex{#1+#2}}\type{#1.#2}}}
+
+% \setstructurepageregister[][keys:1=,entries:1=]
+
\stopenvironment
diff --git a/doc/context/sources/general/manuals/luatex/luatex-titlepage.tex b/doc/context/sources/general/manuals/luatex/luatex-titlepage.tex
index 307741ee1..d9ca4b3f9 100644
--- a/doc/context/sources/general/manuals/luatex/luatex-titlepage.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex-titlepage.tex
@@ -1,5 +1,4 @@
\environment luatex-style
-\environment luatex-logos
\startcomponent luatex-titlepage
@@ -8,7 +7,7 @@
\switchtobodyfont
[mainfacemedium]
- \definedfont[Bold*default at \the\dimexpr.08\paperheight\relax] \setupinterlinespace
+ \definedfont[Bold*default at \the\dimexpr.06\paperheight\relax] \setupinterlinespace
\setlayer
[page]
@@ -16,55 +15,39 @@
\setlayerframed
[page]
- [preset=middletop,
- voffset=.05\paperheight]
+ [preset=righttop,
+ location=middletop,
+ hoffset=.500\measured{paperwidth},
+ voffset=.175\measured{paperheight}]
[align=middle,
- foregroundcolor=blue,
+ foregroundcolor=white,
frame=off]
- {Lua\TeX\\Reference Manual}
+ {\documentvariable{manual}\crlf Reference\crlf Manual}
- \definedfont[Bold*default at 18pt] \setupinterlinespace
+ \definedfont[Bold*default at 14pt] \setupinterlinespace
\setlayerframed
[page]
[preset=rightbottom,
- offset=.01\paperheight]
+ offset=.025\measured{paperheight}]
[align=flushright,
- foregroundcolor=blue,
+ foregroundcolor=white,
frame=off]
{\doifsomething{\documentvariable{status}}{\documentvariable{status}\par}
\currentdate[month,space,year]\par
Version \documentvariable{version}}
-\stopstandardmakeup
-
-\startstandardmakeup
-
- \start
- \raggedleft
- \definedfont[Bold*default at 48pt]
- \setupinterlinespace
- \blue Lua\TeX \endgraf Reference \endgraf Manual \endgraf
- \stop
-
- \vfill
-
- \definedfont[Bold*default at 12pt]
-
- \starttabulate[|l|l|]
- \NC copyright \EQ Lua\TeX\ development team \NC \NR
- \NC more info \EQ www.luatex.org \NC \NR
- \NC version \EQ \currentdate \doifsomething{\documentvariable{snapshot}}{(snapshot \documentvariable{snapshot})} \NC \NR
- \stoptabulate
+ \setlayerframed
+ [page]
+ [preset=middle,
+ hoffset=-.5\dimexpr\measured{paperwidth}-\measured{spinewidth}\relax]
+ [width=.7\measured{paperwidth},
+ align=normal,
+ foregroundstyle=\bf,
+ foregroundcolor=white,
+ frame=off]
+ {\getbuffer[backpage]}
\stopstandardmakeup
-\setupbackgrounds
- [leftpage]
- [setups=pagenumber:left]
-
-\setupbackgrounds
- [rightpage]
- [setups=pagenumber:right]
-
\stopcomponent
diff --git a/doc/context/sources/general/manuals/luatex/luatex.tex b/doc/context/sources/general/manuals/luatex/luatex.tex
index 3025788bf..1486abd49 100644
--- a/doc/context/sources/general/manuals/luatex/luatex.tex
+++ b/doc/context/sources/general/manuals/luatex/luatex.tex
@@ -1,11 +1,12 @@
% macros=mkvi
+% \nopdfcompression
+
% \disabledirectives[vspacing.synchronizepage]
% wsl /data/context/runcontext.sh --global --path=/mnt/c/data/develop/context/manuals/mkiv/external/luatex luatex.tex
%
% same runtime as regular context or linux
-
% author : Hans Hagen with Taco Hoekwater, Luigi Scarso & Hartmut Henkel
% copyright : PRAGMA ADE & ConTeXt Development Team
% license : Creative Commons Attribution ShareAlike 4.0 International
@@ -22,10 +23,6 @@
% comment : Some (parts of) chapters might have been published in TugBoat, the NTG Maps, the
% ConTeXt Group journal or otherwise. Thanks to the editors for corrections. Also
% thanks to users for testing, feedback and corrections.
-%
-% 238 pages : 2017-07-06
-% luatex 9.5 sec / luajittex 7.0 sec
-% Dell 7600 / i7 3840QM / passmark 1.922 / Windows 10 64 bit
% \tex vs \type vs \syntax vs. \luatex
% \em \it \/
@@ -33,12 +30,28 @@
% "context --nodates --nocompression luatex" can be used for comparison
% runs, not that we do it
+% todo: all (sub)section to start/stop
+
% \enabledirectives[hyphenator.flatten]
% \setupsynctex[state=start,method=max] % adds 5 pct overhead
+% compoundhyphenmode : looks okay
+% endlocalcontrol : very experimental
+% fixupboxesmode : very experimental
+% mathflattenmode : looks okay
+% mathrulethicknessmode : looks okay
+
+% after adding primitives: context mult-prm.mkiv
+
\environment luatex-style
+
+\startmode[book]
+ \environment luatex-style-book
+\stopmode
+
\environment luatex-logos
+\environment luatex-private
\startmode[export]
@@ -47,14 +60,14 @@
\stopmode
-\dontcomplain
-
\startdocument
- [status=experimental,
- version=1.08.0]
+ [manual=Lua\TeX,
+ status=experimental,
+ version=1.10]
\startnotmode[*export]
\component luatex-titlepage
+ \component luatex-firstpage
\stopnotmode
\startmode[*export]
@@ -67,6 +80,7 @@
\stopfrontmatter
\startbodymatter
+ \component luatex-preamble
\component luatex-enhancements
\component luatex-modifications
\component luatex-lua
@@ -81,4 +95,9 @@
\component luatex-backend
\stopbodymatter
+\startbackmatter
+ \component luatex-registers
+ \component luatex-statistics
+\stopbackmatter
+
\stopdocument
diff --git a/doc/context/sources/general/manuals/math/math-input.tex b/doc/context/sources/general/manuals/math/math-input.tex
index d395e1865..9b14057d0 100644
--- a/doc/context/sources/general/manuals/math/math-input.tex
+++ b/doc/context/sources/general/manuals/math/math-input.tex
@@ -95,6 +95,36 @@ which gives:
\stopsection
+\startsection [title=Scripts]
+
+With \UNICODE\ providing math symbols and a limited set of super- and subscripts,
+it made sense to add yet another feature. The scripts were already supported for
+a long time, but at some point on the mailing list sequential scripts were
+mentioned. So here is an example of both (some fonts, like the one used for
+verbatim, don't have all symbols but you get the idea anyway):
+
+\startbuffer
+\startformula
+ 𝑷₂₀(0), ∀²𝑥⁰⁺²₂₀: 𝑷₂₀(𝑥⁰⁺²₂₀) ⇒ 𝑷₂₀(s(𝑥⁰⁺²₂₀)) ⊢ ∀¹𝑦⁰⁺¹₂₀ 𝑷₂₀(𝑦⁰⁺¹₂₀)
+\stopformula
+
+\startformula
+ \unstackscripts
+ 𝑷₂₀(0), ∀²𝑥⁰⁺²₂₀: 𝑷₂₀(𝑥⁰⁺²₂₀) ⇒ 𝑷₂₀(s(𝑥⁰⁺²₂₀)) ⊢ ∀¹𝑦⁰⁺¹₂₀ 𝑷₂₀(𝑦⁰⁺¹₂₀)
+\stopformula
+\stopbuffer
+
+\typebuffer
+
+which renders the clueless formulas:
+
+\getbuffer
+
+The \type {\unstackscripts} macro triggers the unstacking of super and
+subscripts.
+
+\stopsection
+
\stopchapter
\stopcomponent
diff --git a/doc/context/sources/general/manuals/metafun/metafun-lua.tex b/doc/context/sources/general/manuals/metafun/metafun-lua.tex
index da35cccde..0794fc879 100644
--- a/doc/context/sources/general/manuals/metafun/metafun-lua.tex
+++ b/doc/context/sources/general/manuals/metafun/metafun-lua.tex
@@ -263,7 +263,7 @@ There are several ways to deal with this table. I will show clumsy as well as
better looking ways.
\startbuffer
-lua("MP = { } MP.data = table.load('demo-data.lua')") ;
+lua("MP.data = table.load('demo-data.lua')") ;
numeric n ;
lua("mp.print('n := ',\#MP.data)") ;
for i=1 upto n :
@@ -524,17 +524,23 @@ The \type {mp} namespace provides the following helpers:
\starttabulate[|l|l|]
\HL
-\NC \type {print(...)} \NC returns one or more values \NC \NR
-\NC \type {pair(x,y)}
- \type {pair(t)} \NC returns a proper pair \NC \NR
-\NC \type {triplet(x,y,z)}
- \type {triplet(t)} \NC returns an \RGB\ color \NC \NR
-\NC \type {quadruple(w,x,y,z)}
- \type {quadruple(t)} \NC returns an \CMYK\ color \NC \NR
-\NC \type {format(fmt,...)} \NC returns a formatted string \NC \NR
+\NC \type {print(...)} \NC returns one or more values \NC \NR
+\NC \type {fprint(fmt,...)} \NC returns a formatted result \NC \NR
+\NC \type {boolean(b)} \NC returns \type {true} or \type {false} \NC \NR
+\NC \type {numeric(f)} \NC returns a floating point number \NC \NR
+\NC \type {integer(i)} \NC returns a whole number \NC \NR
+\NC \type {points(i)} \NC returns a floating point with unit \type {pt} \NC \NR
+\NC \type {pair(x,y)|(t)} \NC returns a proper pair \NC \NR
+\NC \type {pairpoints(x,y)|(t)} \NC returns a proper pair with unit \type {pt} \NC \NR
+\NC \type {triplet(x,y,z)|(t)} \NC returns a \RGB\ color \NC \NR
+\NC \type {tripletpoints(x,y,z)|(t)} \NC returns a \RGB\ color but with unit \type {pt} \NC \NR
+\NC \type {quadruple(w,x,y,z)|(t)} \NC returns a \CMYK\ color \NC \NR
+\NC \type {quadruplepoints(w,x,y,z)|(t)} \NC returns a \CMYK\ color but with unit \type {pt} \NC \NR
+\NC \type {format(fmt,...)} \NC returns a formatted string \NC \NR
\NC \type {quoted(fmt,...)}
- \type {quoted(s)} \NC returns a (formatted) quoted string \NC \NR
-\NC \type {path(t[,connect][,close])} \NC returns a connected (closed) path \NC \NR
+ \type {quoted(s)} \NC returns a (formatted) quoted string \NC \NR
+\NC \type {path(t[,connect][,close])} \NC returns a connected (closed) path \NC \NR
+\NC \type {pathpoints(t[,connect][,close])} \NC returns a connected (closed) path with units \type {pt} \NC \NR
\HL
\stoptabulate
@@ -780,15 +786,15 @@ We load the data in datasets:
\startbuffer
\startMPcode
- lua.mp.datasets.load("foo","foo.tmp") ;
- lua.mp.datasets.load("bar","bar.tmp") ;
+ lua.mp.datasets("load","foo","foo.tmp") ;
+ lua.mp.datasets("load","bar","bar.tmp") ;
fill area
- lua.mp.datasets.foo.Line()
+ lua.mp.datasets("foo","line")
xysized (HSize/2-EmWidth-.25ExHeight,10ExHeight)
withpen pencircle scaled .25ExHeight
withcolor darkyellow ;
fill area
- lua.mp.datasets.bar.Line()
+ lua.mp.datasets("bar","line")
xysized (HSize/2-EmWidth-.25ExHeight,10ExHeight)
shifted (HSize/2+EmWidth,0)
withpen pencircle scaled .25ExHeight
@@ -798,7 +804,7 @@ We load the data in datasets:
\typebuffer
-Because the datasets are stores by name we can use them without worrying about
+Because the datasets are stored by name we can use them without worrying about
them being forgotten:
\startlinecorrection[blank] \getbuffer \stoplinecorrection
@@ -808,8 +814,8 @@ valid:
\starttyping
\startMPcode
- lua.mp.datasets.load("foo.tmp") ;
- lua.mp.datasets.load("bar.tmp") ;
+ lua.mp.datasets("load","foo.tmp") ;
+ lua.mp.datasets("load","bar.tmp") ;
\stopMPcode
\stoptyping
@@ -819,9 +825,9 @@ The following methods are defined for a dataset:
\HL
\NC \type {method} \NC usage \NC \NR
\HL
-\NC \type {Size} \NC the number of subsets in a dataset \NC \NR
-\NC \type {Line} \NC the joined pairs in a dataset making a non|-|closed path \NC \NR
-\NC \type {Data} \NC the table containing the data (in subsets, so there is always at least one subset) \NC \NR
+\NC \type {size} \NC the number of subsets in a dataset \NC \NR
+\NC \type {line} \NC the joined pairs in a dataset making a non|-|closed path \NC \NR
+\NC \type {data} \NC the table containing the data (in subsets, so there is always at least one subset) \NC \NR
\HL
\stoptabulate
@@ -847,7 +853,7 @@ passvariable("triplet",(1/1,1/2,1/3)) ;
passvariable("quad",(1.1,2.2,3.3,4.4)) ;
passvariable("boolean",false) ;
passvariable("path",fullcircle scaled 1cm) ;
-path p[] ; p[1] := fullcircle ; p[2] := fullsquare ;
+save p ; path p[] ; p[1] := fullcircle ; p[2] := fullsquare ;
passarrayvariable("list",p,1,2,1) ; % first last step
\stopMPcalculation
\stopbuffer
@@ -943,6 +949,533 @@ serialization.
\stopsection
+\startsection[title={Interference}]
+
+In this section we will discuss a potential conflict with other mechanisms,
+especially primitives and macros. A simple example of using the interface is:
+
+\startbuffer
+\startluacode
+function MP.AnExample(str)
+ mp.aux.quoted(string.reverse(str))
+end
+\stopluacode
+
+\startMPcode
+draw textext(lua.MP.AnExample("Hi there!"))
+ rotated 45
+ ysized 2cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+The \type {mp} namespace is reserved for functionality provided by \CONTEXT\
+itself so you should not polute it with your own code. Instead use the \type {MP}
+namespace and mix in some uppercase characters.
+
+Here you see a subnamespace \type {aux} which is where officially the helpers are
+organized but they are also accessible directly (as shown in previous sections).
+The reason for the \type {aux} namespace is, apart from propection aginst
+redefinition, also that we have \type {get} and \type {set} namespaces and there
+might be more in the future. At the \LUA\ end you can best use these namespaces
+because they are less likely to be accidentally overwritten by user code.
+
+As mentioned, there can still be conflicts. For instance the following will not
+work:
+
+\startbuffer
+\startluacode
+function MP.reverse(str)
+ mp.aux.quoted(string.reverse(str))
+end
+\stopluacode
+
+\startMPcode
+draw textext(lua.MP.reverse("Hi there!"))
+ rotated -45
+ ysized 2cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+% \startlinecorrection
+% \getbuffer
+% \stoplinecorrection
+
+The reason is that \type {reverse} gets expanded as part of parsing the macro
+name and this command expects an expression. A way out of this is the following:
+
+\startbuffer
+\startluacode
+function MP.reverse(str)
+ mp.aux.quoted(string.reverse(str))
+end
+\stopluacode
+
+\startMPcode
+draw textext(lua.MP("reverse","Hi there!"))
+ rotated -45
+ ysized 2cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+You can add litle bit of protection for your own code by using a prefix in the
+name, like:
+
+\startbuffer
+\startluacode
+MP["mynamespace.reverse"] = function(str)
+ mp.aux.quoted(string.reverse(str))
+end
+\stopluacode
+
+\startMPcode
+draw textext(lua.MP("mynamespace.reverse","Hi there!"))
+ rotated -90
+ ysized 2cm ;
+\stopMPcode
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+\stopsection
+
+\startsection[title=Predefined properties]
+
+As mentioned, the \type {mp} namespace is reserved for commands that come
+with the \CONTEXT|-|\METAFUN\ combination. For instance, a lot of layout
+related calls are there::
+
+\startcolumns[n=3]
+\starttyping
+BackSpace
+BaseLineSkip
+BodyFontSize
+BottomDistance
+BottomHeight
+BottomSpace
+CurrentColumn
+CurrentHeight
+CurrentWidth
+CutSpace
+EmWidth
+ExHeight
+FooterDistance
+FooterHeight
+HeaderDistance
+HeaderHeight
+InnerEdgeDistance
+InnerEdgeWidth
+InnerMarginDistance
+InnerMarginWidth
+LastPageNumber
+LayoutColumnDistance
+LayoutColumns
+LayoutColumnWidth
+LeftEdgeDistance
+LeftEdgeWidth
+LeftMarginDistance
+LeftMarginWidth
+LineHeight
+MakeupHeight
+MakeupWidth
+NOfColumns
+NOfPages
+NOfPages
+NOfSubPages
+OuterEdgeDistance
+OuterEdgeWidth
+OuterMarginDistance
+OuterMarginWidth
+PageDepth
+PageFraction
+PageNumber
+PageNumber
+PageOffset
+PaperBleed
+PaperHeight
+PaperWidth
+PrintPaperHeight
+PrintPaperWidth
+RealPageNumber
+RealPageNumber
+RightEdgeDistance
+RightEdgeWidth
+RightMarginDistance
+RightMarginWidth
+SpineWidth
+StrutDepth
+StrutHeight
+SubPageNumber
+TextHeight
+TextWidth
+TopDistance
+TopHeight
+TopSkip
+TopSpace
+\stoptyping
+\stopcolumns
+
+There all return dimensions, contrary to the next few that return a boolean:
+
+\startcolumns[n=3]
+\starttyping
+OnRightPage
+OnOddPage
+InPageBody
+\stoptyping
+\stopcolumns
+
+There are also calls related to backgrounds:
+
+\startcolumns[n=3]
+\starttyping
+OverlayWidth
+OverlayHeight
+OverlayDepth
+OverlayLineWidth
+OverlayOffset
+\stoptyping
+\stopcolumns
+
+And one related to color:
+
+\startcolumns[n=3]
+\starttyping
+NamedColor
+\stoptyping
+\stopcolumns
+
+In most cases such \type {lua.mp.command()} calls have a \METAPOST\ macro with
+the same name defined.
+
+\stopsection
+
+\startsection[title=Large paths]
+
+The plugins (like those dealing with text) also use calls in the \type {mp}
+namespace but they have sort of protected names, starting with \type {mf_}. These
+are visible but not meant to be used by users. Not only can their name change,
+their functionality can as well.
+
+The following are actually private as they have related macros but also have a
+public alias:
+
+\startlines
+lua.mp.pathlength(name)
+lua.mp.pathpoint(i)
+lua.mp.pathleft(i)
+lua.mp.pathright(i)
+lua.mp.pathreset()
+\stoplines
+
+They are meant for special high|-|performance path access, for example:
+
+\startlinecorrection
+\startMPcode
+ save p, q, r;
+ path p ; p := for i=1 upto 1000 :
+ (i,0) -- (i,4 + uniformdeviate 4) --
+ endfor cycle ;
+ fill p xysized (TextWidth,20mm) withcolor red ;
+
+ path q ; q := for i=1 upto lua.mp.pathlength("p") :
+ if (i mod 4) == 0 : lua.mp.pathpoint(i) -- fi
+ endfor cycle ;
+ fill q xysized (TextWidth,2cm) shifted (0,-45mm) withcolor green ;
+
+ path r ; r := for i inpath p :
+ if not odd (i) : pointof i -- fi
+ endfor cycle ;
+ fill r xysized (TextWidth,2cm) shifted (0,-70mm) withcolor blue ;
+\stopMPcode
+\stoplinecorrection
+
+Because a lookup of a point in \METAPOST\ is a linear lookup over a linked list
+for very large paths the gain is significant when using \LUA\ because there the
+points are stored in an indexed table. The left and right points can be used
+vebose like
+
+\starttyping
+lua.mp.pathpoint(i) controls lua.mp.pathleft(i) and lua.mp.pathright(i)
+\stoptyping
+
+or more terse:
+
+\starttyping
+pointof i controls leftof i and rightof i
+\stoptyping
+
+Beware: this kind of trickery is {\em only} needed when you have very large paths
+that are to be manipulated and the. Otherwise it's overkill.
+
+\stopsection
+
+\startsection[title={Interfacing to \TEX}]
+
+The next bunch of calls is for accessing \TEX\ registers. You can set their
+values and get them as well.
+
+\starttyping
+lua.mp.getmacro(k)
+lua.mp.getdimen(k)
+lua.mp.getcount(k)
+lua.mp.gettoks (k)
+
+lua.mp.setmacro(k,v)
+lua.mp.setdimen(k,v)
+lua.mp.setcount(k,v)
+lua.mp.settoks (k,v)
+\stoptyping
+
+When you mess around with variables and run into issues it might help to
+report values on the console. The \type {report} function does this:
+
+\starttyping
+lua.mp.report(a,b)
+\stoptyping
+
+\startlinecorrection
+\startMPcode
+lua.mp.report("status","a circle") ;
+fill fullcircle xyscaled (2cm,1cm) withcolor red ;
+lua.mp.report("status","its boundingbox [@N,@N,@N,@N]",
+ xpart llcorner currentpicture, ypart llcorner currentpicture,
+ xpart urcorner currentpicture, ypart urcorner currentpicture
+) ;
+draw boundingbox currentpicture withcolor blue ;
+report("status","the size: @Nbp x @Nbp",
+ bbwidth(currentpicture), bbheight(currentpicture)
+) ;
+message("done") ;
+\stopMPcode
+\stoplinecorrection
+
+The console shows:
+
+\starttyping
+metapost > status : a circle
+metapost > status : its boundingbox [-28.34645,-14.17323,28.34645,14.17323]
+metapost > status : the size: 57.1929bp x 28.84647bp
+metapost > message : done
+\stoptyping
+
+There are two more getters. These can be used to access the specific graphic
+related variables set at the \TEX\ end.
+
+\starttyping
+mp.texvar(name)
+mp.texstr(name)
+\stoptyping
+
+If you have adaptive styles you might want to test for modes.
+
+\starttyping
+if lua.mp.mode("screen") : % or processingmode
+ % some action only needed for screen documents
+fi ;
+if lua.mp.systemmode("first") :
+ % some action for the first run
+fi ;
+\stoptyping
+
+For convenience these are wrapped into macros:
+
+\starttyping
+if texmode("screen") :
+ % some action only needed for screen documents
+fi ;
+if systemmode("first") :
+ % some action for the first run
+fi ;
+\stoptyping
+
+When you implement your own helpers you can fall back on some auxiliary functions
+in the \type {mp} namespace. Actually these are collected in \type {mp.aux} and
+thereby protected from being overwritten by mistake. Here they are:
+
+% mp.flush()
+% mp.size(t)
+
+\stopsection
+
+\startsection[title={Interfacing to \METAPOST}]
+
+There is also experimental access to some of the \METAPOST\ internals. In order
+to deal with (large) paths a few more iterator related helpers are provided too.
+
+% mp.set (numeric string path boolean)
+
+\starttyping
+n = mp.getnumeric(name)
+s = mp.getstring(name)
+b = mp.getboolean(name)
+p = mp.getpath(name)
+\stoptyping
+
+A is path a table of tables that have six values: the coordinates and the
+pre- and postcontrol. You can manipulate this table and feed it back into
+\METAPOST.
+
+\startlinecorrection
+\startMPcode
+numeric n ; n := lua.mp.newhash() ;
+
+for i=1 upto 3 :
+ lua.mp.tohash(n,i) ;
+endfor ;
+
+fill fullcircle scaled 10mm withcolor
+ if lua.mp.inhash(n,3) : green else : red fi ;
+
+fill fullcircle scaled 5mm withcolor
+ if lua.mp.inhash(n,4) : green else : red fi ;
+
+lua.mp.disposehash(n)
+\stopMPcode
+\stoplinecorrection
+
+You can also store values with keys and access them later:
+
+\startlinecorrection
+\startMPcode
+numeric n ; n := lua.mp.newhash() ;
+
+for i=1 upto 3 :
+ lua.mp.tohash(n,i,decimal sqrt(i)) ;
+endfor ;
+
+draw textext(lua.mp.fromhash(n,3))
+ ysized 1cm
+ withcolor blue ;
+
+lua.mp.disposehash(n)
+\stopMPcode
+\stoplinecorrection
+
+You can also name your own hash:
+
+\startlinecorrection
+\startMPcode
+lua.mp.newhash("foo") ;
+
+for i=1 upto 3 :
+ lua.mp.tohash("foo",i,decimal sqrt(i)) ;
+endfor ;
+
+draw textext(lua.mp.fromhash("foo",2))
+ ysized 1cm
+ withcolor green ;
+
+lua.mp.disposehash("foo")
+\stopMPcode
+\stoplinecorrection
+
+Although it might look like \METAPOST\ supports arrays the reality is that it
+doesn't really. There is a concept of suffixes but internally these are just a
+way to compose macros. The following test is one that is used in one of the
+\METAFUN\ modules written by Alan Braslau.
+
+\startlinecorrection
+\startMPcode
+path p, q[] ;
+
+if lua.mp.isarray(str q[1]) :
+ fill fullcircle scaled 1cm withcolor red ;
+ draw textext(lua.mp.prefix(str q[1])) withcolor white;
+else :
+ fill fullsquare scaled 1cm withcolor blue ;
+fi ;
+
+currentpicture := currentpicture shifted (-2cm,0) ;
+
+if lua.mp.isarray(str p) :
+ fill fullcircle scaled 1cm withcolor red ;
+else :
+ fill fullsquare scaled 1cm withcolor blue ;
+fi ;
+\stopMPcode
+\stoplinecorrection
+
+Another helper relates to extensions that \METAFUN\ adds to \METAPOST. When you
+iterate over a picture you can recognize these as objects. The next code shows
+the \LUA\ call as well as the more convenient macro call. So, \type {textext}
+clearly is a foreign object.
+
+\startlinecorrection
+\startMPcode
+picture p ; p := image (
+ fill fullcircle scaled 1cm withcolor red ;
+ draw textext("ok") withcolor white ;
+) ;
+
+for i within p :
+ if not picture i :
+ draw i ysized 4cm ;
+ elseif isobject i :
+ draw i xsized 3cm ;
+ else :
+ draw i ysized 4cm ;
+ fi ;
+endfor ;
+
+currentpicture := currentpicture shifted (-6cm,0) ;
+
+for i within p :
+ if isobject(i) :
+ draw i xsized 5cm ;
+ else :
+ draw i ysized 3cm withcolor blue;
+ fi ;
+endfor ;
+\stopMPcode
+\stoplinecorrection
+
+% not yet, still experimental:
+%
+% mp.dataset(str)
+% mp.n(t)
+
+% not for users:
+%
+% mp.defaultcolormodel()
+
+% rather specialized:
+%
+% mp.positionpath(name)
+% mp.positioncurve(name)
+% mp.positionbox(name)
+% mp.positionxy(name)
+% mp.positionpage(name)
+% mp.positionregion(name)
+% mp.positionwhd(name)
+% mp.positionpxy(name)
+% mp.positionanchor()
+
+
+% mp.cleaned
+% mp.format(fmt,str)
+% mp.formatted(fmt,...)
+% mp.graphformat(fmt,num)
+
+\stopsection
+
\stopchapter
% \startMPcode{doublefun}
@@ -1055,6 +1588,4 @@ serialization.
%
% \ctxcommand{mprunvar("x")}
-\stoptext
-
-
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/musings/musings-children.tex b/doc/context/sources/general/manuals/musings/musings-children.tex
new file mode 100644
index 000000000..b814675bb
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-children.tex
@@ -0,0 +1,1253 @@
+% language=uk
+
+% naming-nature.jog
+
+\startcomponent musings-children
+
+\environment musings-style
+
+\definedescription
+ [presomething]
+ [headstyle=\bold,
+ alternative=hanging,
+ width=fit,
+ hang=1]
+
+\startchapter[title={Children of \TEX}]
+
+\startsection[title={The theme}]
+
+Nearly always \TEX\ conferences carry a theme. As there have been many
+conferences the organizers have run out of themes involving fonts, macros and
+typesetting and are now cooking up more fuzzy ones. Take the Bacho\TUG\ 2017
+theme:
+
+\startnarrower[left,8*right] \startpacked
+\startpresomething {Premises}
+ The starting point, what we have, what do we use, what has been achieved?
+\stoppresomething
+\startpresomething {Predilections}
+ How do we act now, how do we want to act, what is important to us and what do
+ we miss?
+\stoppresomething
+\startpresomething {Predictions}
+ What is the future of \TEX, what we'd like to achieve and can we influence
+ it?
+\stoppresomething
+\stoppacked \stopnarrower
+
+My first impression with these three P words was: what do they mean? Followed by
+the thought: this is no longer a place to take kids to. But the Internet gives
+access to the Cambridge Dictionary, so instead of running to the dusty meter of
+dictionaries somewhere else in my place, I made sure that I googled the most
+recent definitions:
+
+\startnarrower[left] \startpacked
+\startpresomething {premise}
+ an idea or theory on which a statement or action is based
+\stoppresomething
+\startpresomething {predilection}
+ if someone has a predilection for something, they like it a lot
+\stoppresomething
+\startpresomething {prediction}
+ a statement about what you think will happen in the future
+\stoppresomething
+\stoppacked \stopnarrower
+
+I won't try to relate these two sets of definitions but several words stand out
+in the second set: idea, theory, action, like, statement and future. Now, as a
+preparation for the usual sobering thoughts that Jerzy, Volker and I have when we
+staring into a Bacho\TEX\ campfire I decided to wrap up some ideas around these
+themes and words. The books that I will mention are just a selection of what you
+can find distributed around my place. This is not some systematic research but
+just the result of a few weeks making a couple of notes while pondering about
+this conference.
+
+\stopsection
+
+\startsection[title=Introduction]
+
+One cannot write the amount of \TEX\ macros that I've written without also liking
+books. If you look at my bookshelves the topics are somewhat spread over the
+possible spectrum of topics: history, biology, astronomy, paleontology, general
+science but surprisingly little math. There are a bunch of typography|-|related
+books but only some have been read: it's the visuals that matter most and as
+there are no real developments I haven't bought new ones in over a decade,
+although I do buy books that look nice for our office display but the content
+should be interesting too. Of course I do have a couple of books about computer
+(related) science and technology but only a few are worth a second look.
+Sometimes I bought computer books expecting to use them (in some project) but I
+must admit that most have not been read and many will soon end up in the paper
+bin (some already went that way). I'll make an exception for Knuth, Wirth and a
+few other fundamental ones that I (want to) read. And, I need to catch up on deep
+learning, so that might need a book.
+
+My colleagues and I have many discussions, especially about what we read, and
+after a few decades one starts seeing patterns. Therefore the last few years it
+was a pleasant surprise for me to run into books and lectures that nicely
+summarize what one has noticed and discussed in a consistent way. My memory is
+not that good, but good enough to let some bells ring.
+
+\startplacefigure[location=top]
+ \startcombination[nx=4,ny=1,width=\textwidth,distance=0pt]
+ {\externalfigure[covers/sapiens.jpg] [height=5cm]} {history}
+ {\externalfigure[covers/homo-deus.jpg] [height=5cm]} {futurology}
+ {\externalfigure[covers/children-of-time.jpg] [height=5cm]} {science fiction}
+ {\externalfigure[covers/superintelligence.jpg][height=5cm]} {informatics}
+ \stopcombination
+\stopplacefigure
+
+The first book that gave me this \quotation {finally a perfect summary of
+historic developments} feeling is \quotation{Sapiens} by Yuval Noah Harari. The
+author summarizes human history from a broad perspective where modern views on
+psychology, anthropology and technical developments are integrated. It's a follow
+up on a history writing trend started by Jared Diamond. The follow up \quotation
+{Homo Deus} looks ahead and is just as well written. It also integrates ideas
+from other fields, for instance those related to development of artificial
+intelligence (Dennett, Bostrom, etc.).
+
+Another inspiration for this talk and article is the 50 hour lecture series on
+behavioral biology by Robert Sapolsky of Stanford University, brought to my
+attention by my nephew Bram who visited a few \TEX\ conferences with me and who
+is now also forced to use \TEX\ for assignments and reports. (How come
+self|-|published books used at universities often look so bad?)
+
+The title of this talk is inspired by the book \quotation {Children of Time} by
+Adrian Tchaikovsky that I read recently. There are science fiction writers who
+focus on long term science and technology, such as some of Alastair Reynolds,
+while others follow up on recent development in all kind of sciences. One can
+recognize aspects of \quotation {Superintelligence} by Bostrom in Neal Asher's
+books, insights in psychology in the older Greg Bear books, while in the
+mentioned \quotation {Children of Time} (socio)biological insights dominate. The
+main thread in that book is the development of intelligence, social behaviour,
+language, script and cooperation in a species quite different from us: spiders.
+It definitely avoids the anthropocentric focus that we normally have.
+
+So how does this relate to the themes of the Bacho\TEX\ conference? I will pick
+out some ways to approach them using ideas from the kind of resources mentioned
+above. I could probably go on and on for pages because once you start relating
+what you read and hear to this \TEX\ ecosystem and community, there is no end.
+So, consider this a snapshot, that somehow relates to the themes:
+
+\startnarrower[left,8*right] \startpacked
+\startpresomething {premise}
+ Let's look at what the live sciences have to say about \TEX\ and friends and
+ let's hope that I don't offend the reader and the field.
+\stoppresomething
+\startpresomething {predilection}
+ Let's figure out what brings us here to this place deeply hidden in the woods,
+ a secret gathering of the \TEX\ sect.
+\stoppresomething
+\startpresomething {prediction}
+ Let's see if the brains present here can predict the future because after
+ all, according to Dennett, that is what brains are for.
+\stoppresomething
+\stoppacked \stopnarrower
+
+At school I was already intrigued by patterns in history: a cyclic, spiral and
+sinusoid social evolution instead of a pure linear sequence of events. It became
+my first typeset|-|by|-|typewriter document: Is history an exact science? Next I
+will use and abuse patterns and ideas to describe the \TEX\ world, not wearing a
+layman's mathematical glasses, but more from the perspective of live sciences,
+where chaos dominates.
+
+\stopsection
+
+\startsection[title={The larger picture}]
+
+History of mankind can be roughly summarized as follows. For a really long time
+we were hunters but at some point (10K years ago) became farmers. As a result we
+could live in larger groups and still feed them. The growing complexity of
+society triggered rules and religion as instruments for stability and
+organization (I use the term religion in its broadest sense here). For quite a
+while cultures came and went, and climate changes are among the reasons.
+
+After the industrial revolution new religions were invented (social, economic and
+national liberalism) and we're now getting dataism (search for Harari on youtube
+for a better summary). Some pretty great minds seem to agree that we're heading
+to a time when humans as we are will be outdated. Massive automation, interaction
+between the self and computer driven ecosystems, lack of jobs and purpose,
+messing around with our genome. Some countries and cultures still have to catch
+up on the industrial revolution, if they manage at all, and maybe we ourselves
+will be just as behind reality soon. Just ask yourself: did you manage to catch
+up? Is \TEX\ a stone age tool or a revolutionary turning point?
+
+A few decades ago a trip to Bacho\TEX\ took more than a day. Now you drive there
+in just over half a day. There was a time that it took weeks: preparation,
+changing horses, avoiding bad roads. Not only your own man|-|hours were involved.
+It became easier later (my first trip took only 24 hours) and recently it turned
+into a piece of cake: you don't pick up maps but start your device; you don't
+need a travel agent but use the Internet; there are no border patrols, you can
+just drive on. (Okay, maybe some day soon border patrols at the Polish border
+show up again, just like road tax police in Germany, but that might be a
+temporary glitch.)
+
+Life gets easier and jobs get lost. Taxi and truck drivers, travel agents, and
+cashiers become as obsolete as agricultural workers before. Next in line are
+doctors, lawyers, typesetters, printers, and all those who think they're safe.
+Well, how many people were needed 400 years ago to produce the proceedings of a
+conference like this in a few days' time span? Why read the introduction of a
+book or a review when you can just listen to the author's summary on the web? How
+many conferences still make proceedings (or go for videos instead), will we
+actually need editors and typesetters in the future? How much easier has it
+become to design a font, including variants? What stories can designers tell in
+the future when programs do the lot? The narrower your speciality is, the worse
+are your changes; hopefully the people present at this conference operate on a
+broader spectrum. It's a snapshot. I will show some book covers as reference but
+am aware that years ago or ahead the selection could have been different.
+
+\stopsection
+
+\startsection[title=Words]
+
+Words (whatever they represent) found a perfect spot to survive: our minds. Then
+they made it from speech (and imagination) into writing: carved in stone, wood,
+lead. At some point they managed to travel over wires but no matter what
+happened, they are still around. Typesetting as visualization is also still
+surrounding us so that might give us a starting point for ensuring a future for
+\TEX\ to work on, because \TEX\ is all about words. There is a lot we don't see;
+imagine if our eyes had microscopic qualities. What if we could hear beyond
+20KHz. Imagine we could see infrared. How is that with words. What tools, similar
+in impact as \TEX, can evolve once we figure that out. What if we get access to
+the areas of our brain that hold information? We went from print to screen and
+\TEX\ could cope with that. Can it cope with what comes next?
+
+The first printing press replaced literal copying by hand. Later we got these
+linotype|-|like machines but apart from a few left, these are already thrown out
+of windows (as we saw in a movie a few Bacho\TeX's ago). Photo|-|typesetting has
+been replaced too and because a traditional centuries old printing press is a
+nice to see item, these probably ring more bells than that gray metal closed box
+typesetters. Organizers of \TEX\ conferences love to bring the audience to old
+printing workshops and museums. At some point computers got used for typesetting
+and in that arena \TEX\ found its place. These gray closed boxes are way less
+interesting than something mechanical that at least invites us to touch it. How
+excited can one be about a stack of \TEX\,Live \DVD{}s?
+
+\stopsection
+
+\startsection[title=Remembering]
+
+Two times I visited the part of the science museum in London with young family
+members: distracted by constantly swiping their small powerful devices, they
+didn't have the least interest in the exhibited computer related items, let alone
+the fact that the couch they were sitting on was a Cray mainframe. Later on,
+climbing on some old monument or an old cannon seemed more fun. So, in a few
+decades folks will still look at wooden printing presses but quickly walk through
+the part of an exhibition where the tools that we use are shown. We need to find
+ways to look interesting. But don't think we're unique: how many kids find
+graphical trend|-|setting games like Myst and Riven still interesting? On the
+other hand a couple of month ago a bunch of nieces and nephews had a lot of fun
+with an old Atari console running low|-|res bitmap games. Maybe there is hope for
+good old \TEX.
+
+If indeed we're heading to a radically different society one can argue if this
+whole discussion makes sense. When the steam engine showed up, the metaphor for
+what went on in our heads was that technology, It's a popular example of speakers
+on this topic: \quotation {venting off steam}. When electricity and radio came
+around metaphors like \quotation {being on the same wavelength} showed up. A few
+decades ago the computer replaced that model although in the meantime the model
+is more neurobiological: we're a hormone and neurotransmitter driven computer. We
+don't have memory the way computers do.
+
+How relevant will page breaks, paragraph and line breaks be in the future? Just
+like \quotation {venting off steam} may make no sense to the youth, asking a
+typesetter to \quotation {give me a break} might not make much sense soon.
+However, when discussing automated typesetting the question \quotation {are we on
+the same page} still has relevance.
+
+Typesetting with a computer might seem like the ultimate solution but it's
+actually rather dumb when we consider truly intelligent systems. On the large
+scale of history and developments what we do might get quite unnoticed. Say that
+mankind survives the next few hundred years one way or the other. Science fiction
+novels by Jack McDevitt have an interesting perspective of rather normal humans
+millennia ahead of us who look back on these times in the same way as we look
+back now. Nothing fundamental changed in the way we run society. Nearly nothing
+from the past is left over and apart from being ruled by \AI{}s people still do
+sort of what they do now. \TEX ? What is that? Well, there once was this great
+computer scientist Knuth (in the remembered row of names like Aristotle |<|I just
+started reading \quotation {The Lagoon} by Armand Leroi|>| Newton, Einstein, his
+will show up) who had a group of followers that used a program that he seems to
+have written. And even that is unlikely to be remembered, unless maybe user
+groups manage to organize an archive and pass that on. Maybe the fact that \TEX\
+was one of the first large scale open source programs, of which someone can study
+the history, makes it a survivor. The first program that was properly documented
+in detail! But then we need to make sure that it gets known and persists.
+
+\startsection[title=Automation]
+
+In a recent interview Daniel Dennett explains that his view of the mind as a big
+neural network, one that can be simulated in software on silicon, is a bit too
+simplistic. He wonders if we shouldn't more tend to think of a network of
+(selfish) neurons that group together in tasks and then compete with each other,
+if only because they want to have something to do.
+
+Maybe attempts to catch the creative mindset and working of a typesetter in
+algorithms is futile. What actually is great typography or good typesetting?
+Recently I took a look at my bookshelf wondering what to get rid of \emdash\
+better do that now than when I'm too old to carry the crap down (crap being
+defined as uninteresting content or bad looking). I was surprised about the
+on|-|the|-|average bad quality of the typesetting and print. It's also not really
+getting better. One just gets accustomed to what is the norm at a certain point.
+Whenever they change the layout and look and feel of the newspaper I read the
+arguments are readability and ease of access. Well, I never had such a hard time
+reading my paper as today (with my old eyes).
+
+Are we, like Dennett, willing to discard old views on our tools and models? When
+my first computer was a \RCA\ 1802 based kit, that had 256 bytes of memory. My
+current laptop (from 2013) is a Dell Precision workstation with an extreme quad
+core processor and 16 GB of memory and ssd storage. Before I arrived there I
+worked with \DECTEN, \VAX\ and the whole range of Intel \CPU{}s. So if you really
+want to compare a brain with a computer, take your choice.
+
+I started with \TEX\ on a 4 MHz desk top with 640 MB memory and a 10 MB hard
+disk. Running \CONTEXT\ \MKIV\ with \LUATEX\ on such a machine is no option at
+all, but I still carry the burden of trying to write efficient code (which is
+still somewhat reflected in the code that makes up \CONTEXT). In the decades that
+we have been using \TEX\ we had to adapt! Demands changed, possibilities changed,
+technologies changed. And they keep changing. How many successive changes can a
+\TEX\ user handle? Sometimes, when I look and listen I wonder.
+
+\startplacefigure[location=top]
+ \startcombination[nx=4,ny=1,width=\textwidth,distance=0pt]
+ {\externalfigure[covers/the-mind-in-the-cave.jpg] [height=5cm]} {paleontology}
+ {\externalfigure[covers/the-ancestors-tale.jpg] [height=5cm]} {evolutionary biology}
+ {\externalfigure[covers/the-good-book-of-human-nature.jpg][height=5cm]} {anthropology}
+ {\externalfigure[covers/chaos-and-harmony.jpg] [height=5cm]} {physics}
+ \stopcombination
+\stopplacefigure
+
+If you look back, that is, if you read about the tens of thousands of years that
+it took humans to evolve (\quotation {The mind in the cave} by Lewis|-|Williams
+is a good exercise) you realize even more in what a fast|-|paced time we live and
+that we're witnessing transitions of another magnitude.
+
+In the evolution of species some tools were invented multiple times, like eyes.
+You see the same in our \TEX\ world: multiple (sub)macro packages, different font
+technologies, the same solutions but with an alternative approach. Some
+disappear, some stay around. Just like different circumstances demand different
+solutions in nature, so do different situations in typesetting, for instance
+different table rendering solutions. Sometime I get the feeling that we focus too
+much on getting rid of all but one solution while more natural would be to accept
+diversity, like bio|-|diversity is accepted. Transitions nowadays happen faster
+but the question is if, like aeons before, we (have to) let them fade away. When
+evolution is discussed the terms \quote {random}, \quote {selection}, \quote
+{fit}, and so on are used. This probably also applies to typography: at some
+point a font can be used a lot, but in the end the best readable and most
+attractive one will survive. Newspapers are printed in many copies, but rare
+beautiful books hold value. Of course, just like in nature some developments
+force the further path of development, we don't suddenly grow more legs or digits
+on our hands. The same happens with \TEX\ on a smaller timescale: successors
+still have the same core technology, also because if we'd drop it, it would be
+something different and then give a reason to reconsider using such technology
+(which likely would result in going by another path).
+
+\stopsection
+
+\startsection[title=Quality]
+
+Richard Dawkins \quotation {The Ancestor's Tale} is a non|-|stop read. In a
+discussion with Jared Diamond about religion and evolution they ponder this
+thread: you holding the hand of your mother who is handing her mother's hand and
+so on till at some point fish get into the picture. The question then is, when do
+we start calling something human? And a related question is, when does what we
+call morality creeps in? Is 50\% neanderthaler human or not?
+
+So, in the history of putting thoughts on paper: where does \TEX\ fit in? When do
+we start calling something automated typesetting? When do we decide that we have
+quality? Is \TEX\ so much different from its predecessors? And when we see
+aspects of \TEX\ (or related font technology) in more modern programs, do we see
+points where we cross qualitative or other boundaries? Is a program doing a
+better job than a human? Where do we stand? There are fields where there is no
+doubt that machines outperform humans. It's probably a bit more difficult in
+aesthetic fields except perhaps when we lower the conditions and expectations
+(something that happens a lot).
+
+For sure \TEX\ will become obsolete, maybe even faster that we think, but so will
+other typesetting technologies. Just look back and have no illusions. Till then
+we can have our fun and eventually, when we have more free time than we need, we
+might use it out of hobbyism. Maybe \TEX\ will be remembered by probably its most
+important side effect: the first large scale open source, the time when users met
+over programs, Knuth's disciples gathered in user groups, etc. The tools that we
+use are just a step in an evolution. And, as with evolution, most branches are
+pruned. So, when in the far future one looks back, will they even notice \TEX ?
+The ancestor's tail turns the tree upside down: at the end of the successful
+branch one doesn't see the dead ends.
+
+Just a thought: \CD{}s and media servers are recently being replaced (or at least
+accompanied) by Long Play records. In the shop where I buy my \CD{}s the space
+allocated to records grows at the cost of more modern media. So, maybe at some
+point retro|-|typesetting will pop up. Of course it might skip \TEX\ and end up
+at woodcutting or printing with lead.
+
+\stopsection
+
+\startsection[title=What mission]
+
+We rely on search engines instead of asking around or browsing libraries. Do
+students really still read books and manuals or do they just search and listen to
+lectures. Harari claims that instead of teaching kids facts in school we should
+just take for granted that they can get all the data they want and that we should
+learn them how to deal with data and adapt to what is coming. We take for granted
+that small devices with human voices show us the route to drive to Bacho\TEX, for
+instance, although by now I can drive it without help. In fact, kids can surprise
+you by asking if we're driving in Germany when we are already in Poland.
+
+We accept that computer programs help physicians in analyzing pictures. Some wear
+watches that warn them about health issues, and I know a few people who monitor
+their sugar levels electronically instead of relying on their own measurements.
+We seem to believe and trust the programs. And indeed, we also believe that \TEX\
+does the job in the best way possible. How many people really understand the way
+\TEX\ works?
+
+We still have mailing lists where we help each other. There are also wikis and
+forums like stack exchange. But who says that even a moderate bit of artificial
+intelligence doesn't answer questions better. Of course there needs to be input
+(manuals, previous answers, etc.) but just like we need fewer people as workforce
+soon, the number of experts needed also can be smaller. And we're still talking
+about a traditional system like \TEX. Maybe the social experience that we have on
+these media will survive somehow, although: how many people are members of
+societies, participate in demonstrations, meet weekly in places where ideas get
+exchanged, compared to a few decades ago? That being said, I love to watch posts
+with beautiful \CONTEXT\ solutions or listen to talks by enthusiastic users who
+do things I hadn't expected. I really hope that this property survives, just like
+I hope that we will be able to see the difference between a real user's response
+and one from an intelligent machine (an unrealistic hope I fear). Satisfaction
+wins and just like our neurological subsystems at some point permanently adapt to
+thresholds (given that you trigger things often enough), we get accustomed to
+what \TEX\ provides and so we stick to it.
+
+\stopsection
+
+\startsection[title={Intelligence versus consciousness}]
+
+Much of what we do is automated. You don't need to think of which leg to move and
+what foot to put down when you walk. Reacting to danger also to a large extent is
+automated. It doesn't help much to start thinking about how dangerous a lion can
+be when it's coming after you, you'd better move fast. Our limbic system is
+responsible for such automated behaviour, for instance driven by emotions. The
+more difficult tasks and thoughts about them happen in the frontal cortex (sort
+of).
+
+\startplacefigure[location=top]
+ \startcombination[nx=4,ny=1,width=\textwidth,distance=0pt]
+ {\externalfigure[covers/death-by-black-hole.jpg] [height=5cm]} {astronomy}
+ {\externalfigure[covers/the-formula.jpg] [height=5cm]} {informatics}
+ {\externalfigure[covers/hals-legacy.jpg] [height=5cm]} {future science}
+ {\externalfigure[covers/lucky-planet.jpg] [height=5cm]} {earth science}
+ \stopcombination
+\stopplacefigure
+
+For most users \TEX\ is like the limbic system: there is not much thinking
+involved, and the easy solutions are the ones used. Just like hitting a nerve
+triggers a chain of reactions, hitting a key eventually produces a typeset
+document. Often this is best because the job needs to get done and no one really
+cares how it looks; just copy a preamble, key in the text and assume that it
+works out well (enough). It is tempting to compare \TEX's penalties, badness and
+other parameters with levels of hormones and neurotransmitters. Their function
+depends on where they get used and the impact can be accumulated, blocked or
+absent. It's all magic, especially when things interact.
+
+Existing \TEX\ users, developers and user groups of course prefer to think
+otherwise, that it is a positive choice by free will. That new users have looked
+around and arrived at \TEX\ for good reason: their frontal cortex steering a
+deliberate choice. Well, it might have played a role but the decision to use
+\TEX\ might in the end be due to survival skills: I want to pass this exam and
+therefore I will use that weird system called \TEX.
+
+All animals, us included, have some level of intelligence but also have this hard
+to describe property that we think makes us what we are. Intelligence and
+consciousness are not the same (at least we know a bit about the first but nearly
+nothing about the second). We can argue about how well composed some music is but
+why we like it is a different matter.
+
+We can make a well thought out choice for using \TEX\ for certain tasks but can
+we say why we started liking it (or not)? Why it gives us pleasure or maybe
+grief? Has it become a drug that we got addicted to? So, one can make an
+intelligent decision about using \TEX\ but getting a grip on why we like it can
+be hard. Do we enjoy the first time struggle? Probably not. Do we like the folks
+involved? Yes, Don Knuth is a special and very nice person. Can we find help and
+run into a friendly community? Yes, and a unique one too, annoying at times,
+often stimulating and on the average friendly for all the odd cases running
+around.
+
+Artificial intelligence is pretty ambitious, so speaking of machine intelligence
+is probably better. Is \TEX\ an intelligent program? There is definitely some
+intelligence built in and the designer of that program is for sure very
+intelligent. The designer is also a conscious entity: he likes what he did and
+finds pleasure in using it. The program on the other hand is just doing its job:
+it doesn't care how it's done and how long it takes: a mindless entity. So here
+is a question: do we really want a more intelligent program doing the job for us,
+or do those who attend conferences like Bacho\TEX\ enjoy \TEX ing so much that
+they happily stay with what they have now? Compared to rockets tumbling down
+and|/|or exploding or Mars landers thrashing themselves due to programming errors
+of interactions, \TEX\ is surprisingly stable and bug free.
+
+\stopsection
+
+\startsection[title={Individual versus group evolution}]
+
+After listening for hours to Sapolsky you start getting accustomed to remarks
+about (unconscious) behaviour driven by genes, expression and environment, aimed
+at \quotation {spreading many copies of your genes}. In most cases that is an
+individual's driving force. However, cooperation between individuals plays a role
+in this. A possible view is that we have now reached a state where survival is
+more dependent on a group than on an individual. This makes sense when we
+consider that developments (around us) can go way faster than regular evolution
+(adaptation) can handle. We take control over evolution, a mechanism that needs
+time to adapt and time is something we don't give it anymore.
+
+Why does \TEX\ stay around? It started with an individual but eventually it's the
+groups that keeps it going. A too|-|small group won't work but too|-|large groups
+won't work either. It's a known fact that one can only handle some 150 social
+contacts: we evolved in small bands that split when they became too large. Larger
+groups demanded abstract beliefs and systems to deal with the numbers: housing,
+food production, protection. The \TEX\ user groups also provide some
+organization: they organize meetings, somehow keep development going and provide
+infrastructure and distributions. They are organized around languages. According
+to Diamond new languages are still discovered but many go extinct too. So the
+potential for language related user groups is not really growing.
+
+Some of the problems that we face in this world have become too large to be dealt
+with by individuals and nations. In spite of what anti|-|globalists want we
+cannot deal with our energy hunger, environmental issues, lack of natural
+resources, upcoming technologies without global cooperation. We currently see a
+regression in cooperation by nationalistic movements, protectionism and the usual
+going back to presumed better times, but that won't work.
+
+Local user groups are important but the number of members is not growing. There
+is some cooperation between groups but eventually we might need to combine the
+groups into one which might succeed unless one wants to come first. Of course we
+will get the same sentiments and arguments as in regular politics but on the
+other hand, we already have the advantage of \TEX\ systems being multi|-|lingual
+and users sharing interest in the diversity of usage and users. The biggest
+challenge is to pass on what we have achieved. We're just a momentary highlight
+and let's not try to embrace some \quotation {\TEX\ first} madness.
+
+\stopsection
+
+\startplacefigure[location=top]
+ \startcombination[nx=4,ny=1,width=\textwidth,distance=0pt]
+ {\externalfigure[covers/3-16.jpg] [height=5cm]} {art}
+ % {\externalfigure[covers/dirt.jpg] [height=5cm]} {history}
+ {\externalfigure[covers/the-winds-of-change.jpg] [height=5cm]} {history}
+ {\externalfigure[covers/pale-blue-dot.jpg] [height=5cm]} {astronomy}
+ {\externalfigure[covers/the-third-chimpanzee.jpg][height=5cm]} {history}
+ \stopcombination
+\stopplacefigure
+
+\startsection[title=Sexes]
+
+Most species have two sexes but it is actually a continuum controlled by hormones
+and genetic expression: we just have to accept it. Although the situation has
+improved there are plenty of places where some gender relationships are
+considered bad even to the extent that one's life can be in danger. Actually
+having strong ideas about these issues is typically human. But in the end one has
+to accept the continuum.
+
+In a similar way we just have to accept that \TEX\ usage, application of \TEX\
+engines, etc.\ is a continuum and not a batch versus \WYSIWYG\ battle any more.
+It's disturbing to read strong recommendations not to use this or that. Of the
+many macro packages that showed up only a few were able to survive. How do users
+of outlines look at bitmaps, how do \DVI\ lovers look at \PDF. But, as
+typesetting relates to esthetics, strong opinions come with the game.
+
+Sapolsky reports about a group of baboons where due to the fact that they get the
+first choice of food the alpha males of pack got poisoned, so that the remaining
+suppressed males who treated the females well became dominant. In fact they can
+then make sure that no new alpha male from outside joins the pack without
+behaving like they do. A sort of social selection. In a similar fashion, until
+now the gatherings of \TEX ies managed to keep its social properties and has not
+been dominated by for instance commerce.
+
+% So, maybe should focus on acceptance and tolerance and then make sure that that
+% we keep what we have and let it not be influenced too much by sectarianism. It
+% makes a nice topic for a meeting of the context (sub)group, that actually has a
+% women as driving force. How can we preserve what we have but still proceed is a
+% legitimate question. Where do we stand in the landscape.
+
+In the animal world often sexes relate to appearance. The word sexy made it to
+other domains as well. Is \TEX\ sexy? For some it is. We often don't see the real
+colors of birds. What looks gray to us looks vivid to a bird which sees in a
+different spectrum. The same is true for \TEX. Some users see a command line
+(shell) and think: this is great! Others just see characters and keystrokes and
+are more attracted to an interactive program. When I see a graphic made by
+\METAPOST, I always note how exact it is. Others don't care if their interactive
+effort doesn't connect the dots well. Some people (also present here) think that
+we should make \TEX\ attractive but keep in mind that like and dislike are not
+fixed human properties. Some mindsets might as well be the result from our
+makeup, others can be driven by culture.
+
+\stopsection
+
+\startsection[title=Religion]
+
+One of Sapolsky's lectures is about religion and it comes in the sequence of
+mental variations including depression and schizophrenia, because all these
+relate to mental states, emotions, thresholds and such (all things human). That
+makes it a tricky topic which is why it has not been taped. As I was raised in a
+moderate Protestant tradition I can imagine that it's an uncomfortable topic
+instead. But there are actually a few years older videos around and they are
+interesting to watch and not as threatening as some might expect. Here I just
+stick to some common characteristics.
+
+If you separate the functions that religions play into for instance explanation
+of the yet unknown, social interactions, control of power and regulation of
+morals, then it's clear why at \TEX\ user group meetings the religious aspect of
+\TEX\ has been discussed in talks. Those who see programs as infallible and
+always right and don't understand the inner working can see it as an almighty
+entity. In the Netherlands church-going diminishes but it looks like alternative
+meetings are replacing it (and I'm not talking of football matches). So what are
+our \TEX\ meetings? What do we believe in? The reason that I bring up this aspect
+is that in the \TEX\ community we can find aspects of the more extremist aspects
+of religions: if you don't use the macro package that I use, you're wrong. If you
+don't use the same operating system as I do, you're evil. You will be punished if
+you use the wrong editor for \TEX ? Why don't you use this library (which, by the
+way, just replaced that other one)? We create angels and daemons. Even for quite
+convinced atheists (it's not hard to run into them on youtube) a religion only
+survives when it has benefits, something that puzzles them. So when we're
+religious about \TEX\ and friends we have to make sure that it's at least
+beneficial. Also, maybe we fall in Dennett's category of \quotation {believers
+who want to believe}: it helps us to do our job if we just believe that we have
+the perfect tool. Religion has inspired visual and aural art and keeps doing
+that. (Don Knuth's current musical composition project is a good example of
+this.)
+
+Scientists can be religious, in flexible ways too, which is demonstrated by Don
+Knuth. In fact, I'm pretty sure \TEX\ would not be in the position it is in now
+if it weren't for his knowledgeable, inspirational, humorous, humble, and always
+positive presence. And for sure he's not at all religious about the open source
+software that he sent viral.
+
+I'm halfway through reading \quotation {The Good Book of Human Nature} (An
+Evolutionary Reading of the Bible) a book about the evolution of the bible and
+monotheism which is quite interesting. It discusses for instance how transitions
+from a hunter to a farmer society demanded a change of rules and introduced
+stories that made sense in that changing paradigm. Staying in one place means
+that possessions became more important and therefore inheritance. Often when
+religion is discussed by behavioral biologists, historians and anthropologists
+they stress this cultural narrative aspect. Also mentioned is that such societies
+were willing to support (in food and shelter) the ones that didn't normally fit
+it but added to the spiritual character of religions. The social and welcoming
+aspect is definitely present in for instance Bacho\TEX\ conferences although a
+bystander can wonder what these folks are doing in the middle of the night around
+a campfire, singing, drinking, frying sausages, spitting fire, and discussing the
+meaning of life.
+
+Those who wrap up the state of religious affairs, do predictions and advocate the
+message, are sometimes called evangelists. I remember a \TEX\ conference in the
+\USA\ where the gospel of \XML\ was preached (by someone from outside the \TEX\
+community). We were all invited to believe it. I was sitting in the back of the
+crowded (!)\ room and that speaker was not at all interested in who spoke before
+and after. Well, I do my share of \XML\ processing with \CONTEXT, but believe me:
+much of the \XML\ that we see is not according to any gospel. It's probably
+blessed the same way as those state officials get blessed when they ask and pray
+for it in public.
+
+It can get worse at \TEX\ conferences. Some present here at Bacho\TEX\ might
+remember the \PDF\ evangelists that we had show up at \TEX\ conferences. You see
+this qualification occasionally and I have become quite allergic to
+qualifications like architect, innovator, visionary, inspirator and evangelist,
+even worse when they look young but qualify as senior. I have no problem with
+religion at all but let's stay away from becoming one. And yes, typography also
+falls into that trap, so we have to be doubly careful.
+
+\stopsection
+
+\startplacefigure[location=top]
+ \startcombination[nx=4,ny=1,width=\textwidth,distance=0pt]
+ {\externalfigure[covers/from-bacteria-to-bach-and-back.jpg][height=5cm]} {philosophy}
+ {\externalfigure[covers/the-lagoon.jpg] [height=5cm]} {science history}
+ {\externalfigure[covers/chaos.jpg] [height=5cm]} {science}
+ {\externalfigure[covers/why-zebras-dont-get-ulcers.jpg] [height=5cm]} {behavioral biology}
+ \stopcombination
+\stopplacefigure
+
+\startsection[title=Chaotic solutions]
+
+The lectures on \quotation {chaos and reductionism} and \quotation {emergence and
+complexity} were the highlights in Sapolsky's lectures. I'm not a good narrator
+so I will not summarize them but it sort of boils down to the fact that certain
+classes of problems cannot be split up in smaller tasks that we understand well,
+after which we can reassemble the solutions to deal with the complex task.
+Emerging systems can however cook up working solutions from random events.
+Examples are colonies of ants and bees.
+
+The \TEX\ community is like a colony: we cook up solutions, often by trial and
+error. We dream of the perfect solutions but deep down know that esthetics cannot
+be programmed in detail. This is a good thing because it doesn't render us
+obsolete. At last year's Bacho\TEX, my nephew Teun and I challenged the anthill
+outside the canteen to typeset the \TEX\ logo with sticks but it didn't persist.
+So we don't need to worry about competition from that end. How do you program a
+hive mind anyway?
+
+When chaos theory evolved in the second half of the previous century not every
+scientist felt happy about it. Instead of converging to more perfect predictions
+and control in some fields a persistent uncertainty became reality.
+
+After about a decade of using \TEX\ and writing macros to solve recurring
+situations I came to the conclusion that striving for a perfect \TEX\ (the
+engine) that can do everything and anything makes no sense. Don Knuth not only
+stopped adding code when he could do what he needed for his books, he also stuck
+to what to me seems reasonable endpoints. Every hard|-|coded solution beyond that
+is just that: a hard|-|coded solution that is not able to deal with the
+exceptions that make up most of the more complex documents. Of course we can
+theorize and discuss at length the perfect never|-|reachable solutions but
+sometimes it makes more sense to admit that an able user of a desktop publishing
+system can do that job in minutes, just by looking at the result and moving
+around an image or piece of text a bit.
+
+There are some hard|-|coded solutions and presets in the programs but with
+\LUATEX\ and \MPLIB\ we try to open those up. And that's about it. Thinking that
+for instance adding features like protrusion or expansion (or whatever else)
+always lead to better results is just a dream. Just as a butterfly flapping its
+wings on one side of the world can have an effect on the other side, so can
+adding a single syllable to your source completely confuse an otherwise clever
+column or page break algorithm. So, we settle for not adding more to the engine,
+and provide just a flexible framework.
+
+A curious observation is that when Edward Lorenz ran into chaotic models it was
+partially due to a restart of a simulation midway, using printed floating point
+numbers that then in the computer were represented with a different accuracy than
+printed. Aware of floating point numbers being represented differently across
+architectures, Don Knuth made sure that \TEX\ was insensitive to this so that its
+outcome was predictable, if you knew how it worked internally. Maybe \LUATEX\
+introduces a bit of chaos because the \LUA\ we use has only floats. In fact, a
+few months ago we did uncover a bug in the backend where the same phenomena gave
+a chaotic crash.
+
+In chaos theory there is the concept of an attractor. When visualized this can be
+the area (seemingly random) covered by a trajectory. Or it can be a single point
+where for instance a pendulum comes to rest. So what is our attractor? We have a
+few actually. First there is the engine, the stable core of primitives always
+present. You often see programs grow more complex every update and for sure that
+happened with \ETEX, \PDFTEX, \XETEX\ and \LUATEX. However there is always the
+core that is supposed to be stable. After some time the new kid arrives at a
+stable state not much different from the parent. The same is true for \METAPOST.
+Fonts are somewhat different because the technology changes but in the end the
+shapes and their interactions become stable as well. Yet another example is \TEX\
+Live: during a year it might diverge from its route but eventually it settles
+down and enters the area where we expect it to end up. The \TEX\ world is at
+times chaotic, but stable in the long run.
+
+So, how about the existence, the reason for it still being around? One can
+speculate about its future trajectory but one thing is sure: as long as we break
+a text into paragraphs and pages \TEX\ is hard to beat. But what if we don't need
+that any more? What if the concept of a page is no longer relevant? What if
+justified texts no longer matter (often designers don't care anyway)? What if
+students are no longer challenged to come up with a nice looking thesis? Do these
+collaborative tools with remote \TEX\ processing really bring new long term users
+or is \TEX\ then just one of the come|-|and|-|go tools?
+
+\stopsection
+
+\startsection[title=Looking ahead]
+
+In an interview (\quotation {World of ideas}) Asimov explains that science
+fiction evolved rapidly when people lived long enough to see that there was a
+future (even for their offspring) that is different from today. It is (at least
+for me) mind boggling to think of an evolution of hundreds of thousands of years
+to achieve something like language. Waiting for the physical being to arrive at a
+spot where you can make sounds, where the brain is suitable for linguistic
+patterns, etc. A few hundred years ago speed of any developments (and science)
+stepped up.
+
+\TEX\ is getting near 40 years old. Now, for software that {\bf is} old! In that
+period we have seen computers evolve: thousands of times faster processing, even
+more increase in memory and storage. If we read about spaceships that travel at a
+reasonable fraction of the speed of light, and think that will not happen soon,
+just think back to the terminals that were sitting in computer labs when \TEX\
+was developed: 300 baud was normal. I actually spent quite some time on
+optimizing time|-|critical components of \CONTEXT\ but on this timescale that is
+really a waste of time. But even temporary bottlenecks can be annoying (and
+costly) enough to trigger such an effort. (Okay, I admit that it can be a
+challenge, a kind of game, too.)
+
+Neil Tyson, in the video \quotation {Storytelling of science} says that when
+science made it possible to make photos it also made possible a transition in
+painting to impressionism. Other technology could make the exact snapshot so
+there was new room for inner feelings and impressions. When the Internet showed
+up we went through a similar transition, but \TEX\ actually dates from before the
+Internet. Did we also have a shift in typesetting? To some extent yes, browsers
+and real time rendering is different from rendering pages on paper. In what space
+and time are \TEX ies rooted?
+
+We get older than previous generations. Quoting Sapolsky \quotation{\unknown\ we
+are now living well enough and long enough to slowly fall apart.} The opposite is
+happening with our tools, especially software: it's useful lifetime becomes
+shorter and changes faster each year. Just look at the version numbers of
+operating systems. Don Knuth expected \TEX\ to last for a long time and compared
+to other software its core concept and implementation is doing surprisingly well.
+We use a tool that suits our lifespan! Let's not stress ourselves out too much
+with complex themes. (It helps to read \quotation {Why zebras don't get ulcers}.)
+
+\stopsection
+
+\startsection[title=Memes]
+
+If you repeat a message often enough, even if it's something not true, it can
+become a meme that gets itself transferred across generations. Conferences like
+this is where they can evolve. We tell ourselves and the audience how good \TEX\
+is and because we spend so many hours, days, weeks, months using it, it actually
+must be good, or otherwise we would not come here and talk about it. We're not so
+stupid as to spend time on something not good, are we? We're always surprised
+when we run into a (potential) customer who seems to know \TEX. It rings a bell,
+and it being around must mean something. Somehow the \TEX\ meme has anchored
+itself when someone attended university. Even if experiences might have been bad
+or usage was minimal. The meme that \TEX\ is the best in math typesetting is a
+strong survivor.
+
+There's a certain kind of person who tries to get away with their own deeds and
+decisions by pointing to \quotation {fake news} and accusations of \quotation
+{mainstream media} cheating on them. But to what extent are our stories true
+about how easy \TEX\ macro packages are to use and how good their result? We have
+to make sure we spread the right memes. And the user groups are the guardians.
+
+Maybe macro packages are like memes too. In the beginning there was a bunch but
+only some survived. It's about adaptation and evolution. Maybe competition was
+too fierce in the beginning. Like ecosystems, organisms and cellular processes in
+biology we can see the \TEX\ ecosystem, users and usage, as a chaotic system.
+Solutions pop up, succeed, survive, lead to new ones. Some look similar and
+slightly different input can give hugely different outcomes. You cannot really
+look too far ahead and you cannot deduce the past from the present. Whenever
+something kicks it off its stable course, like the arrival of color, graphics,
+font technologies, \PDF, \XML, ebooks, the \TEX\ ecosystem has to adapt and find
+its stable state again. The core technology has proven to be quite fit for the
+kind of adaptation needed. But still, do it wrong and you get amplified out of
+existence, don't do anything and the external factors also make you extinct.
+There is no denial that (in the computer domain) \TEX\ is surprisingly stable and
+adaptive. It's also hard not to see how conservatism can lead to extinction.
+
+\startplacefigure[location=top]
+ \startcombination[nx=4,ny=1,width=\textwidth,distance=0pt]
+ {\externalfigure[covers/the-epigenetics-revolution.jpg] [height=5cm]} {genetics}
+ {\externalfigure[covers/dark-matter-and-the-dinosaurs.jpg][height=5cm]} {physics}
+ {\externalfigure[covers/the-world-without-us.jpg] [height=5cm]} {history}
+ {\externalfigure[covers/what-we-cannot-know.jpg] [height=5cm]} {science}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=Inspiration]
+
+I just took some ideas from different fields. I could have mentioned quantum
+biology, which tries to explain some unexplainable phenomena in living creatures.
+For instance how do birds navigate without visible and measurable clues. How do
+people arrive at \TEX\ while we don't really advertise? Or I could mention
+epigenetics and explorations in junk \DNA. It's not the bit of the genome that we
+thought that matters, but also the expression of the genes driven by other
+factors. Offspring not only gets genetic material passed but it can get presets.
+How can the \TEX\ community pass on Knuth's legacy? Do we need to hide the
+message in subtle ways? Or how about the quest for dark matter? Does it really
+exist or do we want (need) it to exist? Does \TEX\ really have that many users,
+or do we cheat by adding the users that are enforced during college but don't
+like it at all? There's enough inspiration for topics at \TEX\ conferences, we
+just have to look around us.
+
+\stopsection
+
+\startsection[title=Stability]
+
+I didn't go into technical aspects of \TEX\ yet. I must admit that after decades
+of writing macros I've reached a point where I can safely say that there will
+never be perfect automated solutions for really complex documents. When books
+about neural networks show up I wondered if it could be applied (but I couldn't).
+When I ran into genetic algorithms I tried to understand its possible impact (but
+I never did). So I stuck to writing solutions for problems using visualization:
+the trial and error way. Of course, speaking of \CONTEXT, I will adapt what is
+needed, and others can do that as well. Is there a new font technology? Fine,
+let's support it as it's no big deal, just a boring programming task. Does a user
+want a new mechanism? No problem, as solving a reduced subset of problems can be
+fun. But to think of \TEX\ in a reductionist way, i.e.\ solving the small
+puzzles, and to expect the whole to work in tandem to solve a complex task is not
+trivial and maybe even impossible. It's a good thing actually, as it keeps us on
+edge. Also, \CONTEXT\ was designed to help you with your own solutions: be
+creative.
+
+I mentioned my nephew Bram. He has seen part of this crowd a few times, just like
+his brother and sister do now. He's into artificial intelligence now. In a few
+years I'll ask him how he sees the current state of \TEX\ affairs. I might learn
+a few tricks in the process.
+
+In \quotation {The world without us} Weisman explores how fast the world would be
+void of traces of humankind. A mere 10.000 years can be more than enough. Looking
+back, that's about the time hunters became farmers. So here's a challenge: say
+that we want an ant culture that evolves to the level of having archaeologists to
+know that we were here at Bacho\TEX\ \unknown\ what would we leave behind?
+
+Sapolsky ends his series by stressing that we should accept and embrace
+individual differences. The person sitting next to you can have the same makeup
+but be just a bit more sensitive to depression or be the few percent with genes
+controlling schizophrenic behaviour. He stresses that knowing how things work or
+where things go wrong doesn't mean that we should fix everything. So look at this
+room full of \TEX ies: we don't need to be all the same, use all the same, we
+don't need some dominance, we just need to accept and especially we need to
+understand that we can never fully understand (and solve) everything forever.
+
+Predictions, one of the themes, can be hard. It's not true that science has the
+answer to everything. There will always be room for speculation and maybe we will
+always need metaphysics too. I just started to read \quotation {What we cannot
+know} by Sautoy. For sure those present here can not predict how \TEX\ will go on
+and|/|or be remembered.
+
+\stopsection
+
+\startsection[title=Children of \TEX]
+
+I mentioned \quotation {Children of time}. The author lets you see their spidery
+world through spider eyes and physiology. They have different possibilities
+(eyesight, smell) than we do and also different mental capabilities. They evolve
+rapidly and have to cope conceptually with signals from a human surveillance
+satellite up in the sky. Eventually they need to deal with a bunch of (of course)
+quarrelling humans who want their place on the planet. We humans have some
+pre|-|occupation with spiders and other creatures. In a competitive world it is
+sometimes better to be suspicious (and avoid and flee) that to take a risk of
+being eaten. A frequently used example is that a rustle in a bush can be the wind
+or a lion, so best is to run.
+
+We are not that well adapted to our current environment. We evolved at a very
+slow pace so there was no need to look ahead more than a year. And so we still
+don't look too far ahead (and choose politicians accordingly). We can also not
+deal that well with statistics (Dawkins's \quotation {Climbing Mount Probability}
+is a good read) so we make false assumptions, or just forget.
+
+Does our typeset text really look that good on the long run, or do we cheat with
+statistics? It's not too hard to find a bad example of something not made by
+\TEX\ and extrapolate that to the whole body of typeset documents. Just like we
+can take a nice example of something done by \TEX\ and assume that what we do
+ourselves is equally okay. I still remember the tests we did with \PDFTEX\ and
+hz. When \THANH\ and I discussed that with Hermann Zapf he was not surprised at
+all that no one saw a difference between the samples and instead was focusing on
+aspects that \TEX ies are told to look at, like two hyphens in a row.
+
+A tool like \TEX\ has a learning curve. If you don't like that just don't use it.
+If you think that someone doesn't like that, don't enforce this tool on that
+someone. And don't use (or lie with) statistics. Much better arguments are that
+it's a long|-|lived stable tool with a large user base and support. That it's not
+a waste of time. Watching a designer like Hermann Zapf draw shapes is more fun
+than watching click and point in heavily automated tools. It's probably also less
+fun to watch a \TEX ie converge towards a solution.
+
+Spiders are resilient. Ants maybe even more. Ants will survive a nuclear blast
+(mutations might even bring them benefits), they can handle the impact of a
+meteorite, a change in climate won't harm them much. Their biggest enemy is
+probably us, when we try to wipe them out with poison. But, as long as they keep
+a low profile they're okay. \TEX\ doesn't fit into the economic model as there is
+no turnaround involved, no paid development, it is often not seen at all, it's
+just a hit in a search engine and even then you might miss it (if only because no
+one pays for it being shown at the top).
+
+We can learn from that. Keeping a low profile doesn't trigger the competition to
+wipe you out. Many (open source) software projects fade away: some big company
+buys out the developer and stalls the project or wraps what they bought in their
+own stuff, other projects go professional and enterprise and alienate the
+original users. Yet others abort because the authors lose interest. Just like the
+ideals of socialism don't automatically mean that every attempt to implement it
+is a success, so not all open source and free software is good (natured) by
+principle either. The fact that communism failed doesn't mean that capitalism is
+better and a long term winner. The same applies to programs, whether successful
+or not.
+
+Maybe we should be like the sheep. Dennett uses these animals as a clever
+species. They found a way to survive by letting themselves (unconsciously) be
+domesticated. The shepherd guarantees food, shelter and protection. He makes sure
+they don't get ill. Speaking biologically: they definitely made sure that many
+copies of their genes survived. Cows did the same and surprisingly many of them
+are related due to the fact that they share the same father (something now trying
+to be reverted). All \TEX\ spin|-|offs relate to the same parent, and those that
+survived are those that were herded by user groups. We see bits and pieces of
+\TEX\ end up in other applications. Hyphenation is one of them. Maybe we should
+settle for that small victory in a future hall of fame.
+
+When I sit on my balcony and look at the fruit trees in my garden, some simple
+math can be applied. Say that one of the apple trees has 100 apples per year and
+say that this tree survives for 25 years (it's one of those small manipulated
+trees). That makes 2.500 apples. Without human intervention only a few of these
+apples make it into new trees, otherwise the whole world would be dominated by
+apple trees. Of course that tree now only survives because we permit it to
+survive, and for that it has to be humble (something that is very hard for modern
+Apples). Anyway, the apple tree doesn't look too unhappy.
+
+A similar calculation can be done for birds that nest in the trees and under my
+roof. Given that the number of birds stays the same, most of energy spent on
+raising offspring is wasted. Nevertheless they seem to enjoy life. Maybe we
+should be content if we get one enthusiastic new user when we demonstrate \TEX\
+to thousands of potential users.
+
+Maybe, coming back to the themes of the conference, we should not come up with
+these kinds of themes. We seem to be quite happy here. Talking about the things
+that we like, meeting people. We just have to make sure that we survive. Why not
+stay low under the radar? That way nothing will see us as a danger. Let's be like
+the ants and spiders, the invisible hive mind that carries our message, whatever
+that is.
+
+When Dennett discusses language he mentions (coined) words that survive in
+language. He also mentions that children pick up language no matter what. Their
+minds are made for it. Other animals don't do that: they listen but don't start
+talking back. Maybe \TEX\ is just made for certain minds. Some like it and pick
+it up, while for others it's just noise. There's nothing wrong with that.
+Predilection can be a user property.
+
+\stopsection
+
+\startsection[title={The unexpected}]
+
+In a discussion with Dawkins the well|-|spoken astrophysicist Neil deGrasse Tyson
+brings up the following. We differ only a few percent in \DNA\ from a chimp but
+quite a lot in brain power, so how would it be if an alien that differs a few
+percent (or more) passes by earth. Just like we don't talk to ants or chimps or
+whatever expecting an intelligent answer, whatever passes earth won't bother
+wasting time on us. Our rambling about the quality of typesetting probably sounds
+alien to many people who just want to read and who happily reflow a text on an
+ebook device, not bothered by a lack of quality.
+
+\startplacefigure[location=top]
+ \startcombination[nx=4,ny=1,width=\textwidth,distance=0pt]
+ {\externalfigure[covers/live-as-we-do-not-know-it.jpg][height=5cm]} {astrobiology}
+ {\externalfigure[covers/life-on-the-edge.jpg] [height=5cm]} {quantumbiology}
+ {\externalfigure[covers/rare-earth.jpg] [height=5cm]} {astrophysics}
+ {\externalfigure[covers/austerity.jpg] [height=5cm]} {economics}
+ \stopcombination
+\stopplacefigure
+
+We tend to take ourselves as reference. In \quotation {Rare Earth} Ward and
+Brownlee extrapolate the possibility of life elsewhere in the universe. They are
+not alone in thinking that while on one hand applying statistics to these
+formulas of possible life on planets there might also be a chance that we're the
+only intelligent species ever evolved. In a follow up, \quotation {Life as we do
+not know it} paleontologist and astrobiologist Ward (one of my favourite authors)
+discusses the possibility of life not based on carbon, which is not natural for a
+carbon based species. Carl Sagan once pointed out that an alien species looking
+down to earth can easily conclude that cars are the dominant species on earth and
+that the thingies crawling in and out them are some kind of parasites. So, when
+we look at the things that somehow end up on paper (as words, sentences,
+ornaments, etc.), what is dominant there? And is what we consider dominant really
+that dominant in the long run? You can look at a nice page as a whole and don't
+see the details of the content. Maybe beauty hides nonsense.
+
+When \TEX ies look around they look to similar technologies. Commands in shells
+and solutions done by scripting and programming. This make sense in the
+perspective of survival. However, if you want to ponder alternatives, maybe not
+for usage but just for fun, a completely different perspective might be needed.
+You must be willing to accept that communicating with a user of a \WYSIWYG\
+program might be impossible. If mutual puzzlement is a fact, then they can either
+be too smart and you can be too dumb or the reverse. Or both approaches can be
+just too alien, based on different technologies and assumptions. Just try to
+explain \TEX\ to a kid 40 years younger or to an 80 year old grandparent for that
+matter. Today you can be very clever in one area and very stupid in another.
+
+In another debate, Neil deGrasse Tyson asks Dawkins the question why in science
+fiction movies the aliens look so human and when they don't, why they look so
+strange, for instance like cumbersome sluggish snails. The response to that is
+one of puzzlement: the opponent has no reference of such movies. In discussions
+old \TEX ies like to suggest that we should convert young users. They often don't
+understand that kids live in a different universe.
+
+How often does that happen to us? In a world of many billions \TEX\ has its place
+and can happily coexist with other typesetting technologies. Users of other
+technologies can be unaware of us and even create wrong images. In fact, this
+also happens in the community itself: (false) assumptions turned into
+conclusions. Solutions that look alien, weird and wrong to users of the same
+community. Maybe something that I present as hip and modern and high|-|\TEX\ and
+promising might be the opposite: backward, old|-|fashioned and of no use to
+others. Or maybe it is, but the audience is in a different mindset. Does it
+matter? Let's just celebrate that diversity. (So maybe, instead of discussing the
+conference theme, I should have talked about how I abuse \LUATEX\ in controlling
+lights in my home as part of some IoT experiments.)
+
+\stopsection
+
+\startsection[title=What drives us]
+
+I'm no fan of economics and big money talk makes me suspicious. I cannot imagine
+working in a large company where money is the drive. It also means that I have
+not much imagination in that area. We get those calls at the office from far away
+countries who are hired to convince us by phone of investments. Unfortunately
+mentioning that you're not at all interested in investments or that multiplying
+money is irrelevant to you does not silence the line. You have to actively kill
+such calls. This is also why I probably don't understand today's publishing world
+where money also dominates. Recently I ran into talks by Mark Blyth about the
+crisis (what crisis?) and I wish I could argue like he does when it comes to
+typesetting and workflows. He discusses quite well that most politicians have no
+clue what the crisis is about.
+
+I think that the same applies to the management of publishers: many have no clue
+what typesetting is about. So they just throw lots of money into the wrong
+activities, just like the central banks seem to do. It doesn't matter if we \TEX
+ies demonstrate cheap and efficient solutions.
+
+Of course there are exceptions. We're lucky to have some customers that do
+understand the issues at hand. Those are also the customers where authors may use
+the tools themselves. Educating publishers, and explaining that authors can do a
+lot, might be a premise, predilection and prediction in one go! Forget about
+those who don't get it: they will lose eventually, unfortunately not before they
+have reaped and wasted the landscape.
+
+Google, Facebook, Amazon, Microsoft and others invest a lot in artificial
+intelligence (or, having all that virtual cash, just buy other companies that
+do). They already have such entities in place to analyze whatever you do. It is
+predicted that at some point they know more about you then you know yourself.
+Reading Luke Dormehl's \quotation {The Formula} is revealing. So what will that
+do with our so|-|called (disputed by some) free will? Can we choose our own
+tools? What if a potential user is told that all his or her friends use
+WhateverOffice so they'd better do that too? Will subtle pressure lead them or
+even us users away from \TEX ? We already see arguments among \TEX ies, like
+\quotation {It doesn't look updated in 3 years, is it still good?} Why update
+something that is still valid? Will the community be forced to update everything,
+sort of fake updates. Who sets out the rules? Do I really need to update (or
+re|-|run) manuals every five years?
+
+Occasionally I visit the Festo website. This is a (family owned) company that
+does research at the level that used to be common in large companies decades ago.
+If I had to choose a job, that would be the place to go to. Just google for
+\quotation {festo bionic learning network} and you understand why. We lack this
+kind of research in the field we talk about today: research not driven by
+commerce, short term profit, long term control, but because it is fundamental
+fun.
+
+Last year Alan Braslau and I spent some time on \BIBTEX. Apart from dealing with
+all the weird aspects of the \APA\ standard, dealing with the inconsistently
+constructed author fields is a real pain. There have been numerous talks about
+that aspect here at Bacho\TEX\ by Jean|-|Michel Hufflen. We're trying to deal
+with a more than 30|-|year|-|old flawed architecture. Just look back over a curve
+that backtracks 30 years of exponential development in software and databases and
+you realize that it's a real waste of time and a lost battle. It's fine to have a
+text based database, and stable formats are great, but the lack of structure is
+appalling and hard to explain to young programmers. Compare that to the Festo
+projects and you realize that there can be more challenging projects. Of course,
+dealing with the old data can be a challenge, a necessity and eventually even be
+fun, but don't even think that it can be presented as something hip and modern.
+We should be willing to admit flaws. No wonder that Jean|-|Michel decided to
+switch to talking about music instead. Way more fun.
+
+Our brains are massively parallel bio|-|machinery. Groups of neurons cooperate
+and compete for attention. Coming up with solutions that match what comes out of
+our minds demands a different approach. Here we still think in traditional
+programming solutions. Will new ideas about presenting information, the follow up
+on books come from this community? Are we the innovative Festo or are we an old
+dinosaur that just follows the fashion?
+
+\stopsection
+
+\startsection[title=User experience]
+
+Here is a nice one. Harari spends many pages explaining that research shows that
+when an unpleasant experience has less unpleasantness at the end of the period
+involved, the overall experience is valued according to the last experience. Now,
+this is something we can apply to working with \TEX: often, the more you reach
+the final state of typesetting the more it feels as all hurdles are in the
+beginning: initial coding, setting up a layout, figuring things out, etc.
+
+It can only get worse if you have a few left|-|over typesetting disasters but
+there adapting the text can help out. Of course seeing it in a cheap bad print
+can make the whole experience bad again. It happens. There is a catch here: one
+can find lots of bad|-|looking documents typeset by \TEX. Maybe there frustration
+(or indifference) prevails.
+
+I sometimes get to see what kind of documents people make with \CONTEXT\ and it's
+nice to see a good looking thesis with diverse topics: science, philosophy,
+music, etc. Here \TEX\ is just instrumental, as what it is used for is way more
+interesting (and often also more complex) than the tool used to get it on paper.
+We have conferences but they're not about rocket science or particle
+accelerators. Proceedings of such conferences can still scream \TEX, but it's the
+content that matters. Here somehow \TEX\ still sells itself, being silently
+present in rendering and presentations. It's like a rootkit: not really
+appreciated and hard to get rid of. Does one discuss the future of rootkits other
+than in the perspective of extinction? So, even as an invisible rootkit, hidden
+in the workings of other programs, \TEX's future is not safe. Sometimes, when you
+install a Linux system, you automatically get this large \TEX\ installation,
+either because of dependencies or because it is seen as a similar toolkit as for
+instance Open (or is it Libre) Office. If you don't need it, that user might as
+well start seeing it as a (friendly) virus.
+
+\stopsection
+
+\startsection[title=Conclusion]
+
+At some point those who introduced computers in typesetting had no problem
+throwing printing presses out of the window. So don't pity yourself if at some
+point in the near future you figure out that professional typesetting is no
+longer needed. Maybe once we let machines rule the world (even more) we will be
+left alone and can make beautiful documents (or whatever) just for the joy, not
+bothering if we use outdated tools. After all, we play modern music on old
+instruments (and the older rock musicians get, the more they seem to like
+acoustic).
+
+There are now computer generated compositions that experienced listeners cannot
+distinguish from old school. We already had copies of paintings that could only
+be determined forgeries by looking at chemical properties. Both of these
+(artificial) arts can be admired and bring joy. So, the same applies to fully
+automated typeset novels (or runtime rendered ebooks). How bad is that really?
+You don't dig channels with your hand. You don't calculate logarithmic tables
+manually any longer.
+
+However, one of the benefits of the Internet is watching and listening to great
+minds. Another is seeing musicians perform, which is way more fun that watching a
+computer (although googling for \quotation {animusic} brings nice visuals).
+Recently I ran into a wooden musical computer made by \quotation {Wintergatan}
+which reminded me of the \quotation {Paige Compositor} that we use in a \LUATEX\
+cartoon. Watching something like that nicely compensates for a day of rather
+boring programming. Watching how the marble machine x (mmx) evolves is yet
+another nice distraction.
+
+Now, the average age of the audience here is pretty high even if we consider that
+we get older. When I see solutions of \CONTEXT\ users (or experts) posted by
+(young) users on the mailing list or stack exchange I often have to smile because
+my answer would have been worse. A programmable system invokes creative
+solutions. My criterion is always that it has to look nice in code and has some
+elegance. Many posted solutions fit. Do we really want more automation? It's more
+fun to admire the art of solutions and I'm amazed how well users use the
+possibilities (even ones that I already forgot).
+
+One of my favourite artists on my weekly \quotation {check youtube} list is Jacob
+Collier. Right from when I ran into him I realized that a new era in music had
+begun. Just google for his name and \quotation {music theory interview} and you
+probably understand what I mean. When Dennett comments on the next generation
+(say up to 25) he wonders how they will evolve as they grow up in a completely
+different environment of connectivity. I can see that when I watch family
+members. Already long ago Greg Bear wrote the novel \quotation {Darwin's
+Children}. It sets you thinking and when looking around you even wonder if there
+is a truth in it.
+
+There are folks here at Bacho\TEX\ who make music. Now imagine that this is a
+conference about music and that the theme includes the word \quotation {future}.
+Then, imagine watching that video. You see some young musicians, one of them
+probably one of the musical masterminds of this century, others instrumental to
+his success, for instance by wrapping up his work. While listening you realize
+that this next generation knows perfectly well what previous generations did and
+achieved and how they influenced the current. You see the future there. Just look
+at how old musicians reflect on such videos. (There are lots of examples of youth
+evolving into prominent musicians around and I love watching them). There is no
+need to discuss the future, in fact, we might make a fool of ourselves doing so.
+Now back to this conference. Do we really want to discuss the future? What we
+think is the future? Our future? Why not just hope that in the flow of getting
+words on a medium we play our humble role and hope we're not forgotten but
+remembered as inspiration.
+
+One more word about predicting the future. When Arthur Clarke's \quotation {2001:
+A Space Odyssey} was turned into a movie in 1968, a lot of effort went into
+making sure that the not so far ahead future would look right. In 1996 scientists
+were asked to reflect on these predictions in \quotation {Hal's Legacy}. It
+turned out that most predictions were plain wrong. For instance computers got way
+smaller (and even smaller in the next 20 years) while (self|-|aware) artificial
+intelligence had not arrived either. So, let's be careful in what we predict (and
+wish for).
+
+\stopsection
+
+\startsection[title=No more themes]
+
+We're having fun here, that's why we come to Bacho\TEX\ (predilection). That
+should be our focus. Making sure that \TEX's future is not so much in the cutting
+edge but in providing fun to its users (prediction). So we just have to make sure
+it stays around (premise). That's how it started out. Just watch at Don Knuth's
+3:16 poster: via \TEX\ and \METAFONT\ he got in contact with designers and I
+wouldn't be surprised if that sub|-|project was among the most satisfying parts.
+So, maybe instead of ambitious themes the only theme that matters is: show what
+you did and how you did it.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/musings/musings-contents.tex b/doc/context/sources/general/manuals/musings/musings-contents.tex
new file mode 100644
index 000000000..45b21ec60
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-contents.tex
@@ -0,0 +1,7 @@
+\startcomponent musings-contents
+
+\starttitle[title=Content]
+ \placelist[chapter][criterium=text,width=2em]
+\stoptitle
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/musings/musings-introduction.tex b/doc/context/sources/general/manuals/musings/musings-introduction.tex
new file mode 100644
index 000000000..d8dadd743
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-introduction.tex
@@ -0,0 +1,31 @@
+% language=uk
+
+\startcomponent musings-introduction
+
+\environment musings-style
+
+\startchapter[title={Introduction}]
+
+This is a collection of articles and wrap|-|ups that don't suit in other manuals
+or collections. Some are published, some meant as draft for a presentation.
+
+The \quotation {Children of \TEX} article is the framework for a presentation at
+Bacho\TEX\ 2017 in Poland, and covers the main theme of the conference. In the
+aftermath of that conference I wrote \quotation {Advertising \TEX} and later
+\quotation {Why use \TEX?}. The 2018 Bacho\TEX\ conference theme is explored in
+\quotation {What’s to stay, what’s to go}. After a short discussion on the
+\CONTEXT\ mailing list about stability (at the moment that \MKII\ had been frozen
+for more than a decade but is still used without problems) I wrote \quotation
+{Stability}.
+
+Many of the thoughts in these articles are influenced by discussions with my
+colleagues Ton Otten and Kees van Marle. Operating in a similar arena, they
+provide me the reflection needed to sort out my thoughts on these matters.
+
+\startlines
+Hans Hagen
+Hasselt NL
+2017\endash 1028
+\stoplines
+
+\stopchapter
diff --git a/doc/context/sources/general/manuals/musings/musings-perception.tex b/doc/context/sources/general/manuals/musings/musings-perception.tex
new file mode 100644
index 000000000..993604473
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-perception.tex
@@ -0,0 +1,180 @@
+% language=uk
+
+\definefontfeature[ligatures][liga=yes,mode=node]
+
+\startcomponent musings-perception
+
+\environment musings-style
+
+\startchapter[title=Advertising \TEX]
+
+I can get upset when I hear \TEX ies boast about the virtues of \TEX\ compared to
+for instance Microsoft Word. Not that I feel responsible for defending a program
+that I never use(d) but attacking something for no good reason makes not much
+sense to me. It is especially annoying when the attack is accompanied by a
+presentation that looks pretty bad in design and typography. The best
+advertisements for \TEX\ should of course come from outside the \TEX\ community,
+by people impressed by its capabilities. How many \TEX ies can really claim that
+Word is bad when they never tried to make something in it with a similar learning
+curve as they had in \TEX\ or the same amount of energy spent in editing and
+perfecting a word|-|processor|-|made document.
+
+In movies where computer technology plays a role one can encounter weird
+assumptions about what computers and programs can do. Run into a server room,
+pull one disk out of a \RAID-5 array and get all information from it. Connect
+some magic device to a usb port of a phone and copy all data from it in seconds.
+Run a high speed picture or fingerprint scan on a computer (probably on a remote
+machine) and show all pictures flying by. Okay, it's not so far from other
+unrealistic aspects in movies, like talking animals, so maybe it is just a
+metaphor for complexity and speed. When zapping channels on my television I saw
+\in{figure}[fig:tex-in-movie] and as the media box permits replay I could make a
+picture. I have no clue what the movie was about or what movie it was so a
+reference is lacking here. Anyway it's interesting that seeing a lot of \TEX\
+code flying by can impress someone: the viewer, even if no \TEX ie will ever see
+that on the console unless in some error or tracing message and even then it's
+hard to get that amount. So, the viewer will never realize that what is seen is
+definitely not what a \TEX ie wants to see.
+
+\startplacefigure[title={\TEX\ in a movie},reference=fig:tex-in-movie]
+ \externalfigure[tex-in-movie.jpg][height=8cm]
+\stopplacefigure
+
+So, as that kind of free advertisement doesn't promote \TEX\ well, what of an
+occasional mentioning of \TEX\ in highly|-|regarded literature? When reading
+\quotation {From bacteria to Bach and back, the evolution of minds} by Daniel
+Dennett I ran into the following:
+
+\startquotation
+In Microsoft Word, for instance, there are the typographical operations of
+superscript and subscript, as illustrated by
+
+\startnarrower
+base\high{power}
+\stopnarrower
+
+and
+
+\startnarrower
+human\low{female}
+\stopnarrower
+
+But try to add another superscript to base\high{power}\emdash it {\em should}
+work, but it doesn't! In mathematics, you can raise powers to powers to powers
+forever, but you can't get Microsoft Word to display these (there are other
+text|-|editing systems, such as TeX, that can). Now, are we sure that human
+languages make use of true recursion, or might some or all of them be more like
+Microsoft Word? Might our interpretation of grammars as recursive be rather an
+elegant mathematical idealization of the actual \quotation {moving parts} of a
+grammar?
+\stopquotation
+
+Now, that book is a wonderfully interesting read and the author often refers to
+other sources. When one reads some reference (with a quote) then one assumes that
+what one reads is correct, and I have no reason to doubt Dennett in this. But
+this remark about \TEX\ has some curious inaccuracies. \footnote {Of course one
+can wonder in general that when one encounters such an inaccuracy, how valid
+other examples and conclusions are. However, consistency in arguments and
+confirmation by other sources can help to counter this.}
+
+First of all a textual raise or lower is normally not meant to be recursive.
+Nesting would have interesting consequences for the interline space so one will
+avoid it whenever possible. There are fonts that have superscript and subscript
+glyphs and even \UNICODE\ has slots for a bunch of characters. I'm not sure what
+Word does: take the special glyph or use a scaled down copy?
+
+Then there is the reference to \TEX\ where we can accept that the \quotation {E}
+is not lowered but just kept as a regular \quotation {e}. Actually the mentioning
+of nested scripts refers to typesetting math and that's what the superscripts and
+subscripts are for in \TEX. In math mode however, one will normally raise or
+lower symbols and numbers, not words: that happens in text mode.
+
+While Word will use the regular text font when scripting in text mode, a \TEX\
+user will either have to use a macro to make sure that the right size (and font)
+is used, or one can revert to math mode. But how to explain that one has to enter
+math and then explicitly choose the right font? Think of this:
+
+\startbuffer
+efficient\high{efficient} or
+efficient$^{\text{efficient}}$ or \par
+{\bf efficient\high{efficient} or
+efficient$^{\text{efficient}}$}
+\stopbuffer
+
+\typebuffer
+
+Which gives (in Cambria)
+
+\getbuffer
+
+Now this,
+
+\startbuffer
+efficient\high{efficient\high{efficient}} or
+efficient$^{\text{efficient$^{\text{efficient}}$}}$ or \par
+{\bf efficient\high{efficient\high{efficient}} or
+efficient$^{\text{efficient$^{\text{efficient}}$}}$}
+\stopbuffer
+
+\typebuffer
+
+will work okay but the math variant is probably quite frightening at a glance for
+an average Word user (or beginner in \TEX) and I can understand why someone would
+rather stick to click and point.
+
+\getbuffer
+
+Oh, and it's tempting to try the following:
+
+\startbuffer
+efficient{\addff{f:superiors}efficient}
+\stopbuffer
+
+\typebuffer
+
+but that only works with fonts that have such a feature, like Cambria:
+
+\blank {\switchtobodyfont[cambria]\getbuffer} \blank
+
+To come back to Dennett's remark: when typesetting math in Word, one just has to
+switch to the math editing mode and one can have nested scripts! And, when using
+\TEX\ one should not use math mode for text scripts. So in the end in both
+systems one has to know what one is doing, and both systems are equally capable.
+
+The recursion example is needed in order to explain how (following recent ideas
+from Chomsky) for modern humans some recursive mechanism is needed in our
+wetware. Now, I won't go into details about that (as I can only mess up an
+excellent explanation) but if you want to refer to \TEX\ in some way, then
+expansion \footnote{Expanding macros actually works well with tail recursion.} of
+(either combined or not) snippets of knowledge might be a more interesting model
+than recursion, because much of what \TEX\ is capable of relates to expansion.
+But I leave that to others to explore. \footnote {One quickly starts thinking of
+how \cs {expandafter}, \type {noexpand}, \type {unexpanded}, \type {protected}
+and other primitives can be applied to language, understanding and also
+misunderstanding.}
+
+Now, comparing \TEX\ to Word is always kind of tricky: Word is a text editor with
+typesetting capabilities and \TEX\ is a typesetting engine with programming
+capabilities. Recursion is not really that relevant in this perspective. Endless
+recursion in scripts makes little sense and even \TEX\ has its limits there: the
+\TEX\ math engine only distinguishes three levels (text, script and scriptscript)
+and sometimes I'd like to have a level more. Deeper nesting is just more of
+scriptscript unless one explicitly enforces some style. So, it's recursive in the
+sense that there can be many levels, but it also sort of freezes at level three.
+
+\startplacefigure[title={Nicer than \TEX},reference=fig:nicer-than-tex]
+ \externalfigure[mathematics.png][width=\textwidth]
+\stopplacefigure
+
+I love \TEX\ and I like what you can do with it and it keeps surprising me. And
+although mathematics is part of that, I seldom have to typeset math myself. So, I
+can't help that \in {figure} [fig:nicer-than-tex] impresses me more. It even has
+the so|-|familiar|-|to|-|\TEX ies dollar symbols in it: the poem \quotation
+{Poetry versus Orchestra} written by Hollie McNish, music composed by Jules
+Buckley and artwork by Martin Pyper (I have the \DVD\ but you can also find it on
+\YOUTUBE). It reminds me of Don Knuth's talk at a \TUG\ meeting. In \TUGBOAT\
+31:2 (2010) you can read Don's announcement of his new typesetting engine i\TEX:
+\quotation {Output can be automatically formatted for lasercutters, embroidery
+machines, \THREED\ printers, milling machines, and other \CNC\ devices \unknown}.
+Now that is something that Word can't do!
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/musings/musings-roadmap.tex b/doc/context/sources/general/manuals/musings/musings-roadmap.tex
new file mode 100644
index 000000000..f8771ba42
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-roadmap.tex
@@ -0,0 +1,372 @@
+% language=uk
+
+% \showfontkerns
+
+\startcomponent musings-roadmap
+
+\environment musings-style
+
+\startchapter[title={\METATEX, a roadmap}]
+
+% \startlines \setupalign[flushright]
+% Hans Hagen
+% Hasselt NL
+% September 2018
+% \stoplines
+
+\startsection[title={Introduction}]
+
+Here I will shortly wrap up the state of \LUATEX\ and \CONTEXT\ in fall 2018. I
+made the first draft of this article as preparation for the \CONTEXT\ meeting
+where we also discussed the future. I updated the text afterwards to match the
+decisions made there. It's also a personal summary of thoughts and discussions
+with team members about where to move next.
+
+\stopsection
+
+\startsection[title={The state of affairs}]
+
+After a dozen years the development of \LUATEX\ has reached a state where adding
+more functionality and|/|or opening up more of the internals makes not much
+sense. Apart from fixes and maybe some minor extensions, version 1.10 is what you
+get. Users can do enough in \LUA\ and there is not much to gain in convenience
+and performance. Of course some of the code can and will be cleaned up, as we
+still see the effects of going from \PASCAL\ to \CWEB\ to \CCODE. In the process
+consistency is on the radar so we might occasionally add a helper. But we also
+don't want to move too far away from the original code, which is for instance why
+we keep names, keys and other properties found in original \TEX, which in turn
+leads to some inconsistencies with extensions added over time. We have to accept
+that.
+
+Because \LUATEX\ development is closely related to \CONTEXT\ development,
+especially \MKIV, we've also reached the moment that we can get rid of some older
+code and assume the latest \LUATEX\ to be used. Because we do so much in \LUA\
+the question is always to what extent the benefits outweigh the drawbacks. Just
+in case you wonder why we use \LUA\ extensively, the main reason is that it is
+easier and more efficient to manage data in this language and modern typesetting
+needs much data. It also permits us to extend regular \TEX\ functionality. But,
+one should not overrate the impact: we still let \TEX\ do what \TEX\ is best at!
+
+Performance is quite important. It doesn't make sense to create a powerful
+typesetting system where processing a page takes a second. We have discussed
+performance before since one of the complaints about \LUATEX\ is that it is slow.
+A simple, basic test is this:
+
+\starttyping
+\starttext
+ \dorecurse{1000}{\input tufte \par}
+\stoptext
+\stoptyping
+
+This involves 1000 times loading a file (and reporting that on the console, which
+can influence runtime), typesetting paragraphs, splitting of a page and of course
+loading fonts and saving to the \PDF\ file. When I run this on a modest machine,
+I get these (relative) timings for the (about) 225 pages:
+
+\starttabulate[|l|c|c|c|c|]
+\BC \TEX\ engine used \BC \PDFTEX \BC \LUATEX \BC \LUAJITTEX \BC \XETEX \NC \NR
+\BC runtime in seconds \NC 2.0 \NC 3.9 \NC 3.0 \NC 8.4 \NC \NR
+\stoptabulate
+
+Now, as expected the 8 bit \PDFTEX\ is the winner here but \LUATEX\ is not doing
+that bad. I don't know why \XETEX\ is so much slower, maybe because its 64 bit
+binary is less optimal. I once noticed that a 64 bit \PDFTEX\ performed worse on
+such a test than \LUATEX, for which I always use 64 bit binaries.
+
+If you consider that often much more is done than in this example, you can take
+my word that \LUATEX\ quickly outpaces \PDFTEX\ on more complex tasks. In that
+sense it is now our benchmark. It must be said that the \MKIV\ code is probably a
+bit more efficient than the \MKII\ code but that doesn't matter much in this
+simple test because hardly any macro magic happens here; it mostly tests basic
+font processing, paragraph building and page construction. I don't think that I
+can squeeze out more pages per second, at least not without users telling me
+where they encounter bottlenecks that don't result from their style coding. It's
+no problem to write inefficient macros (or styles) so normally a user should
+first carefully check her|/|his own work. Using a more modern \CPU\ with proper
+caching and an \SSD\ helps too.
+
+So, to summarize, we can say that with version 1.10 \LUATEX\ is sort of finished.
+Our mission is now to make \LUATEX\ robust and stable. Things can be added and
+improved, but these are small and mostly consistency related.
+
+\stopsection
+
+\startsection[title={More in \LUA}]
+
+Till now I always managed to add functionality to \CONTEXT\ without hampering
+performance too much. Of course the biggest challenge is always in handling fonts
+and common features like color because that all happens in \LUA. So, the question
+is, what if we delegate more of the core functionality to \LUA ? I will discuss a
+few options because the \CONTEXT\ developers and users need to agree on the path
+to follow. One question there is, are the possible performance hits (which can be
+an inconvenience) compensated by better and easier typesetting.
+
+Fonts, colors, special typesetting features like spaced kerning, protrusion,
+expansion, but also dropped caps, line numbering, marginal notes, tables,
+structure related things, floats and spacing are not open for much discussion.
+All the things that happen in \LUA\ combined with macros is there and will stay.
+But how about hyphenation, paragraph building and page building? And how about a
+leaner and meaner, future safe engine?
+
+Hyphenation is handled in the \TEX\ core. But in \CONTEXT\ already for years one
+can also use a \LUA\ based variant. There is room for extensions and improvements
+there. Interesting is that performance is more or less the same, so this is an
+area where we might switch to the \LUA\ method eventually. It compares to fonts,
+where node mode is more or less the standard and base mode the old way.
+
+Building the paragraphs in \LUA\ is also available in \MKIV, although it needs an
+update. Again performance is not that bad, so when we add features not possible
+(or hard to do) in regular \TEX, it might actually pay of to default to the
+par builder written in \LUA.
+
+The page builder is also doable in \LUA\ but so far I only played a bit with a
+\LUA\ based variant. I might pick up that thread. However, when we would switch to
+\LUA\ there, it might have a bit of a penalty, unless we combine it with some
+other mechanisms which is not entirely trivial, as it would mean a diversion from
+the way \TEX\ does it normally.
+
+How about math? We could at some point do math rendering in \LUA\ but because the
+core mechanism is the standard, it doesn't really makes much sense. It would also
+touch the soul of \TEX. But, I might give it a try, just for fun, so that I can
+play with it a bit. It's typically something for cold and rainy days with some
+music in the background.
+
+We already use \LUA\ in the frontend: locating and reading files in \TEX,
+\XML, \LUA\ and whatever input format. Normalization and manipulation is all
+active and available. The backend is also depending on \LUA, like support for
+special \PDF\ features and exporting to \XML . The engine still handles the page
+stream conversion, font inclusion and object management.
+
+The inclusion of images is also handled by the engine, although in \CONTEXT\ we
+can delegate \PDF\ inclusion to \LUA. Interesting is that this has no performance
+hit.
+
+With some juggling the page stream conversion can also be done in \LUA, and I
+might move that code into the \CONTEXT\ distribution. Here we do have a
+performance hit: about one second more runtime on the 14 seconds needed for the
+300 page \LUATEX\ manual and just over more than half a second on a 11 second
+\LUAJITTEX\ run. The manual has lots of tables, verbatim, indices and uses color
+as well as a more than average number of fonts and much time is spent in \LUA. So
+there is a price to pay there. I tried to speed that up but there is not much to
+gain there.
+
+So, say that we default to \LUA\ based hyphenation, which enables some new
+functionality, \LUA\ based par building, which permits some heuristics for corner
+cases, and \LUA\ based page building, which might result in more control over
+tricky cases. A total performance hit of some 5\% is probably acceptable,
+especially because by that time I might have replaced my laptop and won't notice
+the degrade. This still fits in the normal progress and doesn't really demand a
+roadmap or wider acceptance. And of course we would still use the same strategies
+as implemented in traditional \TEX\ as default anyway.
+
+\stopsection
+
+\startsection[title={A more drastic move}]
+
+More fundamental is the question whether we delegate more backend activity to
+\LUA\ code. If we decide to handle the page stream in \LUA, then the next
+question is, why not also delegate object management and font inclusion to
+\LUA. Now, keep in mind that this is all very \CONTEXT\ specific! Already for
+more than a decade we delegate a lot to \LUA, and also we have a rather tight
+control over this core functionality. This would mean that \CONTEXT\ doesn't
+really need the backend code in the engine. \footnote {For generic packages like
+TikZ we (can) provide some primitive emulators, which is rather trivial to
+implement.}
+
+That situation is actually not unique. For instance, already for a while we don't
+need the \LUATEX\ font loader either, as loading the \OPENTYPE\ files is done in
+\LUA. So, we could also get rid of the font loader code. Currently some code is
+shared with the font inclusion in the backend but that can be isolated.
+
+You can see a \TEX\ engine as being made from several parts, but the core really
+concerns only two processes: reading, storing and expanding macros on the one
+hand, and converting a stream of characters into lines, paragraphs, pages etc.
+Fonts are mostly an abstraction: they are visible in so called glyph nodes as
+font identifier (a number) and character code (also a number) properties. The
+result, nowadays being \PDF, is also an abstraction: at some point the engine
+converts the to be shipped out box in \PDF\ instructions, and in our case,
+relatively simple ones. The backend registers which characters and fonts are used
+and also includes the right resources. But, the backend is not part of the core
+as such! It has been introduced in \PDFTEX\ and is a so called extension.
+
+So, what does that all mean for a future version of \CONTEXT\ and \LUATEX ? It
+means that we can decide to follow up with a \CONTEXT\ that does more in \LUA,
+which means not hard coded in a binary, on the one hand, but that we can also
+decide to strip the engine from non|-|core code. But, given that \LUATEX\ is also
+used in other macro packages, this would mean a different engine. We cannot say
+that \LUATEX\ is stable when we also experiment with core components.
+
+We've seen folks picking up experimental versions assuming that it is a precursor
+to official code. So, in order to move on we need to avoid confusion: we need to
+use another name. Choosing a name is always tricky but as Taco already registered
+the \METATEX\ domain, and because in the \CONTEXT\ distribution you will find
+references to \METATEX, we will use that name for the future engine. Adding \LUA\
+to that name makes sense but then the name would become too long.
+
+The main difference between \METATEX\ and \LUATEX\ would be that the former has
+no file lookup library, no hardcoded font loader, and no backend generator (but
+possibly some helpers, and these need time to evolve). We're basically back where
+\TEX\ started but instead of coding these extensions in \PASCAL\ or \CCODE\ we
+use \LUA. We're also kind of back to when we first started experimenting with
+\LUATEX\ in \CONTEXT\ where test, write and rewrite were going in parallel. But,
+as said, we cannot impose that on a wide audience.
+
+If we go for such a lean and mean follow up, then we can also do a more drastic
+cleanup of obsolete code in \CONTEXT\ (dating from \ETEX, \PDFTEX, \ALEPH, etc.).
+We then are sort of back to where it all started: we go back to the basics. This
+might mean dropping some primitives (one can define them as dummy). Of course we
+could generalize some of the \CONTEXT\ code to provide the kicked out
+functionality but would that pay of? Probably not.
+
+Just for the record: replacing the handling of macros, registers, grouping, etc.\
+to \LUA\ is not really an option as the performance hit would make a large system
+like \CONTEXT\ sort of unusable: it's no option and not even considered (although
+I must admit that I have some experimental \LUA\ based \TEX\ parser code around).
+
+It is quite likely that building \METATEX\ from source for the moment will be an
+option to the build script. But we can also decide to simplify that process,
+which is possible because we only need one binary. But in general we can assume
+that one can generate \METATEX\ and \LUATEX\ from the same source. A first step
+probably is a further isolation of the backend code. The fontloader and file
+handling code already can be made optional.
+
+Given that we only need one binary (it being \LUATEX\ or \METATEX) and nowadays
+only use \OPENTYPE\ fonts, one can even start thinking of a mini distribution,
+possibly with a zipped resource tree, something we experimented with in the early
+days of \LUATEX.
+
+Another though I have been playing with is a better separation between low level
+and high level \CONTEXT\ commands, and whether the low level layer should be more
+generic in nature (so that one can run specific packages on top of it instead of
+the whole of \CONTEXT) but that might not be worth the trouble.
+
+\stopsection
+
+\startsection[title={Interlude}]
+
+If we look at the future, it's good to also look at the past. Opening up \TEX\
+the way we did has many advantages but also potential drawbacks. It works quite
+well in \CONTEXT\ because we ship an integrated package. I don't think that there
+are many users who kick in their own callbacks. It is possible but completely up
+to the user to make sure things work out well. Performance hits, interference,
+crashes: those who interfere with the internals can sort that out themselves. I'm
+not sure how well that works out in other macro packages but it is a time bomb if
+users start doing that. Of course the documented interfaces to use \LUA\ in
+\CONTEXT\ are supported. So far I think we're not yet bitten in the tail. We keep
+this aspect out of the discussion.
+
+Another important aspect is stability of the engine. Sometimes we get suggestions
+for changes or patches that works for a specific case but for sure will have side
+effects on \CONTEXT. Just as we don't test \LATEX\ side effects, \LATEX\ users
+don't check \CONTEXT. And we're not even talking of users who expect their code
+to keep working. A tight control over the source is important but cannot be we
+will not be around for ever. This means that at some point \LUATEX\ should not be
+changed any more, even when we observe side effects we want to get rid of,
+because these side effects can be in use. This is another argument for a stripped
+down engine. The less there is to mess with, the less the mess.
+
+\stopsection
+
+\startsection[title={Audience}]
+
+So how about \CONTEXT\ itself? Of course we can make it better. We can add more
+examples and more documentation. We can try to improve support. The main question
+for us (as developers) is who actually is our audience. From the mails coming to
+the \CONTEXT\ support list it looks like a rather diverse group of users.
+
+At \TEX\ meetings there are often discussions about promoting \TEX. I can agree
+on the fact that even for simple documents it makes a lot of sense to use \TEX,
+but who will take the first hurdles? How many people really produce a lot of
+documents? And how many need \TEX\ after maybe a short period of (enforced) usage
+at the university?
+
+It's not trivial to recognize the possibilities and power of the
+\LUATEX|-|\CONTEXT\ combination. We never got any serious requests for support
+from large organizations. In fact, we do use this combination in a few projects
+for educational publishers, but there it's actually the authors and editors doing
+the work. It's seldom company policy to use tools that efficiently automate
+typesetting. I dare to say that publishers are not really an audience at all:
+they normally delegate the task. They might accept \TEX\ documents but let them
+rekey or adapt far|-|far|-|away and as cheap as possible. Thinking of it, the
+main reason for Don Knuth for writing \TEX\ in the first place was the ability to
+control the look and feel and quality. It were developments at typesetters and
+publishers that triggered development of \TEX . It was user demand. And the
+success of \TEX\ was largely due to the unique personality and competence of the
+author.
+
+System integrators qualify as audience but I fear that \TEX\ is not considered
+hip and modern. It doesn't seem to matter if you can demonstrate that it can do a
+wonderful job efficiently and relatively cheap. Also the fact that an
+installation can be very stable on the long run is of no importance. Maybe that
+audience (market place) is all about \quotation {The more we have to program and
+update regularly, the merrier.}. Marketing \TEX\ is difficult.
+
+Those who render multiple products, maintain manuals, have to render many
+documents automatically qualify as audience. But often company policies,
+preferred suppliers, so called standard tools etc.\ are used as argument against
+\TEX. It's a missed opportunity.
+
+One needs a certain mindset to recognize the potential and the question is, how
+do we reach that audience. Drawing a roadmap for that is not easy but worth
+discussing. We're open for suggestions.
+
+% \footnote {It's kind of interesting that recently the \TEX\ User Group announced
+% its presence on Facebook and Twitter. Apart from wondering how that gets updated,
+% one can also wonder how many potential (or even current) users go there, given
+% that these platforms are subjected to rise and fall. I'm on neither of them and
+% don't plan to. Kids (our future users) that I know already said goodbye to them.
+% We'll see how that works out.}
+
+\stopsection
+
+\startsection[title={Conclusion}]
+
+At the \CONTEXT\ user meeting those present agreed that moving forward this way
+makes sense. This means that we will explore a lean and mean \METATEX\ alongside
+\LUATEX. There is no rush and it's all volunteer work so we will take our time
+for this. It boils down to some reshuffling of code so that we can remove the
+built|-|in font loader, file handling, and probably also \SYNCTEX\ because we can
+emulate that. Then the backend with its font inclusion code will be cleaned up a
+bit (we even discussed only supporting modern wide fonts). It's no big deal to
+adapt \CONTEXT\ to this (so it can and will support both \LUATEX\ and \METATEX).
+Eventually the backend might go away but now we're talking years ahead. By then
+we can also explore the option to make \METATEX\ start out as a \LUA\ function
+call (the main control loop) and become reentrant. There will probably not be
+many changes to the opened up \TEX\ kernel, but we might extend the \METAPOST\
+part a bit (some of that was discussed at the meeting) especially because it is a
+nice tool to visualize big data.
+
+As with \LUATEX\ development we will go in small steps so that we keep a working
+system. Of course \LUATEX\ is always there as stable fallback. The experiments
+will mostly happen in the experimental branch and binaries will be generated
+using the compile farm on the \CONTEXT\ garden, just as happens now. This also
+limits testing and exploring to the \CONTEXT\ community so that there are no side
+effects for mainstream \LUATEX\ usage.
+
+Nowadays, instead if roadmaps, we tend to use navigational gadgets that adapt
+themselves to the situation. On the road by car this can mean a detour and when
+walking around it can be going to suggested points of interest. During the
+excursion at the meeting, we noticed that after the drivers (navigators)
+synchronized their gadget with Jano, the routes that were followed differed a
+bit. We saw cars in front of going a different direction and cars behind us
+arriving from a different direction. So, even when we talk about roadmaps, our
+route can be adapted to the situation.
+
+Now here is something to think about. If you look at the \TEX\ community you will
+notice that it's an aging community. User groups seem to loose members, although
+the \CONTEXT\ group is currently still growing. Fortunately we see a new
+generation taking interest and the \CONTEXT\ users are a pleasant mix and it
+makes me stay around. I see it as an \quote {old timers} responsibility to have
+\TEX\ and its environment in a healthy state by the time I retire from it
+(although I have no plans in that direction). In parallel to the upcoming
+development I think we will also see a change in \TEX\ use and usage. This aspect
+was also discussed at the meeting and for sure will get a follow up on the
+mailing lists and future meetings. It might as well influence the decisions we
+make the upcoming years. So far \TEX\ has never failed us in it's flexibility and
+capacity to adapt, so let's end on that positive note.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/musings/musings-stability.tex b/doc/context/sources/general/manuals/musings/musings-stability.tex
new file mode 100644
index 000000000..7dc35c6be
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-stability.tex
@@ -0,0 +1,388 @@
+% language=uk
+
+\environment musings-style
+
+\startcomponent musings-stability
+
+\startchapter[title={Stability}]
+
+\startsubject[title=Introduction]
+
+How stable is \CONTEXT ? This question is hard to answer. For instance \MKII\
+hasn't changed for years and seems to work quite well: no changes equals
+stability. Those who use it can do with what it offers. The potentially sensitive
+dependencies on for instance fonts are probably absent because there is not much
+development in the 8 bit fonts arena. As long as these are available we're okay,
+in fact, \OPENTYPE\ fonts are more a moving target and therefore less stable.
+
+What do we mean by stable? The fundamental differences between an 8 bit engine
+(and fonts) and an \UNICODE\ aware engine able to handle \OPENTYPE\ fonts is
+substantial which is why we dropped some functionality and added some relevant
+new. One can consider that a problem but in practice using fonts has become
+easier so no one is hurt by it. Here we need to keep in mind that \PDFTEX\ is
+really stable: it uses fonts and technology that doesn't change. On the other
+hand \XETEX\ and \LUATEX\ follow new trends. Thereby \XETEX\ uses libraries,
+which introduces a dependency and instability, while \LUATEX\ assumes solutions
+in \LUA\ which means that users and macro writers can tweak and thereby also
+introduce instability (but at least one can adapt that code).
+
+Due to the way the user interface is set up, it is unlikely that \CONTEXT\ will
+change. But the fact that we now have \LUA\ available means that many commands
+have been touched. Most behave compatible, some have more functionality, and of
+course we have a \LUA\ interface. We include a lot of support code which also
+lessens dependencies.
+
+The user input is normally \TEX\ but when you use \XML\ the move to \MKIV\ meant
+that we dropped the \MKII\ way of dealing with it in favour of a completely new
+mechanism. I get the impression that those using \XML\ don't regret that change.
+Talking of stability the \MKIV\ \XML\ interface is typically a mechanism that is
+stable and might change little. We can add new trickery but the old stays as it
+is.
+
+If we look at the output, there is \DVI\ and \PDF. In \MKII\ the \DVI\ could
+become \POSTSCRIPT. As there are different \DVI\ post|-|processors the backend
+code was using a plug|-|in model. Contrary to other macro packages there was only
+one so called format that could adapt itself to the required (engine specific)
+output. A \CONTEXT\ run has always been managed by a wrapper so users were not
+bothered much by what \TEX\ engine they used and|/|or what backend was triggered.
+This changed with \MKIV\ where we use just \LUATEX, always produce \PDF\ and
+optionally can export \XML. But again the run is managed by a wrapper, which
+incidentally is written in \LUA\ and thereby avoids dependencies on for instance
+\PERL, \RUBY\ or \PYTHON, which are moving targets, use libraries and additional
+user code, and thereby are potentially instable too.
+
+The \PDF\ code that is produced is a mix of what the engine spits out and what
+the macro package injects. The code is normally rather simple. This means that
+it's no big deal to support the so called standards. It also means that we can
+support advanced interactivity and other features but these also depends on the
+viewers used. So, stability here is more fluent, for instance because the \PDF\
+standard evolves and|/|or we need to adapt to viewers. Special demands like
+tagged \PDF\ have been supported right from the start but how that evolves
+depends mostly on input from users who need it. Again, that is less important
+(and crucial) for stability than the rendering capabilities.
+
+The fact that we use \LUA\ creates a dependency on that language but the reason
+that we use it is {\em because} it is so stable. We follow the updates and so far
+that worked out well. Now, say that we had a frozen version of \CONTEXT\ 2010 and
+\LUATEX\ 1.09 that uses \LUA\ 5.3, would that work? First of all, in 2010
+\LUATEX\ itself was evolving so the answer is probably \quotation {no}, unless
+one adds a few compatibility patches. I'm not going to try it. The change from
+5.1 to 5.2 to 5.3 was not really a problem I think and the few issues could be
+dealt with easily. If you want long term stability and use a lot of \LUA\ code
+you can take it into account when coding. Avoiding external libraries is a good
+start.
+
+Fonts are more than before moving targets. So, if you want stability there you
+should save them with your document source. The processing of them has evolved
+and has been improved over time. By now it's rather stable. More recent code can
+catch more issues and fixes are relatively easy. But it's an area that you always
+need to check when you update an old distribution. The same is true for language
+related hyphenation patterns and script specific support. The community is no
+longer leading in the math department either (\OPENTYPE\ math is a \MICROSOFT\
+invention). But, the good news is that the \TEX\ ecosystem is always fast to
+adapt and can also often provide more functionality.
+
+Vertical spacing, in fact spacing in general is an aera that can always be
+improved, so there is where you can expect changed. The same is true for side
+floats or mechanisms where content is somehow attached to other moving content,
+for instance marginal notes.
+
+But code dealing with fonts, color, scripts, structure, and specific features
+that once written don't need more, will not change that much. As mentioned for
+fonts, like any resource, we also depend on third parties. Colors can relate to
+standards, but their main properties are unchanged. Support for specific scripts
+can (and will) be improved due to user input and demands so there the users also
+influence stability. Structure doesn't really influence the overall rendering,
+but the way you set it up does, but that's user styling. Of course during the
+transition from \MKII\ to \MKIV\ and the evolution of \LUATEX\ things could be
+broken, but fixing something structural seldom relates to rendering. If for
+instance we improve the interpretation of \BIBTEX\ input , which can be real
+messy, that involves data processing, nor rendering. When we improve support for
+the \APA\ standard, which is complex, it might involve rendering but then that's
+asked for and expected. One cannot do better than the input permits.
+
+\stopsubject
+
+\startsubject[title=Publishers]
+
+When discussing stability and especially stability as requirement we need to look
+at the way \CONTEXT\ is used. So let's look at a few scenarios. Say that a
+publisher gets a camera ready book from an author in \PDF\ format. In that
+case the author can do all tweaks needed. Now say that the publisher also wants
+the source code in a format that makes reuse possible.
+
+But let's face reality. Will that publisher really reformat the document in \PDF\
+again? It's very unlikely. First of all the original \PDF\ can be kept, and
+second, a reformat only makes sense after updating the content or going for a
+completely different layout. It's basically a new book then. In that case literal
+similarity of output is irrelevant. It is a cheap demand without much substance.
+
+When the source is used for a different purpose the tool used to make the \PDF\
+is irrelevant. In that case the coding of the source can matter. If it is in some
+dialect of \TEX, fine, one has to convert it anyway (to suit the other usage). If
+there is an \XML\ export available, fine too as it can be transformed, given that
+the structure is rich enough, something that is unlikely to have been checked
+when the original was archived. Then there could have been the demand for a
+document in some other format and who can guarantee stability of the tools used
+there? Just look at how \MICROSOFT\ Word evolved, or for that matter, its
+competitors. On the average \TEX\ is more stable as one can snapshot a \TEX\ tree
+and run binaries for years, if needed, in a virtual machine.
+
+So, I don't think that a publisher is of any relevance in the discussion about
+stability. Even if we can clearly define what a publisher is, I doubt if
+publishers themselves can be considered long term stable organizations. Not
+today. I'm not sure if (especially the large) publishers really deserve a place
+in the discussion about stability but I'm willing to discuss that when I run into
+one.
+
+The main problem that an author can face when being confronted with the stability
+issue this way is that the times are long gone that publishers have a clue about
+what \TEX\ is, how it evolved and how it always had to and did adapt to changing
+requirements. If you're lucky you will run into someone who does know all this.
+They're normally a bit older and have seen the organization from any angles and
+therefore are fun to work with.
+
+But even then, rendering issues are often not high on their agenda. Outsourcing
+often has become the modus operandi which basically brings us to the second group
+involved in this discussion: suppliers.
+
+\stopsubject
+
+\startsubject[title=Suppliers]
+
+I don't know many suppliers other than the ones we ran into over a few decades.
+At least where I live the departments that are responsible for outsourcing
+typesetting like to deal with only a few large suppliers, interestingly because
+they assume that they are stable. However, in my experience hardly any of those
+seem to have survived. (Of course one can wonder if long term commitment really
+is that important in a world where companies change so fast.) This is somewhat
+obscured by the fact that publishers themselves merge, reorganize, move people
+around, etc. so who can check on the stability of suppliers. It is definitely a
+fact that at least recently hardly any of them played a rol of any relevance in
+the development of stable tools. In the past the membership of \TEX\ user groups
+contained people working at publishers and suppliers but that has changed.
+
+Let's focus on the suppliers that somehow use \TEX\ and let's consider two kind
+of suppliers: small ones, one were only a few people work, and large ones. The
+small ones depend on stable \TEX\ distributions, like \TEX Live where they can
+get the resources from: styles, fonts, patterns, binaries. If they get the
+authors \TEX\ files they need to have that access. They have to rework that input
+into what the customer demands and that likely involves tweaks. So, maybe they
+have developed their own additional code. For that code, stability is their own
+responsibility. Did they tweak core code of a macro package? Fine, but you might
+have it coming when you update. You cannot expect the evolving free meal world to
+stick to your commercial needs. A supplier can play safe and somehow involve the
+developers of macro packages or consult them occasionally, but does that really
+happen often? Interesting is that a few times that I was asked for input it was
+also wrapped in obscurity, as if some holy grail of styling was involved, while
+it's quite likely that the developer of a macro package can write such a style
+(or extra code) easily and probably also better. There really is not that much
+unique code around.
+
+Small suppliers can be on mailing lists where they can contribute, get feedback,
+provide testing, etc. They are part of a process and as such have some influence
+on stability. If they charge by the page, then a change in their tools can be
+reflected in what they charge. Basically redoing a book (or so) after a decade is
+doing a new job. And adapting to some new options in a package, as part of a
+typesetting job is probably no big deal. Is commercial really more stable than
+open source free software? Probably not, except from open source software
+developers whose real objective is to eventually sell their stuff to some company
+(and cash) and even accept it to be ditched. Small suppliers are more flexible.
+
+The large suppliers are a different group. They often guard their secrets and
+stay in the dark. They probably seldom share (fundamental) code and information.
+If they are present in a community it can be for marketing reasons. If at some
+point a large supplier would demand stability, then my first response would be:
+sure I can make you a stable setup and maybe even provide intermediate patches
+but put your money where your mouth is. But that never happened and I've come to
+the conclusion that we can safely ignore that group. The \TEX\ user groups create
+distributions and have for instance funded font development and it are the common
+users who paid for that, not the scale ones. To some extent this is actually good
+because large (software related) organizations often have special agendas that
+can contradict what we aim at in the long term.
+
+From the authors perspective there is a dilemma here. When you submit to a
+publisher who outsources, it can be a demand to deliver in a specific \TEX\
+format. Often a \PDF\ comes with the source then, so that the intended rendering
+is known. Then that source goes to a supplier who then (quite likely) redoes a
+lot of the coding in some stable subset, maybe even in a very old version of the
+macro package. If I were such an author I'd render the document in \quote {as
+stupid as possible mode} because you gain nothing by spending time on the looks.
+So, stability within the package that you use is easy and translation from one to
+another probably also. It's best to check beforehand what will happen with your
+source and let stability, if mentioned, be their problem. After all they get paid
+for it.
+
+Suppliers seldom know \CONTEXT. An interesting question is if they really know
+the alternatives well, apart from the bit they use. A well structured \CONTEXT\
+source (or probably any source) is often easy to convert to another format. You
+can assume that a supplier has tools for that (although we're often surprised
+about the poor quality of tools used). Often the strict demand for some kind of
+format is an excuse for lack of knowledge. Unfortunately you need a large author
+base to change that attitude.
+
+\stopsubject
+
+\startsubject[title=Authors]
+
+Before we move to some variants of the above, first I will look at stability from
+the authors perspective. When a book is being written the typesetting more or
+less happens as part of the process. The way it looks can influence the way you
+write and vise versa. Once the book is done it can go in print and, unless you
+were using beta versions of \CONTEXT\ and updated frequently. Normally you will
+try to work in a stable setup. Of course when a user asks for additional features
+while working on a project, he or she should also accept other beta features
+and side effects.
+
+After a few years an author might decide to update the book. The worst that can
+happen is that the code doesn't run with the latest \CONTEXT. This is not so
+likely because commands are upward compatible. However, the text might come out a
+bit different, for instance because different fonts or patterns are used. But on
+the average paragraphs will come out the same in \TEX. You can encounter
+differences in the vertical spacing and page breaks, because that is where
+improvements are still possible. If you use conceptually and implementation wise
+complex mechanism like side floats, you can also run into compatibility issues.
+But all these don't really matter much because the text will be updated anyway
+and fine|-|tuning of page breaks (if at all) happens at the end. The more you try
+to compete with desk top publishing, and the more tweaks you apply, the greater
+is the risk that you introduce instability. It is okay for a one|-|time job, but
+when you come back to it after a decade, be prepared for surprises.
+
+Even if you stick to the original coding, it makes sense to sacrifice some of that
+stability if new mechanisms have become available. For instance, if you use
+\METAPOST, better ways to solve your problem might have become available. Or if
+you document is 15 years old, a move from \MKII\ to \MKIV\ is a valid option,
+in which case you might also consider using the latest fonts.
+
+Of course, when you made a style where you patched core code, you can expect
+problems, because anything not explicitly mentioned in the interface definition
+files is subjected to change. But you probably see that coming anyway.
+
+So, is an author (or stand alone user) really dependent on stability? Probably
+less than thought. In fact, the operating system, internet and browsers,
+additional tools: all change over time and one adapts. It's something one can
+live with. Just see how people adapt to phones, tablets, social media, electric
+cars, etc. As long as the document processes and reasonable output is generated
+it's fine. And that is always what we aim at! After all we need to be able to use
+it ourselves, don't we?
+
+\stopsubject
+
+\startsubject[title=Projects]
+
+Although it is often overlooked as valid alternative in rendering in large scale
+projects, \CONTEXT\ is perfect as component in a larger whole. Something goes
+in, something comes out. In a long term project one can just install a minimal
+distribution, write styles, and run it for ages. Use a virtual machine and
+we're talking decades without any change. And, when one updates, it's easy to check
+if all still works. Often the demands and styles are simple and predictable. It's
+way more likely that a hard coded solution in some large programming environment has
+stability issues than that the \CONTEXT\ bit has.
+
+If \CONTEXT\ is used in for instance documentation of (say) software, again there
+is no real issue. Such documents are simple, evolve and therefore have no stable
+page flow, and updating \CONTEXT\ is not needed if the once decided upon coding
+is stable. You don't need the latest features. We've written styles and setups for
+such tasks and indeed they run for ages.
+
+It can make me smile to see how much effort sometimes goes in low quality
+rendering where \CONTEXT\ could do a way better job with far less investment in
+time and money but where using some presumed stable toolkit is used instead, one
+that comes with expensive licensing, from companies that come and go but shine in
+marketing. (A valid question is to what extent the quality of and care for
+documentation reflects the core products that a company produces, at least under
+the hood.)
+
+The biggest hurdle in setting up a decent efficient workflow is that it has to be
+seen as a project: proper analysis, proper planning, prototyping and testing,
+etc. You invest first and gain later. When dealing with paper many publishers
+still think in price per page and have problems seeing that a stable mostly
+automated flow in the end can result in a ridiculous low price per page,
+especially in typesetting on demand.
+
+\stopsubsubject
+
+\startsubject[title=Hybrids]
+
+Last I will mention a setup that we sometimes are involved in. An author writes
+books and uses \TEX. The publisher is okay with that and adds some quality
+assurance but in the end the product comes from the author. Maybe images are
+oursourced (not always for the better) but these can be handled easily. It can be that
+a copy|-|editor is involved and that person also then has to use \TEX\ of course,
+or feedback to the author.
+
+Publishers, and this really depends on knowledgeable persons, which as said can
+be fun to work with, can look beyond paper and also decide for additional
+materials, for instance web pages, interactive exercises, etc. In that case
+either \CONTEXT\ input has to be available as \XML\ (an export) or (often better)
+\XML\ is the starting point for multiple output. Contrary to what is believed,
+there are authors out there who have no problem coding in \XML\ directly. They
+think in structured content and reuse! The fact that they can hit a button in the
+editor and see the result in \PDF\ helps a lot. It just works.
+
+Here stability is either achieved by simply not updating during a project. There
+are however cases where an update is needed, for instance because demands
+changed. An example is a project where \ASCIIMATH\ is used which is a moving
+target. Of course one can update just that module, and often that works, but not
+when a module uses some new improved core helpers. Another example is additional
+proofing options.
+
+The budget of such projects seldom permit patching an existing distribution, so
+we then just update to the latest but not after checking if the used style works
+okay. There is no author involvement in this. Depending on the workflow, it can
+even be that the final rendering which involves fine tuning (side) float placement
+or page breaks (often educational documents have special demands) is done by us
+using special directives.
+
+Such hybrid workflows are quite convenient for all parties. The publisher works
+with the author who likes using these tools, the author can do her or his thing
+in the preferred way, and we do what we're best in: supporting this. And it
+scales up pretty well too if needed, without much costs for the publishers.
+
+\stopsubject
+
+\startsubject[title=Conclusion]
+
+So what can we conclude with respect to the demand for stability? First of course
+that it's important that our files keep running well. So, functionality should be
+stable. Freezing a distribution will make sure that during project you don't run
+into issues. Many \CONTEXT\ users update frequently in order to benefit from the
+latest additions. Most will not be harmed by this, but when something really
+breaks it's users like those on the \CONTEXT\ support list (who often also
+contribute in helping out other users) that are listened to first. Publishers
+demands play no role in this, if only because they also play no role in
+typesetting, and if they want to they should also contribute. The same is true
+for large suppliers. We're talking of free software often written without any
+compensation so these parties have no say in the matter unless they pay for it.
+It's small suppliers, authors and general users that matter most. If \CONTEXT\ is
+part of a workflow that we support, of course stability is guaranteed quite well,
+and those paying for that never have an issue with better solutions popping up.
+In fact, \CONTEXT\ is often just a tool then, one that does the job and questions
+about stability don't matter much in practice, as long as it does the job well.
+
+The main engine we use, \LUATEX, will be quite stable from version 1.10 and we'll
+try to make sure that newer versions are capable of running an older \CONTEXT,
+which is easier when no fundamental changes happen in the engine. Maybe a stripped
+down version of \LUATEX\ for \CONTEXT\ can facilitate that objective even more.
+
+Users themselves can try to stick to standard \CONTEXT\ features. The more tricks
+you apply, the less stable your future might be. Most mechanism are not evolving
+but some, like those that deal with columns, might become better over time. But
+typesetting in columns is often a one|-|shot adventure anyway (and who needs
+columns in the future).
+
+Of one thing users can be sure. There will never be a \CONTEXT\ professional or
+\CONTEXT\ enterprise. There is only one variant. All users get the same
+functionality and policies don't change suddenly. There will be no lock in to some
+cloud or web based service either. Of course one can hire us for support of any
+kind but that's independent of the distributed package. There is support by users
+for users on mailing lists and other media. That itself can also guard stability.
+
+But, always keep in mind that stability and progress, either of not driven by the
+environment that we operate in, can be in conflict.
+
+\stopsubject
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/musings/musings-staygo.tex b/doc/context/sources/general/manuals/musings/musings-staygo.tex
new file mode 100644
index 000000000..4be647e47
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-staygo.tex
@@ -0,0 +1,461 @@
+% language=uk
+
+% Written with on repeat:
+%
+% Rai Thistlethwayte: Betty Page (the keyscape version)
+
+% \usemodule[art-01,abr-04]
+%
+% \setupbodyfont[12pt]
+%
+% \startdocument
+% [title={What’s to stay, what’s to go},
+% subtitle={The 2018 Bacho\TeX\ theme},
+% author={Hans Hagen}]
+
+\definedescription
+ [theme]
+ [before=\startnarrower,
+ after=\stopnarrower,
+ title=yes,
+ alternative=serried,
+ width=fit,
+ distance=.5\emwidth,
+ text={\documentvariable{title}:}]
+
+% \starttitle[title=\documentvariable{title}\\\txx\documentvariable{subtitle}]
+
+\startcomponent musings-staygo
+
+\environment musings-style
+
+\startchapter[title={What’s to stay, what’s to go}]
+
+\startsection[title=Introduction]
+
+The following text was written as preparation for a 2018 talk at Bacho\TEX, which
+has this theme. It's mostly a collection of thoughts. It was also more meant as a
+wrapup for the presentation (possibly with some discussions) than an article.
+
+\stopsection
+
+\startsection[title=Attraction]
+
+There are those movies where some whiz-kid sits down behind a computer, keys in a
+few commands, and miracles happen. Ten fingers are used to generate programs that
+work immediately. It's no problem to bypass firewalls. There is no lag over
+network connections. Checking massive databases is no big deal and there's even
+processing power left for real time visualization or long logs to the terminal.
+
+How boring and old fashioned must a regular edit||run||preview cycle look
+compared to this. If we take this 2018 movie reality as reference, in a time when
+one can suck a phone empty with a simple connection, pull a hard drive from a
+raid five array and still get all data immediately available, when we can follow
+realtime whoever we want using cameras spread over the country, it's pretty clear
+that this relatively slow page production engine \TEX\ has no chance to survive,
+unless we want to impress computer illiterate friends with a log flying by on the
+console (which in fact is used in movies to impress as well).
+
+On YouTube you can find these (a few hours) sessions where Jacob Collier
+harmonizes live in one of these Digital Audio Workstation programs. A while later
+on another channel June Lee will transcribe these masterpieces into complex
+sheets of music by ear. Or you can watch the weekly Wintergatan episodes on
+building the Marble Machine from wood using drilling, milling, drawing programs
+etc. There are impressive videos of multi|-|dimensional led arrays made by hand
+and controlled by small computers and robots that solve Rubic Cubes. You can be
+impressed by these Animusic videos, musicians show their craftmanship and
+interesting informative movies are all over the place. I simply cannot imagine
+millions of kids watching a \TEX\ style being written in a few hours. It's a real
+challenge for an attention span. I hope to be proven wrong but I fear that for
+the upcoming generation it's probably already too late because the \quote {whow}
+factor of \TEX\ is low at first encounter. Although: picking up one of Don Knuths
+books can have that effect: a nice mixture of code, typesetting and subtle
+graphics, combined with great care, only possible with a system like \TEX.
+
+\starttheme
+ Biology teaches us that \quote {cool} is not a recipe for \quote {survival}.
+ Not all designs by nature look cool, and it's only efficiency and
+ functionality that matters. Beauty sometimes matters too but many functional
+ mechanisms can do without. So far \TEX\ and its friends were quite capable to
+ survive so there must be something in it that prevents it to be discarded.
+ But survival is hard to explain. So far \TEX\ just stayed around but lack of
+ visual attraction is a missing competitive trait.
+\stoptheme
+
+\stopsection
+
+\startsection[title=Satisfaction]
+
+Biology also teaches us that chemistry can overload reason. When we go for
+short|-|term pleasure instead of long|-|term satisfaction (Google for Simon Sinek
+on this topic), addiction kicks in (for instance driven by crossing the dopamine
+thresholds too often, Google for Robert Sapolsky). Cool might relate more to
+pleasure while satisfaction relates to an effort. Using \TEX\ is not that cool
+and often takes an effort. But the results can be very satisfying. Where \quote
+{cool} is rewarding in the short term, \quote {satisfaction} is more a long term
+effect. So, you probably get the best (experience) out of \TEX\ by using it a
+lifetime. That's why we see so many old \TEX ies here: many like the rewards.
+
+If we want to draw new users we run into the problem that humans are not that
+good in long term visions. This means that we cannot rely on showing cool (and
+easy) features but must make sure that the long term reward is clear. We can try
+to be \quote {cool} to draw in new users, but it will not be the reason they
+stay. Instant success is important for kids who have to make a report for school,
+and a few days \quotation {getting acquainted with a program} doesn't fit in.
+It's hard to make kids addicted to \TEX\ (which could be a dubious objective).
+
+\starttheme
+ As long as the narrative of satisfaction can be told we will see new users.
+ Meetings like Bacho\TEX\ is where the narrative gets told. What will happen
+ when we no longer meet?
+\stoptheme
+
+\stopsection
+
+\startsection[title=Survival]
+
+Survival relates to improvements, stability and discarding of weak aspects.
+Unfortunately that does not work out well in practice. Fully automated
+multi||columns typesetting with all other elements done well too (we just mention
+images) is hard and close to impossible for arbitrary cases, so nature would have
+gotten rid of it. Ligatures can be a pain especially when the language is not
+tagged and some kind of intelligence is needed to selectively disable them. They
+are the tail of the peacock: not that handy but meant to be impressive. Somehow
+it stayed around in automated typesetting, in biology it would be called a freak
+of nature: probably a goodbye in wildlife. And how about page breaks on an
+electronic device: getting rid of them would make the floating figures go away
+and remove boundary conditions often imposed. It would also make widows and clubs
+less of a problem. One can even wonder if with page breaks the windows and clubs
+are the biggest problems, and if one can simply live with them. After all, we can
+live with our own bodily limitations too. After all, (depending on what country
+you live in) you can also live with bad roads, bad weather, polution, taxes, lack
+of healthcare for many, too much sugar in food, and more.
+
+
+\starttheme
+ Animals or plants that can adapt to live on a specific island might not
+ survive elsewhere. Animals or plants introduced in an isolated environment
+ might quickly dominate and wipe out the locals. What are the equivalents in
+ our \TEX\ ecosystem?
+\stoptheme
+
+\stopsection
+
+\startsection[title=Niches]
+
+But arguments will not help us determine if \TEX\ is the fittest for survival.
+It's not a rational thing. Humans are bad in applying statistics in their live,
+and looking far ahead is not a treat needed to survive. Often nature acts in
+retrospect. (Climbing mount probability by Richard Dawkins). So, it doesn't
+matter if we save time in the future if it complicates the current job. If
+governments and companies cannot look ahead and act accordingly, how can we
+extrapolate software (usage) or more specifically typesetting demands. Just look
+at the political developments in the country that hosts this conference. Could we
+have predicted the diminishing popularity of the \EU\ (and disturbing retrograde
+political mess in some countries) of 2018 when we celebrated the moment Poland
+joining the \EU\ at a Bacho\TEX\ campfire?
+
+Extrapolating the future quality of versions of \TEX\ or macro packages also doesn't
+matter much. With machine learning and artificial intelligence around the corner and
+with unavoidable new interfaces that hook into our brains, who knows what systems
+we need in the future. A generic flexible typesetting system is probably not the
+most important tool then. When we discuss quality and design it gets personal so
+a learning system that renders neutrally coded content into a form that suits
+an individual, demands a different kind of tool than we have now.
+
+On the short term (our live span) it makes more sense to look around and see how
+other software (ecosystems) fare. Maybe we can predict \TEX's future from that.
+Maybe we can learn from others mistakes. In the meantime we should not flatter
+ourselves with the idea that a near perfect typesetting system will draw attention
+and be used by a large audience. Factors external to the community play a too
+important role in this.
+
+\starttheme
+ It all depends on how well it fits into a niche. Sometimes survival is only
+ possible by staying low on the radar. But just as we destroy nature and kill
+ animals competing for space, programs get driven out of the software world.
+ On a positive note: in a project that provides open (free) math for schools
+ students expressed to favour a printed book over \WEB|-|only (one curious
+ argument for \WEB\ was that it permits easier listening to music at the same
+ time).
+\stoptheme
+
+\stopsection
+
+\startsection[title=Dominance]
+
+Last year I installed a bit clever (evohome) heating control system. It's
+probably the only \quotation {working out of the box} system that supports 12
+zones but at the same time it has a rather closed interface as any other. One can
+tweak a bit via a web interface but that one works by a proxy outside so there is
+a lock in. Such a system is a gamble because it's closed and we're talking of a
+20 year investment. I was able to add a layer of control (abusing \LUATEX\ as
+\LUA\ engine and \CONTEXT\ as library) so let's see. When I updated the boiler I
+also reconfigured some components (like valves) and was surprised how limited
+upgrading was supported. One ends up with lost settings and weird interference
+and it's because I know a bit of programming that I kept going and managed to add
+more control. Of course, after a few weeks I had to check a few things in the
+manuals, like how to enter the right menu.
+
+So, as the original manuals are stored somewhere, one picks up the smart phone
+and looks for the manual on the web. I have no problem with proper \PDF\ as a
+manual but why not provide a simple standard format document alongside the fancy
+folded A3 one. Is it because it's hard to produce different instances from one
+source? Is it because it takes effort? We're talking of a product that doesn't
+change for years.
+
+\starttheme
+ The availability of flexible tools for producing manuals doesn't mean that
+ they are used as such. They don't support the survival of tools. Bad examples
+ are a threat. Dominant species win.
+\stoptheme
+
+\stopsection
+
+\startsection[title=Extinction]
+
+When I was writing this I happened to visit a bookshop where I always check the
+SciFi section for new publications. I picked out a pocket and wondered if I had
+the wrong glasses on. The text was wobbling and looked kind of weird. On close
+inspection indeed the characters were kind of randomly dancing on the baseline
+and looked like some 150 \DPI\ (at most) scan. (By the way, I checked this the
+next time I was there by showing the book to a nephew.) I get the idea that quite
+some books get published first in the (more expensive) larger formats, so
+normally I wait till a pocket size shows up (which can take a year) so maybe here
+I had to do with a scan of a larger print scaled down.
+
+What does that tell us? First of all that the publisher doesn't care about the
+reader: this book is just unreadable. Second, it demonstrates that the printer
+didn't ask for the original \PDF\ file and then scaled down the outline copy. It
+really doesn't matter in this case if you use some high quality typesetting
+program then. It's also a waste of time to talk to such publishers about quality
+typesetting. The printer probably didn't bother to ask for a \PDF\ file that
+could be scaled down.
+
+\starttheme
+ In the end most of the publishing industry will die and this is just one of
+ the symptoms. Typesetting as we know it might fade away.
+\stoptheme
+
+\stopsection
+
+\startsection[title=Desinterest]
+
+The newspaper that I read has a good reputation for design. But why do they need
+to drastically change the layout and font setup every few years? Maybe like an
+animal marking his or her territory a new department head also has to put a mark
+on the layout. Who knows. For me the paper became pretty hard to read: a too
+light font that suits none of the several glasses that I have. So yes, I spend
+less time reading the paper. In a recent commentary about the 75 year history of
+the paper there was a remark about the introduction of a modern look a few
+decades ago by using a sans serif font. I'm not sure why sans is considered
+modern (most handwriting is sans) and to me some of these sans fonts look pretty
+old fashioned compared to a modern elegant serif (or mix).
+
+\starttheme
+ If marketing and fashion of the day dominate then a wrong decision can result
+ in dying pretty fast.
+\stoptheme
+
+\stopsection
+
+\startsection[title=Persistence]
+
+Around the turn of the century I had to replace my \CD\ player and realized that it
+made more sense to invest in ripping the \CD's to \FLAC\ files and use a decent
+\DAC\ to render the sound. This is a generic approach similar to processing
+documents with \TEX\ and it looks as future proof as well. So, I installed a
+virtual machine running SlimServer and bought a few SlimDevices, although by that
+time they were already called SqueezeBoxes.
+
+What started as an independent supplier of hardware and an open source program
+had gone the (nowadays rather predictable) route of a buy out by a larger company
+(Logitech). That company later ditched the system, even if it had a decent share
+of users. This \quotation {start something interesting and rely on dedicated
+users}, then \quotation {sell yourself (to the highest bidder)} and a bit later
+\quotation {accept that the product gets abandoned} is where open source can fail
+in many aspects: loyal users are ignored and offended with the original author
+basically not caring about it. The only good thing is that because the software
+is open source there can be a follow up, but of course that requires that there
+are users able to program.
+
+I have 5 small boxes and a larger transporter so my setup is for now safe from
+extinction. And I can run the server on any (old) \LINUX\ or \MSWINDOWS\
+distribution. For the record, when I recently connected the 20 year old Cambridge
+CD2 I was surprised how well it sounded on my current headphones. The only
+drawback was that it needs 10 minutes for the transport to warm up and get
+working.
+
+In a similar fashion I can still use \TEX, even when we originally started using
+it with the only viable quality \DVI\ to \POSTSCRIPT\ backend at that time
+(\DVIPSONE). But I'm not so sure what I'd done if I had not been involved in the
+development of \PDFTEX\ and later \LUATEX . As an average user I might just have
+dropped out. As with the \CD\ player, maybe someone will dust off an old \TEX\
+some day and maybe the only hurdle is to get it running on a virtual retro
+machine. Although \unknown\ recently I ran into an issue with a virtual machine
+that didn't provide a console after a \KVM\ host update, so I'm also getting
+pessimistic about that escape for older programs. (Not seldom when a library
+update is forced into the \LUATEX\ repository we face some issue and it's not
+something the average user want (or is able to) cope with.)
+
+\starttheme
+ Sometimes it's hard to go extinct, even when commerce interfered at some
+ point. But it does happen that users successfully take (back) control.
+\stoptheme
+
+\stopsection
+
+\startsection[title=Freedom]
+
+If you buy a book originating in academia written and typeset by the author,
+there is a chance that it is produced by some flavour of \TEX\ and looks quite
+okay. This is because the author could iterate to the product she or he likes.
+Unfortunately the web is also a source of bad looking documents produced by \TEX.
+Even worse is that many authors don't even bother to set up a document layout
+properly, think about structure and choose a font setup that matches well. One
+can argue that only content matters. Fine, but than also one shouldn't claim
+quality simply because \TEX\ has been used.
+
+I've seen examples of material meant for bachelor students that made me pretend
+that I am not familiar with \TEX\ and cannot be held responsible. Letter based
+layouts on A4 paper, or worse, meant for display (or e|-|book devices) without
+bothering to remove the excessive margins. Then these students are forced to use
+some collaborative \TEX\ environment, which makes them dependent on the quality
+standards of fellow students. No wonder that one then sees dozens of packages
+being loaded, abundant copy and paste and replace of already entered formulas and
+interesting mixtures of inline and display math, skips, kerns and whatever can
+help to make the result look horrible.
+
+\starttheme
+ Don't expect enthusiast new users when you impose \TEX\ but take away freedom
+ and force folks to cooperate with those with lesser standards. It will not
+ help quality \TEX\ to stay around. You cannot enforce survival, it just
+ happens or not, probably better with no competition or with a competition so
+ powerful that it doesn't bother with the niches. In fact, keeping a low
+ profile might be best! The number of users is no indication of quality,
+ although one can abuse that statistic selectively?
+\stoptheme
+
+\stopsection
+
+\startsection[title=Diversity]
+
+Diversity in nature is enormous. There are or course niches, but in general there
+are multiple variants of the same. When humans started breeding stock or
+companion animals diversity also was a property. No one is forcing the same dog
+upon everyone or the same cow. However, when industrialization kicks in things
+become worse. Many cows in our country share the same dad. And when we look at
+for instance corn, tomatoes or whatever dominance is not dictated by what nature
+figures out best, but by what commercially makes most sense, even if that means
+that something can't reproduce by itself any longer.
+
+In a similar way the diversity of methods and devices to communicate (on paper)
+at some point turns into commercial uniformity. The diversity is simply very
+small, also in typesetting. And even worse, a user even has to defend
+her|/|himself for a choice of system (even in the \TEX\ community). It's just
+against nature.
+
+\starttheme
+ Normally something stays around till it no longer can survive. However, we
+ humans have a tendency to destroy and commerce is helping a hand here. In
+ that respect it's a surprise that \TEX\ is still around. On the other hand,
+ humans also have a tendency to keep things artificially alive and even
+ revive. Can we revive \TEX\ in a few hundred years given the complex code
+ base and Make infrastructure?
+\stoptheme
+
+\stopsection
+
+\startsection[title=Publishing]
+
+What will happen with publishing? In the production notes of some of my recently
+bought books the author mentions that the first prints were self|-|published
+(either or not sponsored). This means that when a publisher \quotation {takes
+over} (which still happens when one scales up) not much work has to be done.
+Basically the only thing an author needs is a distribution network. My personal
+experience with for instance \CD's produced by a group of musicians is that it is
+often hard to get it from abroad (if at all) simply because one needs a payment
+channel and mail costs are also relatively high.
+
+But both demonstrate that given good facilitating options it is unlikely that
+publishers as we have now have not much change of survival. Add to the argument
+that while in Gutenbergs time a publisher also was involved in the technology,
+today nothing innovative comes from publishers: the internet, ebook devices,
+programs, etc.\ all come from elsewhere. And I get the impression that even in
+picking up on technology publishers lag behind and mostly just react. Even
+arguments like added value in terms of peer review are disappearing with the
+internet where peer groups can take over that task. Huge amounts of money are
+wasted on short|-|term modern media. (I bet similar amounts were never spend on
+typesetting.)
+
+\starttheme
+ Publishers, publishing, publications and their public: as they are now they
+ might not stay around. Lack of long term vision and ideas and decoupling of
+ technology can make sure of that. Publishing will stay but anyone can
+ publish; we only need the infrastructure. Creativity can win over greed and
+ exploitation, small can win over big. And tools like \TEX\ can thrive in
+ there, as it already does on a small scale.
+\stoptheme
+
+\stopsection
+
+\startsection[title=Understanding]
+
+\quotation {Why do you use \TEX?} If we limit this question to typesetting, you
+can think of \quotation {Why don't you use \MSWORD ?} \quotation {Why don't you use
+Indesign?}, \quotation {Why don't you use that macro package?}, \quotation {Why
+don't you use this \TEX\ engine?} and alike. I'm sure that most of the readers
+had to answer questions like this, questions that sort of assume that you're not
+happy with what you use now, or maybe even suggest that you must be stupid not to
+use \unknown
+
+It's not that easy to explain why I use \TEX\ and|/|or why \TEX\ is good a the
+job. If you are in a one|-|to|-|one (or few) sessions you can demonstrate its
+virtues but \quote {selling} it to for instance a publisher is close to
+impossible because this kind of technology is rather unknown and far from the
+click|-|and|-|point paradigm. It's even harder when students get accustomed to
+these interactive books from wherein they can even run code snippets although one
+can wonder how individual these are when a student has the web as a source of
+solutions. Only after a long exposure to similar and maybe imperfect alternatives
+books will get appreciated.
+
+For instance speaking of \quotation {automated typesetting} assumes that one
+knows what typesetting is and also is aware that automated has some benefits. A
+simple \quotation {it's an \XML\ to \PDF\ converter} might work better but that
+assumes \XML\ being used which for instance not always makes sense. And while
+hyphenation, fancy font support and proper justification might impress a \TEX\
+user it often is less of an argument than one thinks.
+
+The \quotation {Why don't you} also can be heard in the \TEX\ community. In the
+worst case it's accompanied by a \quotation {\unknown\ because everybody uses
+\unknown} which of course makes no sense because you can bet that the same user
+will not fall for that argument when it comes to using an operating system or so.
+Also from outside the community there is pressure to use something else: one can
+find defense of minimal markup over \TEX\ markup or even \HTML\ markup as better
+alternative for dissemination than for instance \PDF\ or \TEX\ sources. The
+problem here is that old||timers can reflect on how relatively wonderful a
+current technique really is, given changes over time, but who wants to listen to
+an old|-|timer. Progress is needed and stimulating (which doesn't mean that all
+old technology is obsolete). When I watched Endre eNerd's \quotation {The Time
+Capsule} blu|-|ray I noticed an Ensoniq Fizmo keyboard and looked up what it was.
+I ended up in interesting reads where the bottom line was \quotation {Either you
+get it or you don't}. Reading the threads rang a bell. As with \TEX, you cannot
+decide after a quick test or even a few hours if you (get the concept and) like
+it or not: you need days, weeks, or maybe even months, and some actually never
+really get it after years.
+
+\starttheme
+ It is good to wonder why you use some program but what gets used by others
+ depends on understanding. If we can't explain the benefits there is no
+ future for \TEX. Or more exact: if it no longer provide benefits, it will
+ just disappear. Just walk around a gallery in a science museum that deals
+ with computers: it can be a bit pathetic experience.
+\stoptheme
+
+\stopsection
+
+{\bf Who knows \unknown}
+
+\stoptitle
+
+\stopdocument
diff --git a/doc/context/sources/general/manuals/musings/musings-style.tex b/doc/context/sources/general/manuals/musings/musings-style.tex
new file mode 100644
index 000000000..5ed934f2f
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-style.tex
@@ -0,0 +1,92 @@
+\startenvironment musings-style
+
+\usemodule[abr-04]
+
+\setupbodyfont
+ [pagella]
+
+\setuplayout
+ [topspace=2cm,
+ header=0pt,
+ footer=1.5cm,
+ bottomspace=1cm,
+ width=middle,
+ height=middle]
+
+% \definecolor[maincolor] [darkyellow]
+% \definecolor[extracolor][darkblue]
+
+\definecolor[maincolor] [middleorange]
+\definecolor[extracolor][middleblue]
+
+\setuptype
+ [color=maincolor]
+
+\setuptyping
+ [color=maincolor]
+
+\setuphead
+ [color=maincolor]
+
+\setuphead
+ [chapter]
+ [style=\bfd]
+
+\setuphead
+ [chapter]
+ [after={\blank[3*line]},
+ align=flushright,
+ command=\ChapterCommand]
+
+\starttexdefinition unexpanded ChapterCommand#1#2
+ \hbox to \textwidth {
+ \hss
+ % title
+ #2
+ \doifmode {*sectionnumber} {
+ % distance
+ \hskip10mm
+ % number
+ \struttedbox{\offset[x=-1mm,y=2.5mm]{\scale[height=2cm]{#1}}}
+ }
+ }
+\stoptexdefinition
+
+\setuphead
+ [section]
+ [style=\bfb]
+
+\setuphead
+ [subsection]
+ [style=\bf,
+ before=\blank,
+ after=\blank]
+
+\setuppagenumbering
+ [alternative=doublesided]
+
+\setupfootertexts
+ [][{\getmarking[chapter]\hbox to 2em{\hss\pagenumber}}]
+ [{\hbox to 2em{\pagenumber\hss}\getmarking[chapter]}][]
+
+\setupwhitespace
+ [big]
+
+\setuplist
+ [chapter]
+ [width=3em,
+ before={\testpage[3]\blank},
+ after={\blank[samepage]},
+ color=maincolor,
+ style=bold]
+
+\setuplist
+ [section]
+ [width=3em,
+ before={\blank[nowhite]},
+ after={\blank[nowhite]}]
+
+% \logo [MATHTYPE] {MathType}
+% \logo [SYNCTEX] {Sync\TeX}
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/musings/musings-titlepage.tex b/doc/context/sources/general/manuals/musings/musings-titlepage.tex
new file mode 100644
index 000000000..33eb44d95
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-titlepage.tex
@@ -0,0 +1,46 @@
+\environment musings-style
+
+\startcomponent musings-titlepage
+
+\startMPpage
+
+ fill Page withcolor "maincolor" ;
+
+ draw image (
+ draw textext.bot("m") xysized (20mm, 85mm) shifted (point .8 along (topboundary Page)) shifted (0,-10mm) ;
+ draw textext.bot("u") xysized (20mm, 60mm) shifted (point .7 along (topboundary Page)) shifted (0,-25mm) ;
+ draw textext.bot("s") xysized (20mm, 50mm) shifted (point .6 along (topboundary Page)) shifted (0,-45mm) ;
+ draw textext.bot("i") xysized (20mm,100mm) shifted (point .5 along (topboundary Page)) shifted (0, 00mm) ;
+ draw textext.bot("n") xysized (20mm, 55mm) shifted (point .4 along (topboundary Page)) shifted (0,-20mm) ;
+ draw textext.bot("g") xysized (20mm, 70mm) shifted (point .3 along (topboundary Page)) shifted (0,-20mm) ;
+ draw textext.bot("s") xysized (20mm, 40mm) shifted (point .2 along (topboundary Page)) shifted (0,-15mm) ;
+ ) shifted (0,-120mm) withcolor "white" ;
+
+ draw image (
+ draw textext.bot("c") xysized (20mm, 85mm) shifted (point .8 along (topboundary Page)) shifted (0,-10mm) ;
+ draw textext.bot("o") xysized (20mm, 60mm) shifted (point .7 along (topboundary Page)) shifted (0,-25mm) ;
+ draw textext.bot("n") xysized (20mm, 50mm) shifted (point .6 along (topboundary Page)) shifted (0,-45mm) ;
+ draw textext.bot("t") xysized (20mm,100mm) shifted (point .5 along (topboundary Page)) shifted (0, 00mm) ;
+ draw textext.bot("e") xysized (20mm, 55mm) shifted (point .4 along (topboundary Page)) shifted (0,-20mm) ;
+ draw textext.bot("x") xysized (20mm, 70mm) shifted (point .3 along (topboundary Page)) shifted (0,-20mm) ;
+ draw textext.bot("t") xysized (20mm, 40mm) shifted (point .2 along (topboundary Page)) shifted (0,-15mm) ;
+ ) shifted (0,-10mm) withcolor "white" ;
+
+ draw image (
+ draw textext.bot("h") xysized (10mm, 20.0mm) shifted (point .75 along (topboundary Page)) shifted (0,-10.0mm) ;
+ draw textext.bot("a") xysized (10mm, 22.5mm) shifted (point .70 along (topboundary Page)) shifted (0,-20.0mm) ;
+ draw textext.bot("n") xysized (10mm, 27.5mm) shifted (point .65 along (topboundary Page)) shifted (0,-12.5mm) ;
+ draw textext.bot("s") xysized (10mm, 30.0mm) shifted (point .60 along (topboundary Page)) shifted (0, 0mm) ;
+
+ draw textext.bot("h") xysized (10mm, 25mm) shifted (point .45 along (topboundary Page)) shifted (0,-05.0mm) ;
+ draw textext.bot("a") xysized (10mm, 30mm) shifted (point .40 along (topboundary Page)) shifted (0,-15.0mm) ;
+ draw textext.bot("g") xysized (10mm, 35mm) shifted (point .35 along (topboundary Page)) shifted (0,-17.5mm) ;
+ draw textext.bot("e") xysized (10mm, 20mm) shifted (point .30 along (topboundary Page)) shifted (0,-20.0mm) ;
+ draw textext.bot("n") xysized (10mm, 25mm) shifted (point .25 along (topboundary Page)) shifted (0,-10.0mm) ;
+ ) shifted (0,-235mm) withcolor "white" ;
+
+\stopMPpage
+
+\page[empty]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/musings/musings-whytex.tex b/doc/context/sources/general/manuals/musings/musings-whytex.tex
new file mode 100644
index 000000000..8f9b7de9b
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings-whytex.tex
@@ -0,0 +1,326 @@
+% language=uk
+
+\startcomponent musings-whytex
+
+\environment musings-style
+
+\startchapter[title={Why use \TEX ?}]
+
+\startsection[title={Introduction}]
+
+Let's assume that you know what \TEX\ is: a program that interprets a language
+with the same name that makes it possible to convert (tagged) input into for
+instance \PDF. For many of its users it is a black box: you key in some text, hit
+a button and get some typeset result in return. After a while you start tweaking
+this black box, meet other users (on the web), become more fluent and stick to it
+forever.
+
+But now let's assume that you don't know \TEX\ and are in search of a system
+that helps you create beautiful documents in an efficient way. When your
+documents have a complex structure you are probably willing to spend some time on
+figuring out what the best tool is. Even if a search lets you end up with
+something called \TEX, a three letter word with a dropped E, you still don't
+know what it is. Advertisement for \TEX\ is often pretty weak. It's rather easy
+to point to the numerous documents that can be found on the web. But what exactly
+does \TEX\ do and what are its benefits? In order to answer this we need to know
+who you are: an author, editor, an organization that deals with documents or needs
+to generate readable output, like publishers do.
+
+\stopsection
+
+\startsection[title={Authors}]
+
+We start with authors. Students of sciences that use mathematics don't have much
+of a choice. But most of these documents hardly communicate the message that
+\quotation {Everyone should use \TEX.} or that \quotation {All documents produced
+by \TEX\ look great.} but they do advocate that for rendering math it is a pretty
+good system. The source code of these documents often look rather messy and
+unattractive and for a non|-|math user it can be intimidating. Choosing some
+lightweight click|-|and|-|ping alternative looks attractive.
+lightweight click|-|and|-|ping alternative looks attractive.
+
+Making \TEX\ popular is not going to happen by convincing those who have to write
+an occasional letter or report. They should just use whatever suits them. On the
+other hand if you love consistency, long term support, need math, are dealing
+with a rare language or script, like to reuse content, prefer different styling
+from one source, use one source for multiple documents, or maybe love open source
+tools, then you are a candidate. Of course there is a learning curve but normally
+you can master \TEX\ rather fast and once you get the hang of it there's often no
+way back. But you always need to invest a bit beforehand.
+
+So what authors are candidates for \TEX ? It could be that \TEX\ is the only tool
+that does the job. If so, you probably learned that from someone who saw you
+struggle or had the same experience and wrote or talked about it somewhere. In
+that case using \TEX\ for creating just one document (like a thesis) makes sense.
+Otherwise, you should really wonder if you want to invest time in a tool that you
+probably have to ditch later on as most organizations stick to standard
+(commercial) word processing tools.
+
+Talking to customers we are often surprised that people have heard about \TEX, or
+even used it for a few documents in college. Some universities just prescribe the
+use of \TEX\ for reporting, so not much of a choice there. Memories are normally
+rather positive in the sense that they know that it can do the job and that it's
+flexible.
+
+User group journals, presentations at \TEX\ meetings, journals, books and manuals
+that come with \TEX\ macro packages can all be used to determine if this tool
+suits an author. Actually, I started using \TEX\ because the original \TEX book
+had some magic, and reading it was just that: reading it, as I had no running
+implementation. A few years later, when I had to write (evolving) reports, I
+picked up again. But I'm not a typical user.
+
+\stopsection
+
+\startsection[title={Programmers}]
+
+When you are a programmer who has to generate reports, for instance in \PDF, or
+write manuals, then \TEX\ can really be beneficial. Of course \TEX\ is not always
+an obvious choice, but if you're a bit able to use it it's hard to beat in
+quality, flexibility and efficiency. I'm often surprised that companies are
+willing to pay a fortune for functionality that basically comes for free.
+Programmers are accustomed to running commands and working in a code editor with
+syntax highlighting so that helps too. They too recognize when something can be
+done more efficiently.
+
+When you need to go from some kind of input (document source, database,
+generated) to some rendered output there currently are a few endpoints: a
+(dynamic) \HTML\ page, a \PDF\ document, something useable in a word processor,
+or a representation using the desktop user interface. It's the second category
+where \TEX\ is hard to beat but even using \TEX\ and \METAPOST\ for creating a
+chart can make sense.
+
+There are of course special cases where \TEX\ fits in nicely. Say that you have
+to combine \PDF\ documents. There are numerous tools to do that and \TEX\ is one.
+The advantage of \TEX\ over other tools is that it's trivial to add additional
+text, number pages, provide headers and footers. And it will work forever. Why?
+Because \TEX\ has been around for decades and will be around for decades to come.
+It's an independent component. The problem with choosing for \TEX\ is that the
+starting point is important. The question is not \quotation {What tool should I
+use?} but \quotation {What problem do I need to solve?}. An open discussion about
+the objectives and possibilities is needed, not some checklist based on
+assumptions. If you don't know \TEX\ and have never worked with a programmable
+typesetting environment, you probably don't see the possibilities. In fact, you
+might even choose for \TEX\ for the wrong reasons.
+
+The problem with this category of users is that they seldom have the freedom to
+choose their tools. There are not that many jobs where the management is able to
+recognize the clever programmer who can determine that \TEX\ is suitable for a
+lot of jobs and can save money and time. Even the long term availability and
+support is not an argument since not only most tools (or even apis) changes every
+few years but also organizations themselves change ownership, objectives, and
+personnel on a whim. The concept of \quote {long term} is hard to grasp for most
+people (just look at politics) and it's only in retrospect that one can say
+\quote {We used that toolkit for over a decade.}
+
+\stopsection
+
+\startsection[title={Organizations}]
+
+Authors (often) have the advantage that they can choose themselves: they can use
+what they like. In practice any decent programmer is able to find the suitable
+tools but convincing the management to use one of them can be a challenge. Here
+we're also talking of \quote {comfort zones}: you have to like a tool(chain).
+Organizations normally don't look for \TEX. Special departments are responsible
+for choosing and negotiating whatever is used in a company. Unfortunately
+companies don't always start from the open question \quotation {We have this
+problem, we want to go there, what should we do?} and then discuss options with
+for instance those who know \TEX. Instead requirements are formulated and matches
+are found. The question then is \quotation {Are these requirements cut in stone?}
+and if not (read: we just omit some requirements when most alternatives don't
+meet them), were other requirements forgotten? Therefore organizations can end up
+with the wrong choice (using \TEX\ in a situation where it makes no sense) or
+don't see opportunities (not using \TEX\ while it makes most sense). It doesn't
+help that a hybrid solution (use a mix of \TEX\ and other tools) is often not an
+option. Where an author can just stop using a tool after a few days of
+disappointment, and where a programmer can play around a bit before making a
+choice, an organization probably best can start small with a proof of concept.
+
+Let's take a use case. A publisher wants to automatically convert \XML\ files
+into \PDF. One product can come from multiple sources (we have cases where
+thousands of small \XML\ files combine into one final product). Say that we have
+three different layouts: a theory book, a teachers manual and an answer book. In
+addition special proofing documents have to be rendered. The products might be
+produced on demand with different topics in any combination. There is at least
+one image and table per page, but there can be more. There are color and
+backgrounds used, tables of contents generated, there is extensive cross
+referencing and an index. Of course there is math.
+
+Now let's assume an initial setup costs 20K Euro and, what happens often when the
+real products show up, a revision after one year takes the same amount. We also
+assume 10K for the following eight years for support. So, we end up with 120K
+over 10 years. If one goes cheap we can consider half of that, or we can be
+pessimistic and double the amount.
+
+The first year 10K pages are produced, the second year 20K and after that 30K per
+year. So, we're talking of 270K pages. If we include customer specific documents
+and proofing we might as well end up with a multiple of that.
+
+So, we have 120K Euro divided by 270K pages or about half an Euro per page. But
+likely we have more pages so it costs less. If we double the costs then we can
+assume that some major changes took place which means more pages. In fact we had
+projects where the layout changed, all documents were regenerated and the costs
+were included in the revision, so far from double. We also see many more pages
+being generated so in practice the price per page drops below half an Euro. The
+more we process the cheaper it gets and one server can produce a lot of pages!
+
+Now, the interesting bit of such a calculation is that the costs only concern the
+hours spent on a solution. A \TEX\ based system comes for free and there are no
+license costs. Whatever alternative is taken, even if it is as flexible, it will
+involve additional costs. From the perspective of costs it's very hard to beat
+\TEX. Add to that the possibility for custom extensions, long term usage and the
+fact that one can adapt the system. The main question of course is: does it do
+the job. The only way to find out is to either experiment (which is free),
+consult an expert (not free, but then needed anyway for any solution) or ask an
+expert to make a proof of concept (also not free but relatively cheap and
+definitely cheaper than a failure). In fact, before making decisions about what
+solution is best it might be a good idea to check with an expert anyway, because
+more or less than one thinks might be possible. Also, take into account that the
+\TEX\ ecosystem is often one of the first to support new technologies, and
+normally does that within its existing interface. And there is plenty of free
+support and knowledge available once you know how to find it. Instead of wasting
+time and money on advertisement and fancy websites, effort goes into support and
+development. Even if you doubt that the current provider is around in the decade
+to come, you can be sure that there will be others, simply because \TEX\ attracts
+people. Okay, it doesn't help that large companies like to out source to
+far||far||away and expect support around the corner, so in the end they might
+kill their support chain.
+
+When talking of \TEX\ used in organizations we tend to think of publishers. But
+this is only a small subset of organizations where information gets transformed
+into something presentable. For small organizations the choice for \TEX\ can be
+easy: costs, long term stability, knowing some experts are driving forces. For
+large organizations these factors seem (at least to us) hardly relevant. We've
+(had) projects where actually the choice for using a \TEX\ based solution was (in
+retrospect) a negative one: there was no other tool than this relatively unknown
+thing called \TEX. Or, because the normal tools could not be used, one ended up
+with a solution where (behind the scenes) \TEX\ is used, without the organization
+knowing it. Or, it happened that the problem at hand was mostly one that demands
+in|-|depth knowledge of manipulating content, cleaning up messy data, combining
+resources (images or \PDF\ documents), all things that happen to be available in
+the perspective of \TEX. If you can solve a hard to solve problem for them then
+an organization doesn't care what tool you use. What does matter is that the
+solution runs forever, that costs are controllable and above all, that it
+\quotation {Just works.} And if you can make it work fast, that helps too. We
+can safely claim that when \TEX\ is evaluated as being a good option, that in the
+end it always works out quite well.
+
+Among arguments that (large) organizations like to use against a choice for \TEX\
+(or something comparable) are the size of the company that they buy their
+solution from, the expected availability for support, and the wide|-|spread usage
+of the tool at hand. One can wonder if it also matters that many vendors change
+ownership, change products every few years, change license conditions when they
+like, charge a lot for support or just abort a tool chain. Unfortunately when that
+happens those responsible for choosing such a system can have moved on to another
+job, so this is seldom part of an evaluation. For the supplier the other side of
+the table is just as much of a gamble. In that respect, an organization that
+wants to use an open source (and|/|or free) solution should realize that getting
+a return on investment on such a development is pretty hard to achieve. So, who
+really takes the risk for writing open source?
+
+For us, the reason to develop \CONTEXT\ and make it open is that it fits in our
+philosophy and we like the community. It is actually not really giving us an
+advantage commercially: it costs way more to develop, support and keep
+up|-|to|-|date than it will ever return. We can come up with better, faster and
+easier solutions and in the end we pay the price because it takes less time to
+cook up styles. So there is some backslash involved because commercially a
+difficult solution leads to more billable hours. Luckily we tend to avoid wasting
+time so we improve when possible and then it ends up in the distributed code.
+And, once the solution is there, anyone can use it. Basically also for us it's
+just a tool, like the operating system, editor and viewer are. So, what keep
+development going is mostly the interaction with the community. This also means
+that a customer can't really demand functionality for free: either wait for it to
+show up or pay for it (which seldom happens). Open source is not equivalent with
+\quotation {You get immediately what you want because someone out there writes
+the code.}. There has to be a valid reason and often it's just users and meetings
+or just some challenge that drives it.
+
+This being said, it is hard to convince a company to use \TEX. It has to come
+from users in the organization. Or, what we sometimes see with publishers, it
+comes with an author team or acquired product line where it's the only option.
+Even then we seldom see transfer to other branches in the organizations. No one
+seems to wonder \quotation {How on earth can that \XML\ to \PDF\ project produce
+whatever output in large quantities in a short period of time} while other (past)
+projects failed. It probably relates to the abstraction of the process. Even
+among \TEX\ users it can be that you demonstrate something with a click on a
+button and that many years afterwards someone present at that moment tells you
+that they just discovered that this or that can be done by hitting a button. I'm
+not claiming that \TEX\ is the magic wand for everything but in some areas it's
+pretty much ahead of the pack. Go to a \TEX\ user meeting and you will be surprised
+about the accumulated diverse knowledge present in the room. It's user demand that
+drives \CONTEXT\ development, not commerce.
+
+\stopsection
+
+\startsection[title={Choosing}]
+
+So, where can one find information about \TEX\ and friends? On the web
+one has to use the right search keys, so adding \type {tex} helps: \typ {context
+tex} or \typ {xml tex pdf} and so on. Can one make a fancy hip website, sure, but
+it being a life|-|long, already old and mature environment, and given that it
+comes for free, or is used low|-|budget, not much effort and money can be spent
+on advertising it. A benefit is that no false promises and hypes are made either.
+If you want to know more, just ask the right folks.
+
+For all kind of topics one can find interesting videos and blogs. One can
+subscribe to channels on YouTube or join forums. Unfortunately not that many
+bloggers or vloggers or podcasters come up with original material every time, and
+often one starts to recognize patterns and will get boring by repetition of wisdom
+and arguments. The same is true for manuals. Is a ten year old manual really
+obsolete? Should we just recompile it to fake an update while in fact there has
+been no need for it? Should we post twenty similar presentations while one can
+do? (If one already wants to present the same topic twenty times in the first
+place?) Maybe one should compare \TEX\ with cars: they became better over time
+and can last for decades. And no new user manual is needed.
+
+As with blogs and vlogs advertising \TEX\ carries the danger for triggering
+political discussions and drawing people into discussions that are not pleasant:
+\TEX\ versus some word processor, open versus closed source, free versus paid
+software, this versus that operating system, editor such or editor so.
+
+To summarize, it's not that trivial to come up with interesting information about
+\TEX, unless one goes into details that are beyond the average user. And those
+who are involved are often involved for a long time so it gets more complex over
+time. User group journals that started with tutorials later on became expert
+platforms. This is a side effect of being an old and long|-|term toolkit. If
+you run into it, and wonder if it can serve your purpose, just ask an expert.
+
+Most \TEX\ solutions are open source and come for free as well. Of course if you
+want a specific solution or want support beyond what is offered on mailing lists
+and forums you should be willing to pay for the hours spent. For a professional
+publisher (of whatever kind) this is not a problem, if only because any other
+solution also will cost something. It is hard to come up with a general estimate.
+A popular measure of typesetting costs is the price per page, which can range
+from a couple of euro's per page to two digit numbers. We've heard of cases where
+initial setup costs were charged. If not much manual intervention is needed a
+\TEX\ solution mostly concerns initial costs.
+
+Let's return to the main question \quotation {Why use \TEX ?} in which you can
+replace \TEX\ by one of the macro packages build on top of it, for instance
+\CONTEXT. If an (somewhat older) organization considers using \TEX\ it should
+also ask itself, why it wasn't considered long ago already? For sure there have
+been developments in \TEX\ engines (in \CONTEXT\ we use \LUATEX) as well as
+possibilities of macro packages but if you look at the documents produced with
+them, there is not that much difference with decades ago. Processing has become
+faster, some things have become easier, but new technologies have always been
+supported as soon at they showed up. Advertising is often just repeating an old
+message.
+
+The \TEX\ ecosystem was among the first in supporting for instance \OPENTYPE, and
+the community even made sure that there were free fonts available. A format like
+\PDF\ was supported as soon as it shows up and \TEX\ was the first to demonstrate
+what advanced features were there and how way it was to adapt to changes.
+Processing \XML\ using \TEX\ has never been a big deal and if that is a reason to
+look at this already old and mature technology, then an organization can wonder
+if years and opportunities (for instance for publishing on demand or easy
+updating of manuals) have been lost. Of course there are (and have been)
+alternative tools but the arguments for using \TEX\ or not are not much different
+now. It can be bad marketing of open and free software. It can be that \TEX\ has
+been around too long. It can also be that its message was not understood yet. On
+the other hand, in software development it's quite common to reinvent wheels and
+present old as new. It's never to late to catch on.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/musings/musings.tex b/doc/context/sources/general/manuals/musings/musings.tex
new file mode 100644
index 000000000..e2787dc99
--- /dev/null
+++ b/doc/context/sources/general/manuals/musings/musings.tex
@@ -0,0 +1,21 @@
+\environment musings-style
+
+\startproduct musings
+
+\component musings-titlepage
+
+\startfrontmatter
+ \component musings-contents
+ \component musings-introduction
+\stopfrontmatter
+
+\startbodymatter
+ \component musings-children
+ \component musings-perception
+ \component musings-whytex
+ \component musings-staygo
+ \component musings-stability
+ \component musings-roadmap
+\stopbodymatter
+
+\stopproduct
diff --git a/doc/context/sources/general/manuals/nodes/nodes.tex b/doc/context/sources/general/manuals/nodes/nodes.tex
index e9857f37e..2d97e676a 100644
--- a/doc/context/sources/general/manuals/nodes/nodes.tex
+++ b/doc/context/sources/general/manuals/nodes/nodes.tex
@@ -24,17 +24,6 @@
%
% comment : The cover images are from the NASA website.
-
-% Alan : There is no need for % before \startfootnote .. the less such crap the better
-% (as it might give disappearing content if one wraps).
-%
-% Alan : ḻṯ What is this? An editor glitch?
-%
-% Alan : $≠$ -> just use ≠ (also, soon the gyre fonts will have more symbols in text
-% that match text.
-%
-% Alan : You can use \typ {x = 0} for something that breaks accross lines.
-
%\enabletrackers[metapost.showlog]
\definemeasure [layout:margin] [\paperheight/20]
@@ -89,6 +78,7 @@
% \definesymbol [1] [$\cdot$]
% Dot rather than bullet ... Alan hates bullets! Hans hates too small dots.
+% So, a dash is OK? ;-)
\setupitemize
[symbol=2] % dash rather than bullet, I hate bullets!
@@ -160,12 +150,13 @@
\startbuffer [bib]
@ARTICLE{Krebs1946,
- author = {Krebs, H. A.},
- title = {Cyclic processes in living matter},
- journal = {Enzymologia},
- year = {1946},
- volume = {12},
- pages = {88--100}
+ author = {Krebs, H. A.},
+ title = {Cyclic processes in living matter},
+ journal = {Enzymologia},
+ year = {1946},
+ volume = {12},
+ pages = {88--100}
+ language = {english},
}
@ARTICLE{Bethe1939a,
@@ -180,6 +171,7 @@
issue = {1},
publisher = {American Physical Society},
XXurl = {http://link.aps.org/doi/10.1103/PhysRev.55.103}
+ language = {english},
}
@ARTICLE{Bethe1939b,
@@ -194,6 +186,7 @@
issue = {5},
publisher = {American Physical Society},
XXurl = {http://link.aps.org/doi/10.1103/PhysRev.55.434}
+ language = {english},
}
@BOOK{Lawvere2009,
@@ -204,6 +197,20 @@
publisher = {Cambridge University Press},
address = {Cambridge, UK},
year = {2009}
+ language = {english},
+ }
+
+ @ARTICLE{Braslau2018,
+ title = {ConTeXt nodes},
+ subtitle = {commutative diagrams and related graphics},
+ author = {Braslau, Alan and Hamid, Idris Samawi and Hagen, Hans},
+ year = {2018},
+ journal = {TUGboat},
+ volume = {39},
+ number = {1},
+ ISSN = {0896-3207},
+ url = {https://www.tug.org/TUGboat/Contents/contents39-1.html},
+ language = {english},
}
\stopbuffer
@@ -356,6 +363,11 @@
\startsubject [title=Introduction]
+A draft version of this manual was published in \cite[journal] [Braslau2018].
+\cite [Braslau2018]
+
+\blank
+
The graphical representation of textual diagrams is a very useful tool in the
communication of ideas. In category and topos theory, for example, many key
concepts, formulas, and theorems are expressed by means of \emph {commutative
@@ -683,7 +695,7 @@ The \CONTEXT\ syntax for the current example looks like this:
\stopnodes
\stopbuffer
-\startplacefigure [location=right,
+\startplacefigure [location=right,reference=fig:ConTeXt,
title={Drawn using \CONTEXT\ interface}]
\getbuffer
\stopplacefigure
@@ -692,10 +704,9 @@ The \CONTEXT\ syntax for the current example looks like this:
\startplacefigure [reference=fig:indices,
location=right,
- title={Coordinates and indices.\footnote{For variety, a rectangular oblique
- lattice is drawn in \in{Figure} [fig:indices].}
- }]
-\stopfootnote
+ title={Coordinates and indices.\footnote {For variety, a rectangular oblique
+ lattice is drawn in \in{Figure} [fig:indices].}}
+ ]
\startframed [frame=off,width=.33\textwidth,align=flushright]
\startnodes [dx=3cm,dy=2cm,rotation=60]
\placenode [0,0] {\node{(0,0)}}
@@ -716,14 +727,47 @@ The \CONTEXT\ syntax for the current example looks like this:
This follows the more classic (and limited) approach of placing nodes on the
coordinates of a regular lattice, here defined as a 3~cm square network.
-\footnote {The lattice can be square (\type {dx} $=$ \type {dy}), rectangular
-(\type {dx} $≠$ \type {dy}), or oblique (through \type {rotation} $≠$ 90).} The
-arguments are then $(x,y)$ coordinates of this lattice and the nodes are indexed
+\startfootnote
+ The lattice can be square (\type {dx} $=$ \type {dy}), rectangular
+ (\type {dx} ≠ \type {dy}), or oblique (through \type {rotation} ≠ 90).
+\stopfootnote
+The arguments are then $(x,y)$ coordinates of this lattice and the nodes are indexed
0, 1, 2, … in the order that they are drawn. These are used as reference indices
in the commands \type {\connectnodes} (rather than requiring two \emph {pairs} of
coordinates); see \in {Figure} [fig:indices]. This might seem a bit confusing at
first view, but it simplifies things in the end, really!
+To avoid such confusion, in particular when drawing complicated diagrams
+containing many nodes, the \CONTEXT\ interface allows the use of a \type
+{reference} or tag, assigning a symbolic name to a numbered node. The example of
+\in{Figure} [fig:ConTeXt] can be redrawn a little more verbosely as:
+
+\startbuffer
+ \startnodes [dx=3cm,dy=3cm]
+ \placenode [0,0] [reference=GX] {\node{$G(X)$}}
+ \placenode [1,0] [reference=GY] {\node{$G(Y)$}}
+ \placenode [1,1] [reference=FY] {\node{$F(Y)$}}
+ \placenode [0,1] [reference=FX] {\node{$F(X)$}}
+ \connectnodes [GX,GY] [alternative=arrow,
+ label={\nodeSmall{$G(f)$}},position=bottom]
+ \connectnodes [FX,FY] [alternative=arrow,
+ label={\nodeSmall{$F(f)$}},position=top]
+ \connectnodes [FY,GY] [alternative=arrow,
+ label={\nodeSmall{$η_Y$}}, position=right]
+ \connectnodes [FX,GX] [alternative=arrow,
+ label={\nodeSmall{$η_X$}}, position=left]
+ \stopnodes
+\stopbuffer
+
+\typebuffer [option=TEX]
+
+Notice that, like for all \CONTEXT\ macros, one never mixes a
+comma|-|separated list of arguments (\type {[0,0]}) with a key=value list
+(i.e. \type {[reference=GX]}). Symbolic references are very useful for longer,
+more complicated diagrams; additionally, this easily allows modification such as
+the addition of nodes without having to keep track of counting the order in
+which they were drawn.
+
An identity map, as shown in \in {Figure} [fig:ID], earlier, and, below, in \in
{Figure} [fig:Me] is achieved by connecting a node to itself:
@@ -752,8 +796,6 @@ The scale (diameter) of the circular loop|-|back is set by the keyword \type
straight|-|line segment between them), and the \type {position=} keyword sets its
orientation.
-\page [yes]
-
\startbuffer
\startMPcode
clearnodepath ;
@@ -840,8 +882,6 @@ exterior for the output.
The code is as follows:
-\page [yes]
-
\startbuffer
\startMPcode
save p ; path p[] ;
@@ -1145,7 +1185,7 @@ path:
save p ; % path p ;
\stopTEX
-The \type {save p ;} assures that the path is undefined. This path will later ḻṯ
+The \type {save p ;} assures that the path is undefined. This path will later be
defined based on the contents of the nodes and a desired relative placement. In
fact, it is not even necessary to declare that the suffix will be a path, as the
path will be declared and automatically built once the positions of all the nodes
@@ -1490,8 +1530,6 @@ coordinate taken to be \type {right}, both in the page of the paper. The third
coordinate \type {X} is an oblique projection in a right|-|hand coordinate
system.
-\page [yes]
-
\startbuffer
\startMPcode{three}
save nodepath ;
diff --git a/doc/context/sources/general/manuals/notnow/notnow-sidefloats.tex b/doc/context/sources/general/manuals/notnow/notnow-sidefloats.tex
index 4a8a1ba3b..c7de6c2c5 100644
--- a/doc/context/sources/general/manuals/notnow/notnow-sidefloats.tex
+++ b/doc/context/sources/general/manuals/notnow/notnow-sidefloats.tex
@@ -1,7 +1,5 @@
\usemodule[art-01]
-\starttext
-
\definefloat
[figure-column]
diff --git a/doc/context/sources/general/manuals/onandon/onandon-110.tex b/doc/context/sources/general/manuals/onandon/onandon-110.tex
new file mode 100644
index 000000000..e8b005f24
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-110.tex
@@ -0,0 +1,137 @@
+% language=uk
+
+% After watching \quotation {What Makes This Song Great 30: Alanis Morisette} by
+% Rick Beato, it's tempting to poder \quotation {What makes \TEX\ great}.
+
+\startcomponent onandon-110
+
+\environment onandon-environment
+
+\startchapter[title={Getting there, version 1.10}]
+
+When we decided to turn experiments with a \LUA\ extensions to \PDFTEX\ into
+developing \LUATEX\ as alternative engine we had, in addition to opening up some
+of \TEX's internals, some extensions in mind. Around version 1.00 most was
+already achieved and with version 1.10 we're pretty close to where we want to be.
+The question is, when are we ready? In order to answer that I will look at four
+aspects:
+
+\startitemize[packed]
+\startitem objectives \stopitem
+\startitem functionality \stopitem
+\startitem performance \stopitem
+\startitem stability \stopitem
+\stopitemize
+
+The main {\em objective} was to open up \TEX\ in a way that permit extensions
+without the need to patch the engine. Although it might suit us, we don't want to
+change too much the internals, first of all because \TEX\ is \TEX, the documented
+program with a large legacy. \footnote {This is reflected in the keywords that
+exposed mechanisms use: they reflect internal variable names and constants and as
+a consequence there is inconsistency there.} Discussions about how to extend
+\TEX\ are not easy and seldom lead to an agreement so better is to provide a way
+to do what you like without bothering other users and|/|or interfering with macro
+packages. I think that this objective is met quite well now. Other objectives,
+like embedding basic graphic capabilities using \METAPOST\ have already been met
+long ago. There is more control over the backend and modern fonts can be dealt
+with.
+
+The {\em functionality} in terms of primitives has been extended but within
+reasonable bounds: we only added things that make coding a bit more natural but
+we realize that this is very subjective. So, here again we can say that we met
+our goals. A lot can be achieved via \LUA\ code and users and developers need to
+get accustomed to that if they want to move on with \LUATEX. We will not
+introduce features that get added to or are part of other engines.
+
+We wanted to keeping {\em performance} acceptable. The core \TEX\ engine is
+already pretty fast and it's often the implementation of macros (in macro
+packages) that creates a performance hit. Going \UTF\ has a price as do modern
+fonts. At the time of this writing processing the 270 page \LUATEX\ manual takes
+about 12 seconds (one run), which boils down to over 27 pages per second.
+
+\starttabulate[||c|c|]
+\NC \BC runtime \BC overhead \NC \NR
+\BC \LUATEX \NC $12.0$ \NC $+0.6$ \NC \NR
+\BC \LUAJITTEX \NC $ 9.7$ \NC $+0.5$ \NC \NR
+\stoptabulate
+
+Is this fast or slow? One can do tests with specific improvements (using new
+primitives) but in practice it's very hard to improve performance significantly.
+This is because a test with millions of calls that show a .05 second improvement
+disappears when one only has a few thousand calls. Many small improvements can
+add up, but less that one thinks, especially when macros are already quite
+optimal. Also this runtime includes time normally used for running additional
+programs (e.g.\ for getting bibliographies right).
+
+It must be said that performance is not completely under our control. For
+instance, we have patched the \LUAJIT\ hash function because it favours \URL's
+and therefore favours hashing the middle of the string which is bad for our use
+as we are more interested in the (often unique) start of strings. We also
+compress the format which speeds up loading but not on the native windows 64~bit
+binary. At the time this writing the extra overhead is 2~seconds due to some
+suboptimal gzip handling; the cross compiled 64~bit mingw binaries that I use
+don't suffer from this. When I was testing the 32~bit binaries on the machine of
+a colleague, I was surprised to measure the following differences on a complex
+document with hundreds of \XML\ files, many images and a lot of manipulations.
+
+\starttabulate[||c|c|]
+\NC \BC 1.08 with \LUA\ 5.2 \BC 1.09 with \LUA\ 5.3 \NC \NR
+\BC \LUATEX \NC $21.5$ \NC $15.2$ \NC \NR
+\BC \LUAJITTEX \NC $10.7$ \NC $10.3$ \NC \NR
+\stoptabulate
+
+Now, these are just rough numbers but they demonstrate that the gap between
+\LUATEX\ and \LUAJITTEX\ is becoming less which is good because at this moment it
+looks like \LUAJIT\ will not catch up with \LUA\ 5.3 so at some point we might
+drop it. It will be interesting to see what \LUA\ 5.4 will bring as it offers an
+\ alternative garbage collector. And imagine that the regular \LUA\ virtual
+machine gets more optimized.
+
+You also have to take into account that having a browser open in the background
+of a \TEX\ run has way more impact than a few tenths of a second in \LUATEX\
+performance. The same is true for memory usage: why bother about \LUATEX\ taking
+tens of megabytes for fonts while a few tabs in a browser can bump memory
+consumption to gigabytes of memory usage. Also, using a large \TEX\ tree (say the
+whole of \TEXLIVE) can have a bit of a performance hit! Or what about inefficient
+callbacks, using inefficient \LUA\ code of badly designed solutions? What we
+could gain here we loose there, so I think we can safely say that the current
+implementation of \LUATEX\ is as good as you can (and will) get. Why should we
+introduce obscure optimizations where on workstations \TEX\ is just one of the
+many processes? Why should we bother too much to speed up on servers that have
+start|-|up or job management overhead or are connected to relatively slow remote
+file system? Why squeeze out a few more milliseconds when badly written macros or
+styles can have an way more impact on performance? So, for now we're satisfied
+with performance. Just for the record, the ratio between \CONTEXT\ \MKII\
+running other engines and \LUATEX\ with \MKIV\ for the next snippet of code:
+
+\starttyping
+\dorecurse{250}{\input tufte\par}
+\stoptyping
+
+is 2.8 seconds for \XETEX, 1.5 seconds for \LUATEX, 1.2 seconds for \LUAJITTEX,
+and 0.9 seconds for \PDFTEX. Of course this is not really a practical test but it
+demonstrates the baseline performance on just text. The 64 bit version of \PDFTEX\
+is actually quite a bit slower on my machine. Anyway, \LUATEX\ (1.09) with \MKIV\
+is doing okey here.
+
+That brings us to {\em stability}. In order to achieve that we will not introduce
+many more extensions. That way users get accustomed to what is there (read: there
+is no need to search for what else is possible). Also, it makes that existing
+functionality can become bug free because no new features can interfere. So, at
+some point we have to decide that this is it. If we can do what we want now,
+there are no strong arguments for more. in that perspective version 1.10 can be
+considered very close to what we want to achieve.
+
+Of course development will continue. For instance, the \PDF\ inclusion code will
+be replaced by more lightweight and independent code. Names of functions and
+symbolic constants might be normalized (as mentioned, currently they are often
+related to or derived from internals). More documentation will be added. We will
+quite probably keep up with \LUA\ versions. Also the \FFI\ interface will become
+more stable. And for sure bugs will be fixed. We might add a few more options to
+control behaviour of for instance of math rendering. Some tricky internals (like
+alignments) might get better attribute support if possible. But currently we
+think that most fundamental issues have been dealt with.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-53.tex b/doc/context/sources/general/manuals/onandon/onandon-53.tex
new file mode 100644
index 000000000..0d5dc1b9c
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-53.tex
@@ -0,0 +1,288 @@
+% language=uk
+
+\startcomponent onandon-53
+
+\environment onandon-environment
+
+\startchapter[title={From \LUA\ 5.2 to 5.3}]
+
+When we started with \LUATEX\ we used \LUA\ 5.1 and moved to 5.2 when that became
+available. We didn't run into issues then because there were no fundamental
+changes that could not be dealt with. However, when \LUA\ 5.3 was announced in
+2015 we were not sure if we should make the move. The main reason was that we'd
+chosen \LUA\ because of its clean design which meant that we had only one number
+type: double. In 5.3 on the other hand, deep down a number can be either an
+integer or a floating point quantity.
+
+Internally \TEX\ is mostly (up to) 32-bit integers and when we go from \LUA\ to
+\TEX\ we round numbers. Nonetheless one can expect some benefits in using
+integers. Performance|-|wise we didn't expect much, and memory consumption would
+be the same too. So, the main question then was: can we get the same output and
+not run into trouble due to possible differences in serializing numbers; after
+all \TEX\ is about stability. The serialization aspect is for instance important
+when we compare quantities and|/|or use numbers in hashes.
+
+Apart from this change in number model, which comes with a few extra helpers,
+another extension in 5.3 was that bit|-|wise operations are now part of the
+language. The lpeg library is still not part of stock \LUA. There is some minimal
+\UTF8 support, but less than we provide in \LUATEX\ already. So, looking at these
+changes, we were not in a hurry to update. Also, it made sense to wait till this
+important number|-|related change was stable.
+
+But, a few years later, we still had it on our agenda to test, and after the
+\CONTEXT\ 2017 meeting we decided to give it a try; here are some observations. A
+quick test was just dropping in the new \LUA\ code and seeing if we could make a
+\CONTEXT\ format. Indeed that was no big deal but a test run failed because at
+some point a (for instance) \type {1} became a \type {1.0}. It turned out that
+serializing has some side effects. And with some ad hoc prints for tracing (in
+the \LUATEX\ source) I could figure out what went on. How numbers are seen can
+(to some extent) be deduced from the \type {string.format} function, which is in
+\LUA\ a combination of parsing, splitting and concatenation combined with piping
+to the \CCODE\ \type {sprintf} function. \footnote {Actually, at some point I
+decided to write my own formatter on top of \type {format} and I ended up with
+splitting as well. It's only now that I realize why this is working out so well
+(in terms of performance): simple format (single items) are passed more or less
+directly to \type {sprintf} and as \LUA\ itself is fast, due to some caching, the
+overhead is small compared to the built|-|in splitter method. And the \CONTEXT\
+formatter has many more options and is extensible.}
+
+\starttyping
+local a = 2 * (1/2) print(string.format("%s", a),math.type(x))
+local b = 2 * (1/2) print(string.format("%d", b),math.type(x))
+local c = 2 print(string.format("%d", c),math.type(x))
+local d = -2 print(string.format("%d", d),math.type(x))
+local e = 2 * (1/2) print(string.format("%i", e),math.type(x))
+local f = 2.1 print(string.format("%.0f",f),math.type(x))
+local g = 2.0 print(string.format("%.0f",g),math.type(x))
+local h = 2.1 print(string.format("%G", h),math.type(x))
+local i = 2.0 print(string.format("%G", i),math.type(x))
+local j = 2 print(string.format("%.0f",j),math.type(x))
+local k = -2 print(string.format("%.0f",k),math.type(x))
+\stoptyping
+
+This gives the following results:
+
+\starttabulate[|cBT|c|T|c|cT|]
+\BC a \NC 2 * (1/2)\NC s \NC 1.0 \NC float \NC \NR
+\BC b \NC 2 * (1/2)\NC d \NC 1 \NC float \NC \NR
+\BC c \NC 2 \NC d \NC 2 \NC integer \NC \NR
+\BC d \NC -2 \NC d \NC 2 \NC integer \NC \NR
+\BC e \NC 2 * (1/2)\NC i \NC 1 \NC float \NC \NR
+\BC f \NC 2.1 \NC .0f \NC 2 \NC float \NC \NR
+\BC g \NC 2.0 \NC .0f \NC 2 \NC float \NC \NR
+\BC h \NC 2.1 \NC G \NC 2.1 \NC float \NC \NR
+\BC i \NC 2.0 \NC G \NC 2 \NC float \NC \NR
+\BC j \NC 2 \NC .0f \NC 2 \NC integer \NC \NR
+\BC k \NC -2 \NC .0f \NC 2 \NC integer \NC \NR
+\stoptabulate
+
+This demonstrates that we have to be careful when we need these numbers
+represented as strings. In \CONTEXT\ the number of places where we had to check
+for that was not that large; in fact, only some hashing related to font sizes had
+to be done using explicit rounding.
+
+Another surprising side effect is the following. Instead of:
+
+\starttyping
+local n = 2^6
+\stoptyping
+
+we now need to use:
+
+\starttyping
+local n = 0x40
+\stoptyping
+
+or just:
+
+\starttyping
+local n = 64
+\stoptyping
+
+because we don't want this to be serialized to \type {64.0} which is due to the
+fact that a power results in a float. One can wonder if this makes sense when we
+apply it to an integer.
+
+At any rate, once we could process a file, two documents were chosen for a
+performance test. Some experiments with loops and casts had demonstrated that we
+could expect a small performance hit and indeed, this was the case. Processing
+the \LUATEX\ manual takes 10.7 seconds with 5.2 on my 5-year-old laptop and 11.6
+seconds with 5.3. If we consider that \CONTEXT\ spends 50\% of its time in \LUA,
+then we see a 20\% performance penalty. Processing the \METAFUN\ manual (which
+has lots of \METAPOST\ images) went from less than 20 seconds (\LUAJITTEX\ does
+it in 16 seconds) up to more than 27 seconds. So there we lose more than 50\% on
+the \LUA\ end. When we observed these kinds of differences, Luigi and I
+immediately got into debugging mode, partly out of curiosity, but also because
+consistent performance is important to~us.
+
+Because these numbers made no sense, we traced different sub-mechanisms and
+eventually it became clear that the reason for the speed penalty was that the
+core \typ {string.format} function was behaving quite badly in the \type {mingw}
+cross-compiled binary, as seen by this test:
+
+\starttyping
+local t = os.clock()
+for i=1,1000*1000 do
+ -- local a = string.format("%.3f",1.23)
+ -- local b = string.format("%i",123)
+ local c = string.format("%s",123)
+end
+print(os.clock()-t)
+\stoptyping
+
+\starttabulate[|c|c|c|c|c|]
+\BC \BC lua 5.3 \BC lua 5.2 \BC texlua 5.3 \BC texlua 5.2 \BC \NR
+\BC a \NC 0.43 \NC 0.54 \NC 3.71 (0.47) \NC 0.53 \NC \NR
+\BC b \NC 0.18 \NC 0.24 \NC 3.78 (0.17) \NC 0.22 \NC \NR
+\BC c \NC 0.26 \NC 0.68 \NC 3.67 (0.29) \NC 0.66 \NC \NR
+\stoptabulate
+
+The 5.2 binaries perform the same but the 5.3 Lua binary greatly outperforms
+\LUATEX, and so we had to figure out why. After all, all this integer
+optimization could bring some gain! It took us a while to figure this out. The
+numbers in parentheses are the results after fixing this.
+
+Because font internals are specified in integers one would expect a gain
+in running:
+
+\starttyping
+mtxrun --script font --reload force
+\stoptyping
+
+and indeed that is the case. On my machine a scan results in 2561 registered
+fonts from 4906 read files and with 5.2 that takes 9.1 seconds while 5.3 needs a
+bit less: 8.6 seconds (with the bad format performance) and even less once that
+was fixed. For a test:
+
+\starttyping
+\setupbodyfont[modern] \tf \bf \it \bs
+\setupbodyfont[pagella] \tf \bf \it \bs
+\setupbodyfont[dejavu] \tf \bf \it \bs
+\setupbodyfont[termes] \tf \bf \it \bs
+\setupbodyfont[cambria] \tf \bf \it \bs
+\starttext \stoptext
+\stoptyping
+
+This code needs 30\% more runtime so the question is: how often do we call \type
+{string.format} there? A first run (when we wipe the font cache) needs some
+715,000 calls while successive runs need 115,000 calls so that slow down
+definitely comes from the bad handling of \type {string.format}. When we drop in
+a \LUA\ update or whatever other dependency we don't want this kind of impact. In
+fact, when one uses external libraries that are or can be compiled under the
+\TEX\ Live infrastructure and the impact would be such, it's bad advertising,
+especially when one considers the occasional complaint about \LUATEX\ being
+slower than other engines.
+
+The good news is that eventually Luigi was able to nail down this issue and we
+got a binary that performed well. It looks like \LUA\ 5.3.4 (cross|)|compiles
+badly with \GCC\ 5.3.0 and 6.3.0.
+
+So in the end caching the fonts takes:
+
+\starttabulate[||c|c|]
+\BC \BC caching \BC running \NC \NR
+\BC 5.2 stock \NC 8.3 \NC 1.2 \NC \NR
+\BC 5.3 bugged \NC 12.6 \NC 2.1 \NC \NR
+\BC 5.3 fixed \NC 6.3 \NC 1.0 \NC \NR
+\stoptabulate
+
+So indeed it looks like 5.3 is able to speed up \LUATEX\ a bit, given that one
+integrates it in the right way! Using a recent compiler is needed too, although
+one can wonder when a bad case will show up again. One can also wonder why such a
+slow down can mostly go unnoticed, because for sure \LUATEX\ is not the only
+compiled program.
+
+The next examples are some edge cases that show you need to be aware
+that
+\startitemize[n,text,nostopper]
+ \startitem an integer has its limits, \stopitem
+ \startitem that hexadecimal numbers are integers and \stopitem
+ \startitem that \LUA\ and \LUAJIT\ can be different in details. \stopitem
+\stopitemize
+
+\starttabulate[||T|T|]
+\NC \NC \tx print(0xFFFFFFFFFFFFFFFF) \NC \tx print(0x7FFFFFFFFFFFFFFF) \NC \NR
+\HL
+\BC lua 52 \NC 1.844674407371e+019 \NC 9.2233720368548e+018 \NC \NR
+\BC luajit \NC 1.844674407371e+19 \NC 9.2233720368548e+18 \NC \NR
+\BC lua 53 \NC -1 \NC 9223372036854775807 \NC \NR
+\stoptabulate
+
+So, to summarize the process. A quick test was relatively easy: move 5.3 into the
+code base, adapt a little bit of internals (there were some \LUATEX\ interfacing
+bits where explicit rounding was needed), run tests and eventually fix some
+issues related to the Makefile (compatibility) and \CCODE\ obscurities (the slow
+\type {sprintf}). Adapting \CONTEXT\ was also not much work, and the test suite
+uncovered some nasty side effects. For instance, the valid 5.2 solution:
+
+\starttyping
+local s = string.format("02X",u/1024)
+local s = string.char (u/1024)
+\stoptyping
+
+now has to become (both 5.2 and 5.3):
+
+\starttyping
+local s = string.format("02X",math.floor(u/1024))
+local s = string.char (math.floor(u/1024))
+\stoptyping
+
+or (both 5.2 and (emulated or real) 5.3):
+
+\starttyping
+local s = string.format("02X",bit32.rshift(u,10))
+local s = string.char (bit32.rshift(u,10))
+\stoptyping
+
+or (only 5.3):
+
+\starttyping
+local s = string.format("02X",u >> 10))
+local s = string.char (u >> 10)
+\stoptyping
+
+or (only 5.3):
+
+\starttyping
+local s = string.format("02X",u//1024)
+local s = string.char (u//1024)
+\stoptyping
+
+A conditional section like:
+
+\starttyping
+if LUAVERSION >= 5.3 then
+ local s = string.format("02X",u >> 10))
+ local s = string.char (u >> 10)
+else
+ local s = string.format("02X",bit32.rshift(u,10))
+ local s = string.char (bit32.rshift(u,10))
+end
+\stoptyping
+
+will fail because (of course) the 5.2 parser doesn't like that. In \CONTEXT\ we
+have some experimental solutions for that but that is beyond this summary.
+
+In the process a few \UTF\ helpers were added to the string library so that we
+have a common set for \LUAJIT\ and \LUA\ (the \type {utf8} library that was added
+to 5.3 is not that important for \LUATEX). For now we keep the \type {bit32}
+library on board. Of course we'll not mention all the details here.
+
+When we consider a gain in speed of 5-10\% with 5.3 that also means that the gain
+of \LUAJITTEX\ compared to 5.2 becomes less. For instance in font processing both
+engines now perform closer to the same.
+
+As I write this, we've just entered 2018 and after a few months of testing
+\LUATEX\ with \LUA\ 5.3 we're confident that we can move the code to the
+experimental branch. This means that we will use this version in the \CONTEXT\
+distribution and likely will ship this version as 1.10 in 2019, where it becomes
+the default. The 2018 version of \TEX~Live will have 1.07 with \LUA\ 5.2 while
+intermediate versions of the \LUA\ 5.3 binary will end up on the \CONTEXT\
+garden, probably with number 1.08 and 1.09 (who knows what else we will add or
+change in the meantime).
+
+\stopchapter
+
+\stopcomponent
+
+% collectgarbage("count") -- two return values in 2
diff --git a/doc/context/sources/general/manuals/onandon/onandon-emoji.tex b/doc/context/sources/general/manuals/onandon/onandon-emoji.tex
index 1f67cc528..0a89727a1 100644
--- a/doc/context/sources/general/manuals/onandon/onandon-emoji.tex
+++ b/doc/context/sources/general/manuals/onandon/onandon-emoji.tex
@@ -75,8 +75,8 @@ mentions twice that amount. Currently in \CONTEXT\ we resolve such combinations
when requested.} so imagine what will happen in the future. But, instead of
making a picture for each variant, a different solution has been chosen. For
coloring this seguiemj font uses the (very flexible) stacking technology: a color
-shape is an overlay of colored symbols. The colors are organized in pallets and
-it's no big deal to add additional pallets if needed. Instead of adding
+shape is an overlay of colored symbols. The colors are organized in palettes and
+it's no big deal to add additional palettes if needed. Instead of adding
pre|-|composed shapes (as is needed with bitmaps and \SVG) snippets are used to
build alternative glyphs and these can be combined into new shapes by
substitution and positioning (for that kerns, mark anchoring and distance
@@ -186,11 +186,11 @@ account:
scale too.
\stopitem
\startitem
- How efficient is a shape constructed. In that respect a bitmap or \SVG\ image
+ How efficiently is a shape constructed? In that respect a bitmap or \SVG\ image
is just one entity.
\stopitem
\startitem
- How well can (semi) arbitrary combinations of emoji be provided. Here the
+ How well can a (semi)arbitrary combinations of emoji be provided? Here the
glyph approach wins.
\stopitem
\startitem
@@ -203,17 +203,17 @@ account:
social political reasons.
\stopitem
\startitem
- Are black and white shapes provided alongside color shapes.
+ Are black and white shapes provided alongside color shapes?
\stopitem
\stopitemize
Maybe an \SVG\ or bitmap image can have a lot of detail compared to a stacked
-glyph but, when we're just using pictographic representations, the later is the
+glyph but, when we're just using pictographic representations, the latter is the
best choice.
When I was playing a bit with the skin tone variants and other combinations that
should result in some composed shape, I used the \UNICODE\ test files but I got
-the impression that there are some errors in the test suite, for instance with
+the impression that there were some errors in the test suite, for instance with
respect to modifiers. Maybe the fonts are just doing the wrong thing or maybe
some implement these sequences a bit inconsistent. This will probably improve
over time but the question is if we should intercept issues. I'm not in favour of
@@ -409,7 +409,7 @@ In case you wonder how some of the details above were typeset, there is a module
\NC \type {\ShowEmojiSnippets} \NC show the snippets of a given emoji \NC \NR
\NC \type {\ShowEmojiSnippetsOverlay} \NC show the overlayed snippets of a given emoji \NC \NR
\NC \type {\ShowEmojiGlyphs} \NC show the snippets of a typeset emoji \NC \NR
-\NC \type {\ShowEmojiPalettes} \NC show the color pallets in the current font \NC \NR
+\NC \type {\ShowEmojiPalettes} \NC show the color palletes in the current font \NC \NR
\stoptabulate
Examples of usage are:
diff --git a/doc/context/sources/general/manuals/onandon/onandon-execute.tex b/doc/context/sources/general/manuals/onandon/onandon-execute.tex
new file mode 100644
index 000000000..abb3b4d8a
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-execute.tex
@@ -0,0 +1,396 @@
+% language=uk
+
+\startcomponent onandon-execute
+
+\environment onandon-environment
+
+\startchapter[title={Executing \TEX}]
+
+Much of the \LUA\ code in \CONTEXT\ originates from experiments. When it survives
+in the source code it is probably used, waiting to be used or kept for
+educational purposes. The functionality that we describe here has already been
+present for a while in \CONTEXT, but improved a little starting with \LUATEX\
+1.08 due to an extra helper. The code shown here is generic and not used in
+\CONTEXT\ as such.
+
+Say that we have this code:
+
+\startbuffer
+for i=1,10000 do
+ tex.sprint("1")
+ tex.sprint("2")
+ for i=1,3 do
+ tex.sprint("3")
+ tex.sprint("4")
+ tex.sprint("5")
+ end
+ tex.sprint("\\space")
+end
+\stopbuffer
+
+\typebuffer
+
+% \ctxluabuffer
+
+When we call \type {\directlua} with this snippet we get some 30 pages of \type
+{12345345345}. The printed text is saved till the end of the \LUA\ call, so
+basically we pipe some 170.000 characters to \TEX\ that get interpreted as one
+paragraph.
+
+Now imagine this:
+
+\startbuffer
+\setbox0\hbox{xxxxxxxxxxx} \number\wd0
+\stopbuffer
+
+\typebuffer
+
+which gives \getbuffer. If we check the box in \LUA, with:
+
+\startbuffer
+tex.sprint(tex.box[0].width)
+tex.sprint("\\enspace")
+tex.sprint("\\setbox0\\hbox{!}")
+tex.sprint(tex.box[0].width)
+\stopbuffer
+
+\typebuffer
+
+the result is {\tttf \ctxluabuffer}, which is not what you would expect at first
+sight. However, if you consider that we just pipe to a \TEX\ buffer that gets
+parsed after the \LUA\ call, it will be clear that the reported width is the
+width that we started with. It will work all right if we say:
+
+\startbuffer
+tex.sprint(tex.box[0].width)
+tex.sprint("\\enspace")
+tex.sprint("\\setbox0\\hbox{!}")
+tex.sprint("\\directlua{tex.sprint(tex.box[0].width)}")
+\stopbuffer
+
+\typebuffer
+
+because now we get: {\tttf\ctxluabuffer}. It's not that complex to write some
+support code that makes this more convenient. This can work out quite well but
+there is a drawback. If we use this code:
+
+\startbuffer
+print(status.input_ptr)
+tex.sprint(tex.box[0].width)
+tex.sprint("\\enspace")
+tex.sprint("\\setbox0\\hbox{!}")
+tex.sprint("\\directlua{print(status.input_ptr)\
+ tex.sprint(tex.box[0].width)}")
+\stopbuffer
+
+\typebuffer
+
+Here we get \type {6} and \type {7} reported. You can imagine that when a lot of
+nested \type {\directlua} calls happen, we can get an overflow of the input level
+or (depending on what we do) the input stack size. Ideally we want to do a \LUA\
+call, temporarily go to \TEX, return to \LUA, etc.\ without needing to worry
+about nesting and possible crashes due to \LUA\ itself running into problems. One
+charming solution is to use so|-|called coroutines: independent \LUA\ threads
+that one can switch between --- you jump out from the current routine to another
+and from there back to the current one. However, when we use \type {\directlua}
+for that, we still have this nesting issue and what is worse, we keep nesting
+function calls too. This can be compared to:
+
+\starttyping
+\def\whatever{\ifdone\whatever\fi}
+\stoptyping
+
+where at some point \type {\ifdone} is false so we quit. But we keep nesting when
+the condition is met, so eventually we can end up with some nesting related
+overflow. The following:
+
+\starttyping
+\def\whatever{\ifdone\expandafter\whatever\fi}
+\stoptyping
+
+is less likely to overflow because there we have tail recursion which basically
+boils down to not nesting but continuing. Do we have something similar in
+\LUATEX\ for \LUA ? Yes, we do. We can register a function, for instance:
+
+\starttyping
+lua.get_functions_table()[1] = function() print("Hi there!") end
+\stoptyping
+
+and call that one with:
+
+\starttyping
+\luafunction 1
+\stoptyping
+
+This is a bit faster than calling a function like:
+
+\starttyping
+\directlua{HiThere()}
+\stoptyping
+
+which can also be achieved by
+
+\starttyping
+\directlua{print("Hi there!")}
+\stoptyping
+
+which sometimes can be more convenient. Anyway, a function call is what we can
+use for our purpose as it doesn't involve interpretation and effectively behaves
+like a tail call. The following snippet shows what we have in mind:
+
+\startbuffer[code]
+local stepper = nil
+local stack = { }
+local fid = 0xFFFFFF
+local goback = "\\luafunction" .. fid .. "\\relax"
+
+function tex.resume()
+ if coroutine.status(stepper) == "dead" then
+ stepper = table.remove(stack)
+ end
+ if stepper then
+ coroutine.resume(stepper)
+ end
+end
+
+lua.get_functions_table()[fid] = tex.resume
+
+function tex.yield()
+ tex.sprint(goback)
+ coroutine.yield()
+ texio.closeinput()
+end
+
+function tex.routine(f)
+ table.insert(stack,stepper)
+ stepper = coroutine.create(f)
+ tex.sprint(goback)
+end
+\stopbuffer
+
+\ctxluabuffer[code]
+
+\startbuffer[demo]
+tex.routine(function()
+ tex.sprint(tex.box[0].width)
+ tex.sprint("\\enspace")
+ tex.sprint("\\setbox0\\hbox{!}")
+ tex.yield()
+ tex.sprint(tex.box[0].width)
+end)
+\stopbuffer
+
+\typebuffer[demo]
+We start a routine, jump out to \TEX\ in the middle, come back when we're done
+and continue. This gives us: \ctxluabuffer [demo], which is what we expect.
+
+\setbox0\hbox{xxxxxxxxxxx}
+
+\ctxluabuffer[demo]
+
+This mechanism permits efficient (nested) loops like:
+
+\startbuffer[demo]
+tex.routine(function()
+ for i=1,10000 do
+ tex.sprint("1")
+ tex.yield()
+ tex.sprint("2")
+ tex.routine(function()
+ for i=1,3 do
+ tex.sprint("3")
+ tex.yield()
+ tex.sprint("4")
+ tex.yield()
+ tex.sprint("5")
+ end
+ end)
+ tex.sprint("\\space")
+ tex.yield()
+ end
+end)
+\stopbuffer
+
+\typebuffer[demo]
+
+We do create coroutines, go back and forwards between \LUA\ and \TEX, but avoid
+memory being filled up with printed content. If we flush paragraphs (instead of
+e.g.\ the space) then the main difference is that instead of a small delay due to
+the loop unfolding in a large set of prints and accumulated content, we now get a
+steady flushing and processing.
+
+However, we can still have an overflow of input buffers because we still nest
+them: the limitation at the \TEX\ end has moved to a limitation at the \LUA\ end.
+How come? Here is the code that we use:
+
+\typebuffer[code]
+
+The \type {routine} creates a coroutine, and \type {yield} gives control to \TEX.
+The \type {resume} is done at the \TEX\ end when we're finished there. In
+practice this works fine and when you permit enough nesting and levels in \TEX\
+then you will not easily overflow.
+
+When I picked up this side project and wondered how to get around it, it suddenly
+struck me that if we could just quit the current input level then nesting would
+not be a problem. Adding a simple helper to the engine made that possible (of
+course figuring it out took a while):
+
+\startbuffer[code]
+local stepper = nil
+local stack = { }
+local fid = 0xFFFFFF
+local goback = "\\luafunction" .. fid .. "\\relax"
+
+function tex.resume()
+ if coroutine.status(stepper) == "dead" then
+ stepper = table.remove(stack)
+ end
+ if stepper then
+ coroutine.resume(stepper)
+ end
+end
+
+lua.get_functions_table()[fid] = tex.resume
+
+if texio.closeinput then
+ function tex.yield()
+ tex.sprint(goback)
+ coroutine.yield()
+ texio.closeinput()
+ end
+else
+ function tex.yield()
+ tex.sprint(goback)
+ coroutine.yield()
+ end
+end
+
+function tex.routine(f)
+ table.insert(stack,stepper)
+ stepper = coroutine.create(f)
+ tex.sprint(goback)
+end
+\stopbuffer
+
+\ctxluabuffer[code]
+
+\typebuffer[code]
+
+The trick is in \type {texio.closeinput}, a recent helper and one that should be
+used with care. We assume that the user knows what she or he is doing. On an old
+laptop with a i7-3840 processor running \WINDOWS\ 10 the following snippet takes
+less than 0.35 seconds with \LUATEX\ and 0.26 seconds with \LUAJITTEX.
+
+\startbuffer[code]
+tex.routine(function()
+ for i=1,10000 do
+ tex.sprint("\\setbox0\\hpack{x}")
+ tex.yield()
+ tex.sprint(tex.box[0].width)
+ tex.routine(function()
+ for i=1,3 do
+ tex.sprint("\\setbox0\\hpack{xx}")
+ tex.yield()
+ tex.sprint(tex.box[0].width)
+ end
+ end)
+ end
+end)
+\stopbuffer
+
+\typebuffer[code]
+
+% \testfeatureonce {1} {\setbox0\hpack{\ctxluabuffer[code]}} \elapsedtime
+
+Say that we run the bad snippet:
+
+\startbuffer[code]
+for i=1,10000 do
+ tex.sprint("\\setbox0\\hpack{x}")
+ tex.sprint(tex.box[0].width)
+ for i=1,3 do
+ tex.sprint("\\setbox0\\hpack{xx}")
+ tex.sprint(tex.box[0].width)
+ end
+end
+\stopbuffer
+
+\typebuffer[code]
+
+% \testfeatureonce {1} {\setbox0\hpack{\ctxluabuffer[code]}} \elapsedtime
+
+This time we need 0.12 seconds in both engines. So what if we run this:
+
+\startbuffer[code]
+\dorecurse{10000}{%
+ \setbox0\hpack{x}
+ \number\wd0
+ \dorecurse{3}{%
+ \setbox0\hpack{xx}
+ \number\wd0
+ }%
+}
+\stopbuffer
+
+\typebuffer[code]
+
+% \testfeatureonce {1} {\setbox0\hpack{\getbuffer[code]}} \elapsedtime
+
+Pure \TEX\ needs 0.30 seconds for both engines but there we lose 0.13 seconds on
+the loop code. In the \LUA\ example where we yield, the loop code takes hardly
+any time. As we need only 0.05 seconds more it demonstrates that when we use the
+power of \LUA\ the performance hit of the switch is quite small: we yield 40.000
+times! In general, such differences are far exceeded by the overhead: the time
+needed to typeset the content (which \type {\hpack} doesn't do), breaking
+paragraphs into lines, constructing pages and other overhead involved in the run.
+In \CONTEXT\ we use a slightly different variant which has 0.30 seconds more
+overhead, but that is probably true for all \LUA\ usage in \CONTEXT, but again,
+it disappears in other runtime.
+
+Here is another example:
+
+\startbuffer[code]
+\def\TestWord#1%
+ {\directlua{
+ tex.routine(function()
+ tex.sprint("\\setbox0\\hbox{\\tttf #1}")
+ tex.yield()
+ tex.sprint(math.round(100 * tex.box[0].width/tex.hsize))
+ tex.sprint(" percent of the hsize: ")
+ tex.sprint("\\box0")
+ end)
+ }}
+\stopbuffer
+
+\typebuffer[code] \getbuffer[code]
+
+\startbuffer
+The width of next word is \TestWord {inline}!
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Now, in order to stay realistic, this macro can also be defined as:
+
+\startbuffer[code]
+\def\TestWord#1%
+ {\setbox0\hbox{\tttf #1}%
+ \directlua{
+ tex.sprint(math.round(100 * tex.box[0].width/tex.hsize))
+ } %
+ percent of the hsize: \box0\relax}
+\stopbuffer
+
+\typebuffer[code]
+
+We get the same result: \quotation {\getbuffer}.
+
+We have been using a \LUA|-|\TEX\ mix for over a decade now in \CONTEXT, and have
+never really needed this mixed model. There are a few places where we could
+(have) benefitted from it and we might use it in a few places, but so far we have
+done fine without it. In fact, in most cases typesetting can be done fine at the
+\TEX\ end. It's all a matter of imagination.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-expansion.tex b/doc/context/sources/general/manuals/onandon/onandon-expansion.tex
new file mode 100644
index 000000000..73a0b4953
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-expansion.tex
@@ -0,0 +1,307 @@
+% language=uk
+
+\startcomponent onandon-expansion
+
+\environment onandon-environment
+
+\startchapter[title={More (new) expansion trickery}]
+
+Contrary to what one might expect when looking at macro definitions, \TEX\ is
+pretty efficient. Occasionally I wonder if some extra built in functionality
+could help me write better code but when you program with a bit care there is
+often not much to gain in terms of tokens and performance. \footnote {The long
+trip to the yearly Bacho\TeX\ meeting is always a good opportunity to ponder
+\TEX\ and its features. The new functionality discussed here is a side effect of
+the most recent trip.} Also, some possible extensions probably only would be
+applied a few times which makes them low priority. When you look at the
+extensions brought by \ETEX\ the number is not that large, and \LUATEX\ only
+added a few that deal with the language, for instance \tex {expanded} which is
+like an \tex {edef} without the defining a macro and acts on a token list wrapped
+in (normally) curly braces. Just as reference we mention some of the expansion
+related helpers.
+
+\starttabulate[|l|l|p|]
+\BC command \BC argument \BC
+ comment
+\NC \NR
+\HL
+\NC \tex {expandafter} \NC \type {token} \NC
+ The token after the next token gets expanded (one level only). In tricky
+ \TEX\ code you can often see multiple such commands in sequence which makes a
+ nice puzzle.
+\NC \NR
+\NC \tex {noexpand} \NC \type {token} \NC
+ The token after this command is not expanded in the context of expansion.
+\NC \NR
+\NC \tex {expanded} \NC \type {{tokens}} \NC
+ The given token list is expanded. This command showed up early in \LUATEX\
+ development and was taken from \ETEX\ follow|-|ups. I have mails from 2011
+ mentioning its presence in \PDFTEX\ 1.50 (which was targeted in 2008) but
+ somehow it never ended up in a production version at that time (and we're
+ still not at that version). In \CONTEXT\ we already had a command with that
+ name so there we use \tex {normalexpanded}. Users normally can just use the
+ \CONTEXT\ variant of \type {\expanded}.
+\NC \NR
+\NC \tex {unexpanded} \NC \type {{tokens}} \NC
+ The given token list is hidden from expansion. Again, in \CONTEXT\ we already
+ had a command serving as prefix for definitions so instead we use \tex
+ {normalunexpanded}. In the core of \CONTEXT\ this new \ETEX\ command is hardly
+ used.
+\NC \NR
+\NC \tex {detokenize} \NC \type {{tokens}} \NC
+ The given tokenlist becomes (basically) verbatim \TEX\ code. We had something
+ like that in \CONTEXT\ but have no nameclash. It is used in a few places. It's
+ also an \ETEX\ command.
+\NC \NR
+\NC \tex {scantokens} \NC \type {{tokens}} \NC
+ This primitive interprets its argument as a pseudo file. We don't really use it.
+\NC \NR %
+\NC \tex {scantextokens} \NC \type {{tokens}} \NC
+ This \LUATEX\ primitive does the same but has no end|-|of|-|file side
+ effects. This one is also not really used in \CONTEXT.
+\NC \NR
+\NC \tex {protected} \NC \type {\.def} \NC
+ The definition following this prefix, introduced in \ETEX, is unexpandable in
+ the context of expansion. We already used such a command in \CONTEXT\ but
+ with a completely different meaning so use \tex {normalprotected} as prefix
+ or \tex {unexpanded} which is an alias.
+\NC \NR
+\stoptabulate
+
+Here I will present two other extensions in \LUATEX\ that can come in handy, and
+they are there simply because their effect can hardly be realized otherwise
+(never say never in \TEX). One has to do with immediately applying a definition,
+the other with user defined conditions. The first one relates directly to
+expansion, the second one concerns conditions and relates more to parsing
+branches which on purpose avoids expansion.
+
+For the first one I use some silly examples. I must admit that although I can
+envision useful application, I really need to go over the large amount of
+\CONTEXT\ source code to really find a place where it is making things better.
+Take the following definitions:
+
+\startbuffer
+\newcount\NumberOfCalls
+
+\def\TestMe{\advance\NumberOfCalls1 }
+
+\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+\edef\Tested{\TestMe foo:\the\NumberOfCalls}
+
+\meaning\Tested
+\stopbuffer
+
+\typebuffer
+
+The result is a macro \tex {Tested} that not only has the unexpanded incrementing
+code in its body but also hasn't done any advancing:
+
+\getbuffer
+
+Of course when you're typesetting something, this kind of expansion normally is
+not needed. Instead of the above definition we can define \tex {TestMe} in a way
+that expands the assignment immediately. You need of course to be aware of
+preventing look ahead interference by using a space or \tex {relax} (often an
+expression works better as it doesn't leave an \tex {relax}).
+
+\startbuffer
+\def\TestMe{\immediateassignment\advance\NumberOfCalls1 }
+
+\edef\Tested{\TestMe bar:\the\NumberOfCalls}
+\edef\Tested{\TestMe bar:\the\NumberOfCalls}
+\edef\Tested{\TestMe bar:\the\NumberOfCalls}
+
+\meaning\Tested
+\stopbuffer
+
+\typebuffer
+
+This time the counter gets updated and we don't see interference in the resulting
+\tex {Tested} macro:
+
+\getbuffer
+
+Here is a somewhat silly example of an expanded comparison of two \quote
+{strings}:
+
+\startbuffer
+\def\expandeddoifelse#1#2#3#4%
+ {\immediateassignment\edef\tempa{#1}%
+ \immediateassignment\edef\tempb{#2}%
+ \ifx\tempa\tempb
+ \immediateassignment\def\next{#3}%
+ \else
+ \immediateassignment\def\next{#4}%
+ \fi
+ \next}
+
+\edef\Tested
+ {(\expandeddoifelse{abc}{def}{yes}{nop}/%
+ \expandeddoifelse{abc}{abc}{yes}{nop})}
+
+\meaning\Tested
+\stopbuffer
+
+\typebuffer
+
+I don't remember many cases where I needed such an expanded comparison. We have a
+variant in \CONTEXT\ that uses \LUA\ but that one is not really used in the core.
+Anyway, the above code gives:
+
+\getbuffer
+
+You can do the same assignments as in preambles of \tex {halign} and after \tex
+{accent} which means that assignments to box registers are blocked (boxing
+involves grouping and delayed assignments and so). The error you will get when
+you use a non||assignment command refers to a prefix, because internally such
+commands are called prefixed commands. Leading spaces and \tex {relax} are
+ignored.
+
+In addition to this one|-|time immediate assignment a pseudo token list variant
+is provided, so the above could be rewritten to:
+
+\starttyping
+\def\expandeddoifelse#1#2#3#4%
+ {\immediateassigned {
+ \edef\tempa{#1}
+ \edef\tempb{#2}
+ }%
+ \ifx\tempa\tempb
+ \immediateassignment\def\next{#3}%
+ \else
+ \immediateassignment\def\next{#4}%
+ \fi
+ \next}
+\stoptyping
+
+While \tex {expanded} first builds a token lists that then gets used, the \tex
+{immediateassigned} primitive just walls over the list delimited by curly braces.
+
+A next extension concerns conditions. If you have done a bit of extensive \TEX\
+programming you know that nested conditions need to be properly constructed in
+for instance macro bodies. This is because (for good reason) \TEX\ goes into a
+fast scanning mode when there is a match and it has to skip the \tex {else} upto
+\tex {fi} branch. In order to do that properly a nested \tex {if} in there needs
+to have a matching \tex {fi}.
+
+In practice this is no real problem and careful coding will never give a problem
+here: you can either hide nested code in a macro or somehow jump over nested
+conditions if really needed. Actually you only need to care when you pickup a
+token inside the branch because likely you don't want to pick up for instance a
+\tex {fi} but something that comes after it. Say that we have a sane conditional
+setup like this:
+
+\starttyping
+\newif\iffoo \foofalse
+\newif\ifbar \bartrue
+
+\ifoo
+ \ifbar \else \fi
+\else
+ \ifbar \else \fi
+\fi
+\stoptyping
+
+Here the \tex {iffoo} and \tex {ifbar} need to be equivalent to \tex {iftrue} or
+\tex {iffalse} in order to succeed well and that is what for instance \tex
+{footrue} and \tex {foofalse} will do: change the meaning of \tex {iffoo}.
+
+But imagine that you want something more complex. You want for instance to let
+\tex {ifbar} do some calculations. In that case you want it to behave a bit like
+what a so called \type {vardef} in \METAPOST\ does: the end result is what
+matters. Now, because \TEX\ macros often are a complex mix of expandable and
+non|-|expandable this is not that trivial. One solution is a dedicated definer,
+say \tex {cdef} for defining a macro with conditional properties. I actually
+implemented such a definer a few years ago but left it so long in a folder with
+ideas that I only found it back after I had come up with another solution. It was
+probably proof that it was not that good an idea.
+
+The solution implemented in \LUATEX\ is just a special case of a test: \tex
+{ifcondition}. When looking at the next example, keep in mind that from the
+perspective of \TEX's scanner it only needs to know if something is a token that
+does some test and has a matching \tex {fi}. For that purpose you can consider
+\tex {ifcondition} to be \tex {iftrue}. When \TEX\ actually wants to do a test,
+which is the case in the true branch, then it will simply ignore this \tex
+{ifcondition} primitive and expands what comes after it (which is \TEX's natural
+behaviour). Effectively \tex {ifcondition} has no meaning except from when it has
+to be skipped, in which case it's a token flagged as \tex {if} kind of command.
+
+\starttyping
+\unexpanded\def\something#1#2%
+ {\edef\tempa{#1}%
+ \edef\tempb{#2}
+ \ifx\tempa\tempb}
+
+\ifcondition\something{a}{b}%
+ \ifcondition\something{a}{a}%
+ true 1
+ \else
+ false 1
+ \fi
+\else
+ \ifcondition\something{a}{a}%
+ true 2
+ \else
+ false 2
+ \fi
+\fi
+\stoptyping
+
+Wrapped in a macro you can actually make this fully expandable when you use the
+previously mentioned immediate assignment. Here is another example:
+
+\starttyping
+\unexpanded\def\onoddpage
+ {\ifodd\count0 }
+
+\ifcondition\onoddpage odd \else even \fi page
+\stoptyping
+
+The previously defined comparison macro can now be rewritten as:
+
+\starttyping
+\def\equaltokens#1#2%
+ {\immediateassignment\edef\tempa{#1}%
+ \immediateassignment\edef\tempb{#2}%
+ \ifx\tempa\tempb}
+
+\def\expandeddoifelse#1#2#3#4%
+ {\ifcondition\equaltokens{#1}{#2}%
+ \immediateassignment\def\next{#3}%
+ \else
+ \immediateassignment\def\next{#4}%
+ \fi
+ \next}
+\stoptyping
+
+When used this way it will of course also work without the \tex {ifcondition} but
+when used nested it can be like this. This last example also demonstrates that
+this feature probably only makes sense in more complicated cases where more work
+is done in the \tex {onoddpage} or \tex {equaltokens} macro. And again, I am not
+sure if for instance in \CONTEXT\ I have a real use for it because there are only
+a few cases where nesting like this could benefit. I did some tests with a low
+level macro where it made the code look nicer. It was actually a bit faster but
+most core macros are not called that often. Although the overhead of this feature
+can be neglected, performance should not be the reason for using it: in \CONTEXT\
+for instance one can often only measure such possible speed|-|ups on macros that
+are called tens or hundreds of thousands of times and that seldom happens in a
+real run end even then a change from say 0.827 seconds to 0.815 seconds for 10K
+calls of a complex case is just noise as the opposite can also happen.
+
+Although not strictly necessary these extensions might make some code look better
+so that is why they officially will be available in the 1.09 release of \LUATEX\
+in fall 2018. It might eventually inspire me to go over some code and see where I
+can improve the look and feel.
+
+The last few years I have implemented some more ideas as local experiments, for
+instance \tex {futurelet} variant or a simple (one level) \tex {expand}, but in
+the end rejected them because there is no real benefit in them (no better looking
+code, no gain in performance, hard to document, possible side effects, etc.), so
+it is very unlikely that we will have more extensions like this. After all, we
+could do more than 40 years without them. Although \unknown\ who knows what we
+will provide in \LUATEX\ version~2.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-fences.tex b/doc/context/sources/general/manuals/onandon/onandon-fences.tex
new file mode 100644
index 000000000..133b9bfeb
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-fences.tex
@@ -0,0 +1,499 @@
+% language=uk
+
+\startcomponent onandon-fences
+
+\environment onandon-environment
+
+% avoid context defaults:
+%
+% \mathitalicsmode \plusone % default in context
+% \mathdelimitersmode\plusseven % optional in context
+
+\def\UseMode#1{\appendtoks\mathdelimitersmode#1\to\everymathematics}
+
+\startchapter[title={Tricky fences}]
+
+Occasionally one of my colleagues notices some suboptimal rendering and asks me
+to have a look at it. Now, one can argue about \quotation {what is right} and
+indeed there is not always a best answer to it. Such questions can even be a
+nuisance; let's think of the following scenario. You have a project where \TEX\
+is practically the only solution. Let it be an \XML\ rendering project, which
+means that there are some boundary conditions. Speaking in 2017 we find that in
+most cases a project starts out with the assumption that everything is possible.
+
+Often such a project starts with a folio in mind and therefore by decent tagging
+to match the educational and esthetic design. When rendering is mostly automatic
+and concerns too many (variants) to check all rendering, some safeguards are used
+(an example will be given below). Then different authors, editors and designers
+come into play and their expectations, also about what is best, often conflict.
+Add to that rendering for the web, and devices and additional limitations show
+up: features get dropped and even more cases need to be compensated (the quality
+rules for paper are often much higher). But, all that defeats the earlier
+attempts to do well because suddenly it has to match the lesser format. This in
+turn makes investing in improving rendering very inefficient (read: a bottomless
+pit because it never gets paid and there is no way to gain back the investment).
+Quite often it is spacing that triggers discussions and questions what rendering
+is best. And inconsistency dominates these questions.
+
+So, in case you wonder why I bother with subtle aspects of rendering as discussed
+below, the answer is that it is not so much professional demand but users (like
+my colleagues or those on the mailing lists) that make me look into it and often
+something that looks trivial takes days to sort out (even for someone who knows
+his way around the macro language, fonts and the inner working of the engine).
+And one can be sure that more cases will pop up.
+
+All this being said, let's move on to a recent example. In \CONTEXT\ we support
+\MATHML\ although in practice we're forced to a mix of that standard and
+\ASCIIMATH. When we're lucky, we even get a mix with good old \TEX-encoded math.
+One problem with an automated flow and processing (other than raw \TEX) is that
+one can get anything and therefore we need to play safe. This means for instance
+that you can get input like this:
+
+\starttyping
+f(x) + f(1/x)
+\stoptyping
+
+or in more structured \TEX\ speak:
+
+\startbuffer
+$f(x) + f(\frac{1}{x})$
+\stopbuffer
+
+\typebuffer
+
+Using \TeX\ Gyre Pagella, this renders as: {\UseMode\zerocount\inlinebuffer}, and
+when seeing this a \TEX\ user will revert to:
+
+\startbuffer
+$f(x) + f\left(\frac{1}{x}\right)$
+\stopbuffer
+
+\typebuffer
+
+which gives: {\UseMode\zerocount \inlinebuffer}. So, in order to be robust we can
+always use the \type {\left} and \type {\right} commands, can't we?
+
+\startbuffer
+$f(x) + f\left(x\right)$
+\stopbuffer
+
+\typebuffer
+
+which gives {\UseMode\zerocount \inlinebuffer}, but let's blow up this result a
+bit showing some additional tracing from left to right, now in Latin Modern:
+
+\startbuffer[blownup]
+\startcombination[nx=3,ny=2,after=\vskip3mm]
+ {\scale[scale=4000]{\hbox{$f(x)$}}}
+ {just characters}
+ {\scale[scale=4000]{\ruledhbox{\showglyphs \showfontkerns \showfontitalics$f(x)$}}}
+ {just characters}
+ {\scale[scale=4000]{\ruledhbox{\showglyphs \showfontkerns \showfontitalics \showmakeup$f(x)$}}}
+ {just characters}
+ {\scale[scale=4000]{\hbox{$f\left(x\right)$}}}
+ {using delimiters}
+ {\scale[scale=4000]{\ruledhbox{\showglyphs \showfontkerns \showfontitalics$f\left(x\right)$}}}
+ {using delimiters}
+ {\scale[scale=4000]{\ruledhbox{\showglyphs \showfontkerns \showfontitalics \showmakeup$f\left(x\right)$}}}
+ {using delimiters}
+\stopcombination
+\stopbuffer
+
+\startlinecorrection
+\UseMode\zerocount
+\switchtobodyfont[modern]\getbuffer[blownup]
+\stoplinecorrection
+
+When we visualize the glyphs and kerns we see that there's a space instead of a
+kern when we use delimiters. This is because the delimited sequence is processed
+as a subformula and injected as a so|-|called inner object and as such gets
+spaced according to the ordinal (for the $f$) and inner (\quotation {fenced} with
+delimiters $x$) spacing rules. Such a difference normally will go unnoticed but
+as we mentioned authors, editors and designers being involved, there's a good
+chance that at some point one will magnify a \PDF\ preview and suddenly notice
+that the difference between the $f$ and $($ is a bit on the large side for simple
+unstacked cases, something that in print is likely to go unnoticed. So, even when
+we don't know how to solve this, we do need to have an answer ready.
+
+When I was confronted by this example of rendering I started wondering if there
+was a way out. It makes no sense to hard code a negative space before a fenced
+subformula because sometimes you don't want that, especially not when there's
+nothing before it. So, after some messing around I decided to have a look at the
+engine instead. I wondered if we could just give the non|-|scaled fence case the
+same treatment as the character sequence.
+
+Unfortunately here we run into the somewhat complex way the rendering takes
+place. Keep in mind that it is quite natural from the perspective of \TEX\
+because normally a user will explicitly use \type {\left} and \type {\right} as
+needed, while in our case the fact that we automate and therefore want a generic
+solution interferes (as usual in such cases).
+
+Once read in the sequence \type {f(x)} can be represented as a list:
+
+\starttyping
+list = {
+ {
+ id = "noad", subtype = "ord", nucleus = {
+ {
+ id = "mathchar", fam = 0, char = "U+00066",
+ },
+ },
+ },
+ {
+ id = "noad", subtype = "open", nucleus = {
+ {
+ id = "mathchar", fam = 0, char = "U+00028",
+ },
+ },
+ },
+ {
+ id = "noad", subtype = "ord", nucleus = {
+ {
+ id = "mathchar", fam = 0, char = "U+00078",
+ },
+ },
+ },
+ {
+ id = "noad", subtype = "close", nucleus = {
+ {
+ id = "mathchar", fam = 0, char = "U+00029",
+ },
+ },
+ },
+}
+\stoptyping
+
+The sequence \type {f \left( x \right)} is also a list but now it is a tree (we
+leave out some unset keys):
+
+\starttyping
+list = {
+ {
+ id = "noad", subtype = "ord", nucleus = {
+ {
+ id = "mathchar", fam = 0, char = "U+00066",
+ },
+ },
+ },
+ {
+ id = "noad", subtype = "inner", nucleus = {
+ {
+ id = "submlist", head = {
+ {
+ id = "fence", subtype = "left", delim = {
+ {
+ id = "delim", small_fam = 0, small_char = "U+00028",
+ },
+ },
+ },
+ {
+ id = "noad", subtype = "ord", nucleus = {
+ {
+ id = "mathchar", fam = 0, char = "U+00078",
+ },
+ },
+ },
+ {
+ id = "fence", subtype = "right", delim = {
+ {
+ id = "delim", small_fam = 0, small_char = "U+00029",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+}
+\stoptyping
+
+So, the formula \type {f(x)} is just four characters and stays that way, but with
+some inter|-|character spacing applied according to the rules of \TEX\ math. The
+sequence \typ {f \left( x \right)} however becomes two components: the \type {f}
+is an ordinal noad,\footnote {Noads are the mathematical building blocks.
+Eventually they become nodes, the building blocks of paragraphs and boxed
+material.} and \typ {\left( x \right)} becomes an inner noad with a list as a
+nucleus, which gets processed independently. The way the code is written this is
+what (roughly) happens:
+
+\startitemize
+\startitem
+ A formula starts; normally this is triggered by one or two dollar signs.
+\stopitem
+\startitem
+ The \type {f} becomes an ordinal noad and \TEX\ goes~on.
+\stopitem
+\startitem
+ A fence is seen with a left delimiter and an inner noad is injected.
+\stopitem
+\startitem
+ That noad has a sub|-|math list that takes the left delimiter up to a
+ matching right one.
+\stopitem
+\startitem
+ When all is scanned a routine is called that turns a list of math noads into
+ a list of nodes.
+\stopitem
+\startitem
+ So, we start at the beginning, the ordinal \type {f}.
+\stopitem
+\startitem
+ Before moving on a check happens if this character needs to be kerned with
+ another (but here we have an ordinal|-|inner combination).
+\stopitem
+\startitem
+ Then we encounter the subformula (including fences) which triggers a nested
+ call to the math typesetter.
+\stopitem
+\startitem
+ The result eventually gets packaged into a hlist and we're back one level up
+ (here after the ordinal \type {f}).
+\stopitem
+\startitem
+ Processing a list happens in two passes and, to cut it short, it's the second
+ pass that deals with choosing fences and spacing.
+\stopitem
+\startitem
+ Each time when a (sub)list is processed a second pass over that list
+ happens.
+\stopitem
+\startitem
+ So, now \TEX\ will inject the right spaces between pairs of noads.
+\stopitem
+\startitem
+ In our case that is between an ordinal and an inner noad, which is quite
+ different from a sequence of ordinals.
+\stopitem
+\stopitemize
+
+It's these fences that demand a two-pass approach because we need to know the
+height and depth of the subformula. Anyway, do you see the complication? In our
+inner formula the fences are not scaled, but this is not communicated back in the
+sense that the inner noad can become an ordinal one, as in the simple \type {f(}
+pair. The information is not only lost, it is not even considered useful and the
+only way to somehow bubble it up in the processing so that it can be used in the
+spacing requires an extension. And even then we have a problem: the kerning that
+we see between \type {f(} is also lost. It must be noted that this kerning is
+optional and triggered by setting \type {\mathitalicsmode=1}. One reason for this
+is that fonts approach italic correction differently, and cheat with the
+combination of natural width and italic correction.
+
+Now, because such a workaround is definitely conflicting with the inner workings
+of \TEX, our experimenting demands another variable be created: \type
+{\mathdelimitersmode}. It might be a prelude to more manipulations but for now we
+stick to this one case. How messy it really is can be demonstrated when we render
+our example with Cambria.
+
+\startlinecorrection
+\UseMode\zerocount
+\switchtobodyfont[cambria]\getbuffer[blownup]
+\stoplinecorrection
+
+If you look closely you will notice that the parenthesis are moved up a bit. Also
+notice the more accurate bounding boxes. Just to be sure we also show Pagella:
+
+\startlinecorrection
+\UseMode\zerocount
+\switchtobodyfont[pagella]\getbuffer[blownup]
+\stoplinecorrection
+
+When we really want the unscaled variant to be somewhat compatible with the
+fenced one we now need to take into account:
+
+\startitemize[packed]
+\startitem
+ the optional axis|-|and|-|height|/|depth related shift of the fence (bit 1)
+\stopitem
+\startitem
+ the optional kern between characters (bit 2)
+\stopitem
+\startitem
+ the optional space between math objects (bit 4)
+\stopitem
+\stopitemize
+
+Each option can be set (which is handy for testing) but here we will set them
+all, so, when \type {\mathdelimitersmode=7}, we want cambria to come out as
+follows:
+
+\startlinecorrection
+\UseMode\plusseven
+\switchtobodyfont[cambria]\getbuffer[blownup]
+\stoplinecorrection
+
+When this mode is set the following happens:
+
+\startitemize
+\startitem
+ We keep track of the scaling and when we use the normal size this is
+ registered in the noad (we had space in the data structure for that).
+\stopitem
+\startitem
+ This information is picked up by the caller of the routine that does the
+ subformula and stored in the (parent) inner noad (again, we had space for
+ that).
+\stopitem
+\startitem
+ Kerns between a character (ordinal) and subformula (inner) are kept,
+ which can be bad for other cases but probably less than what we try
+ to solve here.
+\stopitem
+\startitem
+ When the fences are unscaled the inner property temporarily becomes
+ an ordinal one when we apply the inter|-|noad spacing.
+\stopitem
+\stopitemize
+
+Hopefully this is good enough but anything more fancy would demand drastic
+changes in one of the most sensitive mechanisms of \TEX. It might not always work
+out right, so for now I consider it an experiment, which means that it can be
+kept around, rejected or improved.
+
+In case one wonders if such an extension is truly needed, one should also take
+into account that automated typesetting (also of math) is probably one of the
+areas where \TEX\ can shine for a while. And while we can deal with much by using
+\LUA, this is one of the cases where the interwoven and integrated parsing,
+converting and rendering of the math machinery makes it hard. It also fits into a
+further opening up of the inner working by modes.
+
+\startbuffer[simple]
+\dontleavehmode
+\scale
+ [scale=3000]
+ {\ruledhbox
+ {\showglyphs
+ \showfontkerns
+ \showfontitalics
+ $f(x)$}}
+\stopbuffer
+
+\startbuffer[fenced]
+\dontleavehmode
+\scale
+ [scale=3000]
+ {\ruledhbox
+ {\showglyphs
+ \showfontkerns
+ \showfontitalics
+ $f\left(x\right)$}}
+\stopbuffer
+
+\def\TestMe#1%
+ {\bTR
+ \bTD[width=35mm,align=middle,toffset=3mm] \switchtobodyfont[#1]\UseMode\zerocount\getbuffer[simple] \eTD
+ \bTD[width=35mm,align=middle,toffset=3mm] \switchtobodyfont[#1]\UseMode\zerocount\getbuffer[fenced] \eTD
+ \bTD[width=35mm,align=middle,toffset=3mm] \switchtobodyfont[#1]\UseMode\plusseven\getbuffer[simple] \eTD
+ \bTD[width=35mm,align=middle,toffset=3mm] \switchtobodyfont[#1]\UseMode\plusseven\getbuffer[fenced] \eTD
+ \eTR
+ \bTR
+ \bTD[align=middle,nx=2] \type{\mathdelimitersmode=0} \eTD
+ \bTD[align=middle,nx=2] \type{\mathdelimitersmode=7} \eTD
+ \eTR
+ \bTR
+ \bTD[align=middle,nx=4] \switchtobodyfont[#1]\bf #1 \eTD
+ \eTR}
+
+\startbuffer
+\bTABLE[frame=off]
+ \TestMe{modern}
+ \TestMe{cambria}
+ \TestMe{pagella}
+\eTABLE
+\stopbuffer
+
+Another objection to such a solution can be that we should not alter the engine
+too much. However, fences already are an exception and treated specially (tests
+and jumps in the program) so adding this fits reasonably well into that part of
+the design.
+
+In the following examples we demonstrate the results for Latin Modern, Cambria
+and Pagella when \type {\mathdelimitersmode} is set to zero or one. First we show
+the case where \type {\mathitalicsmode} is disabled:
+
+\startlinecorrection
+ \mathitalicsmode\zerocount\getbuffer
+\stoplinecorrection
+
+When we enable \type {\mathitalicsmode} we get:
+
+\startlinecorrection
+ \mathitalicsmode\plusone \getbuffer
+\stoplinecorrection
+
+So is this all worth the effort? I don't know, but at least I got the picture and
+hopefully now you have too. It might also lead to some more modes in future
+versions of \LUATEX.
+
+\startbuffer[simple]
+\dontleavehmode
+\scale
+ [scale=2000]
+ {\ruledhbox
+ {\showglyphs
+ \showfontkerns
+ \showfontitalics
+ $f(x)$}}
+\stopbuffer
+
+\startbuffer[fenced]
+\dontleavehmode
+\scale
+ [scale=2000]
+ {\ruledhbox
+ {\showglyphs
+ \showfontkerns
+ \showfontitalics
+ $f\left(x\right)$}}
+\stopbuffer
+
+\def\TestMe#1%
+ {\bTR
+ \dostepwiserecurse{0}{7}{1}{
+ \bTD[align=middle,toffset=3mm] \switchtobodyfont[#1]\UseMode##1\getbuffer[simple] \eTD
+ }
+ \eTR
+ \bTR
+ \dostepwiserecurse{0}{7}{1}{
+ \bTD[align=middle,toffset=3mm] \switchtobodyfont[#1]\UseMode##1\getbuffer[fenced] \eTD
+ }
+ \eTR
+ \bTR
+ \dostepwiserecurse{0}{7}{1}{
+ \bTD[align=middle]
+ \tttf
+ \ifcase##1\relax
+ \or ns % 1
+ \or it % 2
+ \or ns it % 3
+ \or or % 4
+ \or ns or % 5
+ \or it or % 6
+ \or ns it or % 7
+ \fi
+ \eTD
+ }
+ \eTR
+ \bTR
+ \bTD[align=middle,nx=8] \switchtobodyfont[#1]\bf #1 \eTD
+ \eTR}
+
+\startbuffer
+\bTABLE[frame=off,distance=2mm]
+ \TestMe{modern}
+ \TestMe{cambria}
+ \TestMe{pagella}
+\eTABLE
+\stopbuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+In \CONTEXT, a regular document can specify \type {\setupmathfences
+[method=auto]}, but in \MATHML\ or \ASCIIMATH\ this feature is enabled by default
+(so that we can test it).
+
+We end with a summary of all the modes (assuming italics mode is enabled) in the
+table below.
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-media.tex b/doc/context/sources/general/manuals/onandon/onandon-media.tex
new file mode 100644
index 000000000..f44c3bb19
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-media.tex
@@ -0,0 +1,220 @@
+% language=uk
+
+\startcomponent onandon-media
+
+\environment onandon-environment
+
+\startchapter[title={The state of \PDF}]
+
+\startsection[title={Introduction}]
+
+Below I will spend some words on the state of \PDF\ in \CONTEXT\ mid 2018. These
+are just some reflections, not an in|-|depth discussion of the state of affairs. I
+sometimes feel the need to wrap up.
+
+\stopsection
+
+\startsection[title={Media}]
+
+For over two decades \CONTEXT\ has supported fancy \PDF\ features like movies and
+sound. In fact, as happens more, the flexibility of \TEX\ made it possible to
+support such features right after they became available, often even before other
+applications supported them.
+
+The first approach to support such media clips was relatively easy. In \PDF\ one
+has the text flow, resulting from the typesetting process, either or not enhanced
+with images that are referred to from the flow. In that respect images are an
+integral part of \PDF. On a separate layer there can be annotations. There are
+many kinds and they are originally a sort of extension mechanism that permits
+plugins to add features to a document. Examples of this are hyperlinks and the
+already mentioned media clips. Video was supported by the quicktime movie plugin.
+As far as I know in the meantime that plugin has been dropped as official part of
+Acrobat but one can still plug it in.
+
+Later an extra mechanism was introduced, tagged renditions. It separates the
+views from the media and was more complex. When I first played with it, quite
+some media were possible, and I made a demo that could handle mov, mp3, smi and
+swf files. But last time I checked none of these really worked, apart from the
+swf file. One gets pop|-|ups for missing viewers and a look at the reader
+preferences makes one pessimistic about future support anyway. But one should be
+able to set up a list of useable players with this mechanism (although only an
+Adobe one seems to be okay so we're back to where we started).
+
+At some point support for u3d was added. Interesting is that there is quite some
+infrastructure described in the \PDF\ standard. Also something called rich media
+was introduced and that should replace the former video and audio annotations
+(definitely in \PDF\ version 2) and probably some day the renditions will no
+longer be supported either. Open source \PDF\ viewers just stuck to supporting
+text and static images.
+
+Now, do these rich media work well? Hardly. The standard leaves it to the viewer
+and provides ways to define viewers (although it's unclear to me how that works
+out in practice.) Basically in \PDF\ version 2 there is no native support for
+simple straightforward video. One has to construct a complex set of related
+annotations.
+
+One can give arguments (like security risks) for not supporting all these fancy
+features but then why make rich media part of the specification at all? Browsers
+beat \PDF\ viewers in showing media and as browsers can operate in kiosk mode I
+suppose that it's not that hard to delegate showing whatever you want in an
+embedded window in the \PDF\ viewer. Or why not simply support videolan out of
+the box. All we need is the ability to view movies and control them (play, pause,
+stop, rewind, etc). Where \HTML\ evolved towards easier media support, \PDF\
+evolved to more obscurity.
+
+So, how bad is it really? There are \PDF\ files around that have video! Indeed,
+but the way they're supposed to do this is as follows: currently one actually has
+to embed a shockwave video player (a user interface around something built|-|in)
+and let that player show for instance an mp4 movie. However, support for
+shockwave (flash) will be dropped in 2020 and that renders documents that use it
+obsolete. This even makes one wonder about \JAVASCRIPT\ and widgets like form
+fields, also a rather moving and somewhat unstable target. (I must have a
+document being a calculator somewhere made in the previous century, in the early
+days of \PDF.)
+
+I think that the plugin model failed already rather early in the \PDF\ history if
+only because it made no sense to develop them when in a next version of Acrobat
+the functionality was copied in the core. In a similar fashion \JAVASCRIPT\
+support seems to have stalled.
+
+Unfortunately the open source viewers never catched on with media, forms and
+\JAVASCRIPT\ and therefore there has been no momentum created to keep things
+supported. It all makes efforts spent on supporting this kind of \PDF\ features a
+waste of time. It also makes one careful in using them: it only works on the
+short term.
+
+Get me right, I'm not talking of complex media like 3d or animations but of
+straightforward video support. I understand that the rich media framework tries
+to cover complex cases but it's simple cases that carry the format. On the other
+hand, one can wonder why the \PDF\ format makes it possible to specify behaviour
+that in practice depends on \JAVASCRIPT\ and therefore could as well have been
+delegated to \JAVASCRIPT\ as well. It would probably have been much cleaner.
+\footnote {It looks like mu\PDF\ in 2018 got some support related to widgets aka
+fields but alas not for layers which would be quite useful.}
+
+The \PDF\ version 2 specification mentions \type {3D}, \type {Video} and \type
+{Audio} as primary content types so maybe future viewers will support video out
+of the box. Who knows. We try to keep up in \CONTEXT\ because it's often not that
+complex to support \PDF\ features but with hardly any possibility to test them,
+they have a low priority. And with Acrobat moving to the cloud and thereby
+creating a more of less lifelong dependency on remote resources it doesn't become
+much interesting to explore those routes either.
+
+\stopsection
+
+\startsection[title={Accessibility}]
+
+A popular \PDF\ related topic is accessibility. One aspect of that is tagged
+\PDF. This substandard is in my opinion not something that deserves a price for
+beauty. I know that there are \CONTEXT\ users who need to be compliant but I
+always wonder what a publisher really does with such a file. It's a bit like
+requiring \XML\ as source but at the same time sacrificing really rich encoded
+and sources for tweaks that suite the current limitations of for instance browsers,
+tool|-|chains and competence. We've seen it happen.
+
+Support for tagged \PDF\ has been available in \CONTEXT\ already for a while but
+as far as I know only Acrobat professional can do something with it. The reason
+for tagging is that a document is then useable for (for instance) visually
+impaired users, but aren't they better served with a proper complete and very
+structured source in some format that tools suitable for it can use? How many
+publishers distribute \PDF\ files while they can still make money on prints? How
+many are really interested in distributing enriched content that then can be
+reused somehow? And how many are willing to invest in tools instead of waiting
+for it to happen for free? It's a bit cheap trick to just expect authors (and
+their in the case of \TEX\ free tools) to suit a publishers needs. Anyway, just
+as with advanced interactive documents or forms, I wonder if it will catch on. At
+least no publisher ever asked us and by the time they might do the competition of
+web based dissemination could have driven \PDF\ to the background. But, in
+\CONTEXT\ we will keep supporting such features anyway, if only because it's
+quite doable. But \unknown\ it's user demand that drives development, not the
+market, which means that the motivation for implementing such features depends on
+user input as well as challenging aspects that make it somewhat fun to spend time
+on them.
+
+\stopsection
+
+\startsection[title={Quality assurance}]
+
+Another aspect popping up occasionally is validation. I'm not entirely sure what
+drives that but delegating a problem can be one reason. Often we see publishers
+and printers use old versions of \PDF\ related tools. Also, some workflows are
+kind of ancient anyway and are more driven by \POSTSCRIPT\ history than \PDF\
+possibilities. I sometimes get the impression that it takes at least a decade for
+these things to catch on, and by that time it doesn't matter any more that \TEX\
+and friends were at the front: their users are harassed by what the market
+demands by then.
+
+Support for several standards related to validation is already part of \CONTEXT\
+for quite a while. For instance the bump from \PDF\ 1.7 to 2.0 was hardly worth
+noticing, simply because there are not that many fundamental changes. Adapting
+\LUATEX\ was trivial (and actually not really needed), and macro packages can
+provide what is needed without much problems. So, yes, we can support it without
+much hassle. Personally I never ran into a case where validation was really
+needed. The danger of validation is that it can give a false impression of
+quality. And as with everything quality control created a market. As with other
+features it is users who drive the availability of support for this. After all,
+they are the ones testing it and figuring out the often fuzzy specifications.
+These are things that one can always look at in retrospect (like: it has to be
+done this or that way) while in practice in order to be an early adopter one has
+to gamble a bit and see where it fails or succeeds. Fortunately it's relatively
+easy to adapt macro packages and \CONTEXT\ users are willing to update so it's
+not really an issue.
+
+Putting a stamp of approval on a \PDF\ cannot hide the inconsistencies between
+for instance vector graphics produced by a third party. They also don't expose
+inconsistent use of color and fonts. The page streams produced by \LUATEX\ are
+simple and clean enough to not give problems with validation. The problem lays
+more with resources coming from elsewhere. When you're phoned by a printing house
+about an issue with \RGB\ images in a file where there is no sign of \RGB\ being
+used but where a validator reports an issue, you're lucky when an experienced
+printer dating back decades then replies that he already had that impression and
+will contact the origin. There is no easy way out of this but educating users
+(authors) is an option. However, they are often dependent on the publishers and
+departments that deal with these and those tend to come with directives that the
+authors cannot really argue with (or about).
+
+\stopsection
+
+\startsection[title={Interactivity}]
+
+This is an area where \TEX\ (an therefore also \CONTEXT) always had an edge,
+There is a lot possible and in principle all that \PDF\ provides can be
+supported. But the more fancy one goes, the more one depends on Acrobat.
+Interactivity in \PDF\ evolved stepwise and is mostly market driven. As a result
+it is (or was) not always consistent. This is partly due to the fact that we have
+a chicken|-|egg issue: you need typesetting machinery, viewer as well as a
+standard.
+
+The regular hyperlinks, page or named driven are normally supported by viewers.
+Some redefined named destinations (like going to a next page, or going back in a
+chain of followed links) not always. Launching applications, as it also relates
+to security, can be qualified as an unreliable mechanism. More advanced linking,
+for instance using \JAVASCRIPT\ is hardly supported. In that respect \PDF\
+viewers lag way behind \HTML\ browsers. I understand that there can be security
+risks involved. It's interesting to see that in Acrobat one can mess with
+internals of files which makes the \API\ large and complex, but if we stick to
+the useful core, the amount of interfacing needed is quite small. Lack of support
+in open source viewers (we're talking of about two decades now) made me loose
+interest in these features but they are and will be supported in \CONTEXT. We'll
+see if and when viewers catch up.
+
+Comments and attachments are also part of interactivity and of course we
+supported them right from the start. Some free viewers also support them by now.
+Personally I never use comments but they can be handy for popping up information
+or embedding snippets or (structured) sources (like \MATHML\ or bibliographic
+data). In \CONTEXT\ we can even support \PDF\ inclusion with (a reasonable)
+subset of these so called annotations. As the \PDF\ standard no longer evolves
+much we can expect all these features to become stable.
+
+\stopsection
+
+\startsection[title={Summary}]
+
+We have always supported the fancy \PDF\ features and we will continue doing so
+in \CONTEXT . However, many of them depends on what viewers support, and after
+decades of \PDF\ that is still kind of disappointing, which is not that
+motivating. We'll see what happens.
+
+\stopsection
+
+\stopchapter
diff --git a/doc/context/sources/general/manuals/onandon/onandon-modern.tex b/doc/context/sources/general/manuals/onandon/onandon-modern.tex
new file mode 100644
index 000000000..65b5d0490
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-modern.tex
@@ -0,0 +1,1284 @@
+% language=uk
+
+% 284 instances, 234 shared in backend, 126 common vectors, 108 common hashes, load time 1.343 seconds
+
+%setupversion[alternative=concept,text={not corrected yet}]
+\setupversion[alternative=file,text={not corrected yet}]
+
+\definebodyfontenvironment[24pt]
+
+\usemodule[fonts-effects]
+
+\startcomponent onandon-modern
+
+\environment onandon-environment
+
+\startchapter[title={Modern Latin}]
+
+\startsection[title={Introduction}]
+
+In \CONTEXT, already in \MKII, we have a feature tagged \quote {effects} that can
+be used to render a font in outline or bolder versions. It uses some low level
+\PDF\ directives to accomplish this and it works quite well. When a user on the
+\CONTEXT\ list asked if we could also provide it as a font feature in the
+repertoire of additional features in \CONTEXT, I was a bit reluctant to provide
+that because it operates at another level than the glyph stream. Also, such a
+feature can be abused and result in a bad looking document. However, by adding a
+few simple options to the \LUATEX\ engine such a feature could actually be
+achieved rather easy: it was trivial to implement given that we can influence
+font handling at the \LUA\ end. In retrospect extended and pseudo slanted fonts
+could be done this way too but there we have some historic ballast. Also, the
+backend now handles such transformations very efficient because they are combined
+with font scaling. Anyway, by adding this feature in spite of possible
+objections, I could do some more advanced experiments.
+
+In the following pages I will demonstrate how we support effects as a feature in
+\CONTEXT. Instead of simply applying some magic \PDF\ text operators in the
+backend a more integrated approach is used. The difference with the normal effect
+mechanism is that where the one described here is bound to a font instance while
+the normal mechanism operates on the glyph stream.
+
+\stopsection
+
+\startsection[title={The basics}]
+
+\definefontsynonym[DemoSerif][file:lmroman10-regular]
+
+Let's start with a basic boldening example. First we demonstrate a regular Latin
+Modern sample (using \type {ward.tex}):
+
+\startnarrower
+ \definedfont[DemoSerif*default]
+ \samplefile{ward}
+\stopnarrower
+
+This font looks rather thin (light). Next we define an effect or \type {0.2} and
+typeset the same sample:
+
+\startbuffer
+\definefontfeature
+ [effect-1]
+ [effect=.2]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startnarrower
+ \definedfont[DemoSerif*default,effect-1]
+ \samplefile{ward}
+\stopnarrower
+
+This simple call gives reasonable default results. But you can have more control
+than this. The previous examples use the following properties:
+
+{\definedfont[DemoSerif*default,effect-1] \showfonteffect}
+
+\startbuffer
+\definefontfeature
+ [effect-2]
+ [effect={width=.3}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startnarrower
+ \definedfont[DemoSerif*default,effect-2]
+ \samplefile{ward}
+\stopnarrower
+
+This time we use:
+
+{\definedfont[DemoSerif*default,effect-2] \showfonteffect}
+
+\startbuffer
+\definefontfeature
+ [effect-3]
+ [effect={width=.3,delta=0.4}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startnarrower
+ \showfontkerns
+ \definedfont[DemoSerif*default,effect-3]
+ \samplefile{ward}
+\stopnarrower
+
+We have now tweaked one more property and show the fontkerns in order to see what
+happens with them:
+
+{\definedfont[DemoSerif*default,effect-3] \showfonteffect}
+
+\startbuffer
+\definefontfeature
+ [effect-4]
+ [effect={width=.3,delta=0.4,factor=0.3}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startnarrower
+ \showfontkerns
+ \definedfont[DemoSerif*default,effect-4]
+ \samplefile{ward}
+\stopnarrower
+
+An additional parameter \type {factor} will influence the way (for instance)
+kerns get affected:
+
+{\definedfont[DemoSerif*effect-4] \showfonteffect}
+
+\stopsection
+
+\startsection[title=Outlines]
+
+There are four effects. Normally a font is rendered with effect \type {inner}.
+The \type {outer} effect just draws the outlines while \type {both} gives a
+rather fat result. The \type {hidden} effect hides the text.
+
+\startbuffer
+\definefontfeature
+ [effect-5]
+ [effect={width=0.2,delta=0.4,factor=0.3,effect=inner}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startnarrower
+ \showfontkerns
+ \definedfont[DemoSerif*default,effect-5]
+ \samplefile{ward}
+\stopnarrower
+
+An inner effect is rather useless unless you want to use the other properties of
+this mechanism.
+
+\startbuffer
+\definefontfeature
+ [effect-6]
+ [effect={width=.2,delta=0.4,factor=0.3,effect=outer}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startnarrower
+ \showfontkerns
+ \definedfont[DemoSerif*default,effect-6]
+ \samplefile{ward}
+\stopnarrower
+
+\startbuffer
+\definefontfeature
+ [effect-7]
+ [effect={width=.2,delta=0.4,factor=0.3,effect=both}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startnarrower
+ \showfontkerns
+ \definedfont[DemoSerif*default,effect-7]
+ \samplefile{ward}
+\stopnarrower
+
+\startbuffer
+\definefontfeature
+ [effect-8]
+ [effect={width=.2,delta=0.4,factor=0.3,effect=hidden},
+ boundingbox=yes] % to show something
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We also show the boundingboxes of the glyphs here so that you can see what you're
+missing. Actually this text is still there and you can select it in the viewer.
+
+\startnarrower
+ \showfontkerns
+ \showglyphs
+ \definedfont[DemoSerif*default,effect-8]
+ \samplefile{ward}
+\stopnarrower
+
+\stopsection
+
+\startsection[title=The logic]
+
+In order to support this I had to make some choices. The calculations involved
+are best explained in terms of \CONTEXT\ font machinery.
+
+\startformula
+ \Delta _{\text{wd}} = \text{effect} _{\text{wdelta}}
+ \times \text{parameter}_{\text{hfactor}}
+ \times \text{effect} _{\text{width}}
+ \times 100
+\stopformula
+
+\startformula
+ \Delta _{\text{ht}} = \text{effect} _{\text{hdelta}}
+ \times \text{parameter}_{\text{vfactor}}
+ \times \text{effect} _{\text{width}}
+ \times 100
+\stopformula
+
+\startformula
+ \Delta _{\text{dp}} = \text{effect} _{\text{ddelta}}
+ \times \text{parameter}_{\text{vfactor}}
+ \times \text{effect} _{\text{width}}
+ \times 100
+\stopformula
+
+The factors in the parameter namespace are adapted according to:
+
+\startformula
+ \Delta _{\text{factor}} = \text{effect} _{\text{factor}}
+ \times \text{parameters}_{\text{factor}}
+\stopformula
+
+\startformula
+ \Delta _{\text{hfactor}} = \text{effect} _{\text{hfactor}}
+ \times \text{parameters}_{\text{hfactor}}
+\stopformula
+
+\startformula
+ \Delta _{\text{vfactor}} = \text{effect} _{\text{vfactor}}
+ \times \text{parameters}_{\text{vfactor}}
+\stopformula
+
+The horizontal and vertical scaling factors default to the normal factor that
+defaults to zero so by default we have no additional scaling of for instance
+kerns. The width (wd), height (ht) and depth (dp) of a glyph are adapted in
+relation to the line width. A glyph is shifted in its bounding box by half the
+width correction. The delta defaults to one.
+
+\stopsection
+
+\startsection[title=About features]
+
+This kind of boldening has limitations especially because some fonts use
+positioning features that closely relate to the visual font properties. Let's
+give some examples. The most common positioning is kerning. Take for instance
+these shapes:
+
+\startlinecorrection
+\startMPcode
+ def SampleShapes(expr dx, offset, pw, k) =
+ picture p ; p := image (
+ draw fullcircle scaled 1cm ;
+ draw fullsquare scaled 1cm shifted (dx+k,0) ;
+ draw point 8 of (fullcircle scaled 1cm) withcolor white ;
+ draw point 3.5 of (fullsquare scaled 1cm) shifted (dx+k,0) withcolor white ;
+ ) shifted (offset,0) ;
+ draw p withpen pencircle scaled pw ;
+ draw boundingbox p withcolor white ;
+ enddef ;
+ SampleShapes(15mm, 0mm,1mm,0mm) ;
+ SampleShapes(15mm, 40mm,2mm,0mm) ;
+ SampleShapes(17mm, 80mm,2mm,0mm) ;
+\stopMPcode
+\stoplinecorrection
+
+The first one is that we start with. The circle and square have a line width of
+one unit and a distance (kern) of five units. The second pair has a line width of
+two units and the same distance while the third pair has a distance of seven
+units. So, in the last case we have just increased the kern with a value relative
+to the increase of line width.
+
+\startlinecorrection
+\startMPcode
+ SampleShapes(15mm, 0mm,1mm,0mm) ;
+ SampleShapes(15mm, 40mm,2mm,2mm) ;
+ SampleShapes(17mm, 80mm,2mm,2mm) ;
+\stopMPcode
+\stoplinecorrection
+
+In this example we have done the same but we started with a distance of zero. You
+can consider this a kind of anchoring. This happens in for instance cursive
+scripts where entry and exit points are used to connect shapes. In a latin script
+you can think of a poor|-|mans attachment of a cedilla or ogonek. But what to do
+with for instance an accent on top of a character? In that case we could do the
+same as with kerning. However, when we mix styles we would like to have a
+consistent height so maybe there scaling is not a good idea. This is why we can
+set the factors and deltas explictly for vertical and horizontal movements.
+However, this will only work well when a font is consistent in how it applies
+these movements. In this case, if could recognize cursive anchoring (the last
+pair in the example) we could compensate for it.
+
+\startMPinclusions
+ def SampleShapes(expr dx, offset, pw, k) =
+ picture p ; p := image (
+ draw fullcircle scaled 1cm ;
+ draw fullsquare scaled 1cm shifted (dx+k,0) ;
+ draw point 8 of (fullcircle scaled 1cm) withcolor white ;
+ draw point 3.5 of (fullsquare scaled 1cm) shifted (dx+k,0) withcolor white ;
+ ) shifted (offset,0) ;
+ draw p withpen pencircle scaled pw ;
+ draw boundingbox p withcolor white ;
+ enddef ;
+\stopMPinclusions
+
+\startlinecorrection
+\startMPcode
+ SampleShapes(10mm, 0mm,1mm,0mm) ;
+ SampleShapes(10mm, 40mm,1mm,1mm) ;
+ SampleShapes(10mm, 80mm,2mm,0mm) ;
+ SampleShapes(10mm,120mm,2mm,2mm) ;
+\stopMPcode
+\stoplinecorrection
+
+So, an interesting extension to the positioning part of the font handler could be
+to influence all the scaling factors: anchors, cursives, single and pair wise
+positioning in both directions (so eight independent factors). Technically this
+is no big deal so I might give it a go when I have a need for it.
+
+\stopsection
+
+\startsection[title=Some (extreme) examples]
+
+The last decade buying a font has become a bit of a nightmare simply because you
+have to choose the weights that you need. It's the business model to not stick to
+four shapes in a few weights but offer a whole range and each of course costs
+money.
+
+Latin Modern is based on Computer Modern and is meant for high resolution rendering.
+The design of the font is such that you can create instances but in practice that
+isn't done. One property that let the font stand out is its bold which runs rather
+wide. However, how about cooking up a variant? For this we will use a series of
+definitions:
+
+\startbuffer
+\definefontfeature[effect-2-0-0]
+ [effect={width=0.2,delta=0}]
+\definefontfeature[effect-2-3-0]
+ [effect={width=0.2,delta=0.3}]
+\definefontfeature[effect-2-6-0]
+ [effect={width=0.2,delta=0.6}]
+\definefontfeature[effect-4-0-0]
+ [effect={width=0.4,delta=0}]
+\definefontfeature[effect-4-3-0]
+ [effect={width=0.4,delta=0.3}]
+\definefontfeature[effect-4-6-0]
+ [effect={width=0.4,delta=0.6}]
+\definefontfeature[effect-8-0-0]
+ [effect={width=0.8,delta=0}]
+\definefontfeature[effect-8-3-0]
+ [effect={width=0.8,delta=0.3}]
+\definefontfeature[effect-8-6-0]
+ [effect={width=0.8,delta=0.6}]
+\definefontfeature[effect-8-6-2]
+ [effect={width=0.8,delta=0.6,factor=0.2}]
+\definefontfeature[effect-8-6-4]
+ [effect={width=0.8,delta=0.6,factor=0.4}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+And a helper macro:
+
+\startbuffer
+\starttexdefinition ShowOneSample #1#2#3#4
+ %\testpage[5]
+ %\startsubsubsubject[title=\type{#1}]
+ \start
+ \definedfont[#2*#3 @ 10pt]
+ \setupinterlinespace
+ \startlinecorrection
+ \showglyphs \showfontkerns
+ \scale[sx=#4,sy=#4]{effective n\"ots}
+ \stoplinecorrection
+ \blank[samepage]
+ \dontcomplain
+ \showfontkerns
+ \margintext{\tt\txx\maincolor#1}
+ \samplefile{ward}
+ \par
+ \stop
+ %\stopsubsubsubject
+\stoptexdefinition
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\starttexdefinition ShowSamples #1
+ \startsubsubject[title=#1]
+ \start
+ \ShowOneSample{no effect} {#1}{default} {5}
+ \ShowOneSample{width=0.2\\delta=0} {#1}{default,effect-2-0-0}{5}
+ \ShowOneSample{width=0.2\\delta=0.3} {#1}{default,effect-2-3-0}{5}
+ \ShowOneSample{width=0.2\\delta=0.6} {#1}{default,effect-2-6-0}{5}
+ \ShowOneSample{width=0.4\\delta=0} {#1}{default,effect-4-0-0}{5}
+ \ShowOneSample{width=0.4\\delta=0.3} {#1}{default,effect-4-3-0}{5}
+ \ShowOneSample{width=0.4\\delta=0.6} {#1}{default,effect-4-6-0}{5}
+ \ShowOneSample{width=0.8\\delta=0} {#1}{default,effect-8-0-0}{5}
+ \ShowOneSample{width=0.8\\delta=0.3} {#1}{default,effect-8-3-0}{5}
+ \ShowOneSample{width=0.8\\delta=0.6} {#1}{default,effect-8-6-0}{5}
+ \ShowOneSample{width=0.8\\delta=0.6\\factor=0.2}{#1}{default,effect-8-6-2}{5}
+ \ShowOneSample{width=0.8\\delta=0.6\\factor=0.4}{#1}{default,effect-8-6-4}{5}
+ \stop
+ \stopsubsubject
+\stoptexdefinition
+
+We show some extremes, using the font used in this document. so don't complain
+about beauty here.
+
+\texdefinition{ShowSamples}{Serif}
+\texdefinition{ShowSamples}{SerifBold}
+\texdefinition{ShowSamples}{SerifItalic}
+\texdefinition{ShowSamples}{SerifBoldItalic}
+\texdefinition{ShowSamples}{Sans}
+
+\start
+ \setupalign[flushleft,broad,nothyphenated,verytolerant]
+ \texdefinition{ShowSamples}{Mono}
+\stop
+
+\stopsection
+
+\startsection[title=Pitfall]
+
+The quality of the result depends on how the font is made. For instance,
+ligatures can be whole shapes, replaced glyphs and|/|or repositioned
+glyphs, or whatever the designer thinks reasonable. In \in {figure}
+[fig:ligature-effects-mess] this is demonstrated. We use the following
+feature sets:
+
+\startbuffer
+\definefontfeature
+ [demo-1]
+ [default]
+ [hlig=yes]
+
+\definefontfeature
+ [demo-2]
+ [demo-1]
+ [effect=0.5]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startplacefigure[title={The effects on ligatures.},reference=fig:ligature-effects-mess]
+ \startcombination[1*3]
+ { \scale [scale=5000] {
+ \definedfont[texgyrepagellaregular*demo-1]fist effe
+ \par
+ \definedfont[texgyrepagellaregular*demo-2]fist effe
+ } } {
+ texgyre pagella regular
+ } { \scale [scale=5000] {
+ \definedfont[cambria*demo-1]fist effe
+ \par
+ \definedfont[cambria*demo-2]fist effe
+ } } {
+ cambria
+ } { \scale [scale=5000] {
+ \definedfont[ebgaramond12regular*demo-1]fist effe
+ \par
+ \definedfont[ebgaramond12regular*demo-2]fist effe
+ } } {
+ ebgaramond 12 regular
+ }
+ \stopcombination
+\stopplacefigure
+
+Normally the artifacts (as in the fi ligature in ebgaramond as of 2018) will go
+unnoticed at small sized. Also, when the user has a low res display, printer or
+when the publishers is one of those who print a scanned \PDF\ the reader might
+not notice it at all. Most readers don't even know what to look at.
+
+\stopsection
+
+\startsection[title=A modern Modern]
+
+So how can we make an effective set of Latin Modern that fits in todays look and
+feel. Of course this is a very subjective experiment but we've seen experiments
+with these fonts before (like these cm super collections). Here is an example of
+a typescript definition:
+
+\starttyping
+\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.15,delta=1.00}]
+ \definefontfeature[lm-tt-bold] [effect={width=0.30,delta=1.00}]
+ \definefontfeature[lm-mm-regular][effect={width=0.15,delta=1.00}]
+ \definefontfeature[lm-mm-bold] [effect={width=0.30,delta=1.00}]
+
+ \starttypescript [serif] [modern-latin]
+ \definefontsynonym
+ [Serif] [file:lmroman10-regular]
+ [features={default,lm-rm-regular}]
+ \definefontsynonym
+ [SerifItalic] [file:lmroman10-italic]
+ [features={default,lm-rm-regular}]
+ \definefontsynonym
+ [SerifSlanted] [file:lmromanslant10-regular]
+ [features={default,lm-rm-regular}]
+ \definefontsynonym
+ [SerifBold] [file:lmroman10-regular]
+ [features={default,lm-rm-bold}]
+ \definefontsynonym
+ [SerifBoldItalic] [file:lmroman10-italic]
+ [features={default,lm-rm-bold}]
+ \definefontsynonym
+ [SerifBoldSlanted] [file:lmromanslant10-regular]
+ [features={default,lm-rm-bold}]
+ \stoptypescript
+
+ \starttypescript [sans] [modern-latin]
+ \definefontsynonym
+ [Sans] [file:lmsans10-regular]
+ [features={default,lm-ss-regular}]
+ \definefontsynonym
+ [SansItalic] [file:lmsans10-oblique]
+ [features={default,lm-ss-regular}]
+ \definefontsynonym
+ [SansSlanted] [file:lmsans10-oblique]
+ [features={default,lm-ss-regular}]
+ \definefontsynonym
+ [SansBold] [file:lmsans10-regular]
+ [features={default,lm-ss-bold}]
+ \definefontsynonym
+ [SansBoldItalic] [file:lmsans10-oblique]
+ [features={default,lm-ss-bold}]
+ \definefontsynonym
+ [SansBoldSlanted] [file:lmsans10-oblique]
+ [features={default,lm-ss-bold}]
+ \stoptypescript
+
+ \starttypescript [mono] [modern-latin]
+ \definefontsynonym
+ [Mono] [file:lmmono10-regular]
+ [features={default,lm-tt-regular}]
+ \definefontsynonym
+ [MonoItalic] [file:lmmono10-italic]
+ [features={default,lm-tt-regular}]
+ \definefontsynonym
+ [MonoSlanted] [file:lmmonoslant10-regular]
+ [features={default,lm-tt-regular}]
+ \definefontsynonym
+ [MonoBold] [file:lmmono10-regular]
+ [features={default,lm-tt-bold}]
+ \definefontsynonym
+ [MonoBoldItalic] [file:lmmono10-italic]
+ [features={default,lm-tt-bold}]
+ \definefontsynonym
+ [MonoBoldSlanted] [file:lmmonoslant10-regular]
+ [features={default,lm-tt-bold}]
+ \stoptypescript
+
+ \starttypescript [math] [modern-latin]
+ \loadfontgoodies[lm]
+ \definefontsynonym
+ [MathRoman] [file:latinmodern-math-regular.otf]
+ [features={math\mathsizesuffix,lm-mm-regular,mathextra},
+ goodies=lm]
+ \definefontsynonym
+ [MathRomanBold] [file:latinmodern-math-regular.otf]
+ [features={math\mathsizesuffix,lm-mm-bold,mathextra},
+ goodies=lm]
+ \stoptypescript
+
+ \starttypescript [modern-latin]
+ \definetypeface [\typescriptone]
+ [rm] [serif] [modern-latin] [default]
+ \definetypeface [\typescriptone]
+ [ss] [sans] [modern-latin] [default]
+ \definetypeface [\typescriptone]
+ [tt] [mono] [modern-latin] [default]
+ \definetypeface [\typescriptone]
+ [mm] [math] [modern-latin] [default]
+ \quittypescriptscanning
+ \stoptypescript
+
+\stoptypescriptcollection
+\stoptyping
+
+We show some more samples now for which we use\type {zapf.tex}.
+
+\startbuffer
+ {\tf\samplefile{zapf}}\blank {\bf\samplefile{zapf}}\blank
+ {\it\samplefile{zapf}}\blank {\bi\samplefile{zapf}}\blank
+ {\sl\samplefile{zapf}}\blank {\bs\samplefile{zapf}}\blank
+\stopbuffer
+
+\startsubsubsubject[title={\type{\switchtobodyfont[modern-latin,rm,10pt]}}]
+ \start
+ \switchtobodyfont[modern-latin,rm,10pt]
+ \getbuffer
+ \stop
+\stopsubsubsubject
+
+\startsubsubsubject[title={\type{\switchtobodyfont[modern-latin,ss,10pt]}}]
+ \start
+ \switchtobodyfont[modern-latin,ss,10pt]
+ \getbuffer
+ \stop
+\stopsubsubsubject
+
+\startsubsubsubject[title={\type{\switchtobodyfont[modern-latin,tt,10pt]}}]
+ \start
+ \switchtobodyfont[modern-latin,tt,10pt]
+ \setupalign[flushleft,broad,nothyphenated,verytolerant]
+ \getbuffer
+ \stop
+\stopsubsubsubject
+
+\stopsection
+
+\startsection[title=Finetuning]
+
+In practice we only need to compensate the width but can leave the height
+and depth untouched. In the following examples we see the normal bold next
+to the regular as well as the boldened version. For this we will use a couple
+of definitions:
+
+\startbuffer
+\definefontfeature[lm-bald][effect={width=0.25,effect=both}]
+\definefontfeature[pg-bald][effect={width=0.25,effect=both}]
+\definefontfeature[dj-bald][effect={width=0.35,effect=both}]
+
+\definefontfeature
+ [lm-bold]
+ [effect={width=0.25,hdelta=0,ddelta=0,effect=both},
+ extend=1.10]
+
+\definefontfeature
+ [pg-bold]
+ [effect={width=0.25,hdelta=0,ddelta=0,effect=both},
+ extend=1.00]
+
+\definefontfeature
+ [dj-bold]
+ [effect={width=0.35,hdelta=0,ddelta=0,effect=both},
+ extend=1.05]
+
+\definefont[lmbald][Serif*default,lm-bald sa d]
+\definefont[pgbald][Serif*default,pg-bald sa d]
+\definefont[djbald][Serif*default,dj-bald sa d]
+
+\definefont[lmbold][Serif*default,lm-bold sa d]
+\definefont[pgbold][Serif*default,pg-bold sa d]
+\definefont[djbold][Serif*default,dj-bold sa d]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+We can combine the extend and effect features to get a bold running as wide as a
+normal bold. We limit the height and depth so that we can use regular and bold in
+the same sentence. It's all a matter of taste, but some control is there.
+
+\starttabulate[|l|l|l|l|]
+\NC
+ \BC
+ \tt modern \BC
+ \tt pagella \BC
+ \tt dejavu \NC
+\NR
+\NC
+ \type{\tfd} \NC
+ \switchtobodyfont [modern,24pt]\strut\ruledhbox{\tfd ABC}\NC
+ \switchtobodyfont[pagella,24pt]\strut\ruledhbox{\tfd ABC}\NC
+ \switchtobodyfont [dejavu,24pt]\strut\ruledhbox{\tfd ABC}\NC
+\NR
+\NC
+ \type{\..bald} \NC
+ \switchtobodyfont [modern,24pt]\strut\ruledhbox{\lmbald ABC}\NC
+ \switchtobodyfont[pagella,24pt]\strut\ruledhbox{\pgbald ABC}\NC
+ \switchtobodyfont [dejavu,24pt]\strut\ruledhbox{\djbald ABC}\NC
+\NR
+\NC
+ \type{\bfd} \NC
+ \switchtobodyfont [modern,24pt]\strut\ruledhbox{\bfd ABC}\NC
+ \switchtobodyfont[pagella,24pt]\strut\ruledhbox{\bfd ABC}\NC
+ \switchtobodyfont [dejavu,24pt]\strut\ruledhbox{\bfd ABC}\NC
+\NR
+\NC
+ \type{\..bold} \NC
+ \switchtobodyfont [modern,24pt]\strut\ruledhbox{\lmbold ABC}\NC
+ \switchtobodyfont[pagella,24pt]\strut\ruledhbox{\pgbold ABC}\NC
+ \switchtobodyfont [dejavu,24pt]\strut\ruledhbox{\djbold ABC}\NC
+\NR
+\stoptabulate
+
+Let's take another go at Pagella. We define a few features, colors
+and fonts first:
+
+\startbuffer
+\definefontfeature
+ [pg-fake-1]
+ [effect={width=0.25,effect=both}]
+
+\definefontfeature
+ [pg-fake-2]
+ [effect={width=0.25,hdelta=0,ddelta=0,effect=both}]
+
+\definefont[pgregular] [Serif*default]
+\definefont[pgbold] [SerifBold*default]
+\definefont[pgfakebolda][Serif*default,pg-fake-1]
+\definefont[pgfakeboldb][Serif*default,pg-fake-2]
+
+\definecolor[color-pgregular] [t=.5,a=1,r=.6]
+\definecolor[color-pgbold] [t=.5,a=1,g=.6]
+\definecolor[color-pgfakebolda][t=.5,a=1,b=.6]
+\definecolor[color-pgfakeboldb][t=.5,a=1,r=.6,g=.6]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+When we apply these we get the results of \in {figure} [fig:pagella-compared]
+while we show the same overlayed in \in {figure} [fig:pagella-overlayed]. As you
+can see, the difference in real bold and fake bold is subtle: the inner shape of
+the \quote {o} differs. Also note that the position of the accents doesn't change
+in the vertical direction but moves along with the width.
+
+\def\SampleWord{\^o\"ep\c s}
+
+\startplacefigure[title={Four pagella style variants compared.},reference=fig:pagella-compared]
+ \startcombination[2*2]
+ {
+ \scale [scale=7500] {
+ \ruledhbox{\showglyphs\pgregular \SampleWord}
+ }
+ } {
+ regular (red)
+ } {
+ \scale [scale=7500] {
+ \ruledhbox{\showglyphs\pgbold \SampleWord}
+ }
+ } {
+ bold (green)
+ } {
+ \scale [scale=7500] {
+ \ruledhbox{\showglyphs\pgfakebolda \SampleWord}
+ }
+ } {
+ fakebolda (blue)
+ } {
+ \scale [scale=7500] {
+ \ruledhbox{\showglyphs\pgfakeboldb \SampleWord}
+ }
+ } {
+ fakeboldb (yellow)
+ }
+ \stopcombination
+\stopplacefigure
+
+\startplacefigure[title={Four pagella style variants overlayed.},reference=fig:pagella-overlayed]
+ \startcombination[2*3]
+ {
+ \scale [scale=7500] {
+ \startoverlay
+ {\color[color-pgregular] {\pgregular \SampleWord}}
+ {\color[color-pgbold] {\pgbold \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ bold over regular
+ } {
+ \scale [scale=7500] {
+ \startoverlay
+ {\color[color-pgregular] {\pgregular \SampleWord}}
+ {\color[color-pgfakeboldb]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ fakebolda over regular
+ } {
+ \scale [scale=7500] {
+ \startoverlay
+ {\color[color-pgregular] {\pgregular \SampleWord}}
+ {\color[color-pgfakebolda]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ fakeboldb over regular
+ } {
+ \scale [scale=7500] {
+ \startoverlay
+ {\color[color-pgbold] {\pgbold \SampleWord}}
+ {\color[color-pgfakeboldb]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ fakeboldb over bold
+ } {
+ \scale [scale=7500] {
+ \startoverlay
+ {\color[color-pgfakebolda]{\pgfakebolda \SampleWord}}
+ {\color[color-pgfakeboldb]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ fakeboldb over fakebolda
+ } {
+ \scale [scale=7500] {
+ \startoverlay
+ {\color[color-pgregular] {\pgregular \SampleWord}}
+ {\color[color-pgbold] {\pgbold \SampleWord}}
+ {\color[color-pgfakebolda]{\pgfakebolda \SampleWord}}
+ {\color[color-pgfakeboldb]{\pgfakeboldb \SampleWord}}
+ \stopoverlay
+ }
+ } {
+ all four overlayed
+ }
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
+\startsection[title=The code]
+
+The amount of code involved is not that large and is a nice illustration of what
+\LUATEX\ provides (I have omitted a few lines of tracing and error reporting).
+The only thing added to the font scaler elsewhere is that we pass the \type
+{mode} and \type {width} parameters to \TEX\ so that they get used in the backend
+to inject the few operators needed.
+
+\starttyping
+local effects = {
+ inner = 0,
+ outer = 1,
+ both = 2,
+ hidden = 3,
+}
+
+local function initialize(tfmdata,value)
+ local spec
+ if type(value) == "number" then
+ spec = { width = value }
+ else
+ spec = utilities.parsers.settings_to_hash(value)
+ end
+ local effect = spec.effect or "both"
+ local width = tonumber(spec.width) or 0
+ local mode = effects[effect]
+ if mode then
+ 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
+ tfmdata.parameters.mode = mode
+ tfmdata.parameters.width = width * 1000
+ tfmdata.properties.effect = {
+ effect = effect, width = width,
+ wdelta = wdelta, factor = factor,
+ hdelta = hdelta, hfactor = hfactor,
+ ddelta = ddelta, vfactor = vfactor,
+ }
+ end
+end
+
+local function manipulate(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, char in next, characters do
+ local oldwidth = char.width
+ local oldheight = char.height
+ local olddepth = char.depth
+ if oldwidth and oldwidth > 0 then
+ char.width = oldwidth + wdelta
+ char.commands = {
+ { "right", hshift },
+ { "char", unicode },
+ }
+ end
+ if oldheight and oldheight > 0 then
+ char.height = oldheight + hdelta
+ end
+ if olddepth and olddepth > 0 then
+ char.depth = olddepth + ddelta
+ end
+ end
+ parameters.factor = factor
+ parameters.hfactor = hfactor
+ parameters.vfactor = vfactor
+ end
+end
+
+local specification = {
+ name = "effect",
+ description = "apply effects to glyphs",
+ initializers = {
+ base = initialize,
+ node = initialize,
+ },
+ manipulators = {
+ base = manipulate,
+ node = manipulate,
+ },
+}
+
+fonts.handlers.otf.features.register(specification)
+fonts.handlers.afm.features.register(specification)
+\stoptyping
+
+The real code is slightly more complex because we want to stack virtual features
+properly but the principle is the same.
+
+\stopsection
+
+\startsection[title=Arabic]
+
+It is tempting to test effects with arabic but we need to keep in mind that for
+that we should add some more support in the \CONTEXT\ font handler. Let's define
+some features.
+
+\startbuffer
+\definefontfeature
+ [bolden-arabic-1]
+ [effect={width=0.4}]
+
+\definefontfeature
+ [bolden-arabic-2]
+ [effect={width=0.4,effect=outer}]
+
+\definefontfeature
+ [bolden-arabic-3]
+ [effect={width=0.5,wdelta=0.5,ddelta=.2,hdelta=.2,factor=.1}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+
+\setupalign
+ [righttoleft]
+
+\setupinterlinespace
+ [1.5]
+
+\start
+ \definedfont[arabictest*arabic,bolden-arabic-1 @ 30pt]
+ \samplefile{khatt-ar}\par
+ \definedfont[arabictest*arabic,bolden-arabic-2 @ 30pt]
+ \samplefile{khatt-ar}\par
+ \definedfont[arabictest*arabic,bolden-arabic-3 @ 30pt]
+ \samplefile{khatt-ar}\par
+\stop
+\stopbuffer
+
+With \MICROSOFT\ Arabtype the \type {khatt-ar.tex} looks as follows:
+
+\typebuffer \start \definefontsynonym[arabictest][arabtype] \getbuffer\stop
+
+And with Idris' Husayni we get:
+
+\typebuffer \start \definefontsynonym[arabictest][husayni] \getbuffer\stop
+
+Actually, quite okay are the following. We don't over do bold here and to get
+a distinction we make the original thinner.
+
+\startbuffer
+\definefontfeature[effect-ar-thin] [effect={width=0.01,effect=inner}]
+\definefontfeature[effect-ar-thick][effect={width=0.20,extend=1.05}]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\start
+ \setupalign
+ [righttoleft]
+
+ \setupinterlinespace
+ [1.5]
+
+ \definedfont[husayni*arabic,effect-ar-thin @ 30pt]
+ \samplefile{khatt-ar}\par
+ \definedfont[husayni*arabic,effect-ar-thick @ 30pt]
+ \samplefile{khatt-ar}\par
+\stop
+
+The results are acceptable at small sizes but at larger sizes you will start to
+see kerning, anchoring and cursive artifacts. The outline examples show that the
+amount of overlap differs per font and the more overlap we have the better
+boldening will work.
+
+\startMPinclusions
+ def DrawShapes(expr how) =
+ def SampleShapes(expr offset, pw, xc, xs, xt, yc, ys, yt, txt, more) =
+ numeric l ; l := pw * mm ;
+ picture p ; p := image (
+ draw fullcircle scaled 10 ;
+ draw fullcircle scaled 3 shifted (-3+xc ,8+yc) withcolor "darkred" ;
+ draw fullsquare scaled 3 shifted ( 6+xs ,7+ys) withcolor "darkblue";
+ draw fulltriangle scaled 4 shifted ( 6+xt+5,6+yt) withcolor "darkgreen";
+ ) shifted (offset,0) scaled mm ;
+ draw p
+ withpen pencircle
+ if how = 2 :
+ xscaled l yscaled (l/2) rotated 30 ;
+ else :
+ scaled l ;
+ fi ;
+ draw boundingbox p
+ withcolor "darkyellow" ;
+ draw textext(txt)
+ shifted (xpart center p, -8mm) ;
+ draw textext(more)
+ shifted (xpart center p, -11mm) ;
+ enddef ;
+ SampleShapes( 0,1, 0,0,0, 0, 0, 0, "\tinyfont \setstrut \strut original", "\tinyfont \setstrut \strut ") ;
+ SampleShapes( 25,2, 0,0,0, 0, 0, 0, "\tinyfont \setstrut \strut instance", "\tinyfont \setstrut \strut ") ;
+ SampleShapes( 50,2,-1,1,0, 0, 0, 0, "\tinyfont \setstrut \strut mark", "\tinyfont \setstrut \strut x only") ;
+ SampleShapes( 75,2,-1,1,1, 0, 0, 0, "\tinyfont \setstrut \strut mark + mkmk","\tinyfont \setstrut \strut x only") ;
+ SampleShapes(100,2,-1,1,1, 1, 1, 1, "\tinyfont \setstrut \strut mark + mkmk","\tinyfont \setstrut \strut x and y") ;
+ SampleShapes(125,2,-1,2,2,-1/2,-1/2,-1/2,"\tinyfont \setstrut \strut mark + mkmk","\tinyfont \setstrut \strut x and -y") ;
+ enddef ;
+\stopMPinclusions
+
+In arabic (and sometimes latin) fonts the marks (or accents in latin) are
+attached to base shapes and normally one will use the \type {mark} to anchor a
+mark to a base character or specific component of a ligature. The \type {mkmk}
+feature is then used to anchor marks to other marks. Consider the following
+example.
+
+\startlinecorrection
+\scale
+ [width=\textwidth]
+ {\startMPcode DrawShapes(1) ; \stopMPcode}
+\stoplinecorrection
+
+We start with \type {original}: a base shape with three marks: the red circle and
+blue square anchor to the base and the green triangle anchors to the blue square.
+When we bolden, the shapes will start touching. In the case of latin scripts,
+it's normal to keep the accents on the same height so this is why the third
+picture only shifts in the horizontal direction. The fourth picture demonstrates
+that we need to compensate the two bound marks. One can decide to move the lot up
+as in the fifth picture but that is no option here.
+
+Matters can be even more complex when a non circular pen is introduced. In that
+case a transformation from one font to another using the transformed \OPENTYPE\
+positioning logic (values) is even more tricky and unless one knows the
+properties (and usage) of a mark it makes no sense at all. Actually the sixths
+variant is probably nicer here but there we actually move the marks down!
+
+\startlinecorrection
+\scale
+ [width=\textwidth]
+ {\startMPcode DrawShapes(2) ; \stopMPcode}
+\stoplinecorrection
+
+For effects this means that when it gets applied to such a font, only small
+values work out well.
+
+\stopsection
+
+\startsection[title=Math]
+
+Math is dubious as there is all kind of positioning involved. Future versions
+might deal with this, although bolder math (math itself has bold, so actually
+we're talking of bold with some heavy) is needed for titling. If we keep that
+in mind we can actually just bolden math and probably most will come out
+reasonable well. One of the potential troublemakers is the radical (root) sign
+that can be bound to a rule. Bumping the rules is no big deal and patching the
+relevant radical properties neither, so indeed we can do:
+
+\startbuffer[mathblob]
+2\times\sqrt{\frac{\sqrt{\frac{\sqrt{2}}{\sqrt{2}}}}
+ {\sqrt{\frac{\sqrt{2}}{\sqrt{2}}}}}
+\stopbuffer
+
+\startbuffer
+\switchtobodyfont [modernlatin,17.3pt]
+$
+ \mr \darkblue \getbuffer[mathblob] \quad
+ \mb \darkgreen \getbuffer[mathblob]
+$
+\stopbuffer
+
+\typebuffer \blank \start \getbuffer \stop \blank
+
+Where the \type {mathblob} buffer is:
+
+\typebuffer[mathblob]
+
+Here you also see a fraction rule that has been bumped. In display mode we
+get:
+
+\startbuffer
+\switchtobodyfont[modernlatin,17.3pt]
+\startformula
+ \mr \darkblue \getbuffer[mathblob] \quad
+ \mb \darkgreen \getbuffer[mathblob]
+\stopformula
+\stopbuffer
+
+\typebuffer \blank \start \getbuffer \stop \blank
+
+Extensibles behave well too:
+
+\startbuffer
+\switchtobodyfont [modernlatin,17.3pt]
+\dostepwiserecurse {1} {30} {5} {
+ $
+ \mr \sqrt{\blackrule[width=2mm,height=#1mm,color=darkblue]}
+ \quad
+ \mb \sqrt{\blackrule[width=2mm,height=#1mm,color=darkgreen]}
+ $
+}
+\stopbuffer
+
+\typebuffer \blank \start \getbuffer \stop \blank
+
+\definecolor[colormr] [t=.5,a=1,b=.6]
+\definecolor[colormb] [t=.5,a=1,g=.6]
+
+In \in {figure} [fig:regular-over-bold] we overlay regular and bold. The result
+doesn't look that bad after all, does it? It took however a bit of experimenting
+and a fix in \LUATEX: pickup the value from the font instead of the currently
+used (but frozen) math parameter.
+
+\startplacefigure[title={Modern Latin regular over bold.},reference=fig:regular-over-bold]
+\switchtobodyfont[modernlatin,17.3pt]
+\scale[width=.25\textwidth]{\startoverlay
+ {\color[colormb]{$\mb\sqrt{\frac{1}{x}}$}}
+ {\color[colormr]{$ \sqrt{\frac{1}{x}}$}}
+\stopoverlay}
+\stopplacefigure
+
+In case you wonder how currently normal Latin Modern bold looks, here we go:
+
+\startbuffer
+\switchtobodyfont[latinmodern,17.3pt]
+\startformula
+ \mr \darkblue \getbuffer[mathblob] \quad
+ \mb \darkgreen \getbuffer[mathblob]
+\stopformula
+\stopbuffer
+
+\typebuffer \blank \start \getbuffer \stop \blank
+
+\unexpanded\def\ShowMathSample#1%
+ {\switchtobodyfont[#1,14.4pt]%
+ \mathematics{%
+ \mr \darkblue \getbuffer[mathblob] \quad
+ \mb \darkgreen \getbuffer[mathblob]
+ }}
+
+\unexpanded\def\ShowMathCaption#1%
+ {\switchtobodyfont[#1]%
+ #1:
+ $
+ {\mr2\enspace \scriptstyle2\enspace \scriptscriptstyle2}
+ \enspace
+ {\mb2\enspace \scriptstyle2\enspace \scriptscriptstyle2}
+ $}
+
+\startcombination[3*2]
+ {\ShowMathSample {dejavu}} {\ShowMathCaption{dejavu}}
+ {\ShowMathSample{pagella}} {\ShowMathCaption{pagella}}
+ {\ShowMathSample {termes}} {\ShowMathCaption{termes}}
+ {\ShowMathSample {bonum}} {\ShowMathCaption{bonum}}
+ {\ShowMathSample {schola}} {\ShowMathCaption{schola}}
+ {\ShowMathSample{cambria}} {\ShowMathCaption{cambria}}
+\stopcombination
+
+I must admit that I cheat a bit. In order to get a better looking pseudo math
+we need to extend the shapes horizontally as well as squeeze them a bit vertically.
+So, the real effect definitions more look like this:
+
+\starttyping
+\definefontfeature
+ [boldened-30]
+ [effect={width=0.3,extend=1.15,squeeze=0.985,%
+ delta=1,hdelta=0.225,ddelta=0.225,vshift=0.225}]
+\stoptyping
+
+and because we can calculate the funny values sort of automatically, this gets
+simplified to:
+
+\starttyping
+\definefontfeature
+ [boldened-30]
+ [effect={width=0.30,auto=yes}]
+\stoptyping
+
+We leave it to your imagination to figure out what happens behind the screens.
+Just think of some virtual font magic combined with the engine supported \type
+{extend} and \type {squeeze} function. And because we already support bold math
+in \CONTEXT, you will get it when you are doing bold titling.
+
+\startbuffer
+\def\MathSample
+ {\overbrace{2 +
+ \sqrt{\frac{\sqrt{\frac{\sqrt{2}}{\sqrt{2}}}}
+ {\sqrt{\frac{\sqrt{\underbar{2}}}{\sqrt{\overbar{2}}}}}}}}
+
+\definehead
+ [mysubject]
+ [subject]
+
+\setuphead
+ [mysubject]
+ [style=\tfc,
+ color=darkblue,
+ before=\blank,
+ after=\blank]
+
+\mysubject{Regular\quad$\MathSample\quad\mb\MathSample$}
+
+\setuphead
+ [mysubject]
+ [style=\bfc,
+ color=darkred]
+
+\mysubject{Bold \quad$\MathSample\quad\mb\MathSample$}
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Of course one can argue about the right values for boldening and compensation if
+dimensions so don't expect the current predefined related features to be frozen
+yet.
+
+For sure this mechanism will create more fonts than normal but fortunately it
+can use the low level optimizations for sharing instances so in the end the
+overhead is not that large. This chapter uses 36 different fonts, creates 270
+font instances (different scaling and properties) of which 220 are shared in the
+backend. The load time is 5 seconds in \LUATEX\ and 1.2 seconds in \LUAJITTEX\ on
+a somewhat old laptop with a i7-3840QM processor running 64 bit \MSWINDOWS. Of
+course we load a lot of bodyfonts at different sizes so in a normal run the extra
+loading is limited to just a couple of extra instances for math (normally 3, one
+for each math size).
+
+\stopsection
+
+\startsection[title=Conclusion]
+
+So what can we conclude? When we started with \LUATEX, right from the start
+\CONTEXT\ supported true \UNICODE\ math by using virtual \UNICODE\ math fonts.
+One of the objectives of the \TEX Gyre project is to come up with a robust
+complete set of math fonts, text fonts with a bunch of useful symbols, and
+finally a subset bold math font for titling. Now we have real \OPENTYPE\ math
+fonts, although they are still somewhat experimental. Because we're impatient, we
+now provide bold math by using effects but the future will learn to what extent
+the real bold math fonts will differ and be more pleasant to look at. After all,
+what we describe he is just an experiment that got a bit out of hands.
+
+% And if you wonder if this kind of messing with fonts is okay? Well, you don't
+% know what specs we sometimes get (and then ignore).
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/onandon/onandon-performance.tex b/doc/context/sources/general/manuals/onandon/onandon-performance.tex
index 279383a8c..b1b34443d 100644
--- a/doc/context/sources/general/manuals/onandon/onandon-performance.tex
+++ b/doc/context/sources/general/manuals/onandon/onandon-performance.tex
@@ -28,8 +28,8 @@ So what exactly does performance refer to? If you use \CONTEXT\ there are
probably only two things that matter:
\startitemize[packed]
-\startitem How long does one run take. \stopitem
-\startitem How many runs do I need. \stopitem
+\startitem How long does one run take? \stopitem
+\startitem How many runs do I need? \stopitem
\stopitemize
Processing speed is reported at the end of a run in terms of seconds spent on the
@@ -50,72 +50,74 @@ i7-3840QM as reference. A simple
\stoptext
\stoptyping
-document reports 0.4 seconds but as we wrap the run in an \type {mtxrun}
-management run we have an additional 0.3 overhead (auxiliary file handling, \PDF\
-viewer management, etc). This includes loading the Latin Modern font. With
-\LUAJITTEX\ these times are below 0.3 and 0.2 seconds. It might look like much
-overhead but in an edit|-|preview runs it feels snappy. One can try this:
+document reports 0.4 seconds but, as we wrap the run in an \type {mtxrun}
+management run, we have an additional 0.3 overhead (auxiliary file handling,
+\PDF\ viewer management, etc). This includes loading the Latin Modern font. With
+\LUAJITTEX, these times are below 0.3 and 0.2 seconds. It might look like a lot
+of overhead, but in an edit|-|preview runs it feels snappy. One can try this:
\starttyping
\stoptext
\stoptyping
-which bring down the time to about 0.2 seconds for both engines but as it doesn't
-do anything useful that is is no practice.
+which bring down the time to about 0.2 seconds for both engines but it doesn't
+do anything useful in practice.
-Finishing a document is not that demanding because most gets flushed as we go.
-The more (large) fonts we use, the longer it takes to finish a document but on
+Finishing a document is not that demanding, because most gets flushed as we go.
+The more (large) fonts we use, the longer it takes to finish a document, but, on
the average that time is not worth noticing. The main runtime contribution comes
from processing the pages.
Okay, this is not always true. For instance, if we process a 400 page book from
2500 small \XML\ files with multiple graphics per page, there is a little
-overhead in loading the files and constructing the \XML\ tree as well as in
-inserting the graphics but in such cases one expects a few seconds more runtime. The
-\METAFUN\ manual has some 450 pages with over 2500 runtime generated \METAPOST\
-graphics. It has color, uses quite some fonts, has lots of font switches
-(verbatim too) but still one run takes only 18 seconds in stock \LUATEX\ and less
-that 15 seconds with \LUAJITTEX. Keep these numbers in mind if a non|-|\CONTEXT\
-users barks against the performance tree that his few page mediocre document
-takes 10 seconds to compile: the content, styling, quality of macros and whatever
-one can come up with all plays a role. Personally I find any rate between 10 and
-30 pages per second acceptable, and if I get the lower rate then I normally know
-pretty well that the job is demanding in all kind of aspects.
-
-Over time the \CONTEXT||\LUATEX\ combination, in spite of the fact that more
+overhead in loading the files and in constructing the \XML\ tree as well as in
+inserting the graphics, but in such cases one expects a few seconds longer
+runtime. \METAFUN\ manual has some 450 pages with over 2500 runtime|-|generated
+\METAPOST\ graphics. It has color, uses quite some fonts, has lots of font
+switches (verbatim, too), but, still, one run takes only 18 seconds in stock
+\LUATEX\ and less and less that 15 seconds with \LUAJITTEX. Keep these numbers in
+mind if a non|-|\CONTEXT\ users bark against the performance tree that his few
+page mediocre document takes 10 seconds to compile: the content, styling, quality
+of macros and whatever one can come up with all play a role. Personally I find
+any rate between 10 and 30 pages per second acceptable, and, if I get the lower
+rate, then I normally know pretty well that the job is demanding in all kind of
+aspects.
+
+Over time, the \CONTEXT||\LUATEX\ combination, in spite of the fact that more
functionality has been added, has not become slower. In fact, some subsystems
-have been sped up. For instance font handling is very sensitive for adding
+have been sped up. For instance, font handling is very sensitive to adding
functionality. However, each version so far performed a bit better. Whenever some
neat new trickery was added, at the same time improvements were made thanks to
-more insight in the matter. In practice we're not talking of changes in speed by
+more insight in the matter. In practice, we're not talking of changes in speed by
large factors but more by small percentages. I'm pretty sure that most \CONTEXT\
-users never noticed. Recently a 15\endash30\% speed up (in font handling) was
-realized (for more complex fonts) but only when you use such complex fonts and
-pages full of text you will see a positive impact on the whole run.
+users never noticed. Recently, a 15\endash30\% speed up (in font handling) was
+realized (for more complex fonts), but only when you use such complex fonts and
+pages full of text will you see a positive impact on the whole run.
There is one important factor I didn't mention yet: the efficiency of the
console. You can best check that by making a format (\typ {context --make en}).
When that is done by piping the messages to a file, it takes 3.2 seconds on my
laptop and about the same when done from the editor (\SCITE), maybe because the
\LUATEX\ run and the log pane run on a different thread. When I use the standard
-console it takes 3.8 seconds in Windows 10 Creative update (in older versions it
+console, it takes 3.8 seconds in Windows 10 Creative update (in older versions it
took 4.3 and slightly less when using a console wrapper). The powershell takes
-3.2 seconds which is the same as piping to a file. Interesting is that in Bash on
-Windows it takes 2.8 seconds and 2.6 seconds when piped to a file. Normal runs
-are somewhat slower, but it looks like the 64 bit Linux binary is somewhat faster
-than the 64 bit mingw version. \footnote {Long ago we found that \LUATEX\ is very
-sensitive to for instance the \CPU\ cache so maybe there are some differences due
-to optimization flags and|/|or the fact that bash runs in one thread and all file
-\IO\ in the main windows instance. Who knows.} Anyway, it demonstrates that when
-someone yells a number you need to ask what the conditions where.
-
-At a \CONTEXT\ meeting there has been a presentation about possible speed|-|up of
-a run for instance by using a separate syntax checker to prevent a useless run.
-However, the use case concerned a document that took a minute on the machine
-used, while the same document took a few seconds on mine. At the same meeting we
-also did a comparison of speed for a \LATEX\ run using \PDFTEX\ and the same
-document migrated to \CONTEXT\ \MKIV\ using \LUATEX\ (Harald K\"onigs \XML\
-torture and compatibility test). Contrary to what one might expect, the
+3.2 seconds, which is the same as piping to a file. Interesting is that in Bash
+on Windows, it takes 2.8 seconds and 2.6 seconds when piped to a file. Normal
+runs are somewhat slower, but it looks like the 64 bit Linux binary is somewhat
+faster than the 64 bit mingw version. \footnote {Long ago, we found that \LUATEX\
+is very sensitive to for instance the \CPU\ cache, so maybe there are some
+differences due to optimization flags and|/|or the fact that bash runs in one
+thread, and all file \IO\ takes place in the main Windows instance. Who knows.}
+Anyway, it demonstrates that when someone yells a number you need to ask what the
+conditions were.
+
+At a \CONTEXT\ meeting, there has been a presentation about possible speed|-|up
+of of a run by using, for instance, a separate syntax checker to prevent a
+useless run. However, the use case concerned a document that took a minute on the
+machine used, while the same document took a few seconds on mine. At the same
+meeting, we also did a comparison of speed for a \LATEX\ run using \PDFTEX\ and
+the same document migrated to \CONTEXT\ \MKIV\ using \LUATEX\ (Harald K\"onigs
+\XML\ torture and compatibility test). Contrary to what one might expect, the
\CONTEXT\ run was significantly faster; the resulting document was a few
gigabytes in size.
@@ -126,76 +128,77 @@ gigabytes in size.
I will discuss a few potential bottlenecks next. A complex integrated system like
\CONTEXT\ has lots of components and some can be quite demanding. However, when
something is not used, it has no (or hardly any) impact on performance. Even when
-we spend a lot of time in \LUA\ that is not the reason for a slow|-|down.
+we spend a lot of time in \LUA, that is not the reason for a slow|-|down.
Sometimes using \LUA\ results in a speedup, sometimes it doesn't matter. Complex
-mechanisms like natural tables for instance will not suddenly become less
+mechanisms like natural tables, for instance, will not suddenly become less
complex. So, let's focus on the \quotation {aspects} that come up in those
complaints: fonts and \LUA. Because I only use \CONTEXT\ and occasionally test
with the plain \TEX\ version that we provide, I will not explore the potential
-impact of using truckloads of packages, styles and such, which I'm sure of plays
-a role, but one neglected in the discussion.
+impact of using truckloads of packages, styles, and such, which I'm sure of plays
+a role, but one neglected in my discussion.
\startsubsubject[title=Fonts]
-According to the principles of \LUATEX\ we process (\OPENTYPE) fonts using \LUA.
-That way we have complete control over any aspect of font handling, and can, as
+According to the principles of \LUATEX, we process (\OPENTYPE) fonts using \LUA.
+That way, we have complete control over any aspect of font handling, and can, as
to be expected in \TEX\ systems, provide users what they need, now and in the
-future. In fact, if we didn't had that freedom in \CONTEXT\ I'd probably already
+future. In fact, if we didn't had that freedom in \CONTEXT, I'd probably already
quit using \TEX\ a decade ago and found myself some other (programming) niche.
-After a font is loaded, part of the data gets passed to the \TEX\ engine so that
-it can do its work. For instance, in order to be able to typeset a paragraph,
-\TEX\ needs to know the dimensions of glyphs. Once a font has been loaded
-(that is, the binary blob) the next time it's fetched from a cache. Initial
-loading (and preparation) takes some time, depending on the complexity or size of
-the font. Loading from cache is close to instantaneous. After loading the
-dimensions are passed to \TEX\ but all data remains accessible for any desired
-usage. The \OPENTYPE\ feature processor for instance uses that data and \CONTEXT\
-for sure needs that data (fast accessible) for different purposes too.
-
-When a font is used in so called base mode, we let \TEX\ do the ligaturing and
+After a font has been loaded, part of the data gets passed to the \TEX\ engine,
+so that it can do its work. For instance, in order to be able to typeset a
+paragraph, \TEX\ needs to know the dimensions of glyphs. Once a font has been
+loaded (that is, the binary blob) it's fetched from a cache the next time.
+Initial loading (and preparation) takes some time, depending on the complexity
+and the size of the font. Loading from cache is close to instantaneous. After
+loading, the dimensions are passed to \TEX\ but all data remains accessible for
+any desired usage. The \OPENTYPE\ feature processor, for instance, uses that data
+and \CONTEXT, for sure, needs that data (quickly accessible) for different
+purposes, too.
+
+When a font is used in so|-|called base mode, we let \TEX\ do the ligaturing and
kerning. This is possible with simple fonts and features. If you have a critical
-workflow you might enable base mode, which can be done per font instance.
-Processing in node mode takes some time but how much depends on the font and
-script. Normally there is no difference between \CONTEXT\ and generic usage. In
-\CONTEXT\ we also have dynamic features, and the impact on performance depends on
-usage. In addition to base and node we also have plug mode but that is only used
+workflow, you might enable base mode, which can be done per font instance.
+Processing in node mode takes some time, but how much depends on the font and
+script. Normally, there is no difference between \CONTEXT\ and generic usage. In
+\CONTEXT, we also have dynamic features, and the impact on performance depends on
+usage. In addition to base and node, we also have plug mode, but that is only used
for testing and therefore not advertised.
Every \type {\hbox} and every paragraph goes through the font handler. Because
we support mixed modes, some analysis takes place, and because we do more in
-\CONTEXT, the generic analyzer is more light weight, which again can mean that a
+\CONTEXT, the generic analyzer is more lightweight, which again can mean that a
generic run is not slower than a similar \CONTEXT\ one.
Interesting is that added functionality for variable and|/|or color fonts had no
-impact on performance. Runtime added user features can have some impact but when
-defined well it can be neglected. I bet that when you add additional node list
-handling yourself, its impact on performance is larger. But in the end what
-counts is that the job gets done and the more you demand the higher the price you
-pay.
+impact on performance. Runtime|-|added user features can have some impact, but,
+when defined well, it can be neglected. I bet that when you add additional node
+list handling yourself, its impact on performance will be larger. But in the end
+what counts is that the job gets done and the more you demand the higher the
+price you pay.
\stopsubsubject
\startsubsubject[title=\LUA]
The second possible bottleneck when using \LUATEX\ can be in using \LUA\ code.
-However, using that as argument for slow runs is laughable. For instance
-\CONTEXT\ \MKIV\ can easily spend half its time in \LUA\ and that is not making
+However, using that is laughable as an argument for slow runs. For instance,
+\CONTEXT\ \MKIV\ can easily spend half its time in \LUA, and that is not making
it any slower than \MKII\ using \PDFTEX\ doing equally complex things. For
-instance the embedded \METAPOST\ library makes \MKIV\ way faster than \MKII, and
+instance, the embedded \METAPOST\ library makes \MKIV\ way faster than \MKII, and
the built|-|in \XML\ processing capabilities in \MKIV\ can easily beat \MKII\
\XML\ handling, apart from the fact that it can do more, like filtering by path
and expression. In fact, files that take, say, half a minute in \MKIV, could as
well have taken 15 minutes or more in \MKII\ (and imagine multiple runs then).
-So, for \CONTEXT\ using \LUA\ to achieve its objectives is mandate. The
+So, for \CONTEXT, using \LUA\ to achieve its objectives is mandatory. The
combination of \TEX, \METAPOST\ and \LUA\ is pretty powerful! Each of these
components is really fast. If \TEX\ is your bottleneck, review your macros! When
\LUA\ seems to be the bad, go over your code and make it better. Much of the
-\LUA\ code I see flying around doesn't look that efficient, which is okay because
+\LUA\ code I see flying around doesn't look that efficient, which is okay, because
the interpreter is really fast, but don't blame \LUA\ beforehand, blame your
coding (style) first. When \METAPOST\ is the bottleneck, well, sometimes not much
-can be done about it, but when you know that language well enough you can often
+can be done about it, but when you know that language well enough, you can often
make it perform better.
For the record: every additional mechanism that kicks in, like character spacing
@@ -210,26 +213,26 @@ gets pretty well obscured by other things happening, just that you know.
\startsection[title=Some timing]
-Next I will show some timings related to fonts. For this I use stock \LUATEX\
-(second column) as well as \LUAJITTEX\ (last column) which of course performs
-much better. The timings are given in 3 decimals but often (within a set of runs)
-and as the system load is normally consistent in a set of test runs the last two
-decimals only matter in relative comparison. So, for comparing runs over time
-round to the first decimal. Let's start with loading a bodyfont. This happens
-once per document and normally one has only one bodyfont active. Loading involves
-definitions as well as setting up math so a couple of fonts are actually loaded,
-even if they're not used later on. A setup normally involves a serif, sans, mono,
-and math setup (in \CONTEXT). \footnote {The timing for Latin Modern is so low
+Next, I will show some timings related to fonts. For this, I use stock \LUATEX\
+(second column) as well as \LUAJITTEX\ (last column), which, of course, performs
+much better. The timings are rounded to three decimal places, but, as the system
+load is usually only consistent in a set of test runs, the last two decimals only
+matter in relative comparison. So, for comparing runs over time, round to the
+first decimal. Let's start with loading a bodyfont. This happens once per
+document, and one usually only has one bodyfont active. Loading involves
+definitions as well as setting up math, so a couple of fonts are actually loaded
+even if they're not used later on. A setup normally involves a serif, sans, mono
+and math setup (in \CONTEXT). \footnote {The timing for Latin Modern is so low,
because that font is loaded already.}
\environment onandon-speed-000
\ShowSample{onandon-speed-000} % bodyfont
-There is a bit difference between the font sets but a safe average is 150 milli
-seconds and this is rather constant over runs.
+There is a bit of a difference between the font sets, but a safe average is 150
+milliseconds, and this is rather constant over runs.
-An actual font switch can result in loading a font but this is a one time overhead.
+An actual font switch can result in loading a font, but this is a one|-|time overhead.
Loading four variants (regular, bold, italic and bold italic) roughly takes the
following time:
@@ -239,34 +242,32 @@ Using them again later on takes no time:
\ShowSample{onandon-speed-002} % four variants
-Before we start timing the font handler, first a few baseline benchmarks are
-shown. When no font is applied and nothing else is done with the node list we
-get:
+Before we start timing the font handler, a few baseline benchmarks are shown.
+When no font is applied and nothing else is done with the node list, we get:
\ShowSample{onandon-speed-009}
-A simple monospaced, no features applied, run takes a bit more:
+A simple monospaced, no|-|features|-|applied, run takes a bit more:
\ShowSample{onandon-speed-010}
-Now we show a one font typesetting run. As the two benchmarks before, we just
-typeset a text in a \type {\hbox}, so no par builder interference happens. We use
-the \type {sapolsky} sample text and typeset it 100 times 4 (either of not with
-font switches).
+Now, we show a one|-|font typesetting run. As with the two benchmarks before, we
+just typeset a text in a \type {\hbox}, so no par builder interference happens.
+We use the \type {sapolsky} sample text and typeset it 100 times 4, first without
+font switches.
\ShowSample{onandon-speed-003}
-Much more runtime is needed when we typeset with four font switches. The garamond
-is most demanding. Actually we're not doing 4 fonts there because it has no bold,
-so the numbers are a bit lower than expected for this example. One reason for it
-being demanding is that it has lots of (contextual) lookups. The only comment I
-can make about that is that it also depends on the strategies of the font
-designer. Combining lookups saves space and time so complexity of a font is not
-always a good predictor for performance hits.
+Much more runtime is needed when we typeset with four font switches. Ebgaramond
+is the most demanding. Actually, we're not doing 4 fonts there because ebgaramond
+has no bold, so the numbers are a bit lower than expected for this example. One
+reason for it being demanding is that it has lots of (contextual) lookups.
+Combining lookups saves space and time, so complexity of a font is not always a
+good predictor for performance hits.
% \ShowSample{onandon-speed-004}
-If we typeset paragraphs we get this:
+If we typeset paragraphs, we get the following:
\ShowSample{onandon-speed-005}
@@ -274,11 +275,11 @@ We're talking of some 275 pages here.
\ShowSample{onandon-speed-006}
-There is of course overhead in handling paragraphs and pages:
+There is, of course overhead in handling paragraphs and pages:
\ShowSample{onandon-speed-011}
-Before I discuss these numbers in more details two more benchmarks are
+Before I discuss these numbers in more detail, two more benchmarks are
shown. The next table concerns a paragraph with only a few (bold) words.
\ShowSample{onandon-speed-007}
@@ -290,11 +291,11 @@ typeset using \type{\type}.
When a node list (hbox or paragraph) is processed, each glyph is looked at. One
important property of \LUATEX\ (compared to \PDFTEX) is that it hyphenates the
-whole text, not only the most feasible spots. For the \type {sapolsky} snippet
-this results in 200 potential breakpoints, registered in an equal number of
-discretionary nodes. The snippet has 688 characters grouped into 125 words and
-because it's an English quote we're not hampered with composed characters or
-complex script handling. And, when we mention 100 runs then we actually mean
+whole text, not only the most feasible spots. For the \type {sapolsky} snippet,
+this results in 200 potential breakpoints registered in an equal number of
+discretionary nodes. The snippet has 688 characters grouped into 125 words and,
+because it's an English quote, we're not hampered with composed characters or
+complex script handling. And, when we mention 100 runs, then we actually mean
400 ones when font switching and bodyfonts are compared
\startnarrower
@@ -302,7 +303,7 @@ complex script handling. And, when we mention 100 runs then we actually mean
\input sapolsky \wordright{Robert M. Sapolsky}
\stopnarrower
-In order to get substitutions and positioning right we need not only to consult
+In order to get substitutions and positioning right, we need not only to consult
streams of glyphs but also combinations with preceding pre or replace, or
trailing post and replace texts. When a font has a bit more complex substitutions,
as ebgaramond has, multiple (sometimes hundreds of) passes over the list are made.
@@ -312,15 +313,15 @@ Another factor, one you could easily deduce from the benchmarks, is intermediate
font switches. Even a few such switches (in the last benchmarks) already result
in a runtime penalty. The four switch benchmarks show an impressive increase of
runtime, but it's good to know that such a situation seldom happens. It's also
-important not to confuse for instance a verbatim snippet with a bold one. The
+important not to confuse, for instance, a verbatim snippet with a bold one. The
bold one is indeed leading to a pass over the list, but verbatim is normally
-skipped because it uses a font that needs no processing. That verbatim or bold
+skipped, because it uses a font that needs no processing. That verbatim or bold
have the same penalty is mainly due to the fact that verbatim itself is costly:
the text is picked up using a different catcode regime and travels through \TEX\
and \LUA\ before it finally gets typeset. This relates to special treatments of
-spacing and syntax highlighting and such.
+spacing, syntax highlighting, and such.
-Also keep in mind that the page examples are quite unreal. We use a layout with
+Also, keep in mind that the page examples are quite unreal. We use a layout with
no margins, just text from edge to edge.
\placefigure
@@ -343,19 +344,19 @@ no margins, just text from edge to edge.
{\SampleTitle{onandon-speed-011}}
{\externalfigure[onandon-speed-011][frame=on,orientation=90,width=.45\textheight]}
-So what is a realistic example? That is hard to say. Unfortunately no one ever
-asked us to typeset novels. They are rather brain dead products for a machinery
-so they process fast. On the mentioned laptop 350 word pages in Dejavu fonts can
-be processed at a rate of 75 pages per second with \LUATEX\ and over 100 pages
-per second with \LUAJITTEX . On a more modern laptop or professional server
-performance is of course better. And for automated flows batch mode is your
-friend. The rate is not much worse for a document in a language with a bit more
-complex character handling, take accents or ligatures. Of course \PDFTEX\ is
-faster on such a dumb document but kick in some more functionality and the
-advantage quickly disappears. So, if someone complains that \LUATEX\ needs 10 or
-more seconds for a simple few page document \unknown\ you can bet that when the
-fonts are seen as reason, that the setup is pretty bad. Personally I'd not waste
-time on such a complaint.
+So, what is a realistic example? That is hard to say. Unfortunately, no one has
+ever asked us to typeset novels. They are rather brain dead-products for a
+machinery, so they process fast. On the mentioned laptop, 350 word pages in
+Dejavu fonts can be processed at a rate of 75 pages per second with \LUATEX\ and
+over 100 pages per second with \LUAJITTEX . On a more modern laptop or a
+professional server, the performance is of course better. And, for automated
+flows, batch mode is your friend. The rate is not much worse for a document in a
+language with a bit more complex character handling, take accents or ligatures.
+Of course, \PDFTEX\ is faster on such a dumb document, but kick in some more
+functionality, and the advantage quickly disappears. So, if someone complains
+that \LUATEX\ needs 10 or more seconds for a simple few page document \unknown\
+you can bet that when the fonts are seen as reason, then the setup is pretty bad.
+Personally I would not waste time on such a complaint.
\stopsection
@@ -366,74 +367,75 @@ about the slowness of \LUATEX:
\startsubsubject[title={What engines do you compare?}]
-If you come from \PDFTEX\ you come from an 8~bit world: input and font handling
-are based on bytes and hyphenation is integrated into the par builder. If you use
-\UTF-8\ in \PDFTEX, the input is decoded by \TEX\ macros which carries a speed
+If you come from \PDFTEX, you come from an 8-bit world: input and font handling
+are based on bytes, and hyphenation is integrated into the par builder. If you use
+\UTF-8\ in \PDFTEX, the input is decoded by \TEX\ macros, which carries a speed
penalty. Because in the wide engines macro names can also be \UTF\ sequences,
construction of macro names is less efficient too.
-When you try to use wide fonts, again there is a penalty. Now, if you use \XETEX\
-or \LUATEX\ your input is \UTF-8 which becomes something 32 bit internally. Fonts
-are wide so more resources are needed, apart from these fonts being larger and in
-need of more processing due to feature handling. Where \XETEX\ uses a library,
-\LUATEX\ uses its own handler. Does that have a consequence for performance? Yes
-and no. First of all it depends on how much time is spent on fonts at all, but
-even then the difference is not that large. Sometimes \XETEX\ wins, sometimes
-\LUATEX. One thing is clear: \LUATEX\ is more flexible as we can roll out our own
-solutions and therefore do more advanced font magic. For \CONTEXT\ it doesn't
-matter as we use \LUATEX\ exclusively and rely on the flexible font handler, also
-for future extensions. If really needed you can kick in a library based handler
-but it's (currently) not distributed as we loose other functionality which in
-turn would result in complaints about that fact (apart from conflicting with the
-strive for independence).
-
-There is no doubt that \PDFTEX\ is faster but for \CONTEXT\ it's an obsolete
-engine. The hard coded solutions engine \XETEX\ is also not feasible for
-\CONTEXT\ either. So, in practice \CONTEXT\ users have no choice: \LUATEX\ is
-used, but users of other macro packages can use the alternatives if they are not
-satisfied with performance. The fact that \CONTEXT\ users don't complain about
-speed is a clear signal that this is no issue. And, if you want more speed you
-can use \LUAJITTEX. \footnote {In plug mode we can actually test a library and
-experiments have shown that performance on the average is much worse but it can
+When you try to use wide fonts, there is, again, a penalty. Now, if you use
+\XETEX\ or \LUATEX, your input is \UTF-8, which becomes something 32-bit
+internally. Fonts are wide, so more resources are needed, apart from these fonts
+being larger and in need of more processing due to feature handling. Where
+\XETEX\ uses a library, \LUATEX\ uses its own handler. Does that have a
+consequence for performance? Yes and no. First of all, it depends on how much
+time is spent on fonts at all, but even then, the difference is not that large.
+Sometimes \XETEX\ wins, sometimes it's \LUATEX. One thing is clear: \LUATEX\ is
+more flexible as we can roll out our own solutions and therefore do more advanced
+font magic. For \CONTEXT, it doesn't matter as we use \LUATEX\ exclusively, and
+we rely on the flexible font handler, also for future extensions. If really
+needed, you can kick in a library-based handler but it's (currently) not
+distributed as we lose other functionality, which would, in turn, result in
+complaints about that fact (apart from conflicting with the strive for
+independence).
+
+There is no doubt that \PDFTEX\ is faster, but, for \CONTEXT, it's an obsolete
+engine. The hard-coded-solutions engine \XETEX\ is not feasible for \CONTEXT\
+either. So, in practice, \CONTEXT\ users have no choice: \LUATEX\ is used, but
+users of other macro packages can use the alternatives if they are not satisfied
+with performance. The fact that \CONTEXT\ users don't complain about speed is a
+clear signal that this is a no|-|issue. And, if you want more speed, you can always
+use \LUAJITTEX. \footnote {In plug mode, we can actually test a library and
+experiments have shown that performance on the average is much worse, but it can
be a bit better for complex scripts, although a gain gets unnoticed in normal
documents. So, one can decide to use a library but at the cost of much other
-functionality that \CONTEXT\ offers, so we don't support it.} In the last section
+functionality that \CONTEXT\ offers, so we don't support it.} In the last section,
the different engines will be compared in more detail.
-Just that you know, when we do the four switches example in plain \TEX\ on my
-laptop I get a rate of 40 pages per second, and for one font 180 pages per
-second. There is of course a bit more going on in \CONTEXT\ in page building and
-so, but the difference between plain and \CONTEXT\ is not that large.
+Just that you know, when we do the four|-|switches example in plain \TEX\ on my
+laptop, I get a rate of 40 pages per second, and, for one font, 180 pages per
+second. There is, of course, a bit more going on in \CONTEXT\ in page building
+and so, but the difference between plain and \CONTEXT\ is not that large.
\stopsubsubject
\startsubsubject[title={What macro package is used?}]
-If the answer is that when plain \TEX\ is used, a follow up question is: what
-variant? The \CONTEXT\ distribution ships with \type {luatex-plain} and that is
-our benchmark. If there really is a bottleneck it is worth exploring. But keep in
-mind that in order to be plain, not that much can be done. The \LUATEX\ part is
-just an example of an implementation. We already discussed \CONTEXT, and for
-\LATEX\ I don't want to speculate where performance hits might come from. When
-we're talking fonts, \CONTEXT\ can actually a bit slower than the generic (or
-\LATEX) variant because we can kick in more functionality. Also, when you compare
-macro packages, keep in mind that when node list processing code is added in that
-package the impact depends on interaction with other functionality and depends on
-the efficiency of the code. You can't compare mechanisms or draw general
-conclusions when you don't know what else is done!
+When plain \TEX\ is used, a follow up question is: what variant? The \CONTEXT\
+distribution ships with \type {luatex-plain}, and that is our benchmark. If there
+really is a bottleneck, it is worth exploring, but keep in mind that, in order to
+be plain, not that much can be done. The \LUATEX\ part is just an example of an
+implementation. We already discussed \CONTEXT, and for \LATEX, I don't want to
+speculate where performance hits might come from. When we're talking fonts,
+\CONTEXT\ can actually be a bit slower than the generic (or \LATEX) variant, because
+we can kick in more functionality. Also, when you compare macro packages, keep in
+mind that, when node list processing code is added in that package, the impact
+depends on interaction with other functionality and depends on the efficiency of
+the code. You can't compare mechanisms or draw general conclusions when you don't
+know what else is done!
\stopsubsubject
\startsubsubject[title={What do you load?}]
-Most \CONTEXT\ modules are small and load fast. Of course there can be exceptions
-when we rely on third party code; for instance loading tikz takes a a bit of
-time. It makes no sense to look for ways to speed that system up because it is
-maintained elsewhere. There can probably be gained a bit but again, no user
-complained so far.
+Most \CONTEXT\ modules are small and load fast. Of course, there can be exceptions
+when we rely on third party code; for instance, loading tikz takes a bit of
+time. It makes no sense to look for ways to speed that system up, because it is
+maintained elsewhere. There can probably be gained a bit, but, again, no user
+has complained so far.
-If \CONTEXT\ is not used, one probably also uses a large \TEX\ installations.
-File lookup in \CONTEXT\ is done differently and can can be faster. Even loading
+If \CONTEXT\ is not used, one probably also uses a large \TEX\ installation.
+File lookup in \CONTEXT\ is done differently, and can be faster. Even loading
can be more efficient in \CONTEXT, but it's hard to generalize that conclusion.
If one complains about loading fonts being an issue, just try to measure how much
time is spent on loading other code.
@@ -443,36 +445,36 @@ time is spent on loading other code.
\startsubsubject[title={Did you patch macros?}]
Not everyone is a \TEX pert. So, coming up with macros that are expanded many
-times and|/|or have inefficient user interfacing can have some impact. If someone
-complains about one subsystem being slow, then honestly demands to complain about
+times and|/|or have inefficient user interfacing, can have some impact. If someone
+complains about one subsystem being slow, then honesty demands to complain about
other subsystems as well. You get what you ask for.
\stopsubsubject
\startsubsubject[title={How efficient is the code that you use?}]
-Writing super efficient code only makes sense when it's used frequently. In
-\CONTEXT\ most code is reasonable efficient. It can be that in one document fonts
-are responsible for most runtime, but in another document table construction can
+Writing super|-|efficient code only makes sense when it's used frequently. In
+\CONTEXT, most code is reasonable efficient. It can be that in one document fonts
+are responsible for most runtime, but in another document, table construction can
be more demanding while yet another document puts some stress on interactive
-features. When hz or protrusion is enabled then you run substantially slower
-anyway so when you are willing to sacrifice 10\% or more runtime don't complain
-about other components. The same is true for enabling \SYNCTEX: if you are
-willing to add more than 10\% runtime for that, don't wither about the same
-amount for font handling. \footnote {In \CONTEXT\ we use a \SYNCTEX\ alternative
-that is somewhat faster but it remains a fact that enabling more and more
-functionality will make the penalty of for instance font processing relatively
-small.}
+features. When hz or protrusion is enabled, then you run substantially slower
+anyway, so when you are willing to sacrifice 10 \% or more of runtime, don't
+complain about other components. The same is true for enabling \SYNCTEX: if you
+are willing to add more than 10 \% of runtime for that, don't wither about the
+same amount for font handling. \footnote {In \CONTEXT, we use a \SYNCTEX\
+alternative that is somewhat faster, but it remains a fact that enabling more and
+more functionality will make the penalty of, for instance, font processing
+relatively small.}
\stopsubsubject
\startsubsubject[title={How efficient is the styling that you use?}]
-Probably the most easily overseen optimization is in switching fonts and color.
-Although in \CONTEXT\ font switching is fast, I have no clue about it in other
-macro packages. But in a style you can decide to use inefficient (massive) font
+Probably the most easily overlooked optimization is in switching fonts and colors.
+Although in \CONTEXT, font switching is fast, I have no clue about it in other
+macro packages. But in a style, you can decide to use inefficient (massive) font
switches. The effects can easily be tested by commenting bit and pieces. For
-instance sometimes you need to do a full bodyfont switch when changing a style,
+instance, sometimes you need to do a full bodyfont switch when changing a style,
like assigning \type {\small\bf} to the \type {style} key in \type {\setuphead},
but often using e.g.\ \type {\tfd} is much more efficient and works quite as
well. Just try it.
@@ -481,24 +483,24 @@ well. Just try it.
\startsubsubject[title={Are fonts really the bottleneck?}]
-We already mentioned that one can look in the wrong direction. Maybe once someone
+We already mentioned that one can look in the wrong direction. Maybe, once someone
is convinced that fonts are the culprit, it gets hard to look at the real issue.
-If a similar job in different macro packages has a significant different runtime
+If a similar job in different macro packages has a significantly different runtime,
one can wonder what happens indeed.
It is good to keep in mind that the amount of text is often not as large as you
-think. It's easy to do a test with hundreds of paragraphs of text but in practice
+think. It's easy to do a test with hundreds of paragraphs of text, but, in practice,
we have whitespace, section titles, half empty pages, floats, itemize and similar
-constructs, etc. Often we don't mix many fonts in the running text either. So, in
-the end a real document is the best test.
+constructs, etc. Often, we don't mix many fonts in the running text either. So,
+in the end, a real document is your best test.
\stopsubsubject
\startsubsubject[title={If you use \LUA, is that code any good?}]
You can gain from the faster virtual machine of \LUAJITTEX. Don't expect wonders
-from the jitting as that only pays of for long runs with the same code used over
-and over again. If the gain is high you can even wonder how well written your
+from the jitting as that only pays off in long runs with the same code used over
+and over again. If the gain is high, you can even wonder how well-written your
\LUA\ code is anyway.
\stopsubsubject
@@ -506,18 +508,18 @@ and over again. If the gain is high you can even wonder how well written your
\startsubsubject[title={What if they don't believe you?}]
So, say that someone finds \LUATEX\ slow, what can be done about it? Just advice
-him or her to stick to tool used previously. Then, if arguments come that one
+them to stick to their previously|-|used tool. Then, if arguments come that one
also wants to use \UTF-8, \OPENTYPE\ fonts, a bit of \METAPOST, and is looking
forward to using \LUA\ runtime, the only answer is: take it or leave it. You pay
-a price for progress, but if you do your job well, the price is not that large.
-Tell them to spend time on learning and maybe adapting and bark against their own
+a price for progress, but, if you do your job well, the price is not that high.
+Tell them to spend time on learning and maybe adapting and to bark against their own
tree before barking against those who took that step a decade ago. Most \CONTEXT\
users took that step and someone still using \LUATEX\ after a decade can't be
that stupid. It's always best to first wonder what one actually asks from \LUATEX,
and if the benefit of having \LUA\ on board has an advantage. If not, one can
just use another engine.
-Also think of this. When a job is slow, for me it's no problem to identify where
+Also think of this: when a job is slow, for me it's no problem to identify where
the problem is. The question then is: can something be done about it? Well, I
happily keep the answer for myself. After all, some people always need room to
complain, maybe if only to hide their ignorance or incompetence. Who knows.
@@ -529,13 +531,13 @@ complain, maybe if only to hide their ignorance or incompetence. Who knows.
\startsection[title={Comparing engines}]
The next comparison is to be taken with a grain of salt and concerns the state of
-affairs mid 2017. First of all, you cannot really compare \MKII\ with \MKIV: the
-later has more functionality (or a more advanced implementation of
-functionality). And as mentioned you can also not really compare \PDFTEX\ and the
-wide engines. Anyway, here are some (useless) tests. First a bunch of loads. Keep
+affairs mid-2017. First of all, you cannot really compare \MKII\ with \MKIV: the
+latter has more functionality (or a more advanced implementation of
+functionality). And, as mentioned, you can also not really compare \PDFTEX\ and the
+wide engines. Anyway, here are some (useless) tests. First, a bunch of loads. Keep
in mind that different engines also deal differently with reading files. For
-instance \MKIV\ uses \LUATEX\ callbacks to normalize the input and has its own
-readers. There is a bit more overhead in starting up a \LUATEX\ run and some
+instance, \MKIV\ uses \LUATEX\ callbacks to normalize the input and has its own
+readers. There is a bit more overhead in starting up a \LUATEX\ run, and some
functionality is enabled that is not present in \MKII. The format is also larger,
if only because we preload a lot of useful font, character and script related
data.
@@ -549,7 +551,7 @@ data.
\stoptext
\stoptyping
-When looking at the numbers one should realize that the times include startup and
+When looking at the numbers, one should realize that the times include startup and
job management by the runner scripts. We also run in batchmode to avoid logging
to influence runtime. The average is calculated from 5 runs.
@@ -593,8 +595,7 @@ The second example does a few switches in a paragraph:
\HL
\stoptabulate
-The third examples does a few more, resulting in multiple subranges
-per style:
+The third example does more, resulting in multiple subranges per style:
\starttyping
\starttext
@@ -623,7 +624,7 @@ per style:
The last example adds some color. Enabling more functionality can have an impact
on performance. In fact, as \MKIV\ uses a lot of \LUA\ and is also more advanced
-that \MKII, one can expect a performance hit but in practice the opposite
+that \MKII, one can expect a performance hit, but, in practice, the opposite
happens, which can also be due to some fundamental differences deep down at the
macro level.
@@ -654,20 +655,20 @@ macro level.
\HL
\stoptabulate
-In these measurements the accuracy is a few decimals but a pattern is visible. As
-expected \PDFTEX\ wins on simple documents but starts loosing when things get
-more complex. For these tests I used 64 bit binaries. A 32 bit \XETEX\ with
-\MKII\ performs the same as \LUAJITTEX\ with \MKIV, but a 64 bit \XETEX\ is
-actually quite a bit slower. In that case the mingw cross compiled \LUATEX\
-version does pretty well. A 64 bit \PDFTEX\ is also slower (it looks) that a 32
-bit version. So in the end, there are more factors that play a role. Choosing
-between \LUATEX\ and \LUAJITTEX\ depends on how well the memory limited
+In these measurements, the accuracy is a few decimals, but a pattern is visible.
+As expected, \PDFTEX\ wins on simple documents but starts losing when things get
+more complex. For these tests, I used 64 bit binaries. A 32-bit \XETEX\ with
+\MKII\ performs the same as \LUAJITTEX\ with \MKIV, but a 64-bit \XETEX\ is
+actually quite a bit slower. In that case, the mingw cross|-|compiled \LUATEX\
+version does pretty well. A 64-bit \PDFTEX\ is also slower (it looks) than a
+32-bit version. So, in the end, there are more factors that play a role. Choosing
+between \LUATEX\ and \LUAJITTEX\ depends on how well the memory|-|limited
\LUAJITTEX\ variant can handle your documents and fonts.
Because in most of our recent styles we use \OPENTYPE\ fonts and (structural)
-features as well as recent \METAFUN\ extensions only present in \MKIV\ we cannot
+features as well as recent \METAFUN\ extensions only present in \MKIV, we cannot
compare engines using such documents. The mentioned performance of \LUATEX\ (or
-\LUAJITTEX) and \MKIV\ on the \METAFUN\ manual illustrate that in most cases this
+\LUAJITTEX) and \MKIV\ on the \METAFUN\ manual illustrate that, in most cases, this
combination is a clear winner.
\starttyping
@@ -703,8 +704,8 @@ That leaves the zero run:
\stoptext
\stoptyping
-This gives the following numbers. In longer runs the difference in overhead is
-neglectable.
+This gives the following numbers. In longer runs, the difference in overhead is
+negligible.
% sample 6, number of runs: 5
@@ -719,31 +720,31 @@ neglectable.
\HL
\stoptabulate
-It will be clear that when we use different fonts the numbers will also be
-different. And if you use a lot of runtime \METAPOST\ graphics (for instance for
-backgrounds), the \MKIV\ runs end up at the top. And when we process \XML\ it
+It will be clear that when we use different fonts, the numbers will also be
+different. And, if you use a lot of runtime \METAPOST\ graphics (for instance for
+backgrounds), the \MKIV\ runs end up at the top. And, when we process \XML, it
will be clear that going back to \MKII\ is no longer a realistic option. It must
-be noted that I occasionally manage to improve performance but we've now reached
+be noted that I occasionally manage to improve performance, but we've now reached
a state where there is not that much to gain. Some functionality is hard to
-compare. For instance in \CONTEXT\ we don't use much of the \PDF\ backend
-features because we implement them all in \LUA. In fact, even in \MKII\ already a
-done in \TEX, so in the end the speed difference there is not large and often in
+compare. For instance, in \CONTEXT, we don't use much of the \PDF\ backend
+features because we implement them all in \LUA. In fact, even in \MKII, already
+done in \TEX, so in the end, the speed difference there is not large and often in
favour of \MKIV.
-For the record I mention that shipping out the about 1250 pages has some overhead
-too: about 2 seconds. Here \LUAJITTEX\ is 20\% more efficient which is an
+For the record, I mention that shipping out the about 1250 pages has some overhead
+too: about 2 seconds. Here, \LUAJITTEX\ is 20\% more efficient, which is an
indication of quite some \LUA\ involvement. Loading the input files has an
-overhead of about half a second. Starting up \LUATEX\ takes more time that
+overhead of about half a second. Starting up \LUATEX\ takes more time than
\PDFTEX\ and \XETEX, but that disadvantage disappears with more pages. So, in the
-end there are quite some factors that blur the measurements. In practice what
-matters is convenience: does the runtime feel reasonable and in most cases it
+end, there are quite some factors that blur the measurements. In practice, what
+matters is convenience: does the runtime feel reasonable and, in most cases, it
does.
-If I would replace my laptop with a reasonable comparable alternative that one
+If I would replace my laptop with a reasonable comparable alternative, that one
would be some 35\% faster (single threads on processors don't gain much per year).
-I guess that this is about the same increase in performance that \CONTEXT\
-\MKIV\ got in that period. I don't expect such a gain in the coming years so
-at some point we're stuck with what we have.
+I guess that this is about the same increase in performance than \CONTEXT\
+\MKIV\ got in that period. I don't expect such a gain in the upcoming years, so,
+at some point, we're stuck with what we have.
\stopsection
@@ -754,29 +755,29 @@ go back in time to when the first wide engines showed up, \OMEGA\ was considered
to be slow, although I never tested that myself. Then, when \XETEX\ showed up,
there was not much talk about speed, just about the fact that we could use
\OPENTYPE\ fonts and native \UTF\ input. If you look at the numbers, for sure you
-can say that it was much slower than \PDFTEX. So how come that some people
+can say that it was much slower than \PDFTEX. So, how come that some people
complain about \LUATEX\ being so slow, especially when we take into account that
-it's not that much slower than \XETEX, and that \LUAJITTEX\ is often faster that
-\XETEX. Also, computers have become faster. With the wide engines you get more
+it's not that much slower than \XETEX, and that \LUAJITTEX\ is often faster than
+\XETEX. Also, computers have become faster. With the wide engines, you get more
functionality and that comes at a price. This was accepted for \XETEX\ and is
also acceptable for \LUATEX. But the price is nto that high if you take into
account that hardware performs better: you just need to compare \LUATEX\ (and
\XETEX) runtime with \PDFTEX\ runtime 15 years ago.
As a comparison, look at games and video. Resolution became much higher as did
-color depth. Higher frame rates were in demand. Therefore the hardware had to
-become faster and it did, and as a result the user experience kept up. No user
+color depth. Higher frame rates were in demand. Therefore, the hardware had to
+become faster, and it did, and, as a result, the user experience kept up. No user
will say that a modern game is slower than an old one, because the old one does
500 frames per second compared to some 50 for the new game on the modern
hardware. In a similar fashion, the demands for typesetting became higher:
\UNICODE, \OPENTYPE, graphics, \XML, advanced \PDF, more complex (niche)
typesetting, etc. This happened more or less in parallel with computers becoming
more powerful. So, as with games, the user experience didn't degrade with
-demands. Comparing \LUATEX\ with \PDFTEX\ is like comparing a low res, low frame
-rate, low color game with a modern one. You need to have up to date hardware and
-even then, the writer of such programs need to make sure it runs efficient,
-simply because hardware no longer scales like it did decades ago. You need to
-look at the larger picture.
+demands. Comparing \LUATEX\ with \PDFTEX\ is like comparing a low|-|res,
+low|-|framerate, low|-|color game with a modern one. You need to have
+up|-|to|-|date hardware and even then, the writer of such programs needs to make
+sure that they run efficiently, simply because hardware no longer scales like it
+did decades ago. You need to look at the bigger picture.
\stopsection
diff --git a/doc/context/sources/general/manuals/onandon/onandon-runtoks.tex b/doc/context/sources/general/manuals/onandon/onandon-runtoks.tex
new file mode 100644
index 000000000..b3adeb4a5
--- /dev/null
+++ b/doc/context/sources/general/manuals/onandon/onandon-runtoks.tex
@@ -0,0 +1,531 @@
+% language=uk
+
+\startcomponent onandon-amputating
+
+\environment onandon-environment
+
+\startchapter[title={Amputating code}]
+
+\startsection[title={Introduction}]
+
+Because \CONTEXT\ is already rather old in terms of software life and because it
+evolves over time, code can get replaced by better code. Reasons for this can be:
+
+\startitemize[packed]
+\startitem a better understanding of the way \TEX\ and \METAPOST\ work \stopitem
+\startitem demand for more advanced options \stopitem
+\startitem a brainwave resulting in a better solution \stopitem
+\startitem new functionality provided in \TEX\ engine used \stopitem
+\startitem the necessity to speed up a core process \stopitem
+\stopitemize
+
+Replacing code that in itself does a good job but is no longer the best to be
+used comes with sentiments. It can be rather satisfying to cook up a
+(conceptually as well as codewise) good solution and therefore removing code from
+a file can result in a somewhat bad feeling and even a feeling of losing
+something. Hence the title of this chapter.
+
+Here I will discuss one of the more complex subsystems: the one dealing with
+typeset text in \METAPOST\ graphics. I will stick to the principles and not
+present (much) code as that can be found in archives. This is not a tutorial,
+but more a sort of wrap|-|up for myself. It anyhow show the thinking behind
+this mechanism. I'll also introduce a new \LUATEX\ feature here: subruns.
+
+\stopsection
+
+\startsection[title={The problem}]
+
+\METAPOST\ is meant for drawing graphics and adding text to them is not really
+part of the concept. Its a bit like how \TEX\ sees images: the dimensions matter,
+the content doesn't. This means that in \METAPOST\ a blob of text is an
+abstraction. The native way to create a typeset text picture is:
+
+\starttyping
+picture p ; p := btex some text etex ;
+\stoptyping
+
+In traditional \METAPOST\ this will create a temporary \TEX\ file with the words
+\type {some text} wrapped in a box that when typeset is just shipped out. The
+result is a \DVI\ file that with an auxiliary program will be transformed into a
+\METAPOST\ picture. That picture itself is made from multiple pictures, because
+each sequences of characters becomes a picture and kerns become shifts.
+
+There is also a primitive \type {infont} that takes a text and just converts it
+into a low level text object but no typesetting is done there: so no ligatures
+and no kerns are found there. In \CONTEXT\ this operator is redefined to do the
+right thing.
+
+In both cases, what ends up in the \POSTSCRIPT\ file is references to fonts and
+characters and the original idea is that \DVIPS\ understands what
+fonts to embed. Details are communicated via specials (comments) that \DVIPS\ is
+supposed to intercept and understand. This all happens in an 8~bit (font) universe.
+
+When we moved on to \PDF, a converter from \METAPOST's rather predictable and
+simple \POSTSCRIPT\ code to \PDF\ was written in \TEX. The graphic operators
+became \PDF\ operators and the text was retypeset using the font information and
+snippets of strings and injected at the right spot. The only complication was
+that a non circular pen actually produced two path of which one has to be
+transformed.
+
+At that moment it already had become clear that a more tight integration in
+\CONTEXT\ would happen and not only would that demand a more sophisticated
+handling of text, but it would also require more features not present in
+\METAPOST, like dealing with \CMYK\ colors, special color spaces, transparency,
+images, shading, and more. All this was implemented. In the next sections we will
+only discuss texts.
+
+\stopsection
+
+\startsection[title={Using the traditional method}]
+
+The \type {btex} approach was not that flexible because what happens is that
+\type {btex} triggers the parser to just grabbing everything upto the \type
+{etex} and pass that to an external program. It's special scanner mode and
+because because of that using macros for typesetting texts is a pain. So, instead
+of using this method in \CONTEXT\ we used \type {textext}. Before a run the
+\METAPOST\ file was scanned and for each \type {textext} the argument was copied
+to a file. The \type {btex} calls were scanned to and replaced by \type {textext}
+calls.
+
+For each processed snippet the dimensions were stored in order to be loaded at
+the start of the \METAPOST\ run. In fact, each text was just a rectangle with
+certain dimensions. The \PDF\ converter would use the real snippet (by
+typesetting it).
+
+Of course there had to be some housekeeping in order to make sure that the right
+snippets were used, because the order of definition (as picture) can be different
+from them being used. This mechanism evolved into reasonable robust text handling
+but of course was limited by the fact that the file was scanned for snippets. So,
+the string had to be string and not assembled one. This disadvantage was
+compensated by the fact that we could communicate relevant bits of the
+environment and apply all the usual context trickery in texts in a way that was
+consistent with the rest of the document.
+
+A later implementation could communicate the text via specials which is more
+flexible. Although we talk of this method in the past sense it is still used in
+\MKII.
+
+\stopsection
+
+\startsection[title={Using the library}]
+
+When the \MPLIB\ library showed up in \LUATEX, the same approach was used but
+soon we moved on to a different approach. We already used specials to communicate
+extensions to the backend, using special colors and fake objects as signals. But
+at that time paths got pre- and postscripts fields and those could be used to
+really carry information with objects because unlike specials, they were bound to
+that object. So, all extensions using specials as well as texts were rewritten to
+use these scripts.
+
+The \type {textext} macro changed its behaviour a bit too. Remember that a
+text effectively was just a rectangle with some transformation applied. However
+this time the postscript field carried the text and the prescript field some
+specifics, like the fact that that we are dealing with text. Using the script made
+it possible to carry some more inforation around, like special color demands.
+
+\starttyping
+draw textext("foo") ;
+\stoptyping
+
+Among the prescripts are \typ {tx_index=trial} and \typ {tx_state=trial}
+(multiple prescripts are prepended) and the postscript is \type {foo}. In a
+second run the prescript is \type {tx_index=trial} and \typ {tx_state=final}.
+After the first run we analyze all objects, collect the texts (those with a \type
+{tx_} variables set) and typeset them. As part of the second run we pass the
+dimensions of each indexed text snippet. Internally before the first run we
+\quote {reset} states, then after the first run we \quote {analyze}, and after
+the second run we \quote {process} as part of the conversion of output to \PDF.
+
+\stopsection
+
+\startsection[title={Using \type {runscript}}]
+
+When the \type {runscript} feature was introduced in the library we no longer
+needed to pass the dimensions via subscripted variables. Instead we could just
+run a \LUA\ snippets and ask for the dimensions of a text with some index. This
+is conceptually not much different but it saves us creating \METAPOST\ code that
+stored the dimensions, at the cost of potentially a bit more runtime due to the
+\type {runscript} calls. But the code definitely looks a bit cleaner this way. Of
+course we had to keep the dimensions at the \LUA\ end but we already did that
+because we stored the preprocessed snippets for final usage.
+
+\stopsection
+
+\startsection[title={Using a sub \TEX\ run}]
+
+We now come the current (post \LUATEX\ 1.08) solution. For reasons I will
+mention later a two pass approach is not optimal, but we can live with that,
+especially because \CONTEXT\ with \METAFUN\ (which is what we're talking about
+here) is quit efficient. More important is that it's kind of ugly to do all the
+not that special work twice. In addition to text we also have outlines, graphics
+and more mechanisms that needed two passes and all these became one pass
+features.
+
+A \TEX\ run is special in many ways. At some point after starting up \TEX\
+enters the main loop and begins reading text and expanding macros. Normally you
+start with a file but soon a macro is seen, and a next level of input is entered,
+because as part of the expansion more text can be met, files can be opened,
+other macros be expanded. When a macro expands a token register, another level is
+entered and the same happens when a \LUA\ call is triggered. Such a call can
+print back something to \TEX\ and that has to be scanned as if it came from a
+file.
+
+When token lists (and macros) get expanded, some commands result in direct
+actions, others result in expansion only and processing later as one of more
+tokens can end up in the input stack. The internals of the engine operate in
+miraculous ways. All commands trigger a function call, but some have their own
+while others share one with a switch statement (in \CCODE\ speak) because they
+belong to a category of similar actions. Some are expanded directly, some get
+delayed.
+
+Does it sound complicated? Well, it is. It's even more so when you consider that
+\TEX\ uses nesting, which means pushing and popping local assignments, knows
+modes, like horizontal, vertical and math mode, keeps track of interrupts and at
+the same type triggers typesetting, par building, page construction and flushing
+to the output file.
+
+It is for this reason plus the fact that users can and will do a lot to influence
+that behaviour that there is just one main loop and in many aspects global state.
+There are some exceptions, for instance when the output routine is called, which
+creates a sort of closure: it interrupts the process and for that reason gets
+grouping enforced so that it doesn't influence the main run. But even then the
+main loop does the job.
+
+Starting with version 1.10 \LUATEX\ provides a way to do a local run. There are
+two ways provided: expanding a token register and calling a \LUA\ function. It
+took a bit of experimenting to reach an implementation that works out reasonable
+and many variants were tried. In the appendix we give an example of usage.
+
+The current variant is reasonable robust and does the job but care is needed.
+First of all, as soon as you start piping something to \TEX\ that gets typeset
+you'd better in a valid mode. If not, then for instance glyphs can end up in a
+vertical list and \LUATEX\ will abort. In case you wonder why we don't intercept
+this: we can't because we don't know the users intentions. We cannot enforce a
+mode for instance as this can have side effects, think of expanding \type
+{\everypar} or injecting an indentation box. Also, as soon as you start juggling
+nodes there is no way that \TEX\ can foresee what needs to be copied to
+discarded. Normally it works out okay but because in \LUATEX\ you can cheat in
+numerous ways with \LUA, you can get into trouble.
+
+So, what has this to do with \METAPOST ? Well, first of all we could now use a
+one pass approach. The \type {textext} macro calls \LUA, which then let \TEX\ do
+some typesetting, and then gives back the dimensions to \METAPOST. The \quote
+{analyze} phase is now integrated in the run. For a regular text this works quite
+well because we just box some text and that's it. However, in the next section we
+will see where things get complicated.
+
+Let's summarize the one pass approach: the \type {textext} macro creates
+rectangle with the right dimensions and for doing passes the string to \LUA\
+using \type {runscript}. We store the argument of \type {textext} in a variable,
+then call \type {runtoks}, which expands the given token list, where we typeset a
+box with the stored text (that we fetch with a \LUA\ call), and the \type
+{runscript} passes back the three dimensions as fake \RGB\ color to \METAPOST\
+which applies a \type {scantokens} to the result. So, in principle there is no
+real conceptual difference except that we now analyze in|-|place instead of
+between runs. I will not show the code here because in \CONTEXT\ we use a wrapper
+around \type {runscript} so low level examples won't run well.
+
+\stopsection
+
+\startsection[title={Some aspects}]
+
+An important aspect of the text handling is that the whole text can be
+transformed. Normally this is only some scaling but rotation is also quite valid.
+In the first approach, the original \METAPOST\ one, we have pictures constructed
+of snippets and pictures transform well as long as the backend is not too
+confused, something that can happen when for instance very small or large font
+scales are used. There were some limitations with respect to the number of fonts
+and efficient inclusion when for instance randomization was used (I remember
+cases with thousands of font instances). The \PDF\ backend could handle most
+cases well, by just using one size and scaling at the \PDF\ level. All the \type
+{textext} approaches use rectangles as stubs which is very efficient and permits
+all transforms.
+
+How about color? Think of this situation:
+
+\starttyping
+\startMPcode
+ draw textext("some \color[red]{text}")
+ withcolor green ;
+\stopMPcode
+\stoptyping
+
+And what about the document color? We suffice by saying that this is all well
+supported. Of course using transparency, spot colors etc.\ also needs extensions.
+These are however not directly related to texts although we need to take it into
+account when dealing with the inclusion.
+
+\starttyping
+\startMPcode
+ draw textext("some \color[red]{text}")
+ withcolor "blue"
+ withtransparency (1,0.5) ;
+\stopMPcode
+\stoptyping
+
+What if you have a graphic with many small snippets of which many have the same
+content? These are by default shared, but if needed you can disable it. This makes
+sense if you have a case like this:
+
+\starttyping
+\useMPlibrary[dum]
+
+\startMPcode
+ draw textext("\externalfigure[unknown]") notcached ;
+ draw textext("\externalfigure[unknown]") notcached ;
+\stopMPcode
+\stoptyping
+
+Normally each unknown image gets a nice placeholder with some random properties.
+So, do we want these two to have the same or not? At least you can control it.
+
+When I said that things can get complicated with the one pass approach the
+previous code snippet is a good example. The dummy figure is generated by
+\METAPOST. So, as we have one pass, and jump temporarily back to \TEX,
+we have two problems: we reenter the \MPLIB\ instance again in the middle of
+a run, and we might pipe back something to and|/|or from \TEX\ nested.
+
+The first problem could be solved by starting a new \MPLIB\ session. This
+normally is not a problem as both runs are independent of each other. In
+\CONTEXT\ we can have \METAPOST\ runs in many places and some produce some more
+of less stand alone graphic in the text while other calls produce \PDF\ code in
+the backend that is used in a different way (for instance in a font). In the
+first case the result gets nicely wrapped in a box, while in the second case it
+might directly end up in the page stream. And, as \TEX\ has no knowledge of what
+is needed, it's here that we can get the complications that can lead to aborting
+a run when you are careless. But in any case, if you abort, then you can be sure
+you're doing the wrong thing. So, the second problem can only be solved by
+careful programming.
+
+When I ran the test suite on the new code, some older modules had to be fixed.
+They were doing the right thing from the perspective of intermediate runs and
+therefore independent box handling, putting a text in a box and collecting
+dimensions, but interwoven they demanded a bit more defensive programming. For
+instance, the multi|-|pass approach always made copies snippets while the one
+pass approach does that only when needed. And that confused some old code in a
+module, which incidentally is never used today because we have better
+functionality built|-|in (the \METAFUN\ \type {followtext} mechanism).
+
+The two pass approach has special code for cases where a text is not used.
+Imagine this:
+
+\starttyping
+picture p ; p := textext("foo") ;
+
+draw boundingbox p;
+\stoptyping
+
+Here the \quote {analyze} stage will never see the text because we don't flush p.
+However because \type {textext} is called it can also make sure we still know the
+dimensions. In the next case we do use the text but in two different ways. These
+subtle aspects are dealt with properly and could be made a it simpler in the
+single pass approach.
+
+\starttyping
+picture p ; p := textext("foo") ;
+
+draw p rotated 90 withcolor red ;
+draw p withcolor green ;
+\stoptyping
+
+\stopsection
+
+\startsection[title=One or two runs]
+
+So are we better off now? One problem with two passes is that if you use the
+equation solver you need to make sure that you don't run into the redundant
+equation issue. So, you need to manage your variables well. In fact you need to
+do that anyway because you can call out to \METAPOST\ many times in a run so old
+variables can interfere anyway. So yes, we're better off here.
+
+Are we worse off now? The two runs with in between the text processing is very
+robust. There is no interference of nested runs and no interference of nested
+local \TEX\ calls. So, maybe we're also bit worse off. You need to anyhow keep
+this in mind when you write your own low level \TEX|-|\METAPOST\ interaction
+trickery, but fortunately now many users do that. And if you did write your own
+plugins, you now need to make them single pass.
+
+The new code is conceptually cleaner but also still not trivial because due to
+the mentioned complications. It's definitely less code but somehow amputating the
+old code does hurt a bit. Maybe I should keep it around as reference of how text
+handling evolved over a few decades.
+
+\stopsection
+
+\startsection[title=Appendix]
+
+Because the single pass approach made me finally look into a (although somewhat
+limited) local \TEX\ run, I will show a simple example. For the sake of
+generality I will use \type {\directlua}. Say that you need the dimensions of a
+box while in \LUA:
+
+\startbuffer
+\directlua {
+ tex.sprint("result 1: <")
+
+ tex.sprint("\\setbox0\\hbox{one}")
+ tex.sprint("\\number\\wd0")
+
+ tex.sprint("\\setbox0\\hbox{\\directlua{tex.print{'first'}}}")
+ tex.sprint(",")
+ tex.sprint("\\number\\wd0")
+
+ tex.sprint(">")
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This looks ok, but only because all printed text is collected and pushed into a
+new input level once the \LUA\ call is done. So take this then:
+
+\startbuffer
+\directlua {
+ tex.sprint("result 2: <")
+
+ tex.sprint("\\setbox0\\hbox{one}")
+ tex.sprint(tex.getbox(0).width)
+
+ tex.sprint("\\setbox0\\hbox{\\directlua{tex.print{'first'}}}")
+ tex.sprint(",")
+ tex.sprint(tex.getbox(0).width)
+
+ tex.sprint(">")
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This time we get the widths of the box known at the moment that we are in \LUA,
+but we haven't typeset the content yet, so we get the wrong dimensions. This
+however will work okay:
+
+\startbuffer
+\toks0{\setbox0\hbox{one}}
+\toks2{\setbox0\hbox{first}}
+\directlua {
+ tex.forcehmode(true)
+
+ tex.sprint("<")
+
+ tex.runtoks(0)
+ tex.sprint(tex.getbox(0).width)
+
+ tex.runtoks(2)
+ tex.sprint(",")
+ tex.sprint(tex.getbox(0).width)
+
+ tex.sprint(">")
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+as does this:
+
+\startbuffer
+\toks0{\setbox0\hbox{\directlua{tex.sprint(MyGlobalText)}}}
+\directlua {
+ tex.forcehmode(true)
+
+ tex.sprint("result 3: <")
+
+ MyGlobalText = "one"
+ tex.runtoks(0)
+ tex.sprint(tex.getbox(0).width)
+
+ MyGlobalText = "first"
+ tex.runtoks(0)
+ tex.sprint(",")
+ tex.sprint(tex.getbox(0).width)
+
+ tex.sprint(">")
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+Here is a variant that uses functions:
+
+\startbuffer
+\directlua {
+ tex.forcehmode(true)
+
+ tex.sprint("result 4: <")
+
+ tex.runtoks(function()
+ tex.sprint("\\setbox0\\hbox{one}")
+ end)
+ tex.sprint(tex.getbox(0).width)
+
+ tex.runtoks(function()
+ tex.sprint("\\setbox0\\hbox{\\directlua{tex.print{'first'}}}")
+ end)
+ tex.sprint(",")
+ tex.sprint(tex.getbox(0).width)
+
+ tex.sprint(">")
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {forcemode} is needed when you do this in vertical mode. Otherwise the
+run aborts. Of course you can also force horizontal mode before the call. I'm
+sure that users will be surprised by side effects when they really use this
+feature but that is to be expected: you really need to be aware of the subtle
+interference of input levels and mix of input media (files, token lists, macros
+or \LUA) as well as the fact that \TEX\ often looks one token ahead, and often,
+when forced to typeset something, also can trigger builders. You're warned.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
+
+% \starttext
+
+% \toks0{\hbox{test}} [\ctxlua{tex.runtoks(0)}]\par
+
+% \toks0{\relax\relax\hbox{test}\relax\relax}[\ctxlua{tex.runtoks(0)}]\par
+
+% \toks0{xxxxxxx} [\ctxlua{tex.runtoks(0)}]\par
+
+% \toks0{\hbox{(\ctxlua{context("test")})}} [\ctxlua{tex.runtoks(0)}]\par
+
+% \toks0{\global\setbox1\hbox{(\ctxlua{context("test")})}} [\ctxlua{tex.runtoks(0)}\box1]\par
+
+% \startluacode
+% local s = "[\\ctxlua{tex.runtoks(0)}\\box1]"
+% context("<")
+% context( function() context(s) end)
+% context( function() context(s) end)
+% context(">")
+% \stopluacode\par
+
+% \toks10000{\hbox{\red test1}}
+% \toks10002{\green\hbox{test2}}
+% \toks10004{\hbox{\global\setbox1\hbox to 1000sp{\directlua{context("!4!")}}}}
+% \toks10006{\hbox{\global\setbox3\hbox to 2000sp{\directlua{context("?6?")}}}}
+% \hbox{x\startluacode
+% local s0 = "(\\hbox{\\ctxlua{tex.runtoks(10000)}})"
+% local s2 = "[\\hbox{\\ctxlua{tex.runtoks(10002)}}]"
+% context("<!")
+% -- context( function() context(s0) end)
+% -- context( function() context(s0) end)
+% -- context( function() context(s2) end)
+% context(s0)
+% context(s0)
+% context(s2)
+% context("<")
+% tex.runtoks(10004)
+% context("X")
+% tex.runtoks(10006)
+% context(tex.box[1].width)
+% context("/")
+% context(tex.box[3].width)
+% context("!>")
+% \stopluacode x}\par
+
+
diff --git a/doc/context/sources/general/manuals/onandon/onandon-variable.tex b/doc/context/sources/general/manuals/onandon/onandon-variable.tex
index c73196cef..c308864e6 100644
--- a/doc/context/sources/general/manuals/onandon/onandon-variable.tex
+++ b/doc/context/sources/general/manuals/onandon/onandon-variable.tex
@@ -12,7 +12,7 @@
\startsubject[title=Introduction]
-History shows the tendency to recycle ideas. Often quite some effort is made by
+History shows the tendency to recycle ideas. Often, quite some effort is made by
historians to figure out what really happened, not just long ago, when nothing
was written down and we have to do with stories or pictures at most, but also in
recent times. Descriptions can be conflicting, puzzling, incomplete, partially
@@ -20,64 +20,64 @@ lost, biased, \unknown
Just as language was invented (or evolved) several times, so were scripts. The
same might be true for rendering scripts on a medium. Semaphores came and went
-within decades and how many people know now that they existed and that encryption
+within decades, and how many people know now that they existed and that encryption
was involved? Are the old printing presses truly the old ones, or are older
examples simply gone? One of the nice aspects of the internet is that one can now
-more easily discover similar solutions for the same problem, but with a different
+more easily discover similar solutions to the same problem but with a different
(and independent) origin.
-So, how about this \quotation {new big thing} in font technology: variable fonts.
-In this case, history shows that it's not that new. For most \TEX\ users the
-names \METAFONT\ and \METAPOST\ will ring bells. They have a very well documented
-history so there is not much left to speculation. There are articles, books,
+So, how about this \quotation {next big thing} in font technology: variable fonts?
+In this case, history shows that it's not that new. For most \TEX\ users, the
+names \METAFONT\ and \METAPOST\ will ring bells. They have a very well-documented
+history, so there is not much left to speculation. There are articles, books,
pictures, examples, sources, and more around for decades. So, the ability to
change the appearance of a glyph in a font depending on some parameters is not
new. What probably {\em is} new is that creating variable fonts is done in the
-natural environment where fonts are designed: an interactive program. The
-\METAFONT\ toolkit demands quite some insight in programming shapes in such a way
+natural environment, where fonts are designed: an interactive program. The
+\METAFONT\ toolkit demands quite some insight into programming shapes in such a way
that one can change look and feel depending on parameters. There are not that
-many meta fonts made and one reason is that making them requires a certain mind-
-and skill set. On the other hand, faster computers, interactive programs,
-evolving web technologies, where rea|l|-time rendering and therefore more or less
+many metafonts made, and one reason is that making them requires a certain mind-
+and skillset. On the other hand, faster computers, interactive programs,
+evolving web technologies, where real-time rendering and therefore more or less
real-time tweaking of fonts is a realistic option, all play a role in acceptance.
-But do interactive font design programs make this easier? You still need to be
-able to translate ideas into usable beautiful fonts. Taking the common shapes of
-glyphs, defining extremes and letting a program calculate some interpolations
-will not always bring good results. It's like morphing a picture of your baby's
-face into yours of old age (or that of your grandparent): not all intermediate
-results will look great. It's good to notice that variable fonts are a revival of
-existing techniques and ideas used in, for instance, multiple master fonts. The
-details might matter even more as they can now be exaggerated when some
-transformation is applied.
-
-There is currently (March 2017) not much information about these fonts so what I
+But do interactive font design programs make this easier? You still need to
+translate ideas into usable beautiful fonts. Taking the common shapes of glyphs,
+defining extremes and letting a program calculate some interpolations will not
+always give good results. It's like morphing a picture of your baby's face into
+yours of old age or that of your grandparent: not all intermediate results will
+look great. It's good to notice that variable fonts are a revival of existing
+techniques and ideas used in, for instance, multiple master fonts. The details
+might matter even more as they can now be exaggerated when transformations are
+applied.
+
+There is currently (March 2017) not much information about these fonts, so what I
say next may be partially wrong or at least different from what is intended. The
-perspective will be one from a \TEX\ user and coder. Whatever you think of them,
-these fonts will be out there and for sure there will be nice examples
-circulating soon. And so, when I ran into a few experimental fonts, with
+perspective will be one of a \TEX\ user and coder. Whatever you think of them,
+these fonts will be out there, and, for sure, there will be nice examples
+circulating soon. And so, when I ran into a few experimental fonts with
\POSTSCRIPT\ and \TRUETYPE\ outlines, I decided to have a look at what is inside.
-After all, because it's visual, it's also fun to play with. Let's stress that at
-the moment of this writing I only have a few simple fonts available, fonts that
-are designed for testing and not usage. Some recommended tables were missing and
-no complex \OPENTYPE\ features are used in these fonts.
+After all, because it's visual, it's also fun to play with. Let's stress that, at
+the moment of this writing, I only have a few simple fonts available, fonts that
+are designed for testing and not for usage. Some recommended tables were missing
+and no complex \OPENTYPE\ features were used in these fonts.
\stopsubject
\startsubject[title=The specification]
I'm not that good at reading specifications, first of all because I quickly fall
-asleep with such documents, but most of all because I prefer reading other stuff
+asleep with such documents, but mostly because I prefer reading other stuff
(I do have lots of books waiting to be read). I'm also someone who has to play
with something in order to understand it: trial and error is my modus operandi.
-Eventually it's my intended usage that drives the interface and that is when
+Eventually, it's my intended usage that drives the interface and that is when
everything comes together.
Exploring this technology comes down to: locate a font, get the \OPENTYPE\ 1.8
specification from the \MICROSOFT\ website, and try to figure out what is in the
-font. When I had a rough idea the next step was to get to the shapes and see if I
-could manipulate them. Of course it helped that in \CONTEXT\ we already can load
-fonts and play with shapes (using \METAPOST). I didn't have to install and learn
+font. When I had a rough idea, the next step was to get to the shapes and see if
+I could manipulate them. Of course, it helped that we can already load fonts and
+play with shapes in \CONTEXT using \METAPOST. I didn't have to install and learn
other programs. Once I could render them, in this case by creating a virtual font
with inline \PDF\ literals, a next step was to apply variation. Then came the
first experiments with a possible user interface. Seeing more variation then
@@ -88,18 +88,18 @@ The main extension to the data packaged in a font file concerns the (to be
discussed) axis along which variable fonts operate and deltas to be applied to
coordinates. The \type {gdef} table has been extended and contains information
that is used in \type {gpos} features. There are new \type {hvar}, \type {vvar}
-and \type {mvar} tables that influence the horizontal, vertical and general font
+and \type {mvar} tables that influence the horizontal, vertical, and general font
dimensions. The \type {gvar} table is used for \TRUETYPE\ variants, while the
\type {cff2} table replaces the \type {cff} table for \OPENTYPE\ \POSTSCRIPT\
outlines. The \type {avar} and \type {stat} tables contain some
-meta|-|information about the axes of variations.
+metainformation about the axes of variations.
-It must be said that because this is new technology the information in the
+It must be said that, because this is a new technology, the information in the
standard is not always easy to understand. The fact that we have two rendering
techniques, \POSTSCRIPT\ \type {cff} and \TRUETYPE\ \type {ttf}, also means that
we have different information and perspectives. But this situation is not much
-different from \OPENTYPE\ standards a few years ago: it takes time but in the end
-I will get there. And, after all, users also complain about the lack of
+different from \OPENTYPE\ standards a few years ago: it takes time, but, in the
+end, I will get there. And, after all, users also complain about the lack of
documentation for \CONTEXT, so who am I to complain? In fact, it will be those
\CONTEXT\ users who will provide feedback and make the implementation better in
the~end.
@@ -110,41 +110,41 @@ the~end.
Before we discuss some details, it will be useful to summarize what the font
loader does when a user requests a font at a certain size and with specific
-features enabled. When a font is used the first time, its binary format is
-converted into a form that makes it suitable for use within \CONTEXT\ and
-therefore \LUATEX. This conversion involves collecting properties of the font as
-a whole (official names, general dimensions like x-height and em-width, etc.), of
+features enabled. When a font is used for the first time, its binary format is
+converted into a form that makes it suitable for use in \CONTEXT\ and therefore
+in \LUATEX. This conversion involves collecting the properties of the font as a
+whole (official names, general dimensions like x-height and em-width, etc.), of
glyphs (dimensions, \UNICODE\ properties, optional math properties), and all
-kinds of information that relates to (contextual) replacements of glyphs (small
+kinds of information that relate to (contextual) replacements of glyphs (small
caps, oldstyle, scripts like Arabic) and positioning (kerning, anchoring marks,
-etc.). In the \CONTEXT\ font loader this conversion is done in \LUA.
+etc.). In the \CONTEXT\ font loader, this conversion is done in \LUA.
-The result is stored in a condensed format in a cache and the next time the font
-is needed it loads in an instant. In the cached version the dimensions are
-untouched, so a font at different sizes has just one copy in the cache. Often a
-font is needed at several sizes and for each size we create a copy with scaled
+The result is stored in a condensed format in a cache, and, the next time the font
+is needed, it loads in an instant. In the cached version, the dimensions are
+untouched, so a font at different sizes has just one copy in the cache. Often, a
+font is needed at several sizes, and for each size, we create a copy with scaled
glyph dimensions. The feature-related dimensions (kerning, anchoring, etc.)\ are
shared and scaled when needed. This happens when sequences of characters in the
node list get converted into sequences of glyphs. We could do the same with glyph
-dimensions but one reason for having a scaled copy is that this copy can also
-contain virtual glyphs and these have to be scaled beforehand. In practice there
+dimensions, but one reason for having a scaled copy is that this copy can also
+contain virtual glyphs, and these have to be scaled beforehand. In practice, there
are several layers of caching in order to keep the memory footprint within
-reasonable bounds. \footnote {In retrospect one can wonder if that makes sense;
+reasonable bounds. \footnote {In retrospect, one can wonder if that makes sense;
just look at how much memory a browser uses when it has been open for some time.
-In the beginning of \LUATEX\ users wondered about caching fonts, but again, just
+In the beginning of \LUATEX, users wondered about caching fonts, but again, just
look at what amounts browsers cache: it gets pretty close to the average amount
of writes that a \SSD\ can handle per day within its guarantee.}
When the font is actually used, interaction between characters is resolved using
-the feature|-|related information. When for instance two characters need to be
+the feature|-|related information. When, for instance, two characters need to be
kerned, a lookup results in the injection of a kern, scaled from general
dimensions to the current size of the font.
-When the outlines of glyphs are needed in \METAFUN\ the font is also converted
+When the outlines of glyphs are needed in \METAFUN, the font is also converted
from its binary form to something in \LUA, but this time we filter the shapes.
-For a \type {cff} this comes down to interpreting the \type {charstrings} and
-reducing the complexity to \type {moveto}, \type {lineto} and \type {curveto}
-operators. In the process subroutines are inlined. The result is something that
+For a \type {cff}, this comes down to interpreting the \type {charstrings} and
+reducing the complexity to \type {moveto}, \type {lineto}, and \type {curveto}
+operators. In the process, subroutines are inlined. The result is something that
\METAPOST\ is happy with but that also can be turned into a piece of a \PDF.
We now come to what a variable font actually is: a basic design which is
@@ -170,7 +170,7 @@ endfor ;
\stopMPcode
\stoplinecorrection
-Here we have a linear scaling but glyphs are not normally done that way. There
+Here we have linear scaling, but glyphs are not normally done that way. There
are font collections out there with lots of intermediate variants (say from light
to heavy) and it's more profitable to sell each variant independently. However,
there is often some logic behind it, probably supported by programs that
@@ -178,68 +178,69 @@ designers use, so why not build that logic into the font and have one file that
represents many intermediate forms. In fact, once we have multiple axes, even
when the designer has clear ideas of the intended usage, nothing will prevent
users from tinkering with the axis properties in ways that will fulfil their
-demands but hurt the designers eyes. We will not discuss that dilemma here.
+demands (and hurt the designer's eyes). I will not discuss that dilemma here.
When a variable font follows the route described above, we face a problem. When
-you load a \TRUETYPE\ font it will just work. The glyphs are packaged in the same
-format as static fonts. However, a variable font has axes and on each axis a
-value can be set. Each axis has a minimum, maximum and default. It can be that
-the default instance also assumes some transformations are applied. The standard
-recommends adding tables to describe these things but the fonts that I played
-with each lacked such tables. So that leaves some guesswork. But still, just
-loading a \TRUETYPE\ font gives some sort of outcome, although the dimensions
-(widths) might be weird due to lack of a (default) axis being applied.
+you load a \TRUETYPE\ font, it will just work. The glyphs are packaged in the
+same format as static fonts. However, a variable font has axes, and, on each
+axis, a value can be set. Each axis has a minimum, a maximum, and a default. It
+can be that the default instance also assumes some transformations are applied.
+The standard recommends adding tables to describe these things, but the fonts
+that I played with each lacked such tables. So that leaves some guesswork. But
+still, just loading a \TRUETYPE\ font gives some sort of outcome, although the
+dimensions (widths) might be weird due to the lack of a (default) axis being
+applied.
An \OPENTYPE\ font with \POSTSCRIPT\ outlines is different: the internal \type
-{cff} format has been upgraded to \type {cff2} which on the one hand is less
-complicated but on the other hand has a few new operators \emdash\ which results
-in programs that have not been adapted complaining or simply quitting on them.
+{cff} format has been upgraded to \type {cff2}, which on the one hand is less
+complicated, but on the other hand has a few new operators, which results
+in programs that have not been adapted complaining or simply crashing on them.
One could argue that a font is just a resource and that one only has to pass it
-along but that's not what works well in practice. Take \LUATEX. We can of course
-load the font and apply axis vales so that we can process the document as we
-normally do. But at some point we have to create a \PDF. We can simply embed the
-\TRUETYPE\ files but no axis values are applied. This is because, even if we add
-the relevant information, there is no way in current \PDF\ formats to deal with
-it. For that, we should be able to pass all relevant axis|-|related information
-as well as specify what values to use along these axes. And for \TRUETYPE\ fonts
-this information is not part of the shape description so then we in fact need to
-filter and pass more. An \OPENTYPE\ \POSTSCRIPT\ font is much cleaner because
-there we have the information needed to transform the shape mostly in the glyph
-description. There we only need to carry some extra information on how to apply
-these so|-|called blend values. The region|/|axis model used there only demands
-passing a relatively simple table (stripped down to what we need). But, as said
-above, \type {cff2} is not backward-compatible so a viewer will (currently)
-simply not show anything.
-
-Recalling how we load fonts, how does that translate with variable changes? If we
+along, but that's not what works well in practice. Take \LUATEX. We can, of
+course, load the font and apply axis vales, so that we can process the document
+as we normally do. But, at some point, we have to create a \PDF\ file. We can
+simply embed the \TRUETYPE\ files, but no axis values are applied. This is
+because, even if we add the relevant information, there is no way in the current
+\PDF\ formats to deal with it. For that, we should be able to pass all relevant
+axis|-|related information as well as specify what values to use along these
+axes. And, for \TRUETYPE\ fonts, this information is not part of the shape
+description so then we need to filter and pass more. An \OPENTYPE\ \POSTSCRIPT\
+font is much cleaner, because there we have the information needed to transform
+the shape mostly in the glyph description. There, we only need to carry some
+extra information on how to apply these so|-|called blend values. The
+region|/|axis model used there only demands passing a relatively simple table
+(stripped down to what we need). But, as said above, \type {cff2} is not
+backward-compatible, so a viewer will (currently) simply not show anything.
+
+Recalling how we load fonts, how does that change with variable changes? If we
have two characters with glyphs that get transformed and that have a kern between
them, the kern may or may not transform. So, when we choose values on an axis,
-then not only glyph properties change but also relations. We no longer can share
-positional information and scale afterwards because each instance can have
+then not only glyph properties change but also relations. We can no longer share
+positional information and scale afterwards, because each instance can have
different values to start with. We could carry all that information around and
-apply it at runtime but because we're typesetting documents with a static design
+apply it at runtime, but, because we're typesetting documents with a static design,
it's more convenient to just apply it once and create an instance. We can use the
-same caching as mentioned before but each chosen instance (provided by the font
+same caching as mentioned before, but each chosen instance (provided by the font
or made up by user specifications) is kept in the cache. As a consequence, using
a variable font has no overhead, apart from initial caching.
So, having dealt with that, how do we proceed? Processing a font is not different
from what we already had. However, I would not be surprised if users are not
-always satisfied with, for instance, kerning, because in such fonts a lot of care
-has to be given to this by the designer. Of course I can imagine that programs
+always satisfied with, for instance, kerning, because in such fonts, a lot of care
+has to be given to this by the designer. Of course, I can imagine that programs
used to create fonts deal with this, but even then, there is a visual aspect to
-it too. The good news is that in \CONTEXT\ we can manipulate features so in
-theory one can create a so|-|called font goodie file for a specific instance.
+it, too. The good news is that in \CONTEXT\ we can manipulate features, so, in
+theory, one can create a so|-|called font goodie file for a specific instance.
\stopsubject
\startsubject[title=Shapes]
-For \OPENTYPE\ \POSTSCRIPT\ shapes we always have to do a dummy rendering in
-order to get the right bounding box information. For \TRUETYPE\ this information
+For \OPENTYPE\ \POSTSCRIPT\ shapes, we always have to do a dummy rendering in
+order to get the right bounding box information. For \TRUETYPE, this information
is already present but not when we use a variable instance, so I had to do a bit
-of coding for that. Here we face a problem. For \TEX\ we need the width, height
+of coding for that. Here we face a problem. For \TEX, we need the width, height
and depth of a glyph. Consider the following case:
\startlinecorrection
@@ -259,16 +260,16 @@ draw boundingbox currentpicture
The shape has a bounding box that fits the shape. However, its left corner is not
at the origin. So, when we calculate a tight bounding box, we cannot use it for
actually positioning the glyph. We do use it (for horizontal scripts) to get the
-height and depth but for the width we depend on an explicit value. In \OPENTYPE\
-\POSTSCRIPT\ we have the width available and how the shape is positioned relative
-to the origin doesn't much matter. In a \TRUETYPE\ shape a bounding box is part
-of the specification, as is the width, but for a variable font one has to use
-so-called phantom points to recalculate the width and the test fonts I had were
+height and depth, but for the width, we depend on an explicit value. In \OPENTYPE\
+\POSTSCRIPT, we have the width available, and how the shape is positioned relative
+to the origin doesn't much matter. In a \TRUETYPE\ shape, a bounding box is part
+of the specification, as is the width, but for a variable font, one has to use
+so|-|called phantom points to recalculate the width, and the test fonts I had were
not suitable for investigating this.
At any rate, once I could generate documents with typeset text using variable
-fonts it became time to start thinking about a user interface. A variable font
-can have predefined instances but of course a user also wants to mess with axis
+fonts, it was time to start thinking about a user interface. A variable font
+can have predefined instances, but, of course, a user also wants to mess with axis
values. Take one of the test fonts: Adobe Variable Font Prototype. It has several
instances:
@@ -310,7 +311,7 @@ The Avenir Next variable demo font (currently) provides:
\SampleFont {avenirnextvariable} {heavy condensed} {heavycondensed}
\stoptabulate
-Before we continue I will show a few examples of variable shapes. Here we use some
+Before we continue, I will show a few examples of variable shapes. Here, we use some
\METAFUN\ magic. Just take these definitions for granted.
\startbuffer[a]
@@ -357,15 +358,15 @@ Before we continue I will show a few examples of variable shapes. Here we use so
\typebuffer[a,b,c,d]
The results are shown in \in {figure} [fig:whatever:1]. What we see here is that
-as long as we fill the shape everything will look as expected but using an
-outline only won't. The crucial (control) points are moved to different locations
-and as a result they can end up inside the shape. Giving up outlines is the price
-we evidently need to pay. Of course this is not unique for variable fonts
-although in practice static fonts behave better. To some extent we're back to
+as long as we fill the shape everything will look as expected, but only using an
+outline won't. The crucial (control) points are moved to different locations
+and, as a result, they can end up inside the shape. Giving up outlines is the price
+we evidently need to pay. Of course this is not unique for variable fonts,
+although, in practice, static fonts behave better. To some extent, we're back to
where we were with \METAFONT\ and (for instance) Computer Modern: because these
originate in bitmaps (and probably use similar design logic) we also can have
overlap and bits and pieces pasted together and no one will notice that. The
-first outline variants of Computer Modern also had such artifacts while in the
+first outline variants of Computer Modern also had such artifacts, while in the
static Latin Modern successors, outlines were cleaned up.
\startplacefigure[title=Four variants,reference=fig:whatever:1]
@@ -377,9 +378,10 @@ static Latin Modern successors, outlines were cleaned up.
\stopcombination
\stopplacefigure
-The fact that we need to preprocess an instance but only know how to do that when
-we have gotten the information about axis values from the font means that the
-font handler has to be adapted to keep caching correct. Another definition is:
+The fact that we need to preprocess an instance, but that we only know how to do
+that after we have retrieved information about axis values from the font means
+that the font handler has to be adapted to keep caching correct. Another
+definition is:
\starttyping
\definefontfeature
@@ -392,9 +394,9 @@ font handler has to be adapted to keep caching correct. Another definition is:
[name:adobevariablefontprototype*lightdefault]
\stoptyping
-Here the complication is that where normally features are dealt with after
+Here, the complication is that where normally features are dealt with after
loading, the axis feature is part of the preparation (and caching). If you want
-the virtual font solution you can do this:
+the virtual font solution, you can do this:
\starttyping
\definefontfeature
@@ -408,12 +410,12 @@ the virtual font solution you can do this:
[name:adobevariablefontprototype*inlinelightdefault]
\stoptyping
-When playing with these fonts it was hard to see if loading was done right. For
-instance not all values make sense. It is beyond the scope of this article, but
-axes like weight, width, contrast and italic values get applied differently to
-so|-|called regions (subspaces). So say that we have an $x$ coordinate with value
-$50$. This value can be adapted in, for instance, four subspaces (regions), so we
-actually get:
+When playing with these fonts, it was hard to see if loading was done right. For
+instance, not all values make sense. It is beyond the scope of this article, but
+axes like weight, width, contrast, and italic values get applied differently to
+so|-|called regions (subspaces). So, say that we have an $x$ coordinate with the
+value $50$. This value can be adapted in, for instance, four subspaces (regions),
+so we actually get:
\startformula
x^\prime = x
@@ -423,11 +425,11 @@ actually get:
+ s_4 \times x_4
\stopformula
-The (here) four scale factors $s_n$ are determined by the axis value. Each axis
+The (here four) scale factors $s_n$ are determined by the axis value. Each axis
has some rules about how to map the values $230$ for weight and $50$ for contrast
-to such a factor. And each region has its own translation from axis values to
-these factors. The deltas $x_1,\dots,x_4$ are provided by the font. For a
-\POSTSCRIPT|-|based font we find sequences like:
+to such a factor. Each region has its own translation from axis values to these
+factors. The deltas $x_1,\dots,x_4$ are provided by the font. In a
+\POSTSCRIPT|-|based font, we find sequences like:
\starttyping
1 <setvstore>
@@ -437,10 +439,10 @@ these factors. The deltas $x_1,\dots,x_4$ are provided by the font. For a
A store refers to a region specification. From there the factors are calculated
using the chosen values on the axis. The deltas are part of the glyphs
-specification. Officially there can be multiple region specifications, but how
+specification. Officially, there can be multiple region specifications, but how
likely it is that they will be used in real fonts is an open question.
-For \TRUETYPE\ fonts the deltas are not in the glyph specification but in a
+In \TRUETYPE\ fonts, the deltas are not in the glyph specification but in a
dedicated \type {gvar} table.
\starttyping
@@ -448,7 +450,7 @@ apply x deltas [10 -30 40 -60] to x 120
apply y deltas [30 -10 -30 20] to y 100
\stoptyping
-Here the deltas come from tables outside the glyph specification and their
+Here, the deltas come from tables outside the glyph specification and their
application is triggered by a combination of axis values and regions.
The following two examples use Avenir Next Variable and demonstrate that kerning
@@ -488,19 +490,19 @@ is adapted to the variant.
\startsubject[title=Embedding]
-Once we're done typesetting and a \PDF\ file has to be created there are three
+Once we're done typesetting and a \PDF\ file has to be created, there are three
possible routes:
\startitemize
\startitem
We can embed the shapes as \PDF\ images (inline literal) using virtual
- font technology. We cannot use so|-|called xforms here because we want to
+ font technology. We cannot use so|-|called xforms here, because we want to
support color selectively in text.
\stopitem
\startitem
- We can wait till the \PDF\ format supports such fonts, which might happen
- but even then we might be stuck for years with viewers getting there. Also
- documents need to get printed, and when printer support might
+ We can wait till the \PDF\ format supports such fonts, which might
+ happen, but even then we might be stuck for years with viewers getting
+ there. Also, documents need to be printed, and when printer support might
arrive is another unknown.
\stopitem
\startitem
@@ -512,43 +514,43 @@ possible routes:
Once I could interpret the right information in the font, the first route was the
way to go. A side effect of having a converter for both outline types meant that
it was trivial to create a virtual font at runtime. This option will stay in
-\CONTEXT\ as pseudo|-|feature \type {variableshapes}.
+\CONTEXT\ as a pseudo|-|feature \type {variableshapes}.
-When trying to support variable fonts I tried to limit the impact on the backend
+When trying to support variable fonts, I tried to limit the impact on the backend
code. Also, processing features and such was not touched. The inclusion of the
right shapes is done via a callback that requests the blob to be injected in the
-\type {cff} or \type {glyf} table. When implementing this I actually found out
-that the \LUATEX\ backend also does some juggling of charstrings, to serve the
-purpose of inlining subroutines. In retrospect I could have learned a few tricks
-faster by looking at that code but I never realized that it was there. Looking at
-the code again, it strikes me that the whole inclusion could be done with \LUA\
-code and some day I will give that a try.
+\type {cff} or \type {glyf} table. When implementing this, I actually found out
+that the \LUATEX\ backend also does some juggling of charstrings to inline
+subroutines. In retrospect, I could have learned a few tricks faster by looking
+at that code, but I never realized that it was there. Looking at the code again,
+it strikes me that the whole inclusion could be done with \LUA\ code, and, some
+day, I will give that a try.
\stopsubject
\startsubject[title=Conclusion]
-When I first heard about variable fonts I was confident that when they showed up
-they could be supported. Of course a specimen was needed to prove this. A first
-implementation demonstrates that indeed it's no big deal to let \CONTEXT\ with
-\LUATEX\ handle such fonts. Of course we need to fill in some gaps which can be
-done once we have complete fonts. And then of course users will demand more
-control. In the meantime the helper script that deals with identifying fonts by
-name has been extended and the relevant code has been added to the distribution.
-At some point the \CONTEXT\ Garden will provide the \LUATEX\ binary that has the
-callback.
-
-I end with a warning. On the one hand this technology looks promising but on the
-other hand one can easily get lost. Probably most such fonts operate over a
-well|-|defined domain of values but even then one should be aware of complex
+When I first heard about variable fonts, I was confident that when they showed
+up, they could be supported. Of course, a specimen was needed to prove this. A
+first implementation demonstrates that, indeed, it's no big deal to let \CONTEXT\
+with \LUATEX\ handle such fonts. Of course, we need to fill in some gaps, which
+can be done once we have complete fonts. And then, of course, users will demand
+more control. In the meantime, the helper script that deals with identifying
+fonts by name has been extended, and the relevant code has been added to the
+distribution. At some point, the \CONTEXT\ Garden will provide the \LUATEX\
+binary that has the callback.
+
+I end on a warning note. On the one hand, this technology looks promising, but on
+the other hand, one can easily get lost. Most such fonts probably operate over a
+well|-|defined domain of values, but, even then, one should be aware of complex
interactions with features like positioning or replacements. Not all combinations
-can be tested. It's probably best to stick to fonts that have all the relevant
+can be tested. It's probably best to stick with fonts that have all the relevant
tables and don't depend on properties of a specific rendering technology.
-Although support is now present in the core of \CONTEXT\ the official release
-will happen at the \CONTEXT\ meeting in 2017. By then I hope to have tested more
-fonts. Maybe the interface has also been extended by then because after all,
-\TEX\ is about control.
+Although support is now present in the core of \CONTEXT, the official release
+will happen at the \CONTEXT\ meeting in 2017. By then, I hope to have tested more
+fonts. Maybe the interface will also have been extended by then, because, after
+all, \TEX\ is about control.
\stopsubject
diff --git a/doc/context/sources/general/manuals/onandon/onandon.tex b/doc/context/sources/general/manuals/onandon/onandon.tex
index 60b626a5e..00b01f9ae 100644
--- a/doc/context/sources/general/manuals/onandon/onandon.tex
+++ b/doc/context/sources/general/manuals/onandon/onandon.tex
@@ -35,22 +35,18 @@
\startbodymatter
\component onandon-decade
\component onandon-ffi
- % \startchapter[title=Variable fonts] First published in user group magazines. \stopchapter
- \component onandon-variable
+ \component onandon-variable % first published in user group magazines
\component onandon-emoji
- \startchapter[title={Children of \TEX}] First published in user group magazines. \stopchapter
- % \component onandon-children
\component onandon-performance
\component onandon-editing
- \startchapter[title={Advertising \TEX}] First published in user group magazines. \stopchapter
- % \component onandon-perception
- \startchapter[title={Tricky fences}] First published in user group magazines. \stopchapter
- % \component onandon-fences
- % \component onandon-media
- \startchapter[title={From 5.2 to 5.3}] Maybe first published in user group magazines. \stopchapter
- % \component onandon-53
- \startchapter[title={Executing \TEX}] Maybe first published in user group magazines. \stopchapter
- % \component onandon-execute
+ \component onandon-fences % first published in user group magazines
+ \component onandon-media
+ \component onandon-53 % first published in user group magazines
+ \component onandon-execute % first published in user group magazines
+ \component onandon-modern
+ \component onandon-expansion
+ \component onandon-runtoks
+ \component onandon-110
\stopbodymatter
\stopproduct
diff --git a/doc/context/sources/general/manuals/rules/rules-mkiv.tex b/doc/context/sources/general/manuals/rules/rules-mkiv.tex
index 00ab49c25..e1d8acfaa 100644
--- a/doc/context/sources/general/manuals/rules/rules-mkiv.tex
+++ b/doc/context/sources/general/manuals/rules/rules-mkiv.tex
@@ -257,8 +257,10 @@ A running box is seen as text. As you (probably) expect, a nested ornamental
rule is supported as well:
\startbuffer
-\underbars{We see this \high{\tfxx\underdot{®}} symbol \runninghbox to 1cm{\hss} often.}
-\underbar {We see this \high{\tfxx\underdot{®}} symbol \runninghbox to 1cm{\hss} often.}
+\underbars
+ {We see this \high{\tfxx\underdot{®}} symbol \runninghbox to 1cm{\hss} often.}
+\underbar
+ {We see this \high{\tfxx\underdot{®}} symbol \runninghbox to 1cm{\hss} often.}
\stopbuffer
\typebuffer
@@ -269,6 +271,30 @@ This time we get (you might need a magnifier to see it):
\getbuffer
\stoplines
+We end this section with an extreme example:
+
+\startbuffer
+\definebar
+ [xbarone]
+ [text=\lower\exheight\hbox{\darkred \infofont +},
+ repeat=yes]
+\definebar
+ [xbartwo]
+ [text=\lower\exheight\hbox{\darkblue\infofont +},
+ repeat=yes,
+ continue=yes]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+Klein : \xbarone{\samplefile {klein}\removeunwantedspaces}\par
+Sapolsky : \xbartwo{\samplefile{sapolsky}\removeunwantedspaces}\par
+\stopbuffer
+
+\typebuffer \getbuffer
+
+
\stopsubject
\startsubject[title=Shifting]
@@ -307,7 +333,7 @@ or: \inlinebuffer\ Here we just shift words but you can shift more than that
although I haven't yet seen a useful example of that:
\startbuffer
-We can \shiftup {\input{tufte}} whole paragraphs if we really want.
+We can \shiftup {\samplefile{tufte}} whole paragraphs if we really want.
\stopbuffer
\typebuffer
@@ -352,7 +378,7 @@ an educational feature.
color=darkred]
\startlinefiller[filler-1]
- \input ward
+ \samplefile{ward}
\stoplinefiller
\stopbuffer
@@ -366,7 +392,7 @@ paragraph.
\startbuffer
\startalign[flushleft,broad]
\startlinefiller[filler-1]
- \input ward
+ \samplefile{ward}
\stoplinefiller
\stopalign
\stopbuffer
@@ -386,7 +412,7 @@ a \type {middle} alignment:
\startbuffer
\startalign[middle]
\startlinefiller[filler-1]
- \input ward
+ \samplefile{ward}
\stoplinefiller
\stopalign
\stopbuffer
@@ -397,7 +423,7 @@ a \type {middle} alignment:
\startalign[middle]
\startnarrower
\startlinefiller[filler-1]
- \input ward
+ \samplefile{ward}
\stoplinefiller
\stopnarrower
\stopalign
@@ -418,7 +444,7 @@ to the margins if you like:
\startalign[middle]
\startnarrower
\startlinefiller[filler-1][scope=global]
- \input ward
+ \samplefile{ward}
\stoplinefiller
\stopnarrower
\stopalign
@@ -436,7 +462,7 @@ You can also use a \type {left} or \type {right} scope, as in:
\startalign[middle]
\startnarrower
\startlinefiller[filler-1][scope=right]
- \input ward
+ \samplefile{ward}
\stoplinefiller
\stopnarrower
\stopalign
@@ -452,7 +478,7 @@ Only the right rules extend into the margins.
\startalign[middle]
\startnarrower
\startlinefiller[filler-1][scope=right,location=right]
- \input ward
+ \samplefile{ward}
\stoplinefiller
\stopnarrower
\stopalign
@@ -498,7 +524,7 @@ The previous example now looks like:
\startalign[middle,r2l]
\startnarrower[4*middle]
\startlinefiller[filler-1] [scope=global]
- \input ward
+ \samplefile{ward}
\stoplinefiller
\stopnarrower
\stopalign
@@ -534,7 +560,7 @@ use a latin script example for convenience.
% \startlinefiller[filler-1] [scope=global,align=middle]
% \parindent 100pt
% \parfillskip 100pt
-% \input ward
+% \samplefile{ward}
% \stoplinefiller
% \stopnarrower
% \stopbuffer
@@ -544,7 +570,7 @@ use a latin script example for convenience.
\startlinefiller[filler-1] [scope=global,align={middle,r2l}]
\parindent 100pt
\parfillskip 100pt
- \input ward
+ \samplefile{ward}
\stoplinefiller
\stopnarrower
\stopbuffer
@@ -623,9 +649,11 @@ primitive here, so we follow the \TEX\ conventions of keywords.
\startbuffer
\ruledhbox\bgroup
- \darkgray \frule width 100mm height 10mm depth 8mm radius 2mm line 2pt type fill\relax
+ \darkgray
+ \frule width 100mm height 10mm depth 8mm radius 2mm line 2pt type fill\relax
\hskip-100mm
- \darkred \frule width 100mm height 10mm depth 8mm radius 2mm line 2pt\relax
+ \darkred
+ \frule width 100mm height 10mm depth 8mm radius 2mm line 2pt\relax
\hskip-100mm
\hbox to 100mm{\white \bold \hfill some handy word with frames\hfill}%
\egroup
@@ -784,11 +812,11 @@ command:
\stoptyping
\startbuffer
-\input ward \hiddenbar {\color[red]{invisible}}
-\input ward \hiddenbar {\quad\color[red]{invisible}\quad}
-\input ward \hiddenbar{\quad\quad\quad\color[red]{invisible}\quad\quad\quad}
-\input ward \hiddenbar {\color[red]{invisible}\quad\quad\quad\quad\quad\quad}
-\input ward
+\samplefile{ward}\hiddenbar {\color[red]{invisible}}
+\samplefile{ward}\hiddenbar {\quad\color[red]{invisible}\quad}
+\samplefile{ward}\hiddenbar{\quad\quad\quad\color[red]{invisible}\quad\quad\quad}
+\samplefile{ward}\hiddenbar {\color[red]{invisible}\quad\quad\quad\quad\quad\quad}
+\samplefile{ward}
\stopbuffer
\getbuffer
@@ -807,8 +835,8 @@ the spacing is kept at a linebreak:
[left={\quads[3]},
right={\quads[3]}]
-\widehiddenbar{invisible} \input weisman
-\widehiddenbar{invisible} \input weisman
+\widehiddenbar{invisible} \samplefile{weisman}
+\widehiddenbar{invisible} \samplefile{weisman}
\widehiddenbar{invisible}
\stopbuffer
@@ -818,4 +846,164 @@ the spacing is kept at a linebreak:
\stopsubject
+\startsubject[title=Tabulate]
+
+The previously discussed mechanism is also available in the tabulate mechanism.
+We start with simple backgrounds:
+
+\startbuffer
+\starttabulate
+ \NL[darkred] foo \NC bar \NC \NR
+ \NL[darkgreen] foo \NC bar \NC \NR
+ \NL[darkblue] foo \NC \samplefile{tufte} \NC \NR
+ \NL[darkgray] foo \NC bar \NC \NR
+ \NL[darkyellow] foo \NC bar \NC \NR
+ \LL
+\stoptabulate
+\stopbuffer
+
+\typebuffer
+
+This comes out as:
+
+{\startcolor[white]\getbuffer\stopcolor}
+
+There are several two character commands that deal with this:
+
+\starttabulate[|c|c|l|]
+\BC command \BC related to \BC effect \NC
+\NC \type{\NL} \NC \type{\NC} \NC Normal with Line \NC \NR
+\NC \type{\ND} \NC \type{\NC} \NC Normal with Default Line \NC \NR
+\NC \type{\LB} \NC \type{\BC} \NC Bold with Line \NC \NR
+\NC \type{\DB} \NC \type{\BC} \NC Bold with Default Line \NC \NR
+\NC \type{\NF} \NC \type{\NC} \NC Normal with Filler \NC \NR
+\NC \type{\NP} \NC \type{\NC} \NC Normal with Predefined Filler \NC \NR
+\NC \type{\FB} \NC \type{\BC} \NC Bold with Filler \NC \NR
+\NC \type{\NA} \NC \type{\NC} \NC Normal with Auto Toggled Line \NC \NR
+\NC \type{\BA} \NC \type{\BC} \NC Bold with Auto Toggled Line \NC \NR
+\stoptabulate
+
+Before we show more, we set up tabulate:
+
+\startbuffer[setup]
+\setuptabulate
+ [blank={small,samepage},
+ headstyle=bold,
+ rulecolor=darkred,
+ rulethickness=1pt,
+ background=foo,
+ backgroundcolor=darkred,
+ foregroundcolor=white]
+\stopbuffer
+
+\typebuffer[setup]
+
+This time we don't set colors in the table itself:
+
+\startbuffer
+\starttabulate[|l|l|]
+ \DB foos \BC bars \BC \NR
+ \TB
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \LL
+\stoptabulate
+\stopbuffer
+
+\typebuffer {\getbuffer[setup]\getbuffer}
+
+Instead of coming up with a separate mechanism for hooking in \METAPOST\ we
+use the linefiller mechanism. We use these graphics:
+
+\startbuffer
+\startuseMPgraphic{foo}
+ fill unitsquare
+ xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8)
+ shifted (-ExHeight/8,ExHeight/16)
+ withcolor RuleColor ;
+\stopuseMPgraphic
+
+\startuseMPgraphic{bar}
+ fill unitsquare
+ xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8)
+ shifted (-ExHeight/8,ExHeight/16)
+ randomized ExHeight
+ withcolor RuleColor ;
+\stopuseMPgraphic
+\stopbuffer
+
+\typebuffer \getbuffer
+
+With these fillers:
+
+\startbuffer
+\definelinefiller[foo][mp=foo,color=darkgreen]
+\definelinefiller[bar][mp=bar,color=darkred]
+\stopbuffer
+
+\typebuffer \getbuffer
+
+An example of usage is:
+
+\startbuffer
+\linefillerhbox[foo] to 12cm{\hss\strut\white\bf FOO\hss} \blank
+\linefillerhbox[bar] to 10cm{\hss\strut\white\bf BAR\hss} \blank
+\linefillerhbox[foo] to 9cm{\hss\strut\white\bf FOO\hss} \blank
+\linefillerhbox[bar] to 14cm{\hss\strut\white\bf BAR\hss}
+\stopbuffer
+
+\typebuffer \blank \getbuffer \blank
+
+We can rely on the default:
+
+\startbuffer
+\starttabulate[|||]
+ \PB foo \BC bars \BC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+\stoptabulate
+\stopbuffer
+
+\typebuffer \start\getbuffer[setup]\getbuffer\stop
+
+or be explicit:
+
+\startbuffer
+\starttabulate[|||]
+ \FB[bar] foos \BC bars \BC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+ \NC foo foo foo \NC bar bar bar bar \NC \NR
+\stoptabulate
+\stopbuffer
+
+\typebuffer \start\getbuffer[setup]\getbuffer\stop
+
+The auto variants will switch between colors:
+
+\startbuffer
+\setuptabulate[backgroundcolor:1=darkred]
+\setuptabulate[backgroundcolor:2=darkgreen]
+\setuptabulate[backgroundcolor:3=darkblue]
+
+\starttabulate[|||]
+ \BA foo foo foo \BC bar bar bar bar \NC \NR
+ \BA foo foo foo \BC bar bar bar bar \NC \NR
+ \BA foo foo foo \BC bar bar bar bar \NC \NR
+ \BA foo foo foo \BC bar bar bar bar \NC \NR
+ \BA foo foo foo \BC bar bar bar bar \NC \NR
+ \BA foo foo foo \BC bar bar bar bar \NC \NR
+\stoptabulate
+\stopbuffer
+
+\typebuffer \start\getbuffer[setup]\getbuffer\stop
+
+
+\stopsubject
+
\stopdocument
diff --git a/doc/context/sources/general/manuals/texit/texit-conditions.tex b/doc/context/sources/general/manuals/texit/texit-conditions.tex
new file mode 100644
index 000000000..83fb0a7bc
--- /dev/null
+++ b/doc/context/sources/general/manuals/texit/texit-conditions.tex
@@ -0,0 +1,108 @@
+\environment texit-style
+
+\startcomponent texit-conditions
+
+\startchapter[title={Conditions}]
+
+In case you wonder why we have modes in \CONTEXT, here is an example that might
+convince you. The \TEX\ language has conditionals and they are in fact quite
+efficient, take for instance:
+
+\startTEX
+\ifnum\scratchcounter>10
+ \ifdim\scratchdimen>10pt
+ one
+ \else
+ two
+ \fi
+\else
+ three
+\fi
+\stopTEX
+
+When the first test fails, \TEX\ will do a fast scan over the following tokens
+and expand the \type {three} branch. In order to do such a fast scan, the nested
+condition needs to be properly balanced: the \type {\else} is optional but the
+nested \type {\fi} definitely isn't. Now imagine that you use a few pseudo
+booleans, like:
+
+\startTEX
+\newif\ifalpha \alphatrue
+\newif\ifbeta \betatrue
+\stopTEX
+
+And you need it in:
+
+\startTEX
+\ifalpha
+ \ifbeta
+ YES
+ \else
+ NOP
+ \fi
+\else
+ NOP
+\fi
+\stopTEX
+
+This happens occasionally in real applications and one can either repeat the
+\type {NOP} or wrap it in a macro in order to save tokens. However, way more
+natural would be something like this:
+
+\startTEX
+\ifalphaorbeta
+ YES
+\else
+ NOP
+\fi
+\stopTEX
+
+This basically would introduce a new kind concept: an expandable macro flagged as
+\type {\if} kind of token. I actually experimented with that in \LUATEX\ but
+rejected it eventually. Instead \type {\ifcondition} was introduced. This is
+basically equivalent to \type {\iffalse} when \TEX\ is in fast \type {\if*}
+skipping mode, but when a real test happens the next argument is expanded. That
+macro is expected to end up as something equivalent to \type {\iftrue} or \type
+{\iffalse} so that other the nexct branch or the \type {\else} is entered. Here
+is an example:
+
+\startTEX
+\ifcondition\alphaorbeta
+ YES
+\else
+ NOP
+\fi
+\stopTEX
+
+There are several ways to define \type {\alphaorbeta} now and we show a few here.
+It's up to you to figure out which ons is the most efficient.
+
+\startTEX
+\def\alphaorbeta{\ifcase0\ifalpha \else\ifbeta \else1\fi\fi\relax}
+\def\alphaorbeta{\ifcase \ifalpha0\else\ifbeta0\else1\fi\fi\relax}
+\def\alphaorbeta{\ifnum1=\ifalpha1\else\ifbeta1\else0\fi\fi\relax}
+\def\alphaorbeta{\ifnum 0\ifalpha1\fi \ifbeta1\fi >1\relax}
+\stopTEX
+
+Now, do we expect users to come up with such constructs? Of course not. Even in
+\CONTEXT\ we don't really need them, although there are a few places where they
+can be used. In \CONTEXT\ you would just do this:
+
+\startTEX
+\enablemode[alpha]
+\enablemode[beta]
+
+\doifelsemode {alpha,beta} {
+ YES
+} {
+ NOP
+}
+\stopTEX
+
+Of course such a verbose macro is less efficient but even if you use this test
+10.000 times in a run it will not take more than 0.06 seconds on a decent 2013
+laptop.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/texit/texit-contents.tex b/doc/context/sources/general/manuals/texit/texit-contents.tex
new file mode 100644
index 000000000..f22db1c38
--- /dev/null
+++ b/doc/context/sources/general/manuals/texit/texit-contents.tex
@@ -0,0 +1,9 @@
+\environment texit-style
+
+\startcomponent texit-contents
+
+\starttitle[title={Contents}]
+ \placelist[chapter]
+\stoptitle
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/texit/texit-introduction.tex b/doc/context/sources/general/manuals/texit/texit-introduction.tex
new file mode 100644
index 000000000..cfe87c25a
--- /dev/null
+++ b/doc/context/sources/general/manuals/texit/texit-introduction.tex
@@ -0,0 +1,24 @@
+\environment texit-style
+
+\startcomponent texit-introduction
+
+\startchapter[title={Introduction}]
+
+I needed a place to collect examples of \TEX\ coding and this is it. The examples
+presented here are an unorganized bunch. Some originate in questions asked on the
+mailing list. Others are byproducts of tests made when playing with some (new)
+functionality. When you plan to use \TEX\ for a long time, it doesn't hurt to see
+a bit of \TEX\ coding but when possible I will also show the \CONTEXT\ way.
+
+I hope that this document is useful. You can of course always try to challenge me
+for more examples. Hopefully I will not forget about this document and extend it
+occasionaly.
+
+\startlines
+Hans Hagen
+Hasselt NL
+\stoplines
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/texit/texit-leaders.tex b/doc/context/sources/general/manuals/texit/texit-leaders.tex
new file mode 100644
index 000000000..ed224da5c
--- /dev/null
+++ b/doc/context/sources/general/manuals/texit/texit-leaders.tex
@@ -0,0 +1,247 @@
+\environment texit-style
+
+\startcomponent texit-leaders
+
+\startchapter[title={Leaders}]
+
+The following example comes from a question on the \CONTEXT\ list. It
+exhibits a few low level tricks. For the purpose of this example we
+use \type {\ruledhbox} instead of \type {\hbox}. We start with a simple
+command that puts something at the end of a line:
+
+\startbuffer
+\starttexdefinition MyFill #1
+ \removeunwantedspaces
+ \hfill
+ \ruledhbox{#1}
+\stoptexdefinition
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+We use this in:
+
+\startbuffer[sample]
+\startitemize[packed,joinedup][rightmargin=3em]
+ \startitem
+ \samplefile{ward}\MyFill{DW}
+ \stopitem
+\stopitemize
+\stopbuffer
+
+\typebuffer[sample][option=TEX]
+
+and get:
+
+\getbuffer[sample]
+
+But, the requirement was that we move the number towards the right margin, so
+instead we need something:
+
+\startbuffer
+\starttexdefinition MyFill #1
+ \removeunwantedspaces
+ \hfill
+ \rlap{\ruledhbox to \rightskip{\hss#1}}
+\stoptexdefinition
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+This already looks more like it:
+
+\getbuffer[sample]
+
+But also part of the requirements was that there should be dots between the end
+of the last sentence and the number. In low level \TEX\ speak that means using
+leaders: repeated boxed content where the repitition is driven by a glue
+specification. Let's naively use leaders now:
+
+\startbuffer
+\starttexdefinition MyFill #1
+ \leaders
+ \ruledhbox to 1em{\hss.\hss}
+ \hfill
+ \ruledhbox{#1}
+\stoptexdefinition
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+Let's see what we get:
+
+\getbuffer[sample]
+
+Again we need to move the number to the right. This time we need a different
+solution because we need to fill the space in between. When \TEX\ ends a
+paragraph it adds \type {\parfillskip} so we will now manipulate that parameter.
+
+\startbuffer
+\starttexdefinition MyFill #1
+ \parfillskip-1\rightskip plus 1fil\relax
+ \leaders
+ \ruledhbox to 1em{\hss.\hss}
+ \hfill
+ \ruledhbox{#1}
+\stoptexdefinition
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+Does it look better?
+
+\getbuffer[sample]
+
+Indeed it does, but watch this:
+
+\startbuffer[sample]
+\startitemize[packed,joinedup][rightmargin=8.5em]
+ \startitem
+ \samplefile{ward}\MyFill{DW}\par
+ \samplefile{ward}\par
+ \samplefile{ward}\MyFill{DW}
+ \stopitem
+\stopitemize
+\stopbuffer
+
+\typebuffer[sample][option=TEX]
+
+The first \type {\MyFill} will set the \type {\parfillskip} to a value that will
+also be used later on.
+
+\getbuffer[sample]
+
+The way out is the following
+
+\startbuffer
+\starttexdefinition MyFill #1
+ \begingroup
+ \parfillskip-1\rightskip plus 1fil\relax
+ \leaders
+ \ruledhbox to 1em{\hss.\hss}
+ \hfill
+ \ruledhbox{#1}
+ \par
+ \endgroup
+\stoptexdefinition
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+This looks more or less okay. The \type {\par} keeps the adaption local but for
+it to work well, the \type {\par} must be inside the group.
+
+\getbuffer[sample]
+
+Now it's time to go for perfection! First of all, we get rid of any leading
+spacing. If we need some we should inject it after a cleanup. We also use a
+different leader command. Instead of \type {to} we use a \type {spread} so that
+we get half the emwidth and not something slightly less due to the width of the
+period.
+
+\startbuffer
+\starttexdefinition MyFill #1
+ \removeunwantedspaces
+ \begingroup
+ \parfillskip-1\rightskip plus 1fil\relax
+ \cleaders
+ \ruledhbox spread 1em{\hss.\hss}
+ \hfill
+ \ruledhbox{#1}
+ \par
+ \endgroup
+\stoptexdefinition
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+So, we end up here:
+
+\startbuffer[sample]
+\startitemize[packed,joinedup][rightmargin=5em]
+ \startitem
+ \samplefile{sapolsky}\MyFill{RS}\par
+ \stopitem
+\stopitemize
+\stopbuffer
+
+\getbuffer[sample]
+
+For which we used this:
+
+\typebuffer[sample][option=TEX]
+
+Finally we get rid of the tracing:
+
+\startbuffer
+\starttexdefinition unexpanded MyFill #1
+ \begingroup
+ \parfillskip-1\rightskip plus 1fil\relax
+ \leaders
+ \hbox to \emwidth{\hss.\hss}
+ \hfill
+ \hbox{#1}
+ \par
+ \endgroup
+\stoptexdefinition
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+Watch a few more details. It brings us to:
+
+\getbuffer[sample]
+
+\page
+
+\startbuffer
+\definefiller
+ [MyFiller]
+ [offset=.25\emwidth,
+ method=middle]
+
+\starttexdefinition unexpanded MyFill #1
+ \begingroup
+ \parfillskip-1\rightskip plus 1fil\relax
+ \filler[MyFiller]%
+ \hbox{#1}
+ \par
+ \endgroup
+\stoptexdefinition
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+\getbuffer[sample]
+
+When writing these examples I realized that it's rather trivial to add this
+option to the already existing filler mechanism. The definition of such a filler
+looks like this:
+
+\startbuffer
+\definefiller
+ [MyFiller]
+ [offset=.25\emwidth,
+ rightmargindistance=-\rightskip,
+ method=middle]
+\stopbuffer
+
+\typebuffer[option=TEX] \getbuffer
+
+\startbuffer[sample]
+\startitemize[packed,joinedup][rightmargin=5em]
+ \startitem
+ \samplefile{sapolsky}\fillupto[MyFiller]{RS}
+ \stopitem
+\stopitemize
+\stopbuffer
+
+The sample code now becomes:
+
+\typebuffer[sample][option=TEX]
+
+Ans as expected renders as:
+
+\getbuffer[sample]
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/texit/texit-lookahead.tex b/doc/context/sources/general/manuals/texit/texit-lookahead.tex
new file mode 100644
index 000000000..03eaecabe
--- /dev/null
+++ b/doc/context/sources/general/manuals/texit/texit-lookahead.tex
@@ -0,0 +1,387 @@
+\environment texit-style
+
+\startcomponent texit-lookahead
+
+\startchapter[title={Lookahead}]
+
+When you look at the \TEX\ source of a macro package, your can often see
+constructs like this:
+
+\startTEX
+\def\foo#1%
+ {We do something with "#1".}
+\stopTEX
+
+or maybe:
+
+\startTEX
+\def\foo#1{%
+ We do something with "#1".%
+}
+\stopTEX
+
+Normally the percentage symbol is used to indicate a comment, but here
+are no comments. In these cases, it makes the definition effectively
+
+\startTEX
+\def\foo#1{do something with "#1"!}
+\stopTEX
+
+which is different from when we would not have that percent sign there:
+
+\startTEX
+\def\foo#1 {We do something with "#1"!}
+\stopTEX
+
+That variant is valid \TEX\ code but expects a space as delimiter of the
+argument to \type {\foo}. This means that you can say:
+
+\startTEX
+\foo{1} \foo 2 \foo {34} and \foo 56 .
+\stopTEX
+
+while this can trigger an error message (when no space is seen at some point) or
+at least give unexpected results.
+
+\startTEX
+\foo{1}\foo 2\foo {34}and\foo 56.
+\stopTEX
+
+A different use of the percent is seen in cases like this:
+
+\startTEX
+\def\foo#1%
+ {We do something %
+ with "#1".}
+\stopTEX
+
+This time we want to preserve the space after \type {something} because an
+end|-|of|-|line would either or not collapse it with \type {with} depending on
+how the endofline character is set up. Normally
+
+\startTEX
+\def\foo#1%
+ {We do something
+ with "#1".}
+\stopTEX
+
+will also add a space after something but when \TEX\ is set up to ignore lines
+you get a collapse. So the explicit space is a robust way out. Both cases of
+using or omitting the comment symbol are easy to spot as they trigger an error
+or result in weird typeset results.
+
+\startbuffer[defs]
+\def\fooA#1%
+ {\ifnum#1>100
+ yes\else nop%
+ \fi}
+
+\def\fooB#1{\ifnum#1>100 yes\else nop \fi}
+
+\def\fooC#1%
+ {\ifnum#1>100%
+ yes\else nop%
+ \fi}
+\stopbuffer
+
+\typebuffer[defs][option=TEX] \getbuffer[defs]
+
+We test this with:
+
+\startbuffer[demo]
+\fooA{100} \fooB{100} \fooC{100}
+\fooA{101} \fooB{101} \fooC{101}
+\stopbuffer
+
+\typebuffer[demo][option=TEX]
+
+And the result is probably what you expect:
+
+\startlines
+\getbuffer[demo]
+\stoplines
+
+\startbuffer[defs]
+\def\fooA#1%
+ {\ifnum#1>100
+ 1\else 0%
+ \fi}
+
+\def\fooB#1{\ifnum#1>100 1\else 0\fi}
+
+\def\fooC#1%
+ {\ifnum#1>100%
+ 1\else 0%
+ \fi}
+\stopbuffer
+
+However, when we have the following macro body:
+
+\typebuffer[defs][option=TEX] \getbuffer[defs]
+
+We get this output. Do you see the issue?
+
+\startlines
+\getbuffer[demo]
+\stoplines
+
+A preferred way to catch this is the following as a \type {\relax} ends scanning
+for a number:
+
+\startbuffer[defs]
+\def\foo#1%
+ {\ifnum#1>100\relax
+ 1\else 0%
+ \fi}
+\stopbuffer
+
+\typebuffer[defs][option=TEX] \getbuffer[defs]
+
+However, watch what happens here:
+
+\startbuffer[demo]
+\edef\result{\foo{123}}
+\stopbuffer
+
+\typebuffer[demo][option=TEX] \getbuffer[demo]
+
+The \type {\result} macro has the following body:
+
+\expanded{\setbuffer[result]\meaning\result\endbuffer}
+
+\typebuffer[result][option=TEX]
+
+A neat trick out of this is the following:
+
+\startbuffer[defs]
+\def\foo#1%
+ {\ifnum#1>\numexpr100\relax
+ 1\else 0%
+ \fi}
+\stopbuffer
+
+\typebuffer[defs][option=TEX] \getbuffer[defs]
+
+\getbuffer[demo]
+
+Now the body of \type {\result} looks like this:
+
+\expanded{\setbuffer[result]\meaning\result\endbuffer}
+
+\typebuffer[result][option=TEX]
+
+Of course this also works:
+
+\startTEX
+\def\foo#1%
+ {\ifnum#1>100 %
+ 1\else 0%
+ \fi}
+\stopTEX
+
+as a space also delimits scanning the number. But that method can actually introduce
+that space in the output. Think of this definition:
+
+\startbuffer[defs]
+\def\foo#1#2%
+ {\ifnum#1>#2 %
+ 1\else 0%
+ \fi}
+\stopbuffer
+
+\typebuffer[defs][option=TEX] \getbuffer[defs]
+
+What if \type {#2} has a trailing space? What if it is a verbose number? What if
+it is a counter variable?
+
+\startbuffer[demo]
+\scratchcounter=100
+ [\foo{101}{100}] [\foo{101}{100 }] [\foo{101}\scratchcounter]
+\scratchcounter=101
+ [\foo{100}{101}] [\foo{100}{101 }] [\foo{100}\scratchcounter]
+\stopbuffer
+
+\typebuffer[demo][option=TEX]
+
+\startlines
+\getbuffer[demo]
+\stoplines
+
+If you really want to introduce an unpredictable situation, use a coding style like
+this:
+
+\startTEX
+\def\foo#1#2#3#4{\if#1=#2#3\else#4\fi}
+\stopTEX
+
+This is not that imaginary as you often see users play safe and do things like this:
+
+\startTEX
+\ifnum\scratchcounterone=\scratchcountertwo%
+ ...
+\else
+ ...
+\fi
+\stopTEX
+
+Here the percent sign is useless as the number scanner already got the number,
+just try:
+
+\startTEX
+\scratchcounterone=1
+\scratchcountertwo=1
+
+\ifnum\scratchcounterone=\scratchcountertwo
+ yes
+\else
+ nop
+\fi
+\stopTEX
+
+A previous one liner formatted like this really is not better!
+
+\startTEX
+\def\foo#1#2#3#4%
+ {\ifnum#1=#2%
+ #3%
+ \else
+ #4%
+ \fi}
+\stopTEX
+
+When you define macros more often than not you don't want unexpected spaces (aka spurious spaces)
+which is why in \CONTEXT\ for instance setups ignores lines:
+
+\startbuffer[defs]
+\startsetups foo
+ here
+ we ignore
+ spaces at the end
+ of a line
+\stopsetups
+\stopbuffer
+
+\typebuffer[defs][option=TEX] \getbuffer[defs]
+
+so we get: \quotation {\directsetup{foo}} which means that the normally few times
+that we {\em do} want spaces we need to be explicit:
+
+\startbuffer[defs]
+\startsetups foo
+ here\space
+ we ignore\space
+ spaces at the end\space
+ of a line\space
+\stopsetups
+\stopbuffer
+
+\typebuffer[defs][option=TEX] \getbuffer[defs]
+
+Now we're okay: \quotation {\directsetup{foo}}. The same is true for:
+
+\startTEX
+\starttexdefinition foo
+ here\space
+ we ignore\space
+ spaces at the end\space
+ of a line\space
+\stoptexdefinition
+\stopTEX
+
+There are more cases where \TEX\ will look further. Take for example skip (glue)
+scanning. A glue specification can have \type {plus} and \type {minus} fields.
+
+\startbuffer[defs]
+\scratchdimenone=10pt
+\scratchskipone =10pt plus 10pt minus 10pt
+\scratchskiptwo =0pt
+\stopbuffer
+
+\typebuffer[defs][option=TEX]
+
+Now take the following test:
+
+\startbuffer[demo]
+{1 \scratchskiptwo 10pt plus 10pt \relax\the\scratchskiptwo}
+{2 \scratchskiptwo \scratchdimenone plus 10pt \relax\the\scratchskiptwo}
+{3 \scratchskiptwo 1\scratchdimenone plus 10pt \relax\the\scratchskiptwo}
+{4 \scratchskiptwo \scratchskipone plus 10pt \relax\the\scratchskiptwo}
+{5 \scratchskiptwo 1\scratchskipone plus 10pt \relax\the\scratchskiptwo}
+\stopbuffer
+
+\typebuffer[demo][option=TEX]
+
+\startlines
+\inlinebuffer[defs]\getbuffer[demo]
+\stoplines
+
+If you wonder what the second \type {\relax} does, here is a variant:
+
+\startlines
+{1 \scratchskiptwo 10pt plus 10pt \the\scratchskiptwo}
+{2 \scratchskiptwo \scratchdimenone plus 10pt \the\scratchskiptwo}
+{3 \scratchskiptwo 1\scratchdimenone plus 10pt \the\scratchskiptwo}
+{4 \scratchskiptwo \scratchskipone plus 10pt \the\scratchskiptwo}
+{5 \scratchskiptwo 1\scratchskipone plus 10pt \the\scratchskiptwo}
+\stoplines
+
+\typebuffer[demo][option=TEX]
+
+\startlines
+\inlinebuffer[defs]\getbuffer[demo]
+\stoplines
+
+In this second variant \TEX\ happily keep looking for a glue specification when
+it sees the \type {\the} so it serializes \type {\scratchskiptwo}. But as it sees
+\type {0pt} then, it stops scanning the glue spec. What we get typeset is the old
+value, not the new one! If you want to prevent this you need to \type {\relax}.
+
+Another case where \TEX\ keeps scanning is the following:
+
+\startbuffer[demo]
+\vrule width 40pt height 2pt depth 5pt \quad
+\vrule width 40pt height 20pt depth 5pt height 10pt \quad
+\vrule width 40pt height 10pt height 20pt \quad
+\vrule width 40pt height 20pt depth 5pt height 10pt width 80pt
+\stopbuffer
+
+\typebuffer[demo][option=TEX]
+
+This gives the rules:
+
+\startlinecorrection \darkgray
+\getbuffer[demo]
+\stoplinecorrection
+
+So you can overload dimensions. The space before the \type {quad} is gobbled as
+part of the look ahead for more keywords.
+
+Often rules (just like glue assignments) are wrapped in macro definitions where the
+macro writer used \type {\relax} to look ahead. That way you prevent an error message
+in cases like:
+
+\startTEX
+\def\foo{\vrule width 40pt height 2pt}
+
+The \foo depth of this thought is amazing.
+\stopTEX
+
+because \type {of} definitely is not a valid dimension. Even more subtle is:
+
+\startTEX
+\def\foo{\hskip 10pt plus 1fil}
+
+The \foo fine points of typesetting can actually become a nightmare.
+\stopTEX
+
+As \TEX\ will now see the \type {f} of \type {fine} as further specification and
+think that you want \type {1fill}.
+
+So, the most important lesson of this chapter is that you need to be aware of the way
+\TEX\ scans for quantities and specifications. In most cases the users can safely use
+a \type {\relax} to prevent a lookahead. And try to avoid adding percent signs all
+over the place.
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/texit/texit-style.tex b/doc/context/sources/general/manuals/texit/texit-style.tex
new file mode 100644
index 000000000..bee526d7b
--- /dev/null
+++ b/doc/context/sources/general/manuals/texit/texit-style.tex
@@ -0,0 +1,52 @@
+\startenvironment texit-style
+
+\setupbodyfont
+ [dejavu,11pt]
+
+\setuphead
+ [chapter]
+ [style=\bfc,
+ header=empty,
+ color=darkgray]
+
+\setuplist
+ [chapter]
+ [alternative=c,
+ width=1.5em]
+
+\setuplayout
+ [width=middle,
+ height=middle,
+ topspace=15mm,
+ backspace=15mm,
+ header=15mm,
+ footer=0mm]
+
+\setupwhitespace
+ [big]
+
+\setupheadertexts
+ []
+
+\setupheadertexts
+ []
+ [{\getmarking[chapter]\quad\pagenumber}]
+ [{\pagenumber\quad\getmarking[chapter]}]
+ []
+
+\setupheader
+ [style=\bf,
+ color=darkgray]
+
+% \setuptype
+% [color=darkred]
+
+% \setuptyping
+% [color=darkred]
+
+\setuppagenumbering
+ [alternative=doublesided]
+
+\usemodule[scite]
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/texit/texit-titlepage.tex b/doc/context/sources/general/manuals/texit/texit-titlepage.tex
new file mode 100644
index 000000000..1b7cabe84
--- /dev/null
+++ b/doc/context/sources/general/manuals/texit/texit-titlepage.tex
@@ -0,0 +1,40 @@
+\environment texit-style
+
+\startcomponent texit-titlepage
+
+\startMPpage
+
+fill Page
+ withcolor "darkyellow"
+ withtransparency (1,.75) ;
+
+draw image (
+ for i=1 upto 500 :
+ draw (((1,-2) ... origin ... (-1,2)) randomized 0.2)
+ scaled 1cm
+ rotated (0 randomized 15)
+ shifted (origin randomized (PaperWidth,PaperHeight))
+ withpen pencircle yscaled 5mm xscaled 2mm rotated 45
+ withcolor "darkmagenta"
+ withtransparency (1,.5)
+ ;
+ endfor ;
+) shifted center Page ;
+
+clip currentpicture to Page ;
+
+draw textext.ulft ("\TeX it") ysized 5cm % indeed, no space after \TeX !
+ shifted lrcorner Page shifted (-1cm,1cm)
+ withcolor white ;
+
+draw textext.llft ("Hans Hagen") ysized 1cm
+ rotated 90
+ shifted urcorner Page shifted (-15mm,-1cm)
+ withcolor white ;
+
+\stopMPpage
+
+\startstandardmakeup[doublesided=no,page=no]
+\stopstandardmakeup
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/texit/texit.tex b/doc/context/sources/general/manuals/texit/texit.tex
new file mode 100644
index 000000000..b8b70c00d
--- /dev/null
+++ b/doc/context/sources/general/manuals/texit/texit.tex
@@ -0,0 +1,19 @@
+\environment texit-style
+
+\startdocument
+
+\component texit-titlepage
+
+\startfrontmatter
+ \component texit-contents
+ \component texit-introduction
+\stopfrontmatter
+
+\startbodymatter
+ \component texit-lookahead
+ \component texit-conditions
+ \component texit-leaders
+ % \component texit-efficiency
+\stopbodymatter
+
+\stopdocument
diff --git a/doc/context/sources/general/manuals/tools/tools-mkiv.tex b/doc/context/sources/general/manuals/tools/tools-mkiv.tex
index 481426756..949a878ca 100644
--- a/doc/context/sources/general/manuals/tools/tools-mkiv.tex
+++ b/doc/context/sources/general/manuals/tools/tools-mkiv.tex
@@ -37,11 +37,17 @@
\setuptyping
[color=DocumentColor]
-\usetypescript
- [iwona]
+\setupalign
+ [tolerant,stretch]
+
+% \usetypescript
+% [iwona]
+%
+% \setupbodyfont
+% [iwona]
\setupbodyfont
- [iwona]
+ [ibmplex,rm]
\setuphead
[chapter]
@@ -53,6 +59,11 @@
[style=\bfb,
color=DocumentColor]
+\setuphead
+ [sub section]
+ [style=\bfa,
+ color=DocumentColor]
+
\setupinteraction
[hidden]
@@ -130,7 +141,7 @@ This manual is work in progress. Feel free to submit additions or corrections.
Before you start reading, it is good to know that in order to get starting with
\CONTEXT, the easiest way to do that is to download the standalone distribution
from \type {contextgarden.net}. After that you only need to make sure that \type
-{luatex} is in your path. The main command you use is then \type {context} and
+{luatex} is in your path. The main command you use is then \sCONTEXT\ and
normally it does all the magic it needs itself.
\stopsection
@@ -488,9 +499,8 @@ You can copy \type {mtxrun.exe} to for instance \type {context.exe} and it will
still use \sMTXRUN\ for locating the right script. It also takes care of mapping
\sTEXMFSTART\ to \sMTXRUN. So we've removed the intermediate \type {cmd} step,
can not run the script as any program, and most of all, we're as efficient as can
-be.
-
-Of course this program is only meaningful for the \CONTEXT\ approach to tools.
+be. Of course this program is only meaningful for the \CONTEXT\ approach to
+tools.
It may all sound more complex than it is but once it works users will not notice
those details. Als, in practice not that much has changed in running the tools
@@ -498,12 +508,909 @@ between \MKII\ and \MKIV\ as we've seen no reason to change the methods.
\stopsection
+\startsection[title={A detailed look at \sMTXRUN}]
+
+This section is derived from Taco Hoekwaters presentation and article for the
+2018 \CONTEXT\ meeting. You might want to read this is you want to benefit from
+even the most obscure features. There is a bit of repetition with the previous
+sections but so be it.
+
+% macros specific to this section
+
+\def\highlighted#1#2#3%
+ {\testpage[4]
+ \dontleavehmode
+ \backgroundline[gray]{\tt\strut #1}
+ \nowhitespace
+ \startnarrower[left]
+ \veryraggedright
+ #2\par
+ \doifsomething{#3}{{\it #3}}
+ \stopnarrower}
+
+\definestartstop
+ [options]
+ [before=\blank,
+ after=\blank]
+
+\def\option#1#2%
+ {\highlighted{--#1}{#2}{}}
+
+\definestartstop
+ [mtxrunscripts]
+ [before=\blank,after=\blank]
+
+\def\mtxrunscriptv#1#2#3#4%
+ {\highlighted{#1}{#3}{#4}}
+
+\def\mtxrunscript#1#2#3%
+ {\highlighted{#1}{#3}{}}
+
+\definestartstop
+ [mtxrunenvironment]
+ [before=\blank,
+ after=\blank]
+
+\def\mtxrunenv#1#2%
+ {\highlighted{#1}{#2}{}}
+
+\startsubsection[title=Common flags]
+
+Much of the code inside \MKIV\ can alter its behaviour based on either \quote
+{trackers} (which add debugging information to the terminal and log output) or
+\quote {directives} or \quote {experiments} (for getting code to perform some
+alternate behaviour). Since this also affects the \LUA\ code within \sMTXRUN\
+itself, it makes sense to list these options first.
+
+Getting information on trackers, directives and experiments. Trackers enable more
+extensive status messages on the console or in \CONTEXT\ additional visual clues.
+Directives change behaviour that are not part of the official interface and have
+no corresponding commands. Experiments are like directives but not official
+(yet).
+
+\startoptions
+ \option
+ {trackers}
+ {show (known) trackers}
+ \option
+ {directives}
+ {show (known) directives}
+ \option
+ {experiments}
+ {show (known) experiments}
+\stopoptions
+
+Enabling directives, trackers and experiments:
+
+\startoptions
+ \option
+ {trackers=list}
+ {enable given trackers}
+ \option
+ {directives=list}
+ {enable given directives}
+ \option
+ {experiments=list}
+ {enable given experiments}
+\stopoptions
+
+The next tree (hidden) options are converted into \quote {directives} entries,
+that are then enabled. These are just syntactic sugar for the relevant directive.
+
+\startoptions
+ \option
+ {silent[=...]}
+ {sets \type {logs.blocked={\%s}}}
+ \option
+ {errors[=...]}
+ {sets \type {logs.errors={\%s}}}
+ \option
+ {noconsole}
+ {sets \type {logs.target=file}}
+\stopoptions
+
+As you can see here, various directives (and even some trackers) have optional
+arguments, which can make specifying such directives on the command line a bit of
+a challenge. Explaining the details of all the directives is outside of the scope
+of this article, but you can look them up in the \CONTEXT\ source by searching
+for \typ {directives.register} and \typ {trackers.register}.
+
+In verbose mode, \sMTXRUN\ itself gives more messages, and it also \typ
+{resolvers.locating}, which is a tracker itself:
+
+\startoptions
+ \option
+ {verbose}
+ {give a bit more info}
+\stopoptions
+
+The \type {--timedlog} (hidden) option starts the \sMTXRUN\ output with a
+timestamp line:
+
+\startoptions
+ \option
+ {timedlog}
+ {prepend output with a timestamp}
+\stopoptions
+
+\stopsubsection
+
+\startsubsection[title=Setup for finding files and configurations]
+
+The next block of options deals with the setup of \sMTXRUN\ itself. You do not
+need to deal with these options unless you are messing with the \CONTEXT\
+distribution yourself instead of relying on a prepackaged solution, or you need
+to use kpathsea for some reason (typically in a \MKII\ environment). In
+particular, \type {--progname} and \type {--tree} are often needed as well when
+using the \type {kpse} options.
+
+\startoptions
+ \option
+ {configurations}
+ {show configuration order, alias \type {--show-configurations}}
+ \option
+ {resolve}
+ {resolve prefixed arguments, see \type {--prefixes}, below}
+\stopoptions
+
+and:
+
+\startoptions
+ \option
+ {usekpse}
+ {use kpse as fallback (when no \MKIV\ and cache installed, often slower)}
+ \option
+ {forcekpse}
+ {force using kpse (handy when no \MKIV\ and cache installed but less
+ functionality)}
+ \option
+ {progname=str}
+ {format or backend}
+ \option
+ {tree=pathtotree}
+ {use given texmf tree (default file: \type {setuptex.tmf})}
+\stopoptions
+
+\stopsubsection
+
+\startsubsection[title=Options for finding files and reporting configurations]
+
+Once the configuration setup is done, it makes sense to have a bunch or options
+to use and|/|or query the configuration.
+
+\startoptions
+ \option
+ {locate}
+ {locate given filename in database (default) or system (uses the
+ sub||options \type {--first}, \type {--all} and \type {--detail})}
+ \option
+ {autogenerate}
+ {regenerate databases if needed (handy when used to run context in an
+ editor)}
+ \option
+ {generate}
+ {generate file database}
+ \option
+ {prefixes}
+ {show supported prefixes for file searches}
+ \option
+ {variables}
+ {show configuration variables (uses the sub||option \type {--pattern},
+ and an alias is \type {--show-variables})}
+ \option
+ {expansions}
+ {show configuration variable expansion (uses the sub||options
+ \type{--pattern}, alias \type {--show-expansions})}
+ \option
+ {expand-braces}
+ {expand complex variable}
+ \option
+ {resolve-path}
+ {expand variable (completely resolve paths)}
+ \option
+ {expand-path}
+ {expand variable (resolve paths)}
+ \option
+ {expand-var}
+ {expand variable (resolves references inside variables, alias
+ \type{--expand-variable})}
+ \option
+ {show-path}
+ {show path expansion of \type {...} (alias \type {--path-value})}
+ \option
+ {var-value}
+ {report value of variable (alias \type {--show-value})}
+ \option
+ {find-file}
+ {report file location; it uses the sub||options \type {--all}, \type
+ {--pattern}, and \type {--format}}
+ \option
+ {find-path}
+ {report path of file}
+\stopoptions
+
+Hidden option:
+
+\startoptions
+ \option
+ {format-path}
+ {report format path}
+\stopoptions
+
+\stopsubsection
+
+\startsubsection[title=Running code]
+
+Here we come to the core functionality of \sMTXRUN: running scripts. First
+there are few options that trigger how the running takes place:
+
+\startoptions
+ \option
+ {path=runpath}
+ {go to given path before execution}
+ \option
+ {ifchanged=filename}
+ {only execute when given file has changed (this loads and saves an md5
+ checksum from \type {filename.md5})}
+ \option
+ {iftouched=old,new}
+ {only execute when given file has changed (time stamp)}
+ \option
+ {timedrun}
+ {run a script or program and time its run (external)}
+\stopoptions
+
+Specifying both \type {--iftouched} and \type {--ifchanged} means both are
+tested, and when either one is false, nothing will happen. These options have to
+come before one of the next options:
+
+\startoptions
+ \option
+ {script}
+ {run an mtx script (where \LUA\ is the preferred method); it has the
+ sub||options \typ {--nofiledatabase}, \typ {--autogenerate}, \type
+ {--load}, and \type {--save}. The latter two are currently no|-|ops}
+ \option
+ {execute}
+ {run a script or program externally (\type {texmfstart} method); it has
+ sub||option \type {--noquotes}}
+ \option
+ {internal}
+ {run a script using built|-|in libraries (alias is \type {--ctxlua})}
+ \option
+ {direct}
+ {run an external program; it has the sub||option \type {--noquotes}}
+\stopoptions
+
+Since scripts potentially have their own options, any options intended for
+\sMTXRUN\ itself have to come {\it before} the option that specifies the script
+to run, and options for the script itself have to come {\it after} the option
+that gives the script name. This is especially true when using \type {--script},
+so it is important to check the order of your options.
+
+Of the four above options, \type {--script} is the most important one, since that
+is the one that finds and executes the \LUA\ \sMTXRUN\ scripts provided by the
+distribution. With \typ {--nofiledatabase}, it will not attempt to resolve any
+file names (which means you need either a local script or a full path name). On
+the opposite side, when you also provide \typ {--autogenerate}, it will not only
+attempt to resolve the file name, it will also regenerate the database if it
+cannot find the script on the first try. In a future version of \CONTEXT, the
+\type {--load} and \type {--save} will allow you to save|/|restore the current
+command line in a file for reuse.
+
+The shell return value of \sMTXRUN\ indicates whether the script was found. When
+you specify something like \type {--script base}, \sMTXRUN\ actually searches
+for \type {mtx-base.lua}, \type {mtx-bases.lua}, \type {mtx-t-base.lua}, \type
+{mtx-t-bases.lua}, and \type {base.lua}, in that order. The
+distribution||supplied scripts normally use \type {mtx-<name>.lua} as template.
+The template names with \type {mtx-t-} prefix is reserved for third||party
+scripts, and \type {<name>.lua} is just a last-ditch effort if nothing else
+works. Scripts are looked for in the local path, and in whatever directories the
+configuration variable \type {LUAINPUTS} points to.
+
+The \type {--execute} options exists mostly for the non||\LUA\ {\MKII} scripts
+that still exist in the distribution. It will try to find a matching interpreter
+for non||\LUA\ scripts, and it is aware of a number of distribution||supplied
+scripts so that if you specify \type {--execute texexec}, it knows that what you
+really want to execute is \type {ruby texexec.rb}. Support is present for \RUBY\
+(\type {.rb}, \LUA\ (\type {.lua}), python (\type {.py}) and \PERL\ (\type {.pl})
+scripts (tested in that order). File resolving uses \type {TEXMFSCRIPTS} from the
+configuration. The shell return value of \sMTXRUN\ indicates whether the script
+was found and executed.
+
+The \type {--internal} option uses the file search method of \type {--execute},
+but then assumes this is a \LUA\ script and executes it internally like \type
+{--script}. This is useful if you have a \LUA\ script in an odd location.
+
+The last of the four options, \type {--direct}, directly executes an external
+program. You need to give the full path for binaries not in the current shell
+\type {PATH}, because no searching is done at all. The shell return value of
+\sMTXRUN\ in this case is a boolean based on the return value of
+\type {os.exec()}.
+
+It is also possible to execute bare \LUA\ code directly:
+
+\startoptions
+ \option
+ {evaluate}
+ {run code passed on the command-line (between quotes)}
+\stopoptions
+
+\stopsubsection
+
+\startsubsection[title=Options for maintenance of \sMTXRUN\ itself]
+
+None of these are advertised. Normally developers should be the only ones needing
+them, but if you made a change to one of the distributed libraries (maybe because
+of a beta bug), you may need to run \type {--selfmerge} and \type {--selfupdate}.
+
+\startoptions
+ \option
+ {selfclean}
+ {remove embedded libraries}
+ \option
+ {selfmerge}
+ {update embedded libraries in \type {mtxrun.lua}}
+ \option
+ {selfupdate}
+ {copy \type {mtxlua.lua} to the executable directory, renamed \type
+ {mtxrun}}
+\stopoptions
+
+\stopsubsection
+
+\startsubsection[title=Creating stubs]
+
+Stubs are little shortcuts that live in some binaries directory. For example, the
+content of the \UNIX||style \sCONTEXT\ shell command is:
+
+\starttyping
+#!/bin/sh
+mtxrun --script context "$@"
+\stoptyping
+
+Apart from the \sCONTEXT\ command itself (which is provided by the distribution),
+use of stubs is discouraged. Still, the \sMTXRUN\ options are there because
+sometimes existing workflows depend on executable tool names like \type
+{ctxtools}.
+
+\startoptions
+ \option
+ {makestubs}
+ {create stubs for (context related) scripts}
+ \option
+ {removestubs}
+ {remove stubs (context related) scripts}
+ \option
+ {stubpath=binpath}
+ {paths where stubs will be written}
+ \option
+ {windows}
+ {create windows (mswin) stubs (alias \type {--mswin})}
+ \option
+ {unix}
+ {create unix (linux) stubs (alias \type {--linux})}
+\stopoptions
+
+\stopsubsection
+
+\startsubsection[title=Remaining options]
+
+The remaining options are hard to group into a subcategory. These are the
+advertised options:
+
+\startoptions
+ \option
+ {systeminfo}
+ {show current operating system, processor, et cetera}
+ \option
+ {edit}
+ {launch editor with found file; the editor is taken from the environment
+ variable \type {MTXRUN_EDITOR}, or \type {TEXMFSTART_EDITOR}, or
+ \type {EDITOR}, or as a last resort: \type {gvim}}
+ \option
+ {launch}
+ {launch files like manuals, assumes os support (uses the sub||options
+ \type {--all}, \type {--pattern} and \type {--list})}
+\stopoptions
+
+While these are sort of hidden options:
+
+\startoptions
+ \option
+ {ansi}
+ {colorize output to terminal using \ANSI\ escapes}
+ \option
+ {associate}
+ {launch files like manuals, assumes os support. this function does not do
+ any file searching, so you have to use either a local file or a full
+ path name}
+ \option
+ {exporthelp}
+ {output the \sMTXRUN\ \XML\ help blob (useful for creating man and \HTML\
+ help pages)}
+ \option
+ {fmt}
+ {shortcut for \type {--script base --fmt}}
+ \option
+ {gethelp}
+ {attempt to look up remote \sCONTEXT\ command help (uses the sub||options
+ \type{--command} and \type {--url})}
+ \option
+ {help}
+ {print the \sMTXRUN\ help screen}
+ \option
+ {locale}
+ {force setup of locale; unless you are certain you need this option, stay
+ away from it, because it can interfere massively with \CONTEXT's \LUA\
+ code}
+ \option
+ {make}
+ {(re)create format files (aliases are \type {--ini} and \type {--compile})}
+ \option
+ {platform}
+ {(alias is \type {--show-platform})}
+ \option
+ {run}
+ {shortcut for \type {--script base --run}}
+ \option
+ {version}
+ {print \sMTXRUN\ version}
+\stopoptions
+
+\stopsubsection
+
+\startsubsection[title=Known scripts]
+
+When you run \type {mtxrun --scripts}, it will output a list of \quote {known}
+scripts. The definition of \quote {known} is important here: the list comprises
+the scripts that are present in the same directory as \type {mtx-context.lua}
+that do not have an extra hyphen in the name (like \type {mtx-t-...}scripts would
+have). In a normal installation, this means it \quote {knows} almost all the
+scripts that are distributed with \CONTEXT. Note: it skips over any files from
+the distribution that do have an extra hyphen, like the \type {mtx-server}
+support scripts.
+
+Since this section is about \sMTXRUN, I'll just present the list of the scripts
+that are \quote {known} in the current \CONTEXT\ beta as output by \sMTXRUN\
+itself, and not get into detail about all of the script functionality (they all
+have \type {--help} options if you want to find out more). Where we still felt the
+need to explain something, there is an extra bit of text in italics.
+
+\startmtxrunscripts
+\mtxrunscript
+ {babel}
+ {1.20}
+ {Babel Input To UTF Conversion}
+\mtxrunscript
+ {base}
+ {1.35}
+ {ConTeXt TDS Management Tool (aka luatools)}
+\mtxrunscript
+ {bibtex}
+ {}
+ {bibtex helpers (obsolete)}
+\mtxrunscript
+ {cache}
+ {0.10}
+ {ConTeXt & MetaTeX Cache Management}
+\mtxrunscript
+ {chars}
+ {0.10}
+ {MkII Character Table Generators}
+\mtxrunscriptv
+ {check}
+ {0.10}
+ {Basic ConTeXt Syntax Checking}
+ {Occasionally useful on big projects, but be warned that it does not actually
+ run any \TEX\ engine, so it is not 100\% reliable.}
+\mtxrunscriptv
+ {colors}
+ {0.10}
+ {ConTeXt Color Management}
+ {This displays icc color tables by name}
+\mtxrunscriptv
+ {convert}
+ {0.10}
+ {ConTeXT Graphic Conversion Helpers}
+ {A wrapper around ghostscript and imagemagick that offers some extra (batch
+ processing) functionality.}
+\mtxrunscript
+ {dvi}
+ {0.10}
+ {ConTeXt DVI Helpers}
+\mtxrunscriptv
+ {epub}
+ {1.10}
+ {ConTeXt EPUB Helpers}
+ {The EPUB manual (\type {epub-mkiv.pdf}) explains how to use this script.}
+\mtxrunscriptv
+ {evohome}
+ {1.00}
+ {Evohome Fetcher}
+ {Evohome is a domotica system that controls your central heating}
+\mtxrunscript
+ {fcd}
+ {1.00}
+ {Fast Directory Change}
+\mtxrunscriptv
+ {flac}
+ {0.10}
+ {ConTeXt Flac Helpers}
+ {Extracts information from \type{.flac} audio files into an \XML\ index.}
+\mtxrunscript
+ {fonts}
+ {0.21}
+ {ConTeXt Font Database Management}
+\mtxrunscript
+ {grep}
+ {0.10}
+ {Simple Grepper}
+\mtxrunscript
+ {interface}
+ {0.13}
+ {ConTeXt Interface Related Goodies}
+\mtxrunscript
+ {metapost}
+ {0.10}
+ {MetaPost to PDF processor}
+\mtxrunscript
+ {metatex}
+ {0.10}
+ {MetaTeX Process Management (obsolete)}
+\mtxrunscript
+ {modules}
+ {1.00}
+ {ConTeXt Module Documentation Generators}
+\mtxrunscriptv
+ {package}
+ {0.10}
+ {Distribution Related Goodies}
+ {This script is used to create the generic \CONTEXT\ code used in
+ \LUA\LATEX~c.s.}
+\mtxrunscriptv
+ {patterns}
+ {0.20}
+ {ConTeXt Pattern File Management}
+ {Hyphenation patterns, that is \unknown}
+\mtxrunscript
+ {pdf}
+ {0.10}
+ {ConTeXt PDF Helpers}
+\mtxrunscript
+ {plain}
+ {1.00}
+ {Plain TeX Runner}
+\mtxrunscript
+ {profile}
+ {1.00}
+ {ConTeXt MkIV LuaTeX Profiler}
+\mtxrunscript
+ {rsync}
+ {0.10}
+ {Rsync Helpers}
+\mtxrunscript
+ {scite}
+ {1.00}
+ {Scite Helper Script}
+\mtxrunscriptv
+ {server}
+ {0.10}
+ {Simple Webserver For Helpers}
+ {There are some subscripts associated with this.}
+\mtxrunscript
+ {synctex}
+ {1.00}
+ {ConTeXt SyncTeX Checker}
+\mtxrunscript
+ {texworks}
+ {1.00}
+ {TeXworks Startup Script}
+\mtxrunscript
+ {timing}
+ {0.10}
+ {ConTeXt Timing Tools}
+\mtxrunscript
+ {tools}
+ {1.01}
+ {Some File Related Goodies}
+\mtxrunscript
+ {unicode}
+ {1.02}
+ {Checker for \type{char-def.lua}}
+\mtxrunscript
+ {unzip}
+ {0.10}
+ {Simple Unzipper}
+\mtxrunscript
+ {update}
+ {1.03}
+ {ConTeXt Minimals Updater}
+\mtxrunscript
+ {watch}
+ {1.00}
+ {ConTeXt Request Watchdog}
+\mtxrunscriptv
+ {youless}
+ {1.10}
+ {YouLess Fetcher}
+ {YouLess is a domotica system that tracks your home energy use.}
+\stopmtxrunscripts
+
+\stopsubsection
+
+\startsubsection[title=Writing your own]
+
+A well|-|written script has some required internal structure. It should start with
+a module definition block. This gives some information about the module, but more
+importantly, it prevents double|-|loading.
+
+Here is an example:
+
+\starttyping
+if not modules then modules = { } end
+
+modules ['mtx-envtest'] = {
+ version = 0.100,
+ comment = "companion to mtxrun.lua",
+ author = "Taco Hoekwater",
+ copyright = "Taco Hoekwater",
+ license = "bsd"
+}
+\stoptyping
+
+Next up is a variable containing the help information. The help information is actually
+a bit of \XML\ stored in \LUA\ string. In the full example listing at the end of this
+article, you can see what the internal structure is supposed to be like.
+
+\starttyping
+local helpinfo = [[
+<?xml version="1.0"?>
+<application>
+ ....
+</application>
+]]
+\stoptyping
+
+And this help information is then used to create an instance of an \type
+{application} table.
+
+\starttyping
+local application = logs.application {
+ name = "envtest",
+ banner = "Mtxrun environment demo",
+ helpinfo = helpinfo,
+}
+\stoptyping
+
+After this call, the \type {application} table contains (amongst some other
+things) three functions that are very useful:
+
+\startmtxrunenvironment
+\mtxrunenv
+ {identify()}
+ {Prints out a banner identifying the current script to the user.}
+\mtxrunenv
+ {report(str)}
+ {For printing information to the terminal with the script name as prefix.}
+\mtxrunenv
+ {export()}
+ {Prints the \type {helpinfo} to the terminal, so it can easily be used for
+ documentation purposes.}
+\stopmtxrunenvironment
+
+Next up, it is good to define your scripts' functionality in functions in a
+private table. This prevents namespace pollution, and looks like this:
+
+\starttyping
+scripts = scripts or { }
+scripts.envtest = scripts.envtest or { }
+
+function scripts.envtest.runtest()
+ application.report("script name is " .. environment.ownname)
+end
+\stoptyping
+
+An finally, identify the current script, followed by handling the provided
+options (usually with an \type {if}||\type {else} statement).
+
+\starttyping
+if environment.argument("exporthelp") then
+ application.export()
+elseif environment.argument('test') then
+ scripts.envtest.runtest()
+else
+ application.help()
+end
+\stoptyping
+
+\stopsubsection
+
+\startsubsection[title=Script environment]
+
+\sMTXRUN\ includes lots of the internal \LUA\ helper libraries from \CONTEXT. We
+actually maintains a version of the script without all those libraries included,
+and before every (beta) \CONTEXT\ release, an amalgamated version of \sMTXRUN\ is
+added to the distribution. In the merging process, most all comments are stripped
+from the embedded libraries, so if you want to know details, it is better to look
+in the original \LUA\ source file.
+
+Inside \sMTXRUN, the full list of embedded libraries can be queried via the array
+\type {own.libs}:
+
+\startalign[flushleft]
+l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua
+l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua
+l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua
+l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua
+util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua
+util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua
+luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua
+trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua
+data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua
+data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua
+data-tmf.lua data -lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
+\stopalign
+
+In fact, the \LUA\ table \type {own} contains some other useful stuff like the
+script's actual disk name and location (\type {own.name} and \type {own.path})
+and some internal variables like a list of all the locations it searches for its
+embedded libraries (\type {own.list}), which is used by the \type {--selfmerge}
+option and also allows the non||amalgamated version to run (since otherwise \type
+{--selfmerge} could not be bootstrapped).
+
+\sMTXRUN\ offers a programming environment that makes it easy to write \LUA\ a
+scripts. The most important element of that environment is a \LUA\ table that is
+conveniently called \type {environment} (\type {util-env} does the actual work of
+setting that up).
+
+The bulk of \type {environment} consists of functions and variables that deal
+with the command||line given by the user as \sMTXRUN\ does quite a bit of work on
+the given command||line. The goal is to safely tuck all the given options into
+the \type {arguments} and \type {files} tables. This work is done by two
+functions called \type {initializearguments()} and \type {splitarguments()}.
+These functions are part of the \type{environment} table, but you should not need
+them as they have been called already once control is passed on to your script.
+
+\startmtxrunenvironment
+\mtxrunenv
+ {arguments}
+ {These are the processed options to the current script. The keys are option
+ names (without the leading dashes) and the value is either \type {true} or a
+ string with one level of shell quotes removed.}
+\mtxrunenv
+ {files}
+ {This array holds all the non||option arguments to the current script.
+ Typically, those are supposed to be files, but they could be any text,
+ really.}
+\mtxrunenv
+ {getargument(name,partial)}
+ {Queries the \type {arguments} table using a function. Its main reason for
+ existence is the \type {partial} argument, which allows scripts to accept
+ shortened command||line options (alias: \type {argument()}).}
+\mtxrunenv
+ {setargument(name,value)}
+ {Sets a value in the \type {arguments} table. This can be useful in
+ complicated scripts with default options.}
+\stopmtxrunenvironment
+
+In case you need access to the full command||line, there are some possibilities:
+
+\startmtxrunenvironment
+\mtxrunenv
+ {arguments_after}
+ {These are the unquoted but otherwise unprocessed arguments to your script as
+ an array.}
+\mtxrunenv
+ {arguments_before}
+ {These are the unquoted but otherwise unprocessed arguments to \sMTXRUN\
+ before your scripts' name (so the last entry is usually \type {--script}).}
+\mtxrunenv
+ {rawarguments}
+ {This is the whole unprocessed command||line as an array.}
+\mtxrunenv
+ {originalarguments}
+ {Like \type{rawarguments}, but with some top||level quotes removed.}
+\mtxrunenv
+ {reconstructcommandline(arg,noquote)}
+ {Tries to reconstruct a command||line from its arguments. It uses \type
+ {originalarguments} if no \type {arg} is given. Take care: due to the
+ vagaries of shell command||line processing, this may or may not work when
+ quoting is involved.}
+\stopmtxrunenvironment
+
+\type{environment} also stores various bits of information you may find useful:
+
+\startmtxrunenvironment
+\mtxrunenv
+ {validengines}
+ {This table contains keys for \type {luatex} and \type {luajittex}. This is
+ only relevant when \sMTXRUN\ itself is called via \LUATEX's \type {luaonly}
+ option.}
+\mtxrunenv
+ {basicengines}
+ {This table maps executable names to \type{validengines} entries.}
+\mtxrunenv
+ {default_texmfcnf}
+ {This is the \type {texmfcnf} value from \type {kpathsea}, processed for use
+ with \MKIV\ in the unlikely event this is needed.}
+\mtxrunenv
+ {homedir}
+ {The user's home directory.}
+\mtxrunenv
+ {ownbin}
+ {The name of the binary used to call \sMTXRUN.}
+\mtxrunenv
+ {ownmain}
+ {The mapped version of \type {ownbin}.}
+\mtxrunenv
+ {ownname}
+ {Full name of this instance of \sMTXRUN.}
+\mtxrunenv
+ {ownpath}
+ {The path this instance of \sMTXRUN\ resides in.}
+\mtxrunenv
+ {texmfos}
+ {Operating system root directory path.}
+\mtxrunenv
+ {texos}
+ {Operating system root directory name.}
+\mtxrunenv
+ {texroot}
+ {\CONTEXT\ root directory path.}
+\stopmtxrunenvironment
+
+As well as some functions:
+
+\startmtxrunenvironment
+\mtxrunenv
+ {texfile(filename)}
+ {Locates a {\TEX} file.}
+\mtxrunenv
+ {luafile(filename)}
+ {Locates a \LUA\ file.}
+\mtxrunenv
+ {loadluafile(filename,version)}
+ {Locates, compiles and loads a \LUA\ file, possibly in compressed \type {.luc}
+ format. In the compressed case, it uses the \type {version} to make sure the
+ compressed form is up||to||date.}
+\mtxrunenv
+ {luafilechunk(filename,silent,macros)}
+ {Locates and compiles a \LUA\ file, returning its contents as data.}
+\mtxrunenv
+ {make_format(name,arguments)}
+ {Creates a format file and stores in in the \CONTEXT\ cache, used by \type
+ {mtxrun --make}.}
+\mtxrunenv
+ {relativepath(path,root)}
+ {Returns a modified version of \type {root} based on the relative path in
+ \type {path}.}
+\mtxrunenv
+ {run_format(name,data,more)}
+ {Run a \TEX\ format file.}
+\stopmtxrunenvironment
+
+\stopsubsection
+
+\startsubsection[title=Shell return values]
+
+As explained earlier, the shell return value of \sMTXRUN\ normally indicates
+whether the script was found. If you are running a \CONTEXT\ release newer than
+September 2018 and want to modify the shell return value from within your script,
+you can use \type {os.exitcode}. Whatever value you assign to that variable will
+be the shell return value of your script.
+
+\stopsubsection
+
+\stopsection
+
\startsubject[title={Colofon}]
\starttabulate[|B|p|]
\NC author \NC \documentvariable{author},
\documentvariable{affiliation},
\documentvariable{location} \NC \NR
+ \NC \NC Taco Hoekwater, extra \sMTXRUN\ section \NC \NR
\NC version \NC \currentdate \NC \NR
\NC website \NC \documentvariable{website} \endash\
\documentvariable{support} \NC \NR
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-commands.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-commands.tex
new file mode 100644
index 000000000..ab9989895
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-commands.tex
@@ -0,0 +1,893 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-commands
+
+\startchapter[title={Commands}]
+
+\startsection[title={nodes and lpaths}]
+
+The amount of commands available for manipulating the \XML\ file is rather large.
+Many of the commands cooperate with the already discussed setups, a fancy name
+for a collection of macro calls either or not mixed with text.
+
+Most of the commands are just shortcuts to \LUA\ calls, which means that the real
+work is done by \LUA. In fact, what happens is that we have a continuous transfer
+of control from \TEX\ to \LUA, where \LUA\ prints back either data (like element
+content or attribute values) or just invokes a setup whereby it passes a
+reference to the node resolved conform the path expression. The invoked setup
+itself might return control to \LUA\ again, etc.
+
+This sounds complicated but examples will show what we mean here. First we
+present the whole repertoire of commands. Because users can read the source code,
+they might uncover more commands, but only the ones discussed here are official.
+The commands are grouped in categories.
+
+In the following sections \cmdinternal {cd:node} means a reference to a node:
+this can be the identifier of the root (the loaded xml tree) or a reference to a
+node in that tree (often the result of some lookup. A \cmdinternal {cd:lpath} is
+a fancy name for a path expression (as with \XSLT) but resolved by \LUA.
+
+\stopsection
+
+\startsection[title={commands}]
+
+There are a lot of commands available but you probably can ignore most of them.
+We try to be complete which means that there is for instance \type {\xmlfirst} as
+well as \type {\xmllast} but you probably never need the last one. There are also
+commands that were used when testing this interface and we see no reason to
+remove them. Some obscure ones are used in modules and after a while even I often
+forget that they exist. To give you an idea of what commands are important we
+show their use in generating the \CONTEXT\ command definitions (\type
+{x-set-11.mkiv}) per January 2016:
+
+\startcolumns[n=2,balance=yes]
+\starttabulate[|l|r|]
+\NC \type {\xmlall} \NC 1 \NC \NR
+\NC \type {\xmlatt} \NC 23 \NC \NR
+\NC \type {\xmlattribute} \NC 1 \NC \NR
+\NC \type {\xmlcount} \NC 1 \NC \NR
+\NC \type {\xmldoif} \NC 2 \NC \NR
+\NC \type {\xmldoifelse} \NC 1 \NC \NR
+\NC \type {\xmlfilterlist} \NC 4 \NC \NR
+\NC \type {\xmlflush} \NC 5 \NC \NR
+\NC \type {\xmlinclude} \NC 1 \NC \NR
+\NC \type {\xmlloadonly} \NC 1 \NC \NR
+\NC \type {\xmlregisterdocumentsetup} \NC 1 \NC \NR
+\NC \type {\xmlsetsetup} \NC 1 \NC \NR
+\NC \type {\xmlsetup} \NC 4 \NC \NR
+\stoptabulate
+\stopcolumns
+
+As you can see filtering, flushing and accessing attributes score high. Below we show
+the statistics of a quite complex rendering (5 variants of schoolbooks: basic book,
+answers, teachers guide, worksheets, full blown version with extensive tracing).
+
+\startcolumns[n=2,balance=yes]
+\starttabulate[|l|r|]
+\NC \type {\xmladdindex} \NC 3 \NC \NR
+\NC \type {\xmlall} \NC 5 \NC \NR
+\NC \type {\xmlappendsetup} \NC 1 \NC \NR
+\NC \type {\xmlapplyselectors} \NC 1 \NC \NR
+\NC \type {\xmlatt} \NC 40 \NC \NR
+\NC \type {\xmlattdef} \NC 9 \NC \NR
+\NC \type {\xmlattribute} \NC 10 \NC \NR
+\NC \type {\xmlbadinclusions} \NC 3 \NC \NR
+\NC \type {\xmlconcat} \NC 3 \NC \NR
+\NC \type {\xmlcount} \NC 1 \NC \NR
+\NC \type {\xmldelete} \NC 11 \NC \NR
+\NC \type {\xmldoif} \NC 39 \NC \NR
+\NC \type {\xmldoifelse} \NC 28 \NC \NR
+\NC \type {\xmldoifelsetext} \NC 13 \NC \NR
+\NC \type {\xmldoifnot} \NC 2 \NC \NR
+\NC \type {\xmldoifnotselfempty} \NC 1 \NC \NR
+\NC \type {\xmlfilter} \NC 100 \NC \NR
+\NC \type {\xmlfirst} \NC 51 \NC \NR
+\NC \type {\xmlflush} \NC 69 \NC \NR
+\NC \type {\xmlflushcontext} \NC 2 \NC \NR
+\NC \type {\xmlinclude} \NC 1 \NC \NR
+\NC \type {\xmlincludeoptions} \NC 5 \NC \NR
+\NC \type {\xmlinclusion} \NC 16 \NC \NR
+\NC \type {\xmlinjector} \NC 1 \NC \NR
+\NC \type {\xmlloaddirectives} \NC 1 \NC \NR
+\NC \type {\xmlmapvalue} \NC 4 \NC \NR
+\NC \type {\xmlmatch} \NC 1 \NC \NR
+\NC \type {\xmlprependsetup} \NC 5 \NC \NR
+\NC \type {\xmlregisterdocumentsetup} \NC 2 \NC \NR
+\NC \type {\xmlregistersetup} \NC 1 \NC \NR
+\NC \type {\xmlremapnamespace} \NC 1 \NC \NR
+\NC \type {\xmlsetfunction} \NC 2 \NC \NR
+\NC \type {\xmlsetinjectors} \NC 2 \NC \NR
+\NC \type {\xmlsetsetup} \NC 11 \NC \NR
+\NC \type {\xmlsetup} \NC 76 \NC \NR
+\NC \type {\xmlstrip} \NC 1 \NC \NR
+\NC \type {\xmlstripanywhere} \NC 1 \NC \NR
+\NC \type {\xmltag} \NC 1 \NC \NR
+\NC \type {\xmltext} \NC 53 \NC \NR
+\NC \type {\xmlvalue} \NC 2 \NC \NR
+\stoptabulate
+\stopcolumns
+
+Here many more are used but this is an exceptional case. The top is again
+dominated by filtering, flushing and attribute consulting. The list can actually
+be smaller. For instance, the \type {\xmlcount} can just as well be \type
+{\xmlfilter} with a \type {count} finalizer. There are also some special ones,
+like the injectors, that are needed for finetuning the final result.
+
+\stopsection
+
+\startsection[title={loading}]
+
+\startxmlcmd {\cmdbasicsetup{xmlloadfile}}
+ loads the file \cmdinternal {cd:file} and registers it under \cmdinternal
+ {cd:name} and applies either given or standard \cmdinternal
+ {cd:xmlsetup} (alias: \type {\xmlload})
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlloadbuffer}}
+ loads the buffer \cmdinternal {cd:buffer} and registers it under
+ \cmdinternal {cd:name} and applies either given or standard
+ \cmdinternal {cd:xmlsetup}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlloaddata}}
+ loads \cmdinternal {cd:text} and registers it under \cmdinternal
+ {cd:name} and applies either given or standard \cmdinternal
+ {cd:xmlsetup}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlloadonly}}
+ loads \cmdinternal {cd:text} and registers it under \cmdinternal
+ {cd:name} and applies either given or standard \cmdinternal
+ {cd:xmlsetup} but doesn't flush the content
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlinclude}}
+ includes the file specified by attribute \cmdinternal {cd:name} of the
+ element located by \cmdinternal {cd:lpath} at node \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlprocessfile}}
+ registers file \cmdinternal {cd:file} as \cmdinternal {cd:name} and
+ process the tree starting with \cmdinternal {cd:xmlsetup} (alias:
+ \type {\xmlprocess})
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlprocessbuffer}}
+ registers buffer \cmdinternal {cd:name} as \cmdinternal {cd:name} and process
+ the tree starting with \cmdinternal {cd:xmlsetup}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlprocessdata}}
+ registers \cmdinternal {cd:text} as \cmdinternal {cd:name} and process
+ the tree starting with \cmdinternal {cd:xmlsetup}
+\stopxmlcmd
+
+The initial setup defaults to \type {xml:process} that is defined
+as follows:
+
+\starttyping
+\startsetups xml:process
+ \xmlregistereddocumentsetups\xmldocument
+ \xmlmain\xmldocument
+\stopsetups
+\stoptyping
+
+First we apply the setups associated with the document (including common setups)
+and then we flush the whole document. The macro \type {\xmldocument} expands to
+the current document id. There is also \type {\xmlself} which expands to the
+current node number (\type {#1} in setups).
+
+\startxmlcmd {\cmdbasicsetup{xmlmain}}
+ returns the whole document
+\stopxmlcmd
+
+Normally such a flush will trigger a chain reaction of setups associated with the
+child elements.
+
+\stopsection
+
+\startsection[title={saving}]
+
+\startxmlcmd {\cmdbasicsetup{xmlsave}}
+ saves the given node \cmdinternal {cd:node} in the file \cmdinternal {cd:file}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmltofile}}
+ saves the match of \cmdinternal {cd:lpath} in the file \cmdinternal {cd:file}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmltobuffer}}
+ saves the match of \cmdinternal {cd:lpath} in the buffer \cmdinternal {cd:buffer}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmltobufferverbose}}
+ saves the match of \cmdinternal {cd:lpath} verbatim in the buffer \cmdinternal
+ {cd:buffer}
+\stopxmlcmd
+
+% \startxmlcmd {\cmdbasicsetup{xmltoparameters}}
+% converts the match of \cmdinternal {cd:lpath} to key|/|values (for tracing)
+% \stopxmlcmd
+
+The next command is only needed when you have messed with the tree using
+\LUA\ code.
+
+\startxmlcmd {\cmdbasicsetup{xmladdindex}}
+ (re)indexes a tree
+\stopxmlcmd
+
+The following macros are only used in special situations and are not really meant
+for users.
+
+\startxmlcmd {\cmdbasicsetup{xmlraw}}
+ flush the content if \cmdinternal {cd:node} with original entities
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{startxmlraw}}
+ flush the wrapped content with original entities
+\stopxmlcmd
+
+\stopsection
+
+\startsection[title={flushing data}]
+
+When we flush an element, the associated \XML\ setups are expanded. The most
+straightforward way to flush an element is the following. Keep in mind that the
+returned values itself can trigger setups and therefore flushes.
+
+\startxmlcmd {\cmdbasicsetup{xmlflush}}
+ returns all nodes under \cmdinternal {cd:node}
+\stopxmlcmd
+
+You can restrict flushing by using commands that accept a specification.
+
+\startxmlcmd {\cmdbasicsetup{xmltext}}
+ returns the text of the matching \cmdinternal {cd:lpath} under \cmdinternal
+ {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlpure}}
+ returns the text of the matching \cmdinternal {cd:lpath} under \cmdinternal
+ {cd:node} without \type {\Ux} escaped special \TEX\ characters
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlflushtext}}
+ returns the text of the \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlflushpure}}
+ returns the text of the \cmdinternal {cd:node} without \type {\Ux} escaped
+ special \TEX\ characters
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlnonspace}}
+ returns the text of the matching \cmdinternal {cd:lpath} under \cmdinternal
+ {cd:node} without embedded spaces
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlall}}
+ returns all nodes under \cmdinternal {cd:node} that matches \cmdinternal
+ {cd:lpath}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmllastmatch}}
+ returns all nodes found in the last match
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlfirst}}
+ returns the first node under \cmdinternal {cd:node} that matches \cmdinternal
+ {cd:lpath}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmllast}}
+ returns the last node under \cmdinternal {cd:node} that matches \cmdinternal
+ {cd:lpath}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlfilter}}
+ at a match of \cmdinternal {cd:lpath} a given filter \type {filter} is applied
+ and the result is returned
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlsnippet}}
+ returns the \cmdinternal {cd:number}\high{th} element under \cmdinternal
+ {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlposition}}
+ returns the \cmdinternal {cd:number}\high{th} match of \cmdinternal
+ {cd:lpath} at node \cmdinternal {cd:node}; a negative number starts at the
+ end (alias: \type {\xmlindex})
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlelement}}
+ returns the \cmdinternal {cd:number}\high{th} child of node \cmdinternal {cd:node};
+ a negative number starts at the end
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlpos}}
+ returns the index (position) in the parent node of \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlconcat}}
+ returns the sequence of nodes that match \cmdinternal {cd:lpath} at
+ \cmdinternal {cd:node} whereby \cmdinternal {cd:text} is put between each
+ match
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlconcatrange}}
+ returns the \cmdinternal {cd:first}\high {th} upto \cmdinternal
+ {cd:last}\high {th} of nodes that match \cmdinternal {cd:lpath} at
+ \cmdinternal {cd:node} whereby \cmdinternal {cd:text} is put between each
+ match
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlcommand}}
+ apply the given \cmdinternal {cd:xmlsetup} to each match of \cmdinternal
+ {cd:lpath} at node \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlstrip}}
+ remove leading and trailing spaces from nodes under \cmdinternal {cd:node}
+ that match \cmdinternal {cd:lpath}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlstripped}}
+ remove leading and trailing spaces from nodes under \cmdinternal {cd:node}
+ that match \cmdinternal {cd:lpath} and return the content afterwards
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlstripnolines}}
+ remove leading and trailing spaces as well as collapse embedded spaces
+ from nodes under \cmdinternal {cd:node} that match \cmdinternal {cd:lpath}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlstrippednolines}}
+ remove leading and trailing spaces as well as collapse embedded spaces from
+ nodes under \cmdinternal {cd:node} that match \cmdinternal {cd:lpath} and
+ return the content afterwards
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlverbatim}}
+ flushes the content verbatim code (without any wrapping, i.e. no fonts
+ are selected and such)
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlinlineverbatim}}
+ return the content of the node as inline verbatim code; no further
+ interpretation (expansion) takes place and spaces are honoured; it uses the
+ following wrapper
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{startxmlinlineverbatim}}
+ wraps inline verbatim mode using the environment specified (a prefix \type
+ {xml:} is added to the environment name)
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldisplayverbatim}}
+ return the content of the node as display verbatim code; no further
+ interpretation (expansion) takes place and leading and trailing spaces and
+ newlines are treated special; it uses the following wrapper
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{startxmldisplayverbatim}}
+ wraps the content in display verbatim using the environment specified (a prefix
+ \type {xml:} is added to the environment name)
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlprettyprint}}
+ pretty print (with colors) the node \cmdinternal {cd:node}; use the \CONTEXT\
+ \SCITE\ lexers when available (\type {\usemodule [scite]})
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlflushspacewise}}
+ flush node \cmdinternal {cd:node} obeying spaces and newlines
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlflushlinewise}}
+ flush node \cmdinternal {cd:node} obeying newlines
+\stopxmlcmd
+
+\stopsection
+
+\startsection[title={information}]
+
+The following commands return strings. Normally these are used in tests.
+
+\startxmlcmd {\cmdbasicsetup{xmlname}}
+ returns the complete name (including namespace prefix) of the
+ given \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlnamespace}}
+ returns the namespace of the given \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmltag}}
+ returns the tag of the element, without namespace prefix
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlcount}}
+ returns the number of matches of \cmdinternal {cd:lpath} at node \cmdinternal
+ {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlatt}}
+ returns the value of attribute \cmdinternal {cd:name} or empty if no such
+ attribute exists
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlattdef}}
+ returns the value of attribute \cmdinternal {cd:name} or \cmdinternal
+ {cd:string} if no such attribute exists
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlrefatt}}
+ returns the value of attribute \cmdinternal {cd:name} or empty if no such
+ attribute exists; a leading \type {#} is removed (nicer for tex)
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlchainatt}}
+ returns the value of attribute \cmdinternal {cd:name} or empty if no such
+ attribute exists; backtracks till a match is found
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlchainattdef}}
+ returns the value of attribute \cmdinternal {cd:name} or \cmdinternal
+ {cd:string} if no such attribute exists; backtracks till a match is found
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlattribute}}
+ finds a first match for \cmdinternal {cd:lpath} at \cmdinternal {cd:node} and
+ returns the value of attribute \cmdinternal {cd:name} or empty if no such
+ attribute exists
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlattributedef}}
+ finds a first match for \cmdinternal {cd:lpath} at \cmdinternal {cd:node} and
+ returns the value of attribute \cmdinternal {cd:name} or \cmdinternal
+ {cd:text} if no such attribute exists
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmllastatt}}
+ returns the last attribute found (this avoids a lookup)
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlsetatt}}
+ set the value of attribute \cmdinternal {cd:name}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlsetattribute}}
+ set the value of attribute \cmdinternal {cd:name} for each match of \cmdinternal
+ {cd:lpath}
+\stopxmlcmd
+
+\stopsection
+
+\startsection[title={manipulation}]
+
+You can use \LUA\ code to manipulate the tree and it makes no sense to duplicate
+this in \TEX. In the future we might provide an interface to some of this
+functionality. Keep in mind that manipuating the tree might have side effects as
+we maintain several indices into the tree that also needs to be updated then.
+
+\stopsection
+
+\startsection[title={integration}]
+
+If you write a module that deals with \XML, for instance processing cals tables,
+then you need ways to control specific behaviour. For instance, you might want to
+add a background to the table. Such directives are collected in \XML\ files and
+can be loaded on demand.
+
+\startxmlcmd {\cmdbasicsetup{xmlloaddirectives}}
+ loads \CONTEXT\ directives from \cmdinternal {cd:file} that will get
+ interpreted when processing documents
+\stopxmlcmd
+
+A directives definition file looks as follows:
+
+\starttyping
+<?xml version="1.0" standalone="yes"?>
+
+<directives>
+ <directive attribute='id' value="100"
+ setup="cdx:100"/>
+ <directive attribute='id' value="101"
+ setup="cdx:101"/>
+ <directive attribute='cdx' value="colors" element="cals:table"
+ setup="cdx:cals:table:colors"/>
+ <directive attribute='cdx' value="vertical" element="cals:table"
+ setup="cdx:cals:table:vertical"/>
+ <directive attribute='cdx' value="noframe" element="cals:table"
+ setup="cdx:cals:table:noframe"/>
+ <directive attribute='cdx' value="*" element="cals:table"
+ setup="cdx:cals:table:*"/>
+</directives>
+\stoptyping
+
+Examples of usage can be found in \type {x-cals.mkiv}. The directive is triggered
+by an attribute. Instead of a setup you can specify a setup to be applied before
+and after the node gets flushed.
+
+\startxmlcmd {\cmdbasicsetup{xmldirectives}}
+ apply the setups directive associated with the node
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldirectivesbefore}}
+ apply the before directives associated with the node
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldirectivesafter}}
+ apply the after directives associated with the node
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlinstalldirective}}
+ defines a directive that hooks into a handler
+\stopxmlcmd
+
+Normally a directive will be put in the \XML\ file, for instance as:
+
+\starttyping
+<?context-mathml-directive minus reduction yes ?>
+\stoptyping
+
+Here the \type {mathml} is the general class of directives and \type {minus} a
+subclass, in our case a specific element.
+
+\stopsection
+
+\startsection[title={setups}]
+
+The basic building blocks of \XML\ processing are setups. These are just
+collections of macros that are expanded. These setups get one argument passed
+(\type {#1}):
+
+\starttyping
+\startxmlsetups somedoc:somesetup
+ \xmlflush{#1}
+\stopxmlsetups
+\stoptyping
+
+This argument is normally a number that internally refers to a specific node in
+the \XML\ tree. The user should see it as an abstract reference and not depend on
+its numeric property. Just think of it as \quote {the current node}. You can (and
+probably will) call such setups using:
+
+\startxmlcmd {\cmdbasicsetup{xmlsetup}}
+ expands setup \cmdinternal {cd:setup} and pass \cmdinternal {cd:node} as
+ argument
+\stopxmlcmd
+
+However, in most cases the setups are associated to specific elements,
+something that users of \XSLT\ might recognize as templates.
+
+\startxmlcmd {\cmdbasicsetup{xmlsetfunction}}
+ associates function \cmdinternal {cd:luafunction} to the elements in
+ namespace \cmdinternal {cd:name} that match \cmdinternal {cd:lpath}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlsetsetup}}
+ associates setups \cmdinternal {cd:setup} (\TEX\ code) with the matching
+ nodes of \cmdinternal {cd:lpath} or root \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlprependsetup}}
+ pushes \cmdinternal {cd:setup} to the front of global list of setups
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlappendsetup}}
+ adds \cmdinternal {cd:setup} to the global list of setups to be applied
+ (alias: \type{\xmlregistersetup})
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlbeforesetup}}
+ pushes \cmdinternal {cd:setup} into the global list of setups; the
+ last setup is the position
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlaftersetup}}
+ adds \cmdinternal {cd:setup} to the global list of setups; the last setup
+ is the position
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlremovesetup}}
+ removes \cmdinternal {cd:setup} from the global list of setups
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlprependdocumentsetup}}
+ pushes \cmdinternal {cd:setup} to the front of list of setups to be applied
+ to \cmdinternal {cd:name}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlappenddocumentsetup}}
+ adds \cmdinternal {cd:setup} to the list of setups to be applied to
+ \cmdinternal {cd:name} (you can also use the alias: \type
+ {\xmlregisterdocumentsetup})
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlbeforedocumentsetup}}
+ pushes \cmdinternal {cd:setup} into the setups to be applied to \cmdinternal
+ {cd:name}; the last setup is the position
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlafterdocumentsetup}}
+ adds \cmdinternal {cd:setup} to the setups to be applied to \cmdinternal
+ {cd:name}; the last setup is the position
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlremovedocumentsetup}}
+ removes \cmdinternal {cd:setup} from the global list of setups to be applied
+ to \cmdinternal {cd:name}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlresetsetups}}
+ removes all global setups
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlresetdocumentsetups}}
+ removes all setups from the \cmdinternal {cd:name} specific list of setups to
+ be applied
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlflushdocumentsetups}{setup}}
+ applies \cmdinternal {cd:setup} (can be a list) to \cmdinternal {cd:name}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlregisteredsetups}}
+ applies all global setups to the current document
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlregistereddocumentsetups}}
+ applies all document specific \cmdinternal {cd:setup} to document
+ \cmdinternal {cd:name}
+\stopxmlcmd
+
+\stopsection
+
+\startsection[title={testing}]
+
+The following test macros all take a \cmdinternal {cd:node} as first argument
+and an \cmdinternal {cd:lpath} as second:
+
+\startxmlcmd {\cmdbasicsetup{xmldoif}}
+ expands to \cmdinternal {cd:true} when \cmdinternal {cd:lpath} matches at
+ node \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifnot}}
+ expands to \cmdinternal {cd:true} when \cmdinternal {cd:lpath} does not match
+ at node \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifelse}}
+ expands to \cmdinternal {cd:true} when \cmdinternal {cd:lpath} matches at
+ node \cmdinternal {cd:node} and to \cmdinternal {cd:false} otherwise
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoiftext}}
+ expands to \cmdinternal {cd:true} when the node matching \cmdinternal
+ {cd:lpath} at node \cmdinternal {cd:node} has some content
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifnottext}}
+ expands to \cmdinternal {cd:true} when the node matching \cmdinternal
+ {cd:lpath} at node \cmdinternal {cd:node} has no content
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifelsetext}}
+ expands to \cmdinternal {cd:true} when the node matching \cmdinternal
+ {cd:lpath} at node \cmdinternal {cd:node} has content and to \cmdinternal
+ {cd:false} otherwise
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifatt}}
+ expands to \cmdinternal {cd:true} when the attribute matching \cmdinternal
+ {cd:node} and the name given as second argument matches the third argument
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifnotatt}}
+ expands to \cmdinternal {cd:true} when the attribute matching \cmdinternal
+ {cd:node} and the name given as second argument differs from the third
+ argument
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifelseatt}}
+ expands to \cmdinternal {cd:true} when the attribute matching \cmdinternal
+ {cd:node} and the name given as second argument matches the third argument
+ and to \cmdinternal {cd:false} otherwise
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifelseempty}}
+ expands to \cmdinternal {cd:true} when the node matching \cmdinternal
+ {cd:lpath} at node \cmdinternal {cd:node} is empty and to \cmdinternal
+ {cd:false} otherwise
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifelseselfempty}}
+ expands to \cmdinternal {cd:true} when the node is empty and to \cmdinternal
+ {cd:false} otherwise
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifselfempty}}
+ expands to \cmdinternal {cd:true} when \cmdinternal {cd:node} is empty
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifnotselfempty}}
+ expands to \cmdinternal {cd:true} when \cmdinternal {cd:node} is not empty
+\stopxmlcmd
+
+\stopsection
+
+\startsection[title={initialization}]
+
+The general setup command (not to be confused with setups) that deals with the
+\MKIV\ tree handler is \type {\setupxml}. There are currently only a few options.
+
+\cmdfullsetup{setupxml}
+
+When you set \type {default} to \cmdinternal {cd:text} elements with no setup
+assigned will end up as text. When set to \type {hidden} such elements will be
+hidden. You can apply the default yourself using:
+
+\startxmlcmd {\cmdbasicsetup{xmldefaulttotext}}
+ presets the tree with root \cmdinternal {cd:node} to the handlers set up with
+ \type {\setupxml} option \cmdinternal{default}
+\stopxmlcmd
+
+You can set \type {compress} to \type {yes} in which case comment is stripped
+from the tree when the file is read.
+
+\startxmlcmd {\cmdbasicsetup{xmlregisterns}}
+ associates an internal namespace (like \type {mml}) with one given in the
+ document as \URL\ (like mathml)
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlremapname}}
+ changes the namespace and tag of the matching elements
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlremapnamespace}}
+ replaces all references to the given namespace to a new one (applied
+ recursively)
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlchecknamespace}}
+ sets the namespace of the matching elements unless a namespace is already set
+\stopxmlcmd
+
+\stopsection
+
+\startsection[title={helpers}]
+
+Often an attribute will determine the rendering and this may result in many
+tests. Especially when we have multiple attributes that control the output such
+tests can become rather extensive and redundant because one gets $n\times m$ or
+more such tests.
+
+Therefore we have a convenient way to map attributes onto for instance strings or
+commands.
+
+\startxmlcmd {\cmdbasicsetup{xmlmapvalue}}
+ associate a \cmdinternal {cd:text} with a \cmdinternal {cd:category} and
+ \cmdinternal {cd:name} (alias: \type{\xmlmapval})
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlvalue}}
+ expand the value associated with a \cmdinternal {cd:category} and
+ \cmdinternal {cd:name} and if not resolved, expand to the \cmdinternal
+ {cd:text} (alias: \type{\xmlval})
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmldoifelsevalue}}
+ associate a \cmdinternal {cd:text} with a \cmdinternal {cd:category} and
+ \cmdinternal {cd:name}
+\stopxmlcmd
+
+This is used as follows. We define a couple of mappings in the same category:
+
+\starttyping
+\xmlmapvalue{emph}{bold} {\bf}
+\xmlmapvalue{emph}{italic}{\it}
+\stoptyping
+
+Assuming that we have associated the following setup with the \type {emph}
+element, we can say (with \type {#1} being the current element):
+
+\starttyping
+\startxmlsetups demo:emph
+ \begingroup
+ \xmlvalue{emph}{\xmlatt{#1}{type}}{}
+ \endgroup
+\stopxmlsetups
+\stoptyping
+
+In this case we have no default. The \type {type} attribute triggers the actions,
+as in:
+
+\starttyping
+normal <emph type='bold'>bold</emph> normal
+\stoptyping
+
+This mechanism is not really bound to elements and attributes so you can use this
+mechanism for other purposes as well.
+
+\stopsection
+
+\startsection[title={Parameters}]
+
+\startbuffer[test]
+<something whatever="alpha">
+ <what>
+ beta
+ </what>
+</something>
+\stopbuffer
+
+\startbuffer
+\startxmlsetups xml:mysetups
+ \xmlsetsetup{\xmldocument}{*}{xml:*}
+\stopxmlsetups
+
+\xmlregistersetup{xml:mysetups}
+
+\startxmlsetups xml:something
+ parameter : \xmlpar {#1}{whatever}\par
+ attribute : \xmlatt {#1}{whatever}\par
+ text : \xmlfirst {#1}{what} \par
+ \xmlsetpar{#1}{whatever}{gamma}
+ parameter : \xmlpar {#1}{whatever}\par
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:what
+ what: \xmlflush{#1}\par
+ parameter : \xmlparam{#1}{..}{whatever}\par
+\stopxmlsetups
+
+\xmlprocessbuffer{main}{test}{}
+\stopbuffer
+
+Say that we have this \XML\ blob:
+
+\typebuffer[test]
+
+With:
+
+\typebuffer
+
+we get:
+
+\getbuffer
+
+Parameters are stored with a node.
+
+\startxmlcmd {\cmdbasicsetup{xmlpar}}
+ returns the value of parameter \cmdinternal {cd:name} or empty if no such
+ parameter exists
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlparam}}
+ finds a first match for \cmdinternal {cd:lpath} at \cmdinternal {cd:node} and
+ returns the value of parameter \cmdinternal {cd:name} or empty if no such
+ parameter exists
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmllastpar}}
+ returns the last parameter found (this avoids a lookup)
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlsetpar}}
+ set the value of parameter \cmdinternal {cd:name}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlsetparam}}
+ set the value of parameter \cmdinternal {cd:name} for each match of \cmdinternal
+ {cd:lpath}
+\stopxmlcmd
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-contents.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-contents.tex
new file mode 100644
index 000000000..e0787ec5f
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-contents.tex
@@ -0,0 +1,12 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-contents
+
+\starttitle[title=Contents]
+
+\placelist
+ [chapter,section]
+
+\stoptitle
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-converter.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-converter.tex
new file mode 100644
index 000000000..a457f962b
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-converter.tex
@@ -0,0 +1,300 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-converter
+
+\startchapter[title={Setting up a converter}]
+
+\startsection[title={from structure to setup}]
+
+We use a very simple document structure for demonstrating how a converter is
+defined. In practice a mapping will be more complex, especially when we have a
+style with complex chapter openings using data coming from all kind of places,
+different styling of sections with the same name, selectively (out of order)
+flushed content, special formatting, etc.
+
+\typefile{manual-demo-1.xml}
+
+Say that this document is stored in the file \type {demo.xml}, then the following
+code can be used as starting point:
+
+\starttyping
+\startxmlsetups xml:demo:base
+ \xmlsetsetup{#1}{document|section|p}{xml:demo:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{demo}{xml:demo:base}
+
+\startxmlsetups xml:demo:document
+ \starttitle[title={Contents}]
+ \placelist[chapter]
+ \stoptitle
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:demo:section
+ \startchapter[title=\xmlfirst{#1}{/title}]
+ \xmlfirst{#1}{/content}
+ \stopchapter
+\stopxmlsetups
+
+\startxmlsetups xml:demo:p
+ \xmlflush{#1}\endgraf
+\stopxmlsetups
+
+\xmlprocessfile{demo}{demo.xml}{}
+\stoptyping
+
+Watch out! These are not just setups, but specific \XML\ setups which get an
+argument passed (the \type {#1}). If for some reason your \XML\ processing fails,
+it might be that you mistakenly have used a normal setup definition. The argument
+\type {#1} represents the current node (element) and is a unique identifier. For
+instance a \type {<p>..</p>} can have an identifier {demo::5}. So, we can get
+something:
+
+\starttyping
+\xmlflush{demo::5}\endgraf
+\stoptyping
+
+but as well:
+
+\starttyping
+\xmlflush{demo::6}\endgraf
+\stoptyping
+
+Keep in mind that the references tor the actual nodes (elements) are
+abstractions, you never see those \type {<id>::<number>}'s, because we will use
+either the abstract \type {#1} (any node) or an explicit reference like \type
+{demo}. The previous setup when issued will be like:
+
+\starttyping
+\startchapter[title=\xmlfirst{demo::3}{/title}]
+ \xmlfirst{demo::4}{/content}
+\stopchapter
+\stoptyping
+
+Here the \type {title} is used to typeset the chapter title but also for an entry
+in the table of contents. At the moment the title is typeset the \XML\ node gets
+looked up and expanded in real text. However, for the list it gets stored for
+later use. One can argue that this is not needed for \XML, because one can just
+filter all the titles and use page references, but then one also looses the
+control one normally has over such titles. For instance it can be that some
+titles are rendered differently and for that we need to keep track of usage.
+Doing that with transformations or filtering is often more complex than leaving
+that to \TEX. As soon as the list gets typeset, the reference (\type {demo::#3})
+is used for the lookup. This is because by default the title is stored as given.
+So, as long as we make sure the \XML\ source is loaded before the table of
+contents is typeset we're ok. Later we will look into this in more detail, for
+now it's enough to know that in most cases the abstract \type {#1} reference will
+work out ok.
+
+Contrary to the style definitions this interface looks rather low level (with no
+optional arguments) and the main reason for this is that we want processing to be
+fast. So, the basic framework is:
+
+\starttyping
+\startxmlsetups xml:demo:base
+ % associate setups with elements
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{demo}{xml:demo:base}
+
+% define setups for matches
+
+\xmlprocessfile{demo}{demo.xml}{}
+\stoptyping
+
+In this example we mostly just flush the content of an element and in the case of
+a section we flush explicit child elements. The \type {#1} in the example code
+represents the current element. The line:
+
+\starttyping
+\xmlsetsetup{demo}{*}{-}
+\stoptyping
+
+sets the default for each element to \quote {just ignore it}. A \type {+} would
+make the default to always flush the content. This means that at this point we
+only handle:
+
+\starttyping
+<section>
+ <title>Some title</title>
+ <content>
+ <p>a paragraph of text</p>
+ </content>
+</section>
+\stoptyping
+
+In the next section we will deal with the slightly more complex itemize and
+figure placement. At first sight all these setups may look overkill but keep in
+mind that normally the number of elements is rather limited. The complexity is
+often in the style and having access to each snippet of content is actually
+quite handy for that.
+
+\stopsection
+
+\startsection[title={alternative solutions}]
+
+Dealing with an itemize is rather simple (as long as we forget about
+attributes that control the behaviour):
+
+\starttyping
+<itemize>
+ <item>first</item>
+ <item>second</item>
+</itemize>
+\stoptyping
+
+First we need to add \type {itemize} to the setup assignment (unless we've used
+the wildcard \type {*}):
+
+\starttyping
+\xmlsetsetup{demo}{document|section|p|itemize}{xml:demo:*}
+\stoptyping
+
+The setup can look like:
+
+\starttyping
+\startxmlsetups xml:demo:itemize
+ \startitemize
+ \xmlfilter{#1}{/item/command(xml:demo:itemize:item)}
+ \stopitemize
+\stopxmlsetups
+
+\startxmlsetups xml:demo:itemize:item
+ \startitem
+ \xmlflush{#1}
+ \stopitem
+\stopxmlsetups
+\stoptyping
+
+An alternative is to map item directly:
+
+\starttyping
+\xmlsetsetup{demo}{document|section|p|itemize|item}{xml:demo:*}
+\stoptyping
+
+and use:
+
+\starttyping
+\startxmlsetups xml:demo:itemize
+ \startitemize
+ \xmlflush{#1}
+ \stopitemize
+\stopxmlsetups
+
+\startxmlsetups xml:demo:item
+ \startitem
+ \xmlflush{#1}
+ \stopitem
+\stopxmlsetups
+\stoptyping
+
+Sometimes, a more local solution using filters and \type {/command(...)} makes more
+sense, especially when the \type {item} tag is used for other purposes as well.
+
+Explicit flushing with \type {command} is definitely the way to go when you have
+complex products. In one of our projects we compose math school books from many
+thousands of small \XML\ files, and from one source set several products are
+typeset. Within a book sections get done differently, content gets used, ignored
+or interpreted differently depending on the kind of content, so there is a
+constant checking of attributes that drive the rendering. In that a generic setup
+for a title element makes less sense than explicit ones for each case. (We're
+talking of huge amounts of files here, including multiple images on each rendered
+page.)
+
+When using \type {command} you can pass two arguments, the first is the setup for
+the match, the second one for the miss, as in:
+
+\starttyping
+\xmlfilter{#1}{/element/command(xml:true,xml:false)}
+\stoptyping
+
+Back to the example, this leaves us with dealing with the resources, like
+figures:
+
+\starttyping
+<resource type='figure'>
+ <caption>A picture of a cow.</caption>
+ <content><external file="cow.pdf"/></content>
+</resource>
+\stoptyping
+
+Here we can use a more restricted match:
+
+\starttyping
+\xmlsetsetup{demo}{resource[@type='figure']}{xml:demo:figure}
+\xmlsetsetup{demo}{external}{xml:demo:*}
+\stoptyping
+
+and the definitions:
+
+\starttyping
+\startxmlsetups xml:demo:figure
+ \placefigure
+ {\xmlfirst{#1}{/caption}}
+ {\xmlfirst{#1}{/content}}
+\stopxmlsetups
+
+\startxmlsetups xml:demo:external
+ \externalfigure[\xmlatt{#1}{file}]
+\stopxmlsetups
+\stoptyping
+
+At this point it is good to notice that \type {\xmlatt{#1}{file}} is passed as it
+is: a macro call. This means that when a macro like \type {\externalfigure} uses
+the first argument frequently without first storing its value, the lookup is done
+several times. A solution for this is:
+
+\starttyping
+\startxmlsetups xml:demo:external
+ \expanded{\externalfigure[\xmlatt{#1}{file}]}
+\stopxmlsetups
+\stoptyping
+
+Because the lookup is rather fast, normally there is no need to bother about this
+too much because internally \CONTEXT\ already makes sure such expansion happens
+only once.
+
+An alternative definition for placement is the following:
+
+\starttyping
+\xmlsetsetup{demo}{resource}{xml:demo:resource}
+\stoptyping
+
+with:
+
+\starttyping
+\startxmlsetups xml:demo:resource
+ \placefloat
+ [\xmlatt{#1}{type}]
+ {\xmlfirst{#1}{/caption}}
+ {\xmlfirst{#1}{/content}}
+\stopxmlsetups
+\stoptyping
+
+This way you can specify \type {table} as type too. Because you can define your
+own float types, more complex variants are also possible. In that case it makes
+sense to provide some default behaviour too:
+
+\starttyping
+\definefloat[figure-here][figure][default=here]
+\definefloat[figure-left][figure][default=left]
+\definefloat[table-here] [table] [default=here]
+\definefloat[table-left] [table] [default=left]
+
+\startxmlsetups xml:demo:resource
+ \placefloat
+ [\xmlattdef{#1}{type}{figure}-\xmlattdef{#1}{location}{here}]
+ {\xmlfirst{#1}{/caption}}
+ {\xmlfirst{#1}{/content}}
+\stopxmlsetups
+\stoptyping
+
+In this example we support two types and two locations. We default to a figure
+placed (when possible) at the current location.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-examples.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-examples.tex
new file mode 100644
index 000000000..064510d6d
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-examples.tex
@@ -0,0 +1,948 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-examples
+
+\startchapter[title=Examples]
+
+\startsection[title=attribute chains]
+
+In \CSS, when an attribute is not present, the parent element is checked, and when
+not found again, the lookup follows the chain till a match is found or the root is
+reached. The following example demonstrates how such a chain lookup works.
+
+\startbuffer[test]
+<something mine="1" test="one" more="alpha">
+ <whatever mine="2" test="two">
+ <whocares mine="3">
+ <!-- this is a test -->
+ </whocares>
+ </whatever>
+</something>
+\stopbuffer
+
+\typebuffer[test]
+
+We apply the following setups to this tree:
+
+\startbuffer[setups]
+\startxmlsetups xml:common
+ [
+ \xmlchainatt{#1}{mine},
+ \xmlchainatt{#1}{test},
+ \xmlchainatt{#1}{more},
+ \xmlchainatt{#1}{none}
+ ]\par
+\stopxmlsetups
+
+\startxmlsetups xml:something
+ something: \xmlsetup{#1}{xml:common}
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:whatever
+ whatever: \xmlsetup{#1}{xml:common}
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:whocares
+ whocares: \xmlsetup{#1}{xml:common}
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:mysetups
+ \xmlsetsetup{#1}{something|whatever|whocares}{xml:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{example-1}{xml:mysetups}
+
+\xmlprocessbuffer{example-1}{test}{}
+\stopbuffer
+
+\typebuffer[setups]
+
+This gives:
+
+\start
+ \getbuffer[setups]
+\stop
+
+\stopsection
+
+\startsection[title=conditional setups]
+
+Say that we have this code:
+
+\starttyping
+\xmldoifelse {#1} {/what[@a='1']} {
+ \xmlfilter {#1} {/what/command('xml:yes')}
+} {
+ \xmlfilter {#1} {/what/command('xml:nop')}
+}
+\stoptyping
+
+Here we first determine if there is a child \type {what} with attribute \type {a}
+set to \type {1}. Depending on the outcome again we check the child nodes for
+being named \type {what}. A faster solution which also takes less code is this:
+
+\starttyping
+\xmlfilter {#1} {/what[@a='1']/command('xml:yes','xml:nop')}
+\stoptyping
+
+\stopsection
+
+\startsection[title=manipulating]
+
+Assume that we have the following \XML\ data:
+
+\startbuffer[test]
+<A>
+ <B>right</B>
+ <B>wrong</B>
+</A>
+\stopbuffer
+
+\typebuffer[test]
+
+But, instead of \type {right} we want to see \type {okay}. We can do that with a
+finalizer:
+
+\startbuffer
+\startluacode
+local rehash = {
+ ["right"] = "okay",
+}
+
+function xml.finalizers.tex.Okayed(collected,what)
+ for i=1,#collected do
+ if what == "all" then
+ local str = xml.text(collected[i])
+ context(rehash[str] or str)
+ else
+ context(str)
+ end
+ end
+end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startbuffer
+\startxmlsetups xml:A
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:B
+ (It's \xmlfilter{#1}{./Okayed("all")})
+\stopxmlsetups
+
+\startxmlsetups xml:testsetups
+ \xmlsetsetup{#1}{A|B}{xml:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{example-2}{xml:testsetups}
+\xmlprocessbuffer{example-2}{test}{}
+\stopbuffer
+
+\typebuffer
+
+The result is: \start \inlinebuffer \stop
+
+\stopsection
+
+\startsection[title=cross referencing]
+
+A rather common way to add cross references to \XML\ files is to borrow the
+asymmetrical id's from \HTML. This means that one cannot simply use a value
+of (say) \type {href} to locate an \type {id}. The next example came up on
+the \CONTEXT\ mailing list.
+
+\startbuffer[test]
+<doc>
+ <p>Text
+ <a href="#fn1" class="footnoteref" id="fnref1"><sup>1</sup></a> and
+ <a href="#fn2" class="footnoteref" id="fnref2"><sup>2</sup></a>
+ </p>
+ <div class="footnotes">
+ <hr />
+ <ol>
+ <li id="fn1"><p>A footnote.<a href="#fnref1">↩</a></p></li>
+ <li id="fn2"><p>A second footnote.<a href="#fnref2">↩</a></p></li>
+ </ol>
+ </div>
+</doc>
+\stopbuffer
+
+\typebuffer[test]
+
+We give two variants for dealing with such references. The first solution does
+lookups and depending on the size of the file can be somewhat inefficient.
+
+\startbuffer
+\startxmlsetups xml:doc
+ \blank
+ \xmlflush{#1}
+ \blank
+\stopxmlsetups
+
+\startxmlsetups xml:p
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:footnote
+ (variant 1)\footnote
+ {\xmlfirst
+ {example-3-1}
+ {div[@class='footnotes']/ol/li[@id='\xmlrefatt{#1}{href}']}}
+\stopxmlsetups
+
+\startxmlsetups xml:initialize
+ \xmlsetsetup{#1}{p|doc}{xml:*}
+ \xmlsetsetup{#1}{a[@class='footnoteref']}{xml:footnote}
+ \xmlsetsetup{#1}{div[@class='footnotes']}{xml:nothing}
+\stopxmlsetups
+
+\xmlresetdocumentsetups{*}
+\xmlregisterdocumentsetup{example-3-1}{xml:initialize}
+
+\xmlprocessbuffer{example-3-1}{test}{}
+\stopbuffer
+
+\typebuffer
+
+This will typeset two footnotes.
+
+\getbuffer
+
+The second variant collects the references so that the time spend on lookups is
+less.
+
+\startbuffer
+\startxmlsetups xml:doc
+ \blank
+ \xmlflush{#1}
+ \blank
+\stopxmlsetups
+
+\startxmlsetups xml:p
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startluacode
+ userdata.notes = {}
+\stopluacode
+
+\startxmlsetups xml:collectnotes
+ \ctxlua{userdata.notes['\xmlrefatt{#1}{id}'] = '#1'}
+\stopxmlsetups
+
+\startxmlsetups xml:footnote
+ (variant 2)\footnote
+ {\xmlflush
+ {\cldcontext{userdata.notes['\xmlrefatt{#1}{href}']}}}
+\stopxmlsetups
+
+\startxmlsetups xml:initialize
+ \xmlsetsetup{#1}{p|doc}{xml:*}
+ \xmlsetsetup{#1}{a[@class='footnoteref']}{xml:footnote}
+ \xmlfilter{#1}{div[@class='footnotes']/ol/li/command(xml:collectnotes)}
+ \xmlsetsetup{#1}{div[@class='footnotes']}{}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{example-3-2}{xml:initialize}
+
+\xmlprocessbuffer{example-3-2}{test}{}
+\stopbuffer
+
+\typebuffer
+
+This will again typeset two footnotes:
+
+\getbuffer
+
+\stopsection
+
+\startsection[title=mapping values]
+
+One way to process options \type {frame} in the example below is to map the
+values to values known by \CONTEXT.
+
+\startbuffer[test]
+<a>
+ <nattable frame="on">
+ <tr><td>#1</td><td>#2</td><td>#3</td><td>#4</td></tr>
+ <tr><td>#5</td><td>#6</td><td>#7</td><td>#8</td></tr>
+ </nattable>
+ <nattable frame="off">
+ <tr><td>#1</td><td>#2</td><td>#3</td><td>#4</td></tr>
+ <tr><td>#5</td><td>#6</td><td>#7</td><td>#8</td></tr>
+ </nattable>
+ <nattable frame="no">
+ <tr><td>#1</td><td>#2</td><td>#3</td><td>#4</td></tr>
+ <tr><td>#5</td><td>#6</td><td>#7</td><td>#8</td></tr>
+ </nattable>
+</a>
+\stopbuffer
+
+\typebuffer[test]
+
+\startbuffer
+\startxmlsetups xml:a
+ \xmlflush{#1}
+\stopxmlsetups
+
+\xmlmapvalue {nattable:frame} {on} {on}
+\xmlmapvalue {nattable:frame} {yes} {on}
+\xmlmapvalue {nattable:frame} {off} {off}
+\xmlmapvalue {nattable:frame} {no} {off}
+
+\startxmlsetups xml:nattable
+ \startplacetable[title=#1]
+ \setupTABLE[frame=\xmlval{nattable:frame}{\xmlatt{#1}{frame}}{on}]%
+ \bTABLE
+ \xmlflush{#1}
+ \eTABLE
+ \stopplacetable
+\stopxmlsetups
+
+\startxmlsetups xml:tr
+ \bTR
+ \xmlflush{#1}
+ \eTR
+\stopxmlsetups
+
+\startxmlsetups xml:td
+ \bTD
+ \xmlflush{#1}
+ \eTD
+\stopxmlsetups
+
+\startxmlsetups xml:testsetups
+ \xmlsetsetup{example-4}{a|nattable|tr|td|}{xml:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{example-4}{xml:testsetups}
+
+\xmlprocessbuffer{example-4}{test}{}
+\stopbuffer
+
+The \type {\xmlmapvalue} mechanism is rather efficient and involves a minimum
+of testing.
+
+\typebuffer
+
+We get:
+
+\getbuffer
+
+\stopsection
+
+\startsection[title=using \LUA]
+
+In this example we demonstrate how you can delegate rendering to \LUA. We
+will construct a so called extreme table. The input is:
+
+\startbuffer[demo]
+<?xml version="1.0" encoding="utf-8"?>
+
+<a>
+ <b> <c>1</c> <d>Text</d> </b>
+ <b> <c>2</c> <d>More text</d> </b>
+ <b> <c>2</c> <d>Even more text</d> </b>
+ <b> <c>2</c> <d>And more</d> </b>
+ <b> <c>3</c> <d>And even more</d> </b>
+ <b> <c>2</c> <d>The last text</d> </b>
+</a>
+\stopbuffer
+
+\typebuffer[demo]
+
+The processor code is:
+
+\startbuffer[process]
+\startxmlsetups xml:test_setups
+ \xmlsetsetup{#1}{a|b|c|d}{xml:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{example-5}{xml:test_setups}
+
+\xmlprocessbuffer{example-5}{demo}{}
+\stopbuffer
+
+\typebuffer
+
+We color a sequence of the same titles (numbers here) differently. The first
+solution remembers the last title:
+
+\startbuffer
+\startxmlsetups xml:a
+ \startembeddedxtable
+ \xmlflush{#1}
+ \stopembeddedxtable
+\stopxmlsetups
+
+\startxmlsetups xml:b
+ \xmlfunction{#1}{test_ba}
+\stopxmlsetups
+
+\startluacode
+local lasttitle = nil
+
+function xml.functions.test_ba(t)
+ local title = xml.text(t, "/c")
+ local content = xml.text(t, "/d")
+ context.startxrow()
+ context.startxcell {
+ background = "color",
+ backgroundcolor = lasttitle == title and "colorone" or "colortwo",
+ foregroundstyle = "bold",
+ foregroundcolor = "white",
+ }
+ context(title)
+ lasttitle = title
+ context.stopxcell()
+ context.startxcell()
+ context(content)
+ context.stopxcell()
+ context.stopxrow()
+end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+The \type {embeddedxtable} environment is needed because the table is picked up
+as argument.
+
+\startlinecorrection \getbuffer[process] \stoplinecorrection
+
+The second implemetation remembers what titles are already processed so here we
+can color the last one too.
+
+\startbuffer
+\startxmlsetups xml:a
+ \ctxlua{xml.functions.reset_bb()}
+ \startembeddedxtable
+ \xmlflush{#1}
+ \stopembeddedxtable
+\stopxmlsetups
+
+\startxmlsetups xml:b
+ \xmlfunction{#1}{test_bb}
+\stopxmlsetups
+
+\startluacode
+local titles
+
+function xml.functions.reset_bb(t)
+ titles = { }
+end
+
+function xml.functions.test_bb(t)
+ local title = xml.text(t, "/c")
+ local content = xml.text(t, "/d")
+ context.startxrow()
+ context.startxcell {
+ background = "color",
+ backgroundcolor = titles[title] and "colorone" or "colortwo",
+ foregroundstyle = "bold",
+ foregroundcolor = "white",
+ }
+ context(title)
+ titles[title] = true
+ context.stopxcell()
+ context.startxcell()
+ context(content)
+ context.stopxcell()
+ context.stopxrow()
+end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection \getbuffer[process] \stoplinecorrection
+
+A solution without any state variable is given below.
+
+\startbuffer
+\startxmlsetups xml:a
+ \startembeddedxtable
+ \xmlflush{#1}
+ \stopembeddedxtable
+\stopxmlsetups
+
+\startxmlsetups xml:b
+ \xmlfunction{#1}{test_bc}
+\stopxmlsetups
+
+\startluacode
+function xml.functions.test_bc(t)
+ local title = xml.text(t, "/c")
+ local content = xml.text(t, "/d")
+ context.startxrow()
+ local okay = xml.text(t,"./preceding-sibling::/[-1]") == title
+ context.startxcell {
+ background = "color",
+ backgroundcolor = okay and "colorone" or "colortwo",
+ foregroundstyle = "bold",
+ foregroundcolor = "white",
+ }
+ context(title)
+ context.stopxcell()
+ context.startxcell()
+ context(content)
+ context.stopxcell()
+ context.stopxrow()
+end
+\stopluacode
+\stopbuffer
+
+\typebuffer \getbuffer
+
+\startlinecorrection \getbuffer[process] \stoplinecorrection
+
+Here is a solution that delegates even more to \LUA. The previous variants were
+actually not that safe with repect to special characters and didn't handle
+nested elements either but the next one does.
+
+\startbuffer[demo]
+<?xml version="1.0" encoding="utf-8"?>
+
+<a>
+ <b> <c>#1</c> <d>Text</d> </b>
+ <b> <c>#2</c> <d>More text</d> </b>
+ <b> <c>#2</c> <d>Even more text</d> </b>
+ <b> <c>#2</c> <d>And more</d> </b>
+ <b> <c>#3</c> <d>And even more</d> </b>
+ <b> <c>#2</c> <d>Something <i>nested</i> </d> </b>
+</a>
+\stopbuffer
+
+\typebuffer[demo]
+
+We also need to map the \type {i} element.
+
+\startbuffer
+\startxmlsetups xml:a
+ \starttexcode
+ \xmlfunction{#1}{test_a}
+ \stoptexcode
+\stopxmlsetups
+
+\startxmlsetups xml:c
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:d
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:i
+ {\em\xmlflush{#1}}
+\stopxmlsetups
+
+\startluacode
+function xml.functions.test_a(t)
+ context.startxtable()
+ local previous = false
+ for b in xml.collected(lxml.getid(t),"/b") do
+ context.startxrow()
+ local current = xml.text(b,"/c")
+ context.startxcell {
+ background = "color",
+ backgroundcolor = (previous == current) and "colorone" or "colortwo",
+ foregroundstyle = "bold",
+ foregroundcolor = "white",
+ }
+ lxml.first(b,"/c")
+ context.stopxcell()
+ context.startxcell()
+ lxml.first(b,"/d")
+ context.stopxcell()
+ previous = current
+ context.stopxrow()
+ end
+ context.stopxtable()
+end
+\stopluacode
+
+\startxmlsetups xml:test_setups
+ \xmlsetsetup{#1}{a|b|c|d|i}{xml:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{example-5}{xml:test_setups}
+
+\xmlprocessbuffer{example-5}{demo}{}
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection \getbuffer \stoplinecorrection
+
+The question is, do we really need \LUA ? Often we don't, apart maybe from an
+occasional special finalizer. A pure \TEX\ solution is given next:
+
+\startbuffer
+\startxmlsetups xml:a
+ \glet\MyPreviousTitle\empty
+ \glet\MyCurrentTitle \empty
+ \startembeddedxtable
+ \xmlflush{#1}
+ \stopembeddedxtable
+\stopxmlsetups
+
+\startxmlsetups xml:b
+ \startxrow
+ \xmlflush{#1}
+ \stopxrow
+\stopxmlsetups
+
+\startxmlsetups xml:c
+ \xdef\MyCurrentTitle{\xmltext{#1}{.}}
+ \doifelse {\MyPreviousTitle} {\MyCurrentTitle} {
+ \startxcell
+ [background=color,
+ backgroundcolor=colorone,
+ foregroundstyle=bold,
+ foregroundcolor=white]
+ } {
+ \glet\MyPreviousTitle\MyCurrentTitle
+ \startxcell
+ [background=color,
+ backgroundcolor=colortwo,
+ foregroundstyle=bold,
+ foregroundcolor=white]
+ }
+ \xmlflush{#1}
+ \stopxcell
+\stopxmlsetups
+
+\startxmlsetups xml:d
+ \startxcell
+ \xmlflush{#1}
+ \stopxcell
+\stopxmlsetups
+
+\startxmlsetups xml:i
+ {\em\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:test_setups
+ \xmlsetsetup{#1}{*}{xml:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{example-5}{xml:test_setups}
+
+\xmlprocessbuffer{example-5}{demo}{}
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection \getbuffer \stoplinecorrection
+
+You can even save a few lines of code:
+
+\starttyping
+\startxmlsetups xml:c
+ \xdef\MyCurrentTitle{\xmltext{#1}{.}}
+ \startxcell
+ [background=color,
+ backgroundcolor=color\ifx\MyPreviousTitle\MyCurrentTitle one\else two\fi,
+ foregroundstyle=bold,
+ foregroundcolor=white]
+ \xmlflush{#1}
+ \stopxcell
+ \glet\MyPreviousTitle\MyCurrentTitle
+\stopxmlsetups
+\stoptyping
+
+Or if you prefer:
+
+\starttyping
+\startxmlsetups xml:c
+ \xdef\MyCurrentTitle{\xmltext{#1}{.}}
+ \doifelse {\MyPreviousTitle} {\MyCurrentTitle} {
+ \xmlsetup{#1}{xml:c:one}
+ } {
+ \xmlsetup{#1}{xml:c:two}
+ }
+\stopxmlsetups
+
+\startxmlsetups xml:c:one
+ \startxcell
+ [background=color,
+ backgroundcolor=colorone,
+ foregroundstyle=bold,
+ foregroundcolor=white]
+ \xmlflush{#1}
+ \stopxcell
+\stopxmlsetups
+
+\startxmlsetups xml:c:two
+ \startxcell
+ [background=color,
+ backgroundcolor=colortwo,
+ foregroundstyle=bold,
+ foregroundcolor=white]
+ \xmlflush{#1}
+ \stopxcell
+ \global\let\MyPreviousTitle\MyCurrentTitle
+\stopxmlsetups
+\stoptyping
+
+These examples demonstrate that it doesn't hurt to know a little bit of \TEX\
+programming: defining macros and basic comparisons can come in handy. There are
+examples in the test suite, you can peek in the source code, you can consult
+the wiki or you can just ask on the list.
+
+\stopsection
+
+\startsection[title=last match]
+
+For the next example we use the following \XML\ input:
+
+\startbuffer[demo]
+<?xml version "1.0"?>
+<document>
+ <section id="1">
+ <content>
+ <p>first</p>
+ <p>second</p>
+ </content>
+ </section>
+ <section id="2">
+ <content>
+ <p>third</p>
+ <p>fourth</p>
+ </content>
+ </section>
+</document>
+\stopbuffer
+
+\typebuffer[demo]
+
+If you check if some element is present and then act accordingly, you can
+end up with doing the same lookup twice. Although it might sound inefficient,
+in practice it's often not measureable.
+
+\startbuffer
+\startxmlsetups xml:demo:document
+ \type{\xmlall{#1}{/section[@id='2']/content/p}}\par
+ \xmldoif{#1}{/section[@id='2']/content/p} {
+ \xmlall{#1}{/section[@id='2']/content/p}
+ }
+ \type{\xmllastmatch}\par
+ \xmldoif{#1}{/section[@id='2']/content/p} {
+ \xmllastmatch
+ }
+ \type{\xmlall{#1}{last-match::}}\par
+ \xmldoif{#1}{/section[@id='2']/content/p} {
+ \xmlall{#1}{last-match::}
+ }
+ \type{\xmlfilter{#1}{last-match::/command(xml:demo:p)}}\par
+ \xmldoif{#1}{/section[@id='2']/content/p} {
+ \xmlfilter{#1}{last-match::/command(xml:demo:p)}
+ }
+\stopxmlsetups
+
+\startxmlsetups xml:demo:p
+ \quad\xmlflush{#1}\endgraf
+\stopxmlsetups
+
+\startxmlsetups xml:demo:base
+ \xmlsetsetup{#1}{document|p}{xml:demo:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{example-6}{xml:demo:base}
+
+\xmlprocessbuffer{example-6}{demo}{}
+\stopbuffer
+
+\typebuffer
+
+In the second check we just flush the last match, so effective we do an \type
+{\xmlall} here. The third and fourth alternatives demonstrate how we can use
+\type {last-match} as axis. The gain is 10\% or more on the lookup but of course
+typesetting often takes relatively more time than the lookup.
+
+\startpacked
+\getbuffer
+\stoppacked
+
+\stopsection
+
+\startsection[title=Finalizers]
+
+The \XML\ parser is also available outside \TEX. Here is an example of its usage.
+We pipe the result to \TEX\ but you can do with \type {t} whatever you like.
+
+\startbuffer
+local x = xml.load("manual-demo-1.xml")
+local t = { }
+
+for c in xml.collected(x,"//*") do
+ if not c.special and not t[c.tg] then
+ t[c.tg] = true
+ end
+end
+
+context.tocontext(table.sortedkeys(t))
+\stopbuffer
+
+% \typebuffer
+
+This returns:
+
+\ctxluabuffer
+
+We can wrap this in a finalizer:
+
+\startbuffer
+xml.finalizers.taglist = function(collected)
+ local t = { }
+ for i=1,#collected do
+ local c = collected[i]
+ if not c.special then
+ local tg = c.tg
+ if tg and not t[tg] then
+ t[tg] = true
+ end
+ end
+ end
+ return table.sortedkeys(t)
+end
+\stopbuffer
+
+\typebuffer
+
+Or in a more extensive one:
+
+\startbuffer
+xml.finalizers.taglist = function(collected,parenttoo)
+ local t = { }
+ for i=1,#collected do
+ local c = collected[i]
+ if not c.special then
+ local tg = c.tg
+ if tg and not t[tg] then
+ t[tg] = true
+ end
+ if parenttoo then
+ local p = c.__p__
+ if p and not p.special then
+ local tg = p.tg .. ":" .. tg
+ if tg and not t[tg] then
+ t[tg] = true
+ end
+ end
+ end
+ end
+ end
+ return table.sortedkeys(t)
+end
+\stopbuffer
+
+\typebuffer \ctxluabuffer
+
+Usage is as follows:
+
+\startbuffer
+local x = xml.load("manual-demo-1.xml")
+local t = xml.applylpath(x,"//*/taglist()")
+
+context.tocontext(t)
+\stopbuffer
+
+\typebuffer
+
+And indeed we get:
+
+\ctxluabuffer
+
+But we can also say:
+
+\startbuffer
+local x = xml.load("manual-demo-1.xml")
+local t = xml.applylpath(x,"//*/taglist(true)")
+
+context.tocontext(t)
+\stopbuffer
+
+\typebuffer
+
+Now we get:
+
+\ctxluabuffer
+
+\stopsection
+
+\startsection[title=Pure xml]
+
+One might wonder how a \TEX\ macro package would look like when backslashes,
+dollars and percent signs would have no special meaning. In fact, it would be
+rather useless as interpreting commands are triggered by such characters. Any
+formatting or coding system needs such characters. Take \XML: angle brackets and
+ampersands are really special. So, no matter what system we use, we do have to
+deal with the (common) case where these characters need to be seen as they are.
+Normally escaping is the solution.
+
+The \CONTEXT\ interface for \XML\ suffers from this as well. You really don't
+want to know how many tricks are used for dealing with special characters and
+entities: there are several ways these travel through the system and it is
+possible to adapt and cheat. Especially roundtripped data (via tuc file) puts
+some demands on the system because when ts \XML\ can become \TEX\ and vise versa.
+The next example (derived from a mail on the list) demonstrates this:
+
+\starttyping
+\startbuffer[demo]
+<doc>
+ <pre><code>\ConTeXt\ is great</code></pre>
+
+ <pre><code>but you need to know some tricks</code></pre>
+</doc>
+\stopbuffer
+
+\startxmlsetups xml:initialize
+ \xmlsetsetup{#1}{doc|p|code}{xml:*}
+ \xmlsetsetup{#1}{pre/code}{xml:pre:code}
+\stopxmlsetups
+
+\xmlregistersetup{xml:initialize}
+
+\startxmlsetups xml:doc
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:pre:code
+ no solution
+ \comment[symbol=Key, location=inmargin,color=yellow]{\xmlflush{#1}}
+ \par
+ solution one \begingroup
+ \expandUx
+ \comment[symbol=Key, location=inmargin,color=yellow]{\xmlflush{#1}}
+ \endgroup
+ \par
+ solution two
+ \comment[symbol=Key, location=inmargin,color=yellow]{\xmlpure{#1}}
+ \par
+ \xmlprettyprint{#1}{tex}
+\stopxmlsetups
+
+\xmlprocessbuffer{main}{demo}{}
+\stoptyping
+
+The first comment (an interactive feature of \PDF\ comes out as:
+
+\starttyping
+\Ux {5C}ConTeXt\Ux {5C} is great
+\stoptyping
+
+The second and third comment are okay. It's one of the reasons why we have \type
+{\xmlpure}.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-expressions.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-expressions.tex
new file mode 100644
index 000000000..0c126f2f8
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-expressions.tex
@@ -0,0 +1,645 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-expressions
+
+\startchapter[title={Expressions and filters}]
+
+\startsection[title={path expressions}]
+
+In the previous chapters we used \cmdinternal {cd:lpath} expressions, which are a variant
+on \type {xpath} expressions as in \XSLT\ but in this case more geared towards
+usage in \TEX. This mechanisms will be extended when demands are there.
+
+A path is a sequence of matches. A simple path expression is:
+
+\starttyping
+a/b/c/d
+\stoptyping
+
+Here each \type {/} goes one level deeper. We can go backwards in a lookup with
+\type {..}:
+
+\starttyping
+a/b/../d
+\stoptyping
+
+We can also combine lookups, as in:
+
+\starttyping
+a/(b|c)/d
+\stoptyping
+
+A negated lookup is preceded by a \type {!}:
+
+\starttyping
+a/(b|c)/!d
+\stoptyping
+
+A wildcard is specified with a \type {*}:
+
+\starttyping
+a/(b|c)/!d/e/*/f
+\stoptyping
+
+In addition to these tag based lookups we can use attributes:
+
+\starttyping
+a/(b|c)/!d/e/*/f[@type=whatever]
+\stoptyping
+
+An \type {@} as first character means that we are dealing with an attribute.
+Within the square brackets there can be boolean expressions:
+
+\starttyping
+a/(b|c)/!d/e/*/f[@type=whatever and @id>100]
+\stoptyping
+
+You can use functions as in:
+
+\starttyping
+a/(b|c)/!d/e/*/f[something(text()) == "oeps"]
+\stoptyping
+
+There are a couple of predefined functions:
+
+\starttabulate[|l|l|p|]
+\NC \type{rootposition} \type{order} \NC number \NC the index of the matched root element (kind of special) \NC \NR
+\NC \type{position} \NC number \NC the current index of the matched element in the match list \NC \NR
+\NC \type{match} \NC number \NC the current index of the matched element sub list with the same parent \NC \NR
+\NC \type{first} \NC number \NC \NC \NR
+\NC \type{last} \NC number \NC \NC \NR
+\NC \type{index} \NC number \NC the current index of the matched element in its parent list \NC \NR
+\NC \type{firstindex} \NC number \NC \NC \NR
+\NC \type{lastindex} \NC number \NC \NC \NR
+\NC \type{element} \NC number \NC the element's index \NC \NR
+\NC \type{firstelement} \NC number \NC \NC \NR
+\NC \type{lastelement} \NC number \NC \NC \NR
+\NC \type{text} \NC string \NC the textual representation of the matched element \NC \NR
+\NC \type{content} \NC table \NC the node of the matched element \NC \NR
+\NC \type{name} \NC string \NC the full name of the matched element: namespace and tag \NC \NR
+\NC \type{namespace} \type{ns} \NC string \NC the namespace of the matched element \NC \NR
+\NC \type{tag} \NC string \NC the tag of the matched element \NC \NR
+\NC \type{attribute} \NC string \NC the value of the attribute with the given name of the matched element \NC \NR
+\stoptabulate
+
+There are fundamental differences between \type {position}, \type {match} and
+\type {index}. Each step results in a new list of matches. The \type {position}
+is the index in this new (possibly intermediate) list. The \type {match} is also
+an index in this list but related to the specific match of element names. The
+\type {index} refers to the location in the parent element.
+
+Say that we have:
+
+\starttyping
+<collection>
+ <resources>
+ <manual>
+ <screen>.1.</screen>
+ <paper>.1.</paper>
+ </manual>
+ <manual>
+ <paper>.2.</paper>
+ <screen>.2.</screen>
+ </manual>
+ <resources>
+ <resources>
+ <manual>
+ <screen>.3.</screen>
+ <paper>.3.</paper>
+ </manual>
+ <resources>
+<collection>
+\stoptyping
+
+The following then applies:
+
+\starttabulate[|l|l|]
+\NC \type {collection/resources/manual[position()==1]/paper} \NC \type{.1.} \NC \NR
+\NC \type {collection/resources/manual[match()==1]/paper} \NC \type{.1.} \type{.3.} \NC \NR
+\NC \type {collection/resources/manual/paper[index()==1]} \NC \type{.2.} \NC \NR
+\stoptabulate
+
+In most cases the \type {position} test is more restrictive than the \type
+{match} test.
+
+You can pass your own functions too. Such functions are defined in the \type
+{xml.expressions} namespace. We have defined a few shortcuts:
+
+\starttabulate[|l|l|]
+\NC \type {find(str,pattern)} \NC \type{string.find} \NC \NR
+\NC \type {contains(str)} \NC \type{string.find} \NC \NR
+\NC \type {oneof(str,...)} \NC is \type{str} in list \NC \NR
+\NC \type {upper(str)} \NC \type{characters.upper} \NC \NR
+\NC \type {lower(str)} \NC \type{characters.lower} \NC \NR
+\NC \type {number(str)} \NC \type{tonumber} \NC \NR
+\NC \type {boolean(str)} \NC \type{toboolean} \NC \NR
+\NC \type {idstring(str)} \NC removes leading hash \NC \NR
+\NC \type {name(index)} \NC full tag name \NC \NR
+\NC \type {tag(index)} \NC tag name \NC \NR
+\NC \type {namespace(index)} \NC namespace of tag \NC \NR
+\NC \type {text(index)} \NC content \NC \NR
+\NC \type {error(str)} \NC quit and show error \NC \NR
+\NC \type {quit()} \NC quit \NC \NR
+\NC \type {print()} \NC print message \NC \NR
+\NC \type {count(pattern)} \NC number of matches \NC \NR
+\NC \type {child(pattern)} \NC take child that matches \NC \NR
+\stoptabulate
+
+
+You can also use normal \LUA\ functions as long as you make sure that you pass
+the right arguments. There are a few predefined variables available inside such
+functions.
+
+\starttabulate[|Tl|l|p|]
+\NC \type{list} \NC table \NC the list of matches \NC \NR
+\NC \type{l} \NC number \NC the current index in the list of matches \NC \NR
+\NC \type{ll} \NC element \NC the current element that matched \NC \NR
+\NC \type{order} \NC number \NC the position of the root of the path \NC \NR
+\stoptabulate
+
+The given expression between \type {[]} is converted to a \LUA\ expression so you
+can use the usual operators:
+
+\starttyping
+== ~= <= >= < > not and or ()
+\stoptyping
+
+In addition, \type {=} equals \type {==} and \type {!=} is the same as \type
+{~=}. If you mess up the expression, you quite likely get a \LUA\ error message.
+
+\stopsection
+
+\startsection[title={css selectors}]
+
+\startbuffer[selector-001]
+<?xml version="1.0" ?>
+
+<a>
+ <b class="one">b.one</b>
+ <b class="two">b.two</b>
+ <b class="one two">b.one.two</b>
+ <b class="three">b.three</b>
+ <b id="first">b#first</b>
+ <c>c</c>
+ <d>d e</d>
+ <e>d e</e>
+ <e>d e e</e>
+ <d>d f</d>
+ <f foo="bar">@foo = bar</f>
+ <f bar="foo">@bar = foo</f>
+ <f bar="foo1">@bar = foo1</f>
+ <f bar="foo2">@bar = foo2</f>
+ <f bar="foo3">@bar = foo3</f>
+ <f bar="foo+4">@bar = foo+4</f>
+ <g>g</g>
+ <g><gg><d>g gg d</d></gg></g>
+ <g><gg><f>g gg f</f></gg></g>
+ <g><gg><f class="one">g gg f.one</f></gg></g>
+ <g>g</g>
+ <g><gg><f class="two">g gg f.two</f></gg></g>
+ <g><gg><f class="three">g gg f.three</f></gg></g>
+ <g><f class="one">g f.one</f></g>
+ <g><f class="three">g f.three</f></g>
+ <h whatever="four five six">@whatever = four five six</h>
+</a>
+\stopbuffer
+
+\xmlloadbuffer{selector-001}{selector-001}
+
+\startxmlsetups xml:selector:demo
+ \advance\scratchcounter\plusone
+ \inleftmargin{\the\scratchcounter}\ignorespaces\xmlverbatim{#1}\par
+\stopxmlsetups
+
+\unexpanded\def\showCSSdemo#1#2%
+ {\blank
+ \textrule{\tttf#2}
+ \startlines
+ \dontcomplain
+ \tttf \obeyspaces
+ \scratchcounter\zerocount
+ \xmlcommand{#1}{#2}{xml:selector:demo}
+ \stoplines
+ \blank}
+
+The \CSS\ approach to filtering is a bit different from the path based one and is
+supported too. In fact, you can combine both methods. Depending on what you
+select, the \CSS\ one can be a little bit faster too. It has the advantage that
+one can select more in one go but at the same time looks a bit less attractive.
+This method was added just to show that it can be done but might be useful too. A
+selector is given between curly braces (after all \CSS\ uses them and they have no
+function yet in the parser.
+
+\starttyping
+\xmlall{#1}{{foo bar .whatever, bar foo .whatever}}
+\stoptyping
+
+The following methods are supported:
+
+\starttabulate[|T||]
+\NC element \NC all tags element \NC \NR
+\NC element-1 > element-2 \NC all tags element-2 with parent tag element-1 \NC \NR
+\NC element-1 + element-2 \NC all tags element-2 preceded by tag element-1 \NC \NR
+\NC element-1 ~ element-2 \NC all tags element-2 preceded by tag element-1 \NC \NR
+\NC element-1 element-2 \NC all tags element-2 inside tag element-1 \NC \NR
+\NC [attribute] \NC has attribute \NC \NR
+\NC [attribute=value] \NC attribute equals value\NC \NR
+\NC [attribute\lettertilde =value] \NC attribute contains value (space is separator) \NC \NR
+\NC [attribute\letterhat ="value"] \NC attribute starts with value \NC \NR
+\NC [attribute\letterdollar="value"] \NC attribute ends with value \NC \NR
+\NC [attribute*="value"] \NC attribute contains value \NC \NR
+\NC .class \NC has class \NC \NR
+\NC \letterhash id \NC has id \NC \NR
+\NC :nth-child(n) \NC the child at index n \NC \NR
+\NC :nth-last-child(n) \NC the child at index n from the end \NC \NR
+\NC :first-child \NC the first child \NC \NR
+\NC :last-child \NC the last child \NC \NR
+\NC :nth-of-type(n) \NC the match at index n \NC \NR
+\NC :nth-last-of-type(n) \NC the match at index n from the end \NC \NR
+\NC :first-of-type \NC the first match \NC \NR
+\NC :last-of-type \NC the last match \NC \NR
+\NC :only-of-type \NC the only match or nothing \NC \NR
+\NC :only-child \NC the only child or nothing \NC \NR
+\NC :empty \NC only when empty \NC \NR
+\NC :root \NC the whole tree \NC \NR
+\stoptabulate
+
+The next pages show some examples. For that we use the demo file:
+
+\typebuffer[selector-001]
+
+The class and id selectors often only make sense in \HTML\ like documents but they
+are supported nevertheless. They are after all just shortcuts for filtering by
+attribute. The class filtering is special in the sense that it checks for a class
+in a list of classes given in an attribute.
+
+\showCSSdemo{selector-001}{{.one}}
+\showCSSdemo{selector-001}{{.one, .two}}
+\showCSSdemo{selector-001}{{.one, .two, \letterhash first}}
+
+Attributes can be filtered by presence, value, partial value and such. Quotes are
+optional but we advice to use them.
+
+\showCSSdemo{selector-001}{{[foo], [bar=foo]}}
+\showCSSdemo{selector-001}{{[bar\lettertilde=foo]}}
+\showCSSdemo{selector-001}{{[bar\letterhat="foo"]}}
+\showCSSdemo{selector-001}{{[whatever\lettertilde="five"]}}
+
+You can of course combine the methods as in:
+
+\showCSSdemo{selector-001}{{g f .one, g f .three}}
+\showCSSdemo{selector-001}{{g > f .one, g > f .three}}
+\showCSSdemo{selector-001}{{d + e}}
+\showCSSdemo{selector-001}{{d ~ e}}
+\showCSSdemo{selector-001}{{d ~ e, g f .one, g f .three}}
+
+You can also negate the result by using \type {:not} on a simple expression:
+
+\showCSSdemo{selector-001}{{:not([whatever\lettertilde="five"])}}
+\showCSSdemo{selector-001}{{:not(d)}}
+
+The child and match selectors are also supported:
+
+\showCSSdemo{selector-001}{{a:nth-child(3)}}
+\showCSSdemo{selector-001}{{a:nth-last-child(3)}}
+\showCSSdemo{selector-001}{{g:nth-of-type(3)}}
+\showCSSdemo{selector-001}{{g:nth-last-of-type(3)}}
+\showCSSdemo{selector-001}{{a:first-child}}
+\showCSSdemo{selector-001}{{a:last-child}}
+\showCSSdemo{selector-001}{{e:first-of-type}}
+\showCSSdemo{selector-001}{{gg d:only-of-type}}
+
+Instead of numbers you can also give the \type {an} and \type {an+b} formulas
+as well as the \type {odd} and \type {even} keywords:
+
+\showCSSdemo{selector-001}{{a:nth-child(even)}}
+\showCSSdemo{selector-001}{{a:nth-child(odd)}}
+\showCSSdemo{selector-001}{{a:nth-child(3n+1)}}
+\showCSSdemo{selector-001}{{a:nth-child(2n+3)}}
+
+There are a few special cases:
+
+\showCSSdemo{selector-001}{{g:empty}}
+\showCSSdemo{selector-001}{{g:root}}
+\showCSSdemo{selector-001}{{*}}
+
+Combining the \CSS\ methods with the regular ones is possible:
+
+\showCSSdemo{selector-001}{{g gg f .one}}
+\showCSSdemo{selector-001}{g/gg/f[@class='one']}
+\showCSSdemo{selector-001}{g/{gg f .one}}
+
+\startbuffer[selector-002]
+<?xml version="1.0" ?>
+
+<document>
+ <title class="one" >title 1</title>
+ <title class="two" >title 2</title>
+ <title class="one" >title 3</title>
+ <title class="three">title 4</title>
+</document>
+\stopbuffer
+
+The next examples we use this file:
+
+\typebuffer[selector-002]
+
+\xmlloadbuffer{selector-002}{selector-002}
+
+When we filter from this (not too well structured) tree we can use both
+methods to achieve the same:
+
+\showCSSdemo{selector-002}{{document title .one, document title .three}}
+
+\showCSSdemo{selector-002}{/document/title[(@class='one') or (@class='three')]}
+
+However, imagine this file:
+
+\startbuffer[selector-003]
+<?xml version="1.0" ?>
+
+<document>
+ <title class="one">title 1</title>
+ <subtitle class="sub">title 1.1</subtitle>
+ <title class="two">title 2</title>
+ <subtitle class="sub">title 2.1</subtitle>
+ <title class="one">title 3</title>
+ <subtitle class="sub">title 3.1</subtitle>
+ <title class="two">title 4</title>
+ <subtitle class="sub">title 4.1</subtitle>
+</document>
+\stopbuffer
+
+\typebuffer[selector-003]
+
+\xmlloadbuffer{selector-003}{selector-003}
+
+The next filter in easier with the \CSS\ selector methods because these accumulate
+independent (simple) expressions:
+
+\showCSSdemo{selector-003}{{document title .one + subtitle, document title .two + subtitle}}
+
+Watch how we get an output in the document order. Because we render a sequential document
+a combined filter will trigger a sorting pass.
+
+\stopsection
+
+\startsection[title={functions as filters}]
+
+At the \LUA\ end a whole \cmdinternal {cd:lpath} expression results in a (set of) node(s)
+with its environment, but that is hardly usable in \TEX. Think of code like:
+
+\starttyping
+for e in xml.collected(xml.load('text.xml'),"title") do
+ -- e = the element that matched
+end
+\stoptyping
+
+The older variant is still supported but you can best use the previous variant.
+
+\starttyping
+for r, d, k in xml.elements(xml.load('text.xml'),"title") do
+ -- r = root of the title element
+ -- d = data table
+ -- k = index in data table
+end
+\stoptyping
+
+Here \type {d[k]} points to the \type {title} element and in this case all titles
+in the tree pass by. In practice this kind of code is encapsulated in function
+calls, like those returning elements one by one, or returning the first or last
+match. The result is then fed back into \TEX, possibly after being altered by an
+associated setup. We've seen the wrappers to such functions already in a previous
+chapter.
+
+In addition to the previously discussed expressions, one can add so called
+filters to the expression, for instance:
+
+\starttyping
+a/(b|c)/!d/e/text()
+\stoptyping
+
+In a filter, the last part of the \cmdinternal {cd:lpath} expression is a
+function call. The previous example returns the text of each element \type {e}
+that results from matching the expression. When running \TEX\ the following
+functions are available. Some are also available when using pure \LUA. In \TEX\
+you can often use one of the macros like \type {\xmlfirst} instead of a \type
+{\xmlfilter} with finalizer \type {first()}. The filter can be somewhat faster
+but that is hardly noticeable.
+
+\starttabulate[|l|l|p|]
+\NC \type {context()} \NC string \NC the serialized text with \TEX\ catcode regime \NC \NR
+%NC \type {ctxtext()} \NC string \NC \NC \NR
+\NC \type {function()} \NC string \NC depends on the function \NC \NR
+%
+\NC \type {name()} \NC string \NC the (remapped) namespace \NC \NR
+\NC \type {tag()} \NC string \NC the name of the element \NC \NR
+\NC \type {tags()} \NC list \NC the names of the element \NC \NR
+%
+\NC \type {text()} \NC string \NC the serialized text \NC \NR
+\NC \type {upper()} \NC string \NC the serialized text uppercased \NC \NR
+\NC \type {lower()} \NC string \NC the serialized text lowercased \NC \NR
+\NC \type {stripped()} \NC string \NC the serialized text stripped \NC \NR
+\NC \type {lettered()} \NC string \NC the serialized text only letters (cf. \UNICODE) \NC \NR
+%
+\NC \type {count()} \NC number \NC the number of matches \NC \NR
+\NC \type {index()} \NC number \NC the matched index in the current path \NC \NR
+\NC \type {match()} \NC number \NC the matched index in the preceding path \NC \NR
+%
+%NC \type {lowerall()} \NC string \NC \NC \NR
+%NC \type {upperall()} \NC string \NC \NC \NR
+%
+\NC \type {attribute(name)} \NC content \NC returns the attribute with the given name \NC \NR
+\NC \type {chainattribute(name)} \NC content \NC sidem, but backtracks till one is found \NC \NR
+\NC \type {command(name)} \NC content \NC expands the setup with the given name for each found element \NC \NR
+\NC \type {position(n)} \NC content \NC processes the \type {n}\high{th} instance of the found element \NC \NR
+\NC \type {all()} \NC content \NC processes all instances of the found element \NC \NR
+%NC \type {default} \NC content \NC all \NC \NR
+\NC \type {reverse()} \NC content \NC idem in reverse order \NC \NR
+\NC \type {first()} \NC content \NC processes the first instance of the found element \NC \NR
+\NC \type {last()} \NC content \NC processes the last instance of the found element \NC \NR
+\NC \type {concat(...)} \NC content \NC concatinates the match \NC \NC \NR
+\NC \type {concatrange(from,to,...)} \NC content \NC concatinates a range of matches \NC \NC \NR
+\stoptabulate
+
+The extra arguments of the concatinators are: \type {separator} (string), \type
+{lastseparator} (string) and \type {textonly} (a boolean).
+
+These filters are in fact \LUA\ functions which means that if needed more of them
+can be added. Indeed this happens in some of the \XML\ related \MKIV\ modules,
+for instance in the \MATHML\ processor.
+
+\stopsection
+
+\startsection[title={example}]
+
+The number of commands is rather large and if you want to avoid them this is
+often possible. Take for instance:
+
+\starttyping
+\xmlall{#1}{/a/b[position()>3]}
+\stoptyping
+
+Alternatively you can use:
+
+\starttyping
+\xmlfilter{#1}{/a/b[position()>3]/all()}
+\stoptyping
+
+and actually this is also faster as internally it avoids a function call. Of
+course in practice this is hardly measurable.
+
+In previous examples we've already seen quite some expressions, and it might be
+good to point out that the syntax is modelled after \XSLT\ but is not quite the
+same. The reason is that we started with a rather minimal system and have already
+styles in use that depend on compatibility.
+
+\starttyping
+namespace:// axis node(set) [expr 1]..[expr n] / ... / filter
+\stoptyping
+
+When we are inside a \CONTEXT\ run, the namespace is \type {tex}. Hoewever, if
+you want not to print back to \TEX\ you need to be more explicit. Say that we
+typeset examns and have a (not that logical) structure like:
+
+\starttyping
+<question>
+ <text>...</text>
+ <answer>
+ <item>one</item>
+ <item>two</item>
+ <item>three</item>
+ </answer>
+ <alternative>
+ <condition>true</condition>
+ <score>1</score>
+ </alternative>
+ <alternative>
+ <condition>false</condition>
+ <score>0</score>
+ </alternative>
+ <alternative>
+ <condition>true</condition>
+ <score>2</score>
+ </alternative>
+</question>
+\stoptyping
+
+Say that we typeset the questions with:
+
+\starttyping
+\startxmlsetups question
+ \blank
+ score: \xmlfunction{#1}{totalscore}
+ \blank
+ \xmlfirst{#1}{text}
+ \startitemize
+ \xmlfilter{#1}{/answer/item/command(answer:item)}
+ \stopitemize
+ \endgraf
+ \blank
+\stopxmlsetups
+\stoptyping
+
+Each item in the answer results in a call to:
+
+\starttyping
+\startxmlsetups answer:item
+ \startitem
+ \xmlflush{#1}
+ \endgraf
+ \xmlfilter{#1}{../../alternative[position()=rootposition()]/
+ condition/command(answer:condition)}
+ \stopitem
+\stopxmlsetups
+\stoptyping
+
+\starttyping
+\startxmlsetups answer:condition
+ \endgraf
+ condition: \xmlflush{#1}
+ \endgraf
+\stopxmlsetups
+\stoptyping
+
+Now, there are two rather special filters here. The first one involves
+calculating the total score. As we look forward we use a function to deal with
+this.
+
+\starttyping
+\startluacode
+function xml.functions.totalscore(root)
+ local score = 0
+ for e in xml.collected(root,"/alternative") do
+ score = score + xml.filter(e,"xml:///score/number()") or 0
+ end
+ tex.write(score)
+end
+\stopluacode
+\stoptyping
+
+Watch how we use the namespace to keep the results at the \LUA\ end.
+
+The second special trick shown here is to limit a match using the current
+position of the root (\type {#}) match.
+
+As you can see, a path expression can be more than just filtering a few nodes. At
+the end of this manual you will find a bunch of examples.
+
+\stopsection
+
+\startsection[title={tables}]
+
+If you want to know how the internal \XML\ tables look you can print such a
+table:
+
+\starttyping
+print(table.serialize(e))
+\stoptyping
+
+This produces for instance:
+
+% s = xml.convert("<document><demo label='whatever'>some text</demo></document>")
+% print(table.serialize(xml.filter(s,"demo")[1]))
+
+\starttyping
+t={
+ ["at"]={
+ ["label"]="whatever",
+ },
+ ["dt"]={ "some text" },
+ ["ns"]="",
+ ["rn"]="",
+ ["tg"]="demo",
+}
+\stoptyping
+
+The \type {rn} entry is the renamed namespace (when renaming is applied). If you
+see tags like \type {@pi@} this means that we don't have an element, but (in this
+case) a processing instruction.
+
+\starttabulate[|l|p|]
+\NC \type {@rt@} \NC the root element \NC \NR
+\NC \type {@dd@} \NC document definition \NC \NR
+\NC \type {@cm@} \NC comment, like \type {<!-- whatever -->} \NC \NR
+\NC \type {@cd@} \NC so called \type {CDATA} \NC \NR
+\NC \type {@pi@} \NC processing instruction, like \type {<?whatever we want ?>} \NC \NR
+\stoptabulate
+
+There are many ways to deal with the content, but in the perspective of \TEX\
+only a few matter.
+
+\starttabulate[|l|p|]
+\NC \type {xml.sprint(e)} \NC print the content to \TEX\ and apply setups if needed \NC \NR
+\NC \type {xml.tprint(e)} \NC print the content to \TEX\ (serialize elements verbose) \NC \NR
+\NC \type {xml.cprint(e)} \NC print the content to \TEX\ (used for special content) \NC \NR
+\stoptabulate
+
+Keep in mind that anything low level that you uncover is not part of the official
+interface unless mentioned in this manual.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-filtering.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-filtering.tex
new file mode 100644
index 000000000..5bb5a35de
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-filtering.tex
@@ -0,0 +1,262 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-filtering
+
+\startchapter[title={Filtering content}]
+
+\startsection[title={\TEX\ versus \LUA}]
+
+It will not come as a surprise that we can access \XML\ files from \TEX\ as well
+as from \LUA. In fact there are two methods to deal with \XML\ in \LUA. First
+there are the low level \XML\ functions in the \type {xml} namespace. On top of
+those functions there is a set of functions in the \type {lxml} namespace that
+deals with \XML\ in a more \TEX ie way. Most of these have similar commands at
+the \TEX\ end.
+
+\startbuffer
+\startxmlsetups first:demo:one
+ \xmlfilter {#1} {artist/name[text()='Randy Newman']/..
+ /albums/album[position()=3]/command(first:demo:two)}
+\stopxmlsetups
+
+\startxmlsetups first:demo:two
+ \blank \start \tt
+ \xmldisplayverbatim{#1}
+ \stop \blank
+\stopxmlsetups
+
+\xmlprocessfile{demo}{music-collection.xml}{first:demo:one}
+\stopbuffer
+
+\typebuffer
+
+This gives the following snippet of verbatim \XML\ code. The indentation is
+conform the indentation in the whole \XML\ file. \footnote {The (probably
+outdated) \XML\ file contains the collection stores on my slimserver instance.
+You can use the \type {mtxrun --script flac} to generate such files.}
+
+\doifmodeelse {atpragma} {
+ \getbuffer
+} {
+ \typefile{xml-mkiv-01.xml}
+}
+
+An alternative written in \LUA\ looks as follows:
+
+\startbuffer
+\blank \start \tt \startluacode
+ local m = lxml.load("mine","music-collection.xml") -- m == lxml.id("mine")
+ local p = "artist/name[text()='Randy Newman']/../albums/album[position()=4]"
+ local l = lxml.filter(m,p) -- returns a list (with one entry)
+ lxml.displayverbatim(l[1])
+\stopluacode \stop \blank
+\stopbuffer
+
+\typebuffer
+
+This produces:
+
+\doifmodeelse {atpragma} {
+ \getbuffer
+} {
+ \typefile{xml-mkiv-02.xml}
+}
+
+You can use both methods mixed but in practice we will use the \TEX\ commands in
+regular styles and the mixture in modules, for instance in those dealing with
+\MATHML\ and cals tables. For complex matters you can write your own finalizers
+(the last action to be taken in a match) in \LUA\ and use them at the \TEX\ end.
+
+\stopsection
+
+\startsection[title={a few details}]
+
+In \CONTEXT\ setups are a rather common variant on macros (\TEX\ commands) but
+with their own namespace. An example of a setup is:
+
+\starttyping
+\startsetup doc:print
+ \setuppapersize[A4][A4]
+\stopsetup
+
+\startsetup doc:screen
+ \setuppapersize[S6][S4]
+\stopsetup
+\stoptyping
+
+Given the previous definitions, later on we can say something like:
+
+\starttyping
+\doifmodeelse {paper} {
+ \setup[doc:print]
+} {
+ \setup[doc:screen]
+}
+\stoptyping
+
+Another example is:
+
+\starttyping
+\startsetup[doc:header]
+ \marking[chapter]
+ \space
+ --
+ \space
+ \pagenumber
+\stopsetup
+\stoptyping
+
+in combination with:
+
+\starttyping
+\setupheadertexts[\setup{doc:header}]
+\stoptyping
+
+Here the advantage is that instead of ending up with an unreadable header
+definitions, we use a nicely formatted setup. An important property of setups and
+the reason why they were introduced long ago is that spaces and newlines are
+ignored in the definition. This means that we don't have to worry about so called
+spurious spaces but it also means that when we do want a space, we have to use
+the \type {\space} command.
+
+The only difference between setups and \XML\ setups is that the following ones
+get an argument (\type {#1}) that reflects the current node in the \XML\ tree.
+
+\stopsection
+
+\startsection[title={CDATA}]
+
+What to do with \type {CDATA}? There are a few methods at tle \LUA\ end for
+dealing with it but here we just mention how you can influence the rendering.
+There are four macros that play a role here:
+
+\starttyping
+\unexpanded\def\xmlcdataobeyedline {\obeyedline}
+\unexpanded\def\xmlcdataobeyedspace{\strut\obeyedspace}
+\unexpanded\def\xmlcdatabefore {\begingroup\tt}
+\unexpanded\def\xmlcdataafter {\endgroup}
+\stoptyping
+
+Technically you can overload them but beware of side effects. Normally you won't
+see much \type {CDATA} and whenever we do, it involves special data that needs
+very special treatment anyway.
+
+\stopsection
+
+\startsection[title={Entities}]
+
+As usual with any way of encoding documents you need escapes in order to encode
+the characters that are used in tagging the content, embedding comments, escaping
+special characters in strings (in programming languages), etc. In \XML\ this
+means that in order characters like \type {<} you need an escape like \type
+{&lt;} and in order then to encode an \type {&} you need \type {&amp;}.
+
+In a typesetting workflow using a programming language like \TEX, another problem
+shows up. There we have different special characters, like \type {$ $} for triggering
+math, but also the backslash, braces etc. Even one such special character is already
+enough to have yet another escaping mechanism at work.
+
+Ideally a user should not worry about these issues but it helps figuring out issues
+when you know what happens under the hood. Also it is good to know that in the
+code there are several ways to deal with these issues. Take the following document:
+
+\starttyping
+<text>
+ Here we have a bit of a &lt;&mess&gt;:
+
+ # &#35;
+ % &#37;
+ \ &#92;
+ { &#123;
+ | &#124;
+ } &#125;
+ ~ &#126;
+</text>
+\stoptyping
+
+When the file is read the \type {&lt;} entity will be replaced by \type {<} and
+the \type {&gt;} by \type {>}. The numeric entities will be replaced by the
+characters they refer to. The \type {&mess} is kind of special. We do preload
+a huge list of more or less standardized entities but \type {mess} is not in
+there. However, it is possible to have it defined in the document preamble, like:
+
+\starttyping
+<!DOCTYPE dummy SYSTEM "dummy.dtd" [
+ <!ENTITY mess "what a mess" >
+]>
+\stoptyping
+
+or even this:
+
+\starttyping
+<!DOCTYPE dummy SYSTEM "dummy.dtd" [
+ <!ENTITY mess "<p>what a mess</p>" >
+]>
+\stoptyping
+
+You can also define it in your document style using one of:
+
+\startxmlcmd {\cmdbasicsetup{xmlsetentity}}
+ replaces entity with name \cmdinternal {cd:name} by \cmdinternal {cd:text}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmltexentity}}
+ replaces entity with name \cmdinternal {cd:name} by \cmdinternal {cd:text}
+ typeset under a \TEX\ regime
+\stopxmlcmd
+
+Such a definition will always have a higher priority than the one defined
+in the document. Anyway, when the document is read in all entities are
+resolved and those that need a special treatment because they map to some
+text are stored in such a way that we can roundtrip them. As a consequence,
+as soon as the content gets pushed into \TEX, we need not only to intercept
+special characters but also have to make sure that the following works:
+
+\starttyping
+\xmltexentity {tex} {\TEX}
+\stoptyping
+
+Here the backslash starts a control sequence while in regular content a
+backslash is just that: a backslash.
+
+Special characters are really special when we have to move text around
+in a \TEX\ ecosystem.
+
+\starttyping
+<text>
+ <title>About #3</title>
+</text>
+\stoptyping
+
+If we map and define title as follows:
+
+\starttyping
+\startxmlsetup xml:title
+ \title{\xmlflush{#1}}
+\stopxmlsetup
+\stoptyping
+
+normally something \type {\xmlflush {id::123}} will be written to the
+auxiliary file and in most cases that is quite okay, but if we have this:
+
+\starttyping
+\setuphead[title][expansion=yes]
+\stoptyping
+
+then we don't want the \type {#} to end up as hash because later on \TEX\
+can get very confused about it because it sees some argument then in a
+probably unexpected way. This is solved by escaping the hash like this:
+
+\starttyping
+About \Ux{23}3
+\stoptyping
+
+The \type {\Ux} command will convert its hexadecimal argument into a
+character. Of course one then needs to typeset such a text under a \TEX\
+character regime but that is normally the case anyway.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-introduction.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-introduction.tex
new file mode 100644
index 000000000..e7f0124da
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-introduction.tex
@@ -0,0 +1,42 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-introduction
+
+\startchapter[title={Introduction}]
+
+This manual presents the \MKIV\ way of dealing with \XML. Although the
+traditional \MKII\ streaming parser has a charming simplicity in its control, for
+complex documents the tree based \MKIV\ method is more convenient. It is for this
+reason that the old method has been removed from \MKIV. If you are familiar with
+\XML\ processing in \MKII, then you will have noticed that the \MKII\ commands
+have \type {XML} in their name. The \MKIV\ commands have a lowercase \type {xml}
+in their names. That way there is no danger for confusion or a mixup.
+
+You may wonder why we do these manipulations in \TEX\ and not use \XSLT\ (or
+other transformation methods) instead. The advantage of an integrated approach is
+that it simplifies usage. Think of not only processing the document, but also
+using \XML\ for managing resources in the same run. An \XSLT\ approach is just as
+verbose (after all, you still need to produce \TEX\ code) and probably less
+readable. In the case of \MKIV\ the integrated approach is also faster and gives
+us the option to manipulate content at runtime using \LUA. It has the additional
+advantage that to some extend we can handle a mix of \TEX\ and \XML\ because we
+know when we're doing one or the other.
+
+This manual is dedicated to Taco Hoekwater, one of the first \CONTEXT\ users, and
+also the first to use it for processing \XML. Who could have thought at that time
+that we would have a more convenient way of dealing with those angle brackets.
+The second version for this manual is dedicated to Thomas Schmitz, a power user
+who occasionally became victim of the evolving mechanisms.
+
+\blank
+
+\startlines
+Hans Hagen
+\PRAGMA
+Hasselt NL
+2008\endash2016
+\stoplines
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-lookups.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-lookups.tex
new file mode 100644
index 000000000..e6afaa948
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-lookups.tex
@@ -0,0 +1,314 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-lookups
+
+\startchapter[title={Lookups using lpaths}]
+
+\startsection[title={introduction}]
+
+There is not that much system in the following examples. They resulted from tests
+with different documents. The current implementation evolved out of the
+experimental code. For instance, I decided to add the multiple expressions in row
+handling after a few email exchanges with Jean|-|Michel Huffen.
+
+One of the main differences between the way \XSLT\ resolves a path and our way is
+the anchor. Take:
+
+\starttyping
+/something
+something
+\stoptyping
+
+The first one anchors in the current (!) element so it will only consider direct
+children. The second one does a deep lookup and looks at the descendants as well.
+Furthermore we have a few extra shortcuts like \type {**} in \type {a/**/b} which
+represents all descendants.
+
+The expressions (between square brackets) has to be valid \LUA\ and some
+preprocessing is done to resolve the built in functions. So, you might use code
+like:
+
+\starttyping
+my_lpeg_expression:match(text()) == "whatever"
+\stoptyping
+
+given that \type {my_lpeg_expression} is known. In the examples below we use the
+visualizer to show the steps. Some are shown more than once as part of a set.
+
+\stopsection
+
+\startsection[title={special cases}]
+
+\xmllshow{}
+\xmllshow{*}
+\xmllshow{.}
+\xmllshow{/}
+
+\stopsection
+
+\startsection[title={wildcards}]
+
+\xmllshow{*}
+\xmllshow{*:*}
+\xmllshow{/*}
+\xmllshow{/*:*}
+\xmllshow{*/*}
+\xmllshow{*:*/*:*}
+
+\xmllshow{a/*}
+\xmllshow{a/*:*}
+\xmllshow{/a/*}
+\xmllshow{/a/*:*}
+
+\xmllshow{/*}
+\xmllshow{/**}
+\xmllshow{/***}
+
+\stopsection
+
+\startsection[title={multiple steps}]
+
+\xmllshow{answer}
+\xmllshow{answer/test/*}
+\xmllshow{answer/test/child::}
+\xmllshow{answer/*}
+\xmllshow{answer/*[tag()='p' and position()=1 and text()!='']}
+
+\stopsection
+
+\startsection[title={pitfals}]
+
+\xmllshow{[oneof(lower(@encoding),'tex','context','ctx')]}
+\xmllshow{.[oneof(lower(@encoding),'tex','context','ctx')]}
+
+\stopsection
+
+\startsection[title={more special cases}]
+
+\xmllshow{**}
+\xmllshow{*}
+\xmllshow{..}
+\xmllshow{.}
+\xmllshow{//}
+\xmllshow{/}
+
+\xmllshow{**/}
+\xmllshow{**/*}
+\xmllshow{**/.}
+\xmllshow{**//}
+
+\xmllshow{*/}
+\xmllshow{*/*}
+\xmllshow{*/.}
+\xmllshow{*//}
+
+\xmllshow{/**/}
+\xmllshow{/**/*}
+\xmllshow{/**/.}
+\xmllshow{/**//}
+
+\xmllshow{/*/}
+\xmllshow{/*/*}
+\xmllshow{/*/.}
+\xmllshow{/*//}
+
+\xmllshow{./}
+\xmllshow{./*}
+\xmllshow{./.}
+\xmllshow{.//}
+
+\xmllshow{../}
+\xmllshow{../*}
+\xmllshow{../.}
+\xmllshow{..//}
+
+\stopsection
+
+\startsection[title={more wildcards}]
+
+\xmllshow{one//two}
+\xmllshow{one/*/two}
+\xmllshow{one/**/two}
+\xmllshow{one/***/two}
+\xmllshow{one/x//two}
+\xmllshow{one//x/two}
+\xmllshow{//x/two}
+
+\stopsection
+
+\startsection[title={special axis}]
+
+\xmllshow{descendant::whocares/ancestor::whoknows}
+\xmllshow{descendant::whocares/ancestor::whoknows/parent::}
+\xmllshow{descendant::whocares/ancestor::}
+\xmllshow{child::something/child::whatever/child::whocares}
+\xmllshow{child::something/child::whatever/child::whocares|whoknows}
+\xmllshow{child::something/child::whatever/child::(whocares|whoknows)}
+\xmllshow{child::something/child::whatever/child::!(whocares|whoknows)}
+\xmllshow{child::something/child::whatever/child::(whocares)}
+\xmllshow{child::something/child::whatever/child::(whocares)[position()>2]}
+\xmllshow{child::something/child::whatever[position()>2][position()=1]}
+\xmllshow{child::something/child::whatever[whocares][whocaresnot]}
+\xmllshow{child::something/child::whatever[whocares][not(whocaresnot)]}
+\xmllshow{child::something/child::whatever/self::whatever}
+
+There is also \type {last-match::} that starts with the last found set of nodes.
+This can save some run time when you do lots of tests combined with a same check
+afterwards. There is however one pitfall: you never know what is done with that
+last match in the setup that gets called nested. Take the following example:
+
+\starttyping
+\startbuffer[test]
+<something>
+ <crap> <crapa> <crapb> <crapc> <crapd>
+ <crape>
+ done 1
+ </crape>
+ </crapd> </crapc> </crapb> </crapa>
+ <crap> <crapa> <crapb> <crapc> <crapd>
+ <crape>
+ done 2
+ </crape>
+ </crapd> </crapc> </crapb> </crapa>
+ <crap> <crapa> <crapb> <crapc> <crapd>
+ <crape>
+ done 3
+ </crape>
+ </crapd> </crapc> </crapb> </crapa>
+</something>
+\stopbuffer
+\stoptyping
+
+One way to filter the content is this:
+
+\starttyping
+\xmldoif {#1} {/crap/crapa/crapb/crapc/crapd/crape} {
+ some action
+}
+\stoptyping
+
+It is not unlikely that you will do something like this:
+
+\starttyping
+\xmlfirst {#1} {/crap/crapa/crapb/crapc/crapd/crape} {
+ \xmlfirst{#1}{/crap/crapa/crapb/crapc/crapd/crape}
+}
+\stoptyping
+
+This means that the path is resolved twice but that can be avoided as
+follows:
+
+\starttyping
+\xmldoif{#1}{/crap/crapa/crapb/crapc/crapd/crape}{
+ \xmlfirst{#1}{last-match::}
+}
+\stoptyping
+
+But the next is now guaranteed to work:
+
+\starttyping
+\xmldoif{#1}{/crap/crapa/crapb/crapc/crapd/crape}{
+ \xmlfirst{#1}{last-match::}
+ \xmllast{#1}{last-match::}
+}
+\stoptyping
+
+Because the first one can have done some lookup the last match can be replaced
+and the second call will give unexpected results. You can overcome this with:
+
+\starttyping
+\xmldoif{#1}{/crap/crapa/crapb/crapc/crapd/crape}{
+ \xmlpushmatch
+ \xmlfirst{#1}{last-match::}
+ \xmlpopmatch
+}
+\stoptyping
+
+Does it pay off? Here are some timings of a 10.000 times text and lookup
+like the previous (on a decent January 2016 laptop):
+
+\starttabulate[|r|l|]
+\NC 0.239 \NC \type {\xmldoif {...} {...}} \NC \NR
+\NC 0.292 \NC \type {\xmlfirst {...} {...}} \NC \NR
+\NC 0.538 \NC \type {\xmldoif {...} {...} + \xmlfirst {...} {...}} \NC \NR
+\NC 0.338 \NC \type {\xmldoif {...} {...} + \xmlfirst {...} {last-match::}} \NC \NR
+\NC 0.349 \NC \type {+ \xmldoif {...} {...} + \xmlfirst {...} {last-match::}-} \NC \NR
+\stoptabulate
+
+So, pushing and popping (the last row) is a bit slower than not doing that but it
+is still much faster than not using \type {last-match::} at all. As a shortcut
+you can use \type {=}, as in:
+
+\starttyping
+\xmlfirst{#1}{=}
+\stoptyping
+
+You can even do this:
+
+\starttyping
+\xmlall{#1}{last-match::/text()}
+\stoptyping
+
+or
+
+\starttyping
+\xmlall{#1}{=/text()}
+\stoptyping
+
+
+\stopsection
+
+\startsection[title={some more examples}]
+
+\xmllshow{/something/whatever}
+\xmllshow{something/whatever}
+\xmllshow{/**/whocares}
+\xmllshow{whoknows/whocares}
+\xmllshow{whoknows}
+\xmllshow{whocares[contains(text(),'f') or contains(text(),'g')]}
+\xmllshow{whocares/first()}
+\xmllshow{whocares/last()}
+\xmllshow{whatever/all()}
+\xmllshow{whocares/position(2)}
+\xmllshow{whocares/position(-2)}
+\xmllshow{whocares[1]}
+\xmllshow{whocares[-1]}
+\xmllshow{whocares[2]}
+\xmllshow{whocares[-2]}
+\xmllshow{whatever[3]/attribute(id)}
+\xmllshow{whatever[2]/attribute('id')}
+\xmllshow{whatever[3]/text()}
+\xmllshow{/whocares/first()}
+\xmllshow{/whocares/last()}
+
+\xmllshow{xml://whatever/all()}
+\xmllshow{whatever/all()}
+\xmllshow{//whocares}
+\xmllshow{..[2]}
+\xmllshow{../*[2]}
+
+\xmllshow{/(whocares|whocaresnot)}
+\xmllshow{/!(whocares|whocaresnot)}
+\xmllshow{/!whocares}
+
+\xmllshow{/interface/command/command(xml:setups:register)}
+\xmllshow{/interface/command[@name='xxx']/command(xml:setups:typeset)}
+\xmllshow{/arguments/*}
+\xmllshow{/sequence/first()}
+\xmllshow{/arguments/text()}
+\xmllshow{/sequence/variable/first()}
+\xmllshow{/interface/define[@name='xxx']/first()}
+\xmllshow{/parameter/command(xml:setups:parameter:measure)}
+
+\xmllshow{/(*:library|figurelibrary)/*:figure/*:label}
+\xmllshow{/(*:library|figurelibrary)/figure/*:label}
+\xmllshow{/(*:library|figurelibrary)/figure/label}
+\xmllshow{/(*:library|figurelibrary)/figure:*/label}
+
+\xmlshow {whatever//br[tag(1)='br']}
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-lpath.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-lpath.tex
new file mode 100644
index 000000000..9c8b853c8
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-lpath.tex
@@ -0,0 +1,207 @@
+\input lxml-ctx.mkiv
+
+\ctxlua{dofile("t:/sources/lxml-lpt.lua")}
+
+\startbuffer[xmltest]
+<?xml version='1.0'?>
+
+<!-- this is a test file -->
+
+<something id='1'>
+ <x:whatever id='1.1'>
+ <whocares id='1.1.1'>
+ test a
+ </whocares>
+ <whocaresnot id='1.1.2'>
+ test b
+ </whocaresnot>
+ </x:whatever>
+ <whatever id='2'>
+ <whocares id='2.1'>
+ test c
+ </whocares>
+ <whocaresnot id='2.2'>
+ test d
+ </whocaresnot>
+ </whatever>
+ <whatever id='3'>
+ test e
+ </whatever>
+ <whatever id='4' test="xxx">
+ <whocares id='4.1'>
+ test f
+ </whocares>
+ <whocares id='4.2'>
+ test g
+ </whocares>
+ </whatever>
+ <whatever id='5' test="xxx">
+ <whoknows id='5.1'>
+ <whocares id='5.1.1'>
+ test h
+ </whocares>
+ </whoknows>
+ <whoknows id='5.2'>
+ <whocaresnot id='5.2.1'>
+ test i
+ </whocaresnot>
+ </whoknows>
+ <whoknows id='5.3'>
+ <whocares id='5.3.1'>
+ test j
+ </whocares>
+ </whoknows>
+ </whatever>
+</something>
+\stopbuffer
+
+% \enabletrackers[xml.lparse]
+
+\setuplayout[width=middle,height=middle,header=1cm,footer=1cm,topspace=2cm,backspace=2cm]
+\setupbodyfont[10pt]
+
+\setfalse\xmllshowbuffer
+
+\starttext
+
+\xmllshow{/(*:library|figurelibrary)/*:figure/*:label}
+\xmllshow{/(*:library|figurelibrary)/figure/*:label}
+\xmllshow{/(*:library|figurelibrary)/figure/label}
+\xmllshow{/(*:library|figurelibrary)/figure:*/label}
+
+% \xmllshow{collection[@version='all']/resources/manual[match()==1]/paper/command(xml:overview)}
+% \xmllshow{collection/resources/manual[match()=1]/paper/command(xml:overview)}
+
+% \xmllshow{answer//oeps}
+% \xmllshow{answer/*/oeps}
+% \xmllshow{answer/**/oeps}
+% \xmllshow{answer/***/oeps}
+% \xmllshow{answer/x//oeps}
+% \xmllshow{answer//x/oeps}
+% \xmllshow{//x/oeps}
+% \xmllshow{answer/test/*}
+% \xmllshow{answer/test/child::}
+% \xmllshow{answer/*}
+% \xmllshow{ oeps / answer / .. / * [tag()='p' and position()=1 and text()!=''] / oeps()}
+
+% \xmllshow{ artist / name [text()='Randy Newman'] / .. / albums / album [position()=3] / command(first:demo:two)}
+% \xmllshow{/exa:selectors/exa:selector/exa:list/component[count()>1]}
+
+\stoptext
+
+\xmllshow{/*}
+\xmllshow{child::}
+\xmllshow{child::test}
+\xmllshow{/test/test}
+\xmllshow{../theory/sections/section/exercises}
+\xmllshow{../training/practicalassignments}
+\xmllshow{../../Outcome[position()=rootposition()]/Condition/command(xml:answer:mc:condition)}
+
+% \stoptext
+
+% \typebuffer[xmltest] \page
+
+\xmllshowbuffer{xmltest}{**}{id}
+\xmllshowbuffer{xmltest}{*}{id}
+\xmllshowbuffer{xmltest}{..}{id}
+\xmllshowbuffer{xmltest}{.}{id}
+\xmllshowbuffer{xmltest}{//}{id}
+\xmllshowbuffer{xmltest}{/}{id}
+
+\xmllshowbuffer{xmltest}{**/}{id}
+\xmllshowbuffer{xmltest}{**/*}{id}
+\xmllshowbuffer{xmltest}{**/.}{id}
+\xmllshowbuffer{xmltest}{**//}{id}
+
+\xmllshowbuffer{xmltest}{*/}{id}
+\xmllshowbuffer{xmltest}{*/*}{id}
+\xmllshowbuffer{xmltest}{*/.}{id}
+\xmllshowbuffer{xmltest}{*//}{id}
+
+\xmllshowbuffer{xmltest}{/**/}{id}
+\xmllshowbuffer{xmltest}{/**/*}{id}
+\xmllshowbuffer{xmltest}{/**/.}{id}
+\xmllshowbuffer{xmltest}{/**//}{id}
+
+\xmllshowbuffer{xmltest}{/*/}{id}
+\xmllshowbuffer{xmltest}{/*/*}{id}
+\xmllshowbuffer{xmltest}{/*/.}{id}
+\xmllshowbuffer{xmltest}{/*//}{id}
+
+\xmllshowbuffer{xmltest}{./}{id}
+\xmllshowbuffer{xmltest}{./*}{id}
+\xmllshowbuffer{xmltest}{./.}{id}
+\xmllshowbuffer{xmltest}{.//}{id}
+
+\xmllshowbuffer{xmltest}{../}{id}
+\xmllshowbuffer{xmltest}{../*}{id}
+\xmllshowbuffer{xmltest}{../.}{id}
+\xmllshowbuffer{xmltest}{..//}{id}
+
+\xmllshowbuffer{xmltest}{descendant::whocares/ancestor::whoknows}{id}
+\xmllshowbuffer{xmltest}{descendant::whocares/ancestor::whoknows/parent::}{id}
+\xmllshowbuffer{xmltest}{descendant::whocares/ancestor::}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever/child::whocares}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever/child::whocares|whoknows}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever/child::(whocares|whoknows)}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever/child::!(whocares|whoknows)}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever/child::(whocares)}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever/child::(whocares)[position()>2]}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever[position()>2][position()=1]}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever[whocares][whocaresnot]}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever[whocares][not(whocaresnot)]}{id}
+\xmllshowbuffer{xmltest}{child::something/child::whatever/self::whatever}{id}
+\xmllshowbuffer{xmltest}{/something/whatever}{id}
+\xmllshowbuffer{xmltest}{something/whatever}{id}
+\xmllshowbuffer{xmltest}{/**/whocares}{id}
+\xmllshowbuffer{xmltest}{whoknows/whocares}{id}
+\xmllshowbuffer{xmltest}{whoknows}{id}
+\xmllshowbuffer{xmltest}{whocares[contains(text(),'f') or contains(text(),'g')]}{id}
+\xmllshowbuffer{xmltest}{whocares/first()}{id}
+\xmllshowbuffer{xmltest}{whocares/last()}{id}
+\xmllshowbuffer{xmltest}{whatever/all()}{id}
+\xmllshowbuffer{xmltest}{whocares/position(2)}{id}
+\xmllshowbuffer{xmltest}{whocares/position(-2)}{id}
+\xmllshowbuffer{xmltest}{whocares[1]}{id}
+\xmllshowbuffer{xmltest}{whocares[-1]}{id}
+\xmllshowbuffer{xmltest}{whocares[2]}{id}
+\xmllshowbuffer{xmltest}{whocares[-2]}{id}
+\xmllshowbuffer{xmltest}{whatever[3]/attribute(id)}{id}
+\xmllshowbuffer{xmltest}{whatever[2]/attribute('id')}{id}
+\xmllshowbuffer{xmltest}{whatever[3]/text()}{id}
+\xmllshowbuffer{xmltest}{/whocares/first()}{id}
+\xmllshowbuffer{xmltest}{/whocares/last()}{id}
+
+\xmllshowbuffer{xmltest}{xml://whatever/all()}{id}
+\xmllshowbuffer{xmltest}{whatever/all()}{id}
+\xmllshowbuffer{xmltest}{//whocares}{id}
+\xmllshowbuffer{xmltest}{..[2]}{id}
+\xmllshowbuffer{xmltest}{../*[2]}{id}
+
+\xmllshowbuffer{xmltest}{/(whocares|whocaresnot)}{id}
+\xmllshowbuffer{xmltest}{/!(whocares|whocaresnot)}{id}
+\xmllshowbuffer{xmltest}{/!whocares}{id}
+
+% \page
+
+% \xmllshow{/interface/command/command(xml:setups:register)}
+% \xmllshow{/interface/command[@name='xxx']/command(xml:setups:typeset)}
+% \xmllshow{/arguments/*}
+% \xmllshow{/sequence/first()}
+% \xmllshow{/arguments/text()}
+% \xmllshow{/sequence/variable/first()}
+% \xmllshow{/interface/define[@name='xxx']/first()}
+% \xmllshow{/parameter/command(xml:setups:parameter:measure)}
+
+% \page
+
+% \xmllshow{interface/command/command(xml:setups:register)}
+% \xmllshow{interface/command[@name='xxx']/command(xml:setups:typeset)}
+% \xmllshow{arguments/*}
+% \xmllshow{sequence/first()}
+% \xmllshow{arguments/text()}
+% \xmllshow{sequence/variable/first()}
+% \xmllshow{interface/define[@name='xxx']/first()}
+% \xmllshow{parameter/command(xml:setups:parameter:measure)}
+
+\stoptext
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-style.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-style.tex
new file mode 100644
index 000000000..8bcd74086
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-style.tex
@@ -0,0 +1,155 @@
+\startenvironment xml-mkiv-style
+
+\input lxml-ctx.mkiv
+
+\settrue \xmllshowtitle
+\setfalse\xmllshowwarning
+
+\usemodule[set-11]
+
+\loadsetups[i-context]
+
+% \definehspace[squad][1em plus .25em minus .25em]
+
+\usemodule[abr-02]
+
+\setuplayout
+ [location=middle,
+ marking=on,
+ backspace=20mm,
+ cutspace=20mm,
+ topspace=15mm,
+ header=15mm,
+ footer=15mm,
+ height=middle,
+ width=middle]
+
+\setuppagenumbering
+ [alternative=doublesided,
+ location=]
+
+\setupfootertexts
+ [][pagenumber]
+
+\setupheadertexts
+ [][chapter]
+
+\setupheader
+ [color=colortwo,
+ style=bold]
+
+\setupfooter
+ [color=colortwo,
+ style=bold]
+
+\setuphead
+ [chapter]
+ [page={yes,header,right},
+ header=empty,
+ style=\bfc]
+
+\setupsectionblock
+ [page={yes,header,right}]
+
+\starttexdefinition unexpanded section:chapter:number #1
+ \doifmode{*sectionnumber} {
+ \bf
+ \llap{<\enspace}#1\enspace>
+ }
+\stoptexdefinition
+
+\starttexdefinition unexpanded section:section:number #1
+ \doifmode{*sectionnumber} {
+ \bf
+ \llap{<<\enspace}#1\enspace>>
+ }
+\stoptexdefinition
+
+\starttexdefinition unexpanded section:subsection:number #1
+ \doifmode{*sectionnumber} {
+ \bf
+ \llap{<<<\enspace}#1\enspace>>>
+ }
+\stoptexdefinition
+
+\setuphead[chapter] [numbercolor=black,numbercommand=\texdefinition{section:chapter:number}]
+\setuphead[section] [numbercolor=black,numbercommand=\texdefinition{section:section:number}]
+\setuphead[subsection] [numbercolor=black,numbercommand=\texdefinition{section:subsection:number}]
+\setuphead[subsubsection][numbercolor=,numbercommand=,before=\blank,after=\blank]
+
+\setuphead
+ [section]
+ [style=\bfa]
+
+\setuplist
+ [chapter]
+ [style=bold]
+
+\setupinteractionscreen
+ [option=doublesided]
+
+\setupalign
+ [tolerant,stretch]
+
+\setupwhitespace
+ [big]
+
+\setuptolerance
+ [tolerant]
+
+\doifelsemode {atpragma} {
+ \setupbodyfont[lucidaot,10pt]
+} {
+ \setupbodyfont[dejavu,10pt]
+}
+
+\definecolor[colorone] [b=.5]
+\definecolor[colortwo] [s=.3]
+\definecolor[colorthree][y=.5]
+
+\setuptype
+ [color=colorone]
+
+\setuptyping
+ [color=colorone]
+
+\setuphead
+ [lshowtitle]
+ [style=\tt,
+ color=colorone]
+
+\setuphead
+ [chapter,section]
+ [numbercolor=colortwo,
+ color=colorone]
+
+\definedescription
+ [xmlcmd]
+ [alternative=hanging,
+ width=line,
+ distance=1em,
+ margin=2em,
+ headstyle=monobold,
+ headcolor=colorone]
+
+\setupframedtext
+ [setuptext]
+ [framecolor=colorone,
+ rulethickness=1pt,
+ corner=round]
+
+\usemodule[punk]
+
+\usetypescript[punk]
+
+\definelayer
+ [page]
+ [width=\paperwidth,
+ height=\paperheight]
+
+\definestartstop
+ [smallexample]
+ [before={\blank\bgroup\ss\small\setupwhitespace[medium]\setupblank[medium]},
+ after={\par\egroup\blank}]
+
+\stopenvironment
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-titlepage.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-titlepage.tex
new file mode 100644
index 000000000..427557214
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-titlepage.tex
@@ -0,0 +1,47 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-titlepage
+
+\setuplayout[page]
+
+\startstandardmakeup
+ \startfontclass[none] % nil the current fontclass since it may append its features
+ \EnableRandomPunk
+ \setlayerframed
+ [page]
+ [width=\paperwidth,height=\paperheight,
+ background=color,backgroundcolor=colorone,backgroundoffset=1ex,frame=off]
+ {}
+ \definedfont[demo@punk at 18pt]
+ \setbox\scratchbox\vbox {
+ \hsize\dimexpr\paperwidth+2ex\relax
+ \setupinterlinespace
+ \baselineskip 1\baselineskip plus 1pt minus 1pt
+ \raggedcenter
+ \color[colortwo]{\dorecurse{1000}{XML }}
+ }
+ \setlayer
+ [page]
+ [preset=middle]
+ {\vsplit\scratchbox to \dimexpr\paperheight+2ex\relax}
+ \definedfont[demo@punk at 90pt]
+ \setstrut
+ \setlayerframed
+ [page]
+ [preset=rightbottom,offset=10mm]
+ [foregroundcolor=colorthree,align=flushright,offset=overlay,frame=off]
+ {Dealing\\with XML in\\Con\TeX t MkIV}
+ \definedfont[demo@punk at 18pt]
+ \setstrut
+ \setlayerframed
+ [page]
+ [preset=righttop,offset=10mm,x=3mm,rotation=90]
+ [foregroundcolor=colorthree,align=flushright,offset=overlay,frame=off]
+ {Hans Hagen, Pragma ADE, \currentdate}
+ \tightlayer[page]
+ \stopfontclass
+\stopstandardmakeup
+
+\setuplayout
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv-tricks.tex b/doc/context/sources/general/manuals/xml/xml-mkiv-tricks.tex
new file mode 100644
index 000000000..f8c65ecc9
--- /dev/null
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv-tricks.tex
@@ -0,0 +1,814 @@
+\environment xml-mkiv-style
+
+\startcomponent xml-mkiv-tricks
+
+\startchapter[title={Tips and tricks}]
+
+\startsection[title={tracing}]
+
+It can be hard to debug code as much happens kind of behind the screens.
+Therefore we have a couple of tracing options. Of course you can typeset some
+status information, using for instance:
+
+\startxmlcmd {\cmdbasicsetup{xmlshow}}
+ typeset the tree given by \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlinfo}}
+ typeset the name in the element given by \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlpath}}
+ returns the complete path (including namespace prefix and index) of the
+ given \cmdinternal {cd:node}
+\stopxmlcmd
+
+\startbuffer[demo]
+<?xml version "1.0"?>
+<document>
+ <section>
+ <content>
+ <p>first</p>
+ <p><b>second</b></p>
+ </content>
+ </section>
+ <section>
+ <content>
+ <p><b>third</b></p>
+ <p>fourth</p>
+ </content>
+ </section>
+</document>
+\stopbuffer
+
+Say that we have the following \XML:
+
+\typebuffer[demo]
+
+and the next definitions:
+
+\startbuffer
+\startxmlsetups xml:demo:base
+ \xmlsetsetup{#1}{p|b}{xml:demo:*}
+\stopxmlsetups
+
+\startxmlsetups xml:demo:p
+ \xmlflush{#1}
+ \par
+\stopxmlsetups
+
+\startxmlsetups xml:demo:b
+ \par
+ \xmlpath{#1} : \xmlflush{#1}
+ \par
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{example-10}{xml:demo:base}
+
+\xmlprocessbuffer{example-10}{demo}{}
+\stopbuffer
+
+\typebuffer
+
+This will give us:
+
+\blank \startpacked \getbuffer \stoppacked \blank
+
+If you use \type {\xmlshow} you will get a complete subtree which can
+be handy for tracing but can also lead to large documents.
+
+We also have a bunch of trackers that can be enabled, like:
+
+\starttyping
+\enabletrackers[xml.show,xml.parse]
+\stoptyping
+
+The full list (currently) is:
+
+\starttabulate[|lT|p|]
+\NC xml.entities \NC show what entities are seen and replaced \NC \NR
+\NC xml.path \NC show the result of parsing an lpath expression \NC \NR
+\NC xml.parse \NC show stepwise resolving of expressions \NC \NR
+\NC xml.profile \NC report all parsed lpath expressions (in the log) \NC \NR
+\NC xml.remap \NC show what namespaces are remapped \NC \NR
+\NC lxml.access \NC report errors with respect to resolving (symbolic) nodes \NC \NR
+\NC lxml.comments \NC show the comments that are encountered (if at all) \NC \NR
+\NC lxml.loading \NC show what files are loaded and converted \NC \NR
+\NC lxml.setups \NC show what setups are being associated to elements \NC \NR
+\stoptabulate
+
+In one of our workflows we produce books from \XML\ where the (educational)
+content is organized in many small files. Each book has about 5~chapters and each
+chapter is made of sections that contain text, exercises, resources, etc.\ and so
+the document is assembled from thousands of files (don't worry, runtime inclusion
+is pretty fast). In order to see where in the sources content resides we can
+trace the filename.
+
+\startxmlcmd {\cmdbasicsetup{xmlinclusion}}
+ returns the file where the node comes from
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlinclusions}}
+ returns the list of files where the node comes from
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlbadinclusions}}
+ returns a list of files that were not included due to some problem
+\stopxmlcmd
+
+Of course you have to make sure that these names end up somewhere visible, for
+instance in the margin.
+
+\stopsection
+
+\startsection[title={expansion}]
+
+For novice users the concept of expansion might sound frightening and to some
+extend it is. However, it is important enough to spend some words on it here.
+
+It is good to realize that most setups are sort of immediate. When one setup is
+issued, it can call another one and so on. Normally you won't notice that but
+there are cases where that can be a problem. In \TEX\ you can define a macro,
+take for instance:
+
+\starttyping
+\startxmlsetups xml:foo
+ \def\foobar{\xmlfirst{#1}{/bar}}
+\stopxmlsetups
+\stoptyping
+
+you store the reference top node \type {bar} in \type {\foobar} maybe for later use. In
+this case the content is not yet fetched, it will be done when \type {\foobar} is
+called.
+
+\starttyping
+\startxmlsetups xml:foo
+ \edef\foobar{\xmlfirst{#1}{/bar}}
+\stopxmlsetups
+\stoptyping
+
+Here the content of \type {bar} becomes the body of the macro. But what if
+\type {bar} itself contains elements that also contain elements. When there
+is a setup for \type {bar} it will be triggered and so on.
+
+When that setup looks like:
+
+\starttyping
+\startxmlsetups xml:bar
+ \def\barfoo{\xmlflush{#1}}
+\stopxmlsetups
+\stoptyping
+
+Here we get something like:
+
+\starttyping
+\foobar => {\def\barfoo{...}}
+\stoptyping
+
+When \type {\barfoo} is not defined we get an error and when it is known and expands
+to something weird we might also get an error.
+
+Especially when you don't know what content can show up, this can result in errors
+when an expansion fails, for example because some macro being used is not defined.
+To prevent this we can define a macro:
+
+\starttyping
+\starttexdefinition unexpanded xml:bar:macro #1
+ \def\barfoo{\xmlflush{#1}}
+\stoptexdefinition
+
+\startxmlsetups xml:bar
+ \texdefinition{xml:bar:macro}{#1}
+\stopxmlsetups
+\stoptyping
+
+The setup \type {xml:bar} will still expand but the replacement text now is just the
+call to the macro, think of:
+
+\starttyping
+\foobar => {\texdefinition{xml:bar:macro}{#1}}
+\stoptyping
+
+But this is often not needed, most \CONTEXT\ commands can handle the expansions
+quite well but it's good to know that there is a way out. So, now to some
+examples. Imagine that we have an \XML\ file that looks as follows:
+
+\starttyping
+<?xml version='1.0' ?>
+<demo>
+ <chapter>
+ <title>Some <em>short</em> title</title>
+ <content>
+ zeta
+ <index>
+ <key>zeta</key>
+ <content>zeta again</content>
+ </index>
+ alpha
+ <index>
+ <key>alpha</key>
+ <content>alpha <em>again</em></content>
+ </index>
+ gamma
+ <index>
+ <key>gamma</key>
+ <content>gamma</content>
+ </index>
+ beta
+ <index>
+ <key>beta</key>
+ <content>beta</content>
+ </index>
+ delta
+ <index>
+ <key>delta</key>
+ <content>delta</content>
+ </index>
+ done!
+ </content>
+ </chapter>
+</demo>
+\stoptyping
+
+There are a few structure related elements here: a chapter (with its list entry)
+and some index entries. Both are multipass related and therefore travel around.
+This means that when we let data end up in the auxiliary file, we need to make
+sure that we end up with either expanded data (i.e.\ no references to the \XML\
+tree) or with robust forward and backward references to elements in the tree.
+
+Here we discuss three approaches (and more may show up later): pushing \XML\ into
+the auxiliary file and using references to elements either or not with an
+associated setup. We control the variants with a switch.
+
+\starttyping
+\newcount\TestMode
+
+\TestMode=0 % expansion=xml
+\TestMode=1 % expansion=yes, index, setup
+\TestMode=2 % expansion=yes
+\stoptyping
+
+We apply a couple of setups:
+
+\starttyping
+\startxmlsetups xml:mysetups
+ \xmlsetsetup{\xmldocument}{demo|index|content|chapter|title|em}{xml:*}
+\stopxmlsetups
+
+\xmlregistersetup{xml:mysetups}
+\stoptyping
+
+The main document is processed with:
+
+\starttyping
+\startxmlsetups xml:demo
+ \xmlflush{#1}
+ \subject{contents}
+ \placelist[chapter][criterium=all]
+ \subject{index}
+ \placeregister[index][criterium=all]
+ \page % else buffer is forgotten when placing header
+\stopxmlsetups
+\stoptyping
+
+First we show three alternative ways to deal with the chapter. The first case
+expands the \XML\ reference so that we have an \XML\ stream in the auxiliary
+file. This stream is processed as a small independent subfile when needed. The
+second case registers a reference to the current element (\type {#1}). This means
+that we have access to all data of this element, like attributes, title and
+content. What happens depends on the given setup. The third variant does the same
+but here the setup is part of the reference.
+
+\starttyping
+\startxmlsetups xml:chapter
+ \ifcase \TestMode
+ % xml code travels around
+ \setuphead[chapter][expansion=xml]
+ \startchapter[title=eh: \xmltext{#1}{title}]
+ \xmlfirst{#1}{content}
+ \stopchapter
+ \or
+ % index is used for access via setup
+ \setuphead[chapter][expansion=yes,xmlsetup=xml:title:flush]
+ \startchapter[title=\xmlgetindex{#1}]
+ \xmlfirst{#1}{content}
+ \stopchapter
+ \or
+ % tex call to xml using index is used
+ \setuphead[chapter][expansion=yes]
+ \startchapter[title=hm: \xmlreference{#1}{xml:title:flush}]
+ \xmlfirst{#1}{content}
+ \stopchapter
+ \fi
+\stopxmlsetups
+
+\startxmlsetups xml:title:flush
+ \xmltext{#1}{title}
+\stopxmlsetups
+\stoptyping
+
+We need to deal with emphasis and the content of the chapter.
+
+\starttyping
+\startxmlsetups xml:em
+ \begingroup\em\xmlflush{#1}\endgroup
+\stopxmlsetups
+
+\startxmlsetups xml:content
+ \xmlflush{#1}
+\stopxmlsetups
+\stoptyping
+
+A similar approach is followed with the index entries. Watch how we use the
+numbered entries variant (in this case we could also have used just \type
+{entries} and \type {keys}).
+
+\starttyping
+\startxmlsetups xml:index
+ \ifcase \TestMode
+ \setupregister[index][expansion=xml,xmlsetup=]
+ \setstructurepageregister
+ [index]
+ [entries:1=\xmlfirst{#1}{content},
+ keys:1=\xmltext{#1}{key}]
+ \or
+ \setupregister[index][expansion=yes,xmlsetup=xml:index:flush]
+ \setstructurepageregister
+ [index]
+ [entries:1=\xmlgetindex{#1},
+ keys:1=\xmltext{#1}{key}]
+ \or
+ \setupregister[index][expansion=yes,xmlsetup=]
+ \setstructurepageregister
+ [index]
+ [entries:1=\xmlreference{#1}{xml:index:flush},
+ keys:1=\xmltext{#1}{key}]
+ \fi
+\stopxmlsetups
+
+\startxmlsetups xml:index:flush
+ \xmlfirst{#1}{content}
+\stopxmlsetups
+\stoptyping
+
+Instead of this flush, you can use the predefined setup \type {xml:flush}
+unless it is overloaded by you.
+
+The file is processed by:
+
+\starttyping
+\starttext
+ \xmlprocessfile{main}{test.xml}{}
+\stoptext
+\stoptyping
+
+We don't show the result here. If you're curious what the output is, you can test
+it yourself. In that case it also makes sense to peek into the \type {test.tuc}
+file to see how the information travels around. The \type {metadata} fields carry
+information about how to process the data.
+
+The first case, the \XML\ expansion one, is somewhat special in the sense that
+internally we use small pseudo files. You can control the rendering by tweaking
+the following setups:
+
+\starttyping
+\startxmlsetups xml:ctx:sectionentry
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:ctx:registerentry
+ \xmlflush{#1}
+\stopxmlsetups
+\stoptyping
+
+{\em When these methods work out okay the other structural elements will be
+dealt with in a similar way.}
+
+\stopsection
+
+\startsection[title={special cases}]
+
+Normally the content will be flushed under a special (so called) catcode regime.
+This means that characters that have a special meaning in \TEX\ will have no such
+meaning in an \XML\ file. If you want content to be treated as \TEX\ code, you can
+use one of the following:
+
+\startxmlcmd {\cmdbasicsetup{xmlflushcontext}}
+ flush the given \cmdinternal {cd:node} using the \TEX\ character
+ interpretation scheme
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlcontext}}
+ flush the match of \cmdinternal {cd:lpath} for the given \cmdinternal
+ {cd:node} using the \TEX\ character interpretation scheme
+\stopxmlcmd
+
+We use this in cases like:
+
+\starttyping
+....
+ \xmlsetsetup {#1} {
+ tm|texformula|
+ } {xml:*}
+....
+
+\startxmlsetups xml:tm
+ \mathematics{\xmlflushcontext{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:texformula
+ \placeformula\startformula\xmlflushcontext{#1}\stopformula
+\stopxmlsetups
+\stoptyping
+
+\stopsection
+
+\startsection[title={collecting}]
+
+Say that your document has
+
+\starttyping
+<table>
+ <tr>
+ <td>foo</td>
+ <td>bar<td>
+ </tr>
+</table>
+\stoptyping
+
+And that you need to convert that to \TEX\ speak like:
+
+\starttyping
+\bTABLE
+ \bTR
+ \bTD foo \eTD
+ \bTD bar \eTD
+ \eTR
+\eTABLE
+\stoptyping
+
+A simple mapping is:
+
+\starttyping
+\startxmlsetups xml:table
+ \bTABLE \xmlflush{#1} \eTABLE
+\stopxmlsetups
+\startxmlsetups xml:tr
+ \bTR \xmlflush{#1} \eTR
+\stopxmlsetups
+\startxmlsetups xml:td
+ \bTD \xmlflush{#1} \eTD
+\stopxmlsetups
+\stoptyping
+
+The \type {\bTD} command is a so called delimited command which means that it
+picks up its argument by looking for an \type {\eTD}. For the simple case here
+this works quite well because the flush is inside the pair. This is not the case
+in the following variant:
+
+\starttyping
+\startxmlsetups xml:td:start
+ \bTD
+\stopxmlsetups
+\startxmlsetups xml:td:stop
+ \eTD
+\stopxmlsetups
+\startxmlsetups xml:td
+ \xmlsetup{#1}{xml:td:start}
+ \xmlflush{#1}
+ \xmlsetup{#1}{xml:td:stop}
+\stopxmlsetups
+\stoptyping
+
+When for some reason \TEX\ gets confused you can revert to a mechanism that
+collects content.
+
+\starttyping
+\startxmlsetups xml:td:start
+ \startcollect
+ \bTD
+ \stopcollect
+\stopxmlsetups
+\startxmlsetups xml:td:stop
+ \startcollect
+ \eTD
+ \stopcollect
+\stopxmlsetups
+\startxmlsetups xml:td
+ \startcollecting
+ \xmlsetup{#1}{xml:td:start}
+ \xmlflush{#1}
+ \xmlsetup{#1}{xml:td:stop}
+ \stopcollecting
+\stopxmlsetups
+\stoptyping
+
+You can even implement solutions that effectively do this:
+
+\starttyping
+\startcollecting
+ \startcollect \bTABLE \stopcollect
+ \startcollect \bTR \stopcollect
+ \startcollect \bTD \stopcollect
+ \startcollect foo\stopcollect
+ \startcollect \eTD \stopcollect
+ \startcollect \bTD \stopcollect
+ \startcollect bar\stopcollect
+ \startcollect \eTD \stopcollect
+ \startcollect \eTR \stopcollect
+ \startcollect \eTABLE \stopcollect
+\stopcollecting
+\stoptyping
+
+Of course you only need to go that complex when the situation demands it. Here is
+another weird one:
+
+\starttyping
+\startcollecting
+ \startcollect \setupsomething[\stopcollect
+ \startcollect foo=\stopcollect
+ \startcollect FOO,\stopcollect
+ \startcollect bar=\stopcollect
+ \startcollect BAR,\stopcollect
+ \startcollect ]\stopcollect
+\stopcollecting
+\stoptyping
+
+\stopsection
+
+\startsection[title={selectors and injectors}]
+
+This section describes a bit special feature, one that we needed for a project
+where we could not touch the original content but could add specific sections for
+our own purpose. Hopefully the example demonstrates its useability.
+
+\enabletrackers[lxml.selectors]
+
+\startbuffer[foo]
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?context-directive message info 1: this is a demo file ?>
+<?context-message-directive info 2: this is a demo file ?>
+
+<one>
+ <two>
+ <?context-select begin t1 t2 t3 ?>
+ <three>
+ t1 t2 t3
+ <?context-directive injector crlf t1 ?>
+ t1 t2 t3
+ </three>
+ <?context-select end ?>
+ <?context-select begin t4 ?>
+ <four>
+ t4
+ </four>
+ <?context-select end ?>
+ <?context-select begin t8 ?>
+ <four>
+ t8.0
+ t8.0
+ </four>
+ <?context-select end ?>
+ <?context-include begin t4 ?>
+ <!--
+ <three>
+ t4.t3
+ <?context-directive injector crlf t1 ?>
+ t4.t3
+ </three>
+ -->
+ <three>
+ t3
+ <?context-directive injector crlf t1 ?>
+ t3
+ </three>
+ <?context-include end ?>
+ <?context-select begin t8 ?>
+ <four>
+ t8.1
+ t8.1
+ </four>
+ <?context-select end ?>
+ <?context-select begin t8 ?>
+ <four>
+ t8.2
+ t8.2
+ </four>
+ <?context-select end ?>
+ <?context-select begin t4 ?>
+ <four>
+ t4
+ t4
+ </four>
+ <?context-select end ?>
+ <?context-directive injector page t7 t8 ?>
+ foo
+ <?context-directive injector blank t1 ?>
+ bar
+ <?context-directive injector page t7 t8 ?>
+ bar
+ </two>
+</one>
+\stopbuffer
+
+\typebuffer[foo]
+
+First we show how to plug in a directive. Processing instructions like the
+following are normally ignored by an \XML\ processor, unless they make sense
+to it.
+
+\starttyping
+<?context-directive message info 1: this is a demo file ?>
+<?context-message-directive info 2: this is a demo file ?>
+\stoptyping
+
+We can define a message handler as follows:
+
+\startbuffer
+\def\MyMessage#1#2#3{\writestatus{#1}{#2 #3}}
+
+\xmlinstalldirective{message}{MyMessage}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+When this file is processed you will see this on the console:
+
+\starttyping
+info > 1: this is a demo file
+info > 2: this is a demo file
+\stoptyping
+
+The file has some sections that can be used or ignored. The recipe for
+obeying \type {t1} and \type {t4} is the following:
+
+\startbuffer
+\xmlsetinjectors[t1]
+\xmlsetinjectors[t4]
+
+\startxmlsetups xml:initialize
+ \xmlapplyselectors{#1}
+ \xmlsetsetup {#1} {
+ one|two|three|four
+ } {xml:*}
+\stopxmlsetups
+
+\xmlregistersetup{xml:initialize}
+
+\startxmlsetups xml:one
+ [ONE \xmlflush{#1} ONE]
+\stopxmlsetups
+
+\startxmlsetups xml:two
+ [TWO \xmlflush{#1} TWO]
+\stopxmlsetups
+
+\startxmlsetups xml:three
+ [THREE \xmlflush{#1} THREE]
+\stopxmlsetups
+
+\startxmlsetups xml:four
+ [FOUR \xmlflush{#1} FOUR]
+\stopxmlsetups
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This typesets:
+
+\startnarrower
+\xmlprocessbuffer{main}{foo}{}
+\stopnarrower
+
+The include coding is kind of special: it permits adding content (in a comment)
+and ignoring the rest so that we indeed can add something without interfering
+with the original. Of course in a normal workflow such messy solutions are
+not needed, but alas, often workflows are not that clean, especially when one
+has no real control over the source.
+
+\startxmlcmd {\cmdbasicsetup{xmlsetinjectors}}
+ enables a list of injectors that will be used
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlresetinjectors}}
+ resets the list of injectors
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlinjector}}
+ expands an injection (command); normally this one is only used
+ (in some setup) or for testing
+\stopxmlcmd
+
+\startxmlcmd {\cmdbasicsetup{xmlapplyselectors}}
+ analyze the tree \cmdinternal {cd:node} for marked sections that
+ will be injected
+\stopxmlcmd
+
+We have some injections predefined:
+
+\starttyping
+\startsetups xml:directive:injector:page
+ \page
+\stopsetups
+
+\startsetups xml:directive:injector:column
+ \column
+\stopsetups
+
+\startsetups xml:directive:injector:blank
+ \blank
+\stopsetups
+\stoptyping
+
+In the example we see:
+
+\starttyping
+<?context-directive injector page t7 t8 ?>
+\stoptyping
+
+When we set \type {\xmlsetinjector[t7]} a pagebreak will injected in that spot.
+Tags like \type {t7}, \type {t8} etc.\ can represent versions.
+
+\stopsection
+
+\startsection[title=preprocessing]
+
+% local match = lpeg.match
+% local replacer = lpeg.replacer("BAD TITLE:","<bold>BAD TITLE:</bold>")
+%
+% function lxml.preprocessor(data,settings)
+% return match(replacer,data)
+% end
+
+\startbuffer[pre-code]
+\startluacode
+ function lxml.preprocessor(data,settings)
+ return string.find(data,"BAD TITLE:")
+ and string.gsub(data,"BAD TITLE:","<bold>BAD TITLE:</bold>")
+ or data
+ end
+\stopluacode
+\stopbuffer
+
+\startbuffer[pre-xml]
+\startxmlsetups pre:demo:initialize
+ \xmlsetsetup{#1}{*}{pre:demo:*}
+\stopxmlsetups
+
+\xmlregisterdocumentsetup{pre:demo}{pre:demo:initialize}
+
+\startxmlsetups pre:demo:root
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups pre:demo:bold
+ \begingroup\bf\xmlflush{#1}\endgroup
+\stopxmlsetups
+
+\starttext
+ \xmlprocessbuffer{pre:demo}{demo}{}
+\stoptext
+\stopbuffer
+
+Say that you have the following \XML\ setup:
+
+\typebuffer[pre-xml]
+
+and that (such things happen) the input looks like this:
+
+\startbuffer[demo]
+<root>
+BAD TITLE: crap crap crap ...
+
+BAD TITLE: crap crap crap ...
+</root>
+\stopbuffer
+
+\typebuffer[demo]
+
+You can then clean up these \type {BAD TITLE}'s as follows:
+
+\typebuffer[pre-code]
+
+and get as result:
+
+\start \getbuffer[pre-code,pre-xml] \stop
+
+The preprocessor function gets as second argument the current settings, an d
+the field \type {currentresource} can be used to limit the actions to
+specific resources, in our case it's \type {buffer: demo}. Afterwards you can
+reset the proprocessor with:
+
+\startluacode
+lxml.preprocessor = nil
+\stopluacode
+
+Future versions might give some more control over preprocessors. For now consider
+it to be a quick hack.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
diff --git a/doc/context/sources/general/manuals/xml/xml-mkiv.tex b/doc/context/sources/general/manuals/xml/xml-mkiv.tex
index 8550badec..77054e79c 100644
--- a/doc/context/sources/general/manuals/xml/xml-mkiv.tex
+++ b/doc/context/sources/general/manuals/xml/xml-mkiv.tex
@@ -31,4368 +31,25 @@
%
% \xmldirect
-\input lxml-ctx.mkiv
-
-\settrue \xmllshowtitle
-\setfalse\xmllshowwarning
-
-\usemodule[set-11]
-
-\loadsetups[i-context]
-
-% \definehspace[squad][1em plus .25em minus .25em]
-
-\usemodule[abr-02]
-
-\setuplayout
- [location=middle,
- marking=on,
- backspace=20mm,
- cutspace=20mm,
- topspace=15mm,
- header=15mm,
- footer=15mm,
- height=middle,
- width=middle]
-
-\setuppagenumbering
- [alternative=doublesided,
- location=]
-
-\setupfootertexts
- [][pagenumber]
-
-\setupheadertexts
- [][chapter]
-
-\setupheader
- [color=colortwo,
- style=bold]
-
-\setupfooter
- [color=colortwo,
- style=bold]
-
-\setuphead
- [chapter]
- [page={yes,header,right},
- header=empty,
- style=\bfc]
-
-\setupsectionblock
- [page={yes,header,right}]
-
-\starttexdefinition unexpanded section:chapter:number #1
- \doifmode{*sectionnumber} {
- \bf
- \llap{<\enspace}#1\enspace>
- }
-\stoptexdefinition
-
-\starttexdefinition unexpanded section:section:number #1
- \doifmode{*sectionnumber} {
- \bf
- \llap{<<\enspace}#1\enspace>>
- }
-\stoptexdefinition
-
-\starttexdefinition unexpanded section:subsection:number #1
- \doifmode{*sectionnumber} {
- \bf
- \llap{<<<\enspace}#1\enspace>>>
- }
-\stoptexdefinition
-
-\setuphead[chapter] [numbercolor=black,numbercommand=\texdefinition{section:chapter:number}]
-\setuphead[section] [numbercolor=black,numbercommand=\texdefinition{section:section:number}]
-\setuphead[subsection][numbercolor=black,numbercommand=\texdefinition{section:subsection:number}]
-
-\setuphead
- [section]
- [style=\bfa]
-
-\setuplist
- [chapter]
- [style=bold]
-
-\setupinteractionscreen
- [option=doublesided]
-
-\setupalign
- [tolerant,stretch]
-
-\setupwhitespace
- [big]
-
-\setuptolerance
- [tolerant]
-
-\doifelsemode {atpragma} {
- \setupbodyfont[lucidaot,10pt]
-} {
- \setupbodyfont[dejavu,10pt]
-}
-
-\definecolor[colorone] [b=.5]
-\definecolor[colortwo] [s=.3]
-\definecolor[colorthree][y=.5]
-
-\setuptype
- [color=colorone]
-
-\setuptyping
- [color=colorone]
-
-\setuphead
- [lshowtitle]
- [style=\tt,
- color=colorone]
-
-\setuphead
- [chapter,section]
- [numbercolor=colortwo,
- color=colorone]
-
-\definedescription
- [xmlcmd]
- [alternative=hanging,
- width=line,
- distance=1em,
- margin=2em,
- headstyle=monobold,
- headcolor=colorone]
-
-\setupframedtext
- [setuptext]
- [framecolor=colorone,
- rulethickness=1pt,
- corner=round]
-
-\usemodule[punk]
-
-\usetypescript[punk]
-
-\definelayer
- [page]
- [width=\paperwidth,
- height=\paperheight]
+\environment xml-mkiv-style
\starttext
-\setuplayout[page]
-
-\startstandardmakeup
- \startfontclass[none] % nil the current fontclass since it may append its features
- \EnableRandomPunk
- \setlayerframed
- [page]
- [width=\paperwidth,height=\paperheight,
- background=color,backgroundcolor=colorone,backgroundoffset=1ex,frame=off]
- {}
- \definedfont[demo@punk at 18pt]
- \setbox\scratchbox\vbox {
- \hsize\dimexpr\paperwidth+2ex\relax
- \setupinterlinespace
- \baselineskip 1\baselineskip plus 1pt minus 1pt
- \raggedcenter
- \color[colortwo]{\dorecurse{1000}{XML }}
- }
- \setlayer
- [page]
- [preset=middle]
- {\vsplit\scratchbox to \dimexpr\paperheight+2ex\relax}
- \definedfont[demo@punk at 90pt]
- \setstrut
- \setlayerframed
- [page]
- [preset=rightbottom,offset=10mm]
- [foregroundcolor=colorthree,align=flushright,offset=overlay,frame=off]
- {Dealing\\with XML in\\Con\TeX t MkIV}
- \definedfont[demo@punk at 18pt]
- \setstrut
- \setlayerframed
- [page]
- [preset=righttop,offset=10mm,x=3mm,rotation=90]
- [foregroundcolor=colorthree,align=flushright,offset=overlay,frame=off]
- {Hans Hagen, Pragma ADE, \currentdate}
- \tightlayer[page]
- \stopfontclass
-\stopstandardmakeup
-
-\setuplayout
+\component xml-mkiv-titlepage
\startfrontmatter
-
-\starttitle[title=Contents]
-
-\placelist
- [chapter,section]
-
-\stoptitle
-
-\startchapter[title={Introduction}]
-
-This manual presents the \MKIV\ way of dealing with \XML. Although the
-traditional \MKII\ streaming parser has a charming simplicity in its control, for
-complex documents the tree based \MKIV\ method is more convenient. It is for this
-reason that the old method has been removed from \MKIV. If you are familiar with
-\XML\ processing in \MKII, then you will have noticed that the \MKII\ commands
-have \type {XML} in their name. The \MKIV\ commands have a lowercase \type {xml}
-in their names. That way there is no danger for confusion or a mixup.
-
-You may wonder why we do these manipulations in \TEX\ and not use \XSLT\ (or
-other transformation methods) instead. The advantage of an integrated approach is
-that it simplifies usage. Think of not only processing the document, but also
-using \XML\ for managing resources in the same run. An \XSLT\ approach is just as
-verbose (after all, you still need to produce \TEX\ code) and probably less
-readable. In the case of \MKIV\ the integrated approach is also faster and gives
-us the option to manipulate content at runtime using \LUA. It has the additional
-advantage that to some extend we can handle a mix of \TEX\ and \XML\ because we
-know when we're doing one or the other.
-
-This manual is dedicated to Taco Hoekwater, one of the first \CONTEXT\ users, and
-also the first to use it for processing \XML. Who could have thought at that time
-that we would have a more convenient way of dealing with those angle brackets.
-The second version for this manual is dedicated to Thomas Schmitz, a power user
-who occasionally became victim of the evolving mechanisms.
-
-\blank
-
-\startlines
-Hans Hagen
-\PRAGMA
-Hasselt NL
-2008\endash2016
-\stoplines
-
-\stopchapter
-
+ \component xml-mkiv-contents
+ \component xml-mkiv-introduction
\stopfrontmatter
\startbodymatter
-
-\startchapter[title={Setting up a converter}]
-
-\startsection[title={from structure to setup}]
-
-We use a very simple document structure for demonstrating how a converter is
-defined. In practice a mapping will be more complex, especially when we have a
-style with complex chapter openings using data coming from all kind of places,
-different styling of sections with the same name, selectively (out of order)
-flushed content, special formatting, etc.
-
-\typefile{manual-demo-1.xml}
-
-Say that this document is stored in the file \type {demo.xml}, then the following
-code can be used as starting point:
-
-\starttyping
-\startxmlsetups xml:demo:base
- \xmlsetsetup{#1}{document|section|p}{xml:demo:*}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{demo}{xml:demo:base}
-
-\startxmlsetups xml:demo:document
- \starttitle[title={Contents}]
- \placelist[chapter]
- \stoptitle
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:demo:section
- \startchapter[title=\xmlfirst{#1}{/title}]
- \xmlfirst{#1}{/content}
- \stopchapter
-\stopxmlsetups
-
-\startxmlsetups xml:demo:p
- \xmlflush{#1}\endgraf
-\stopxmlsetups
-
-\xmlprocessfile{demo}{demo.xml}{}
-\stoptyping
-
-Watch out! These are not just setups, but specific \XML\ setups which get an
-argument passed (the \type {#1}). If for some reason your \XML\ processing fails,
-it might be that you mistakenly have used a normal setup definition. The argument
-\type {#1} represents the current node (element) and is a unique identifier. For
-instance a \type {<p>..</p>} can have an identifier {demo::5}. So, we can get
-something:
-
-\starttyping
-\xmlflush{demo::5}\endgraf
-\stoptyping
-
-but as well:
-
-\starttyping
-\xmlflush{demo::6}\endgraf
-\stoptyping
-
-Keep in mind that the references tor the actual nodes (elements) are
-abstractions, you never see those \type {<id>::<number>}'s, because we will use
-either the abstract \type {#1} (any node) or an explicit reference like \type
-{demo}. The previous setup when issued will be like:
-
-\starttyping
-\startchapter[title=\xmlfirst{demo::3}{/title}]
- \xmlfirst{demo::4}{/content}
-\stopchapter
-\stoptyping
-
-Here the \type {title} is used to typeset the chapter title but also for an entry
-in the table of contents. At the moment the title is typeset the \XML\ node gets
-looked up and expanded in real text. However, for the list it gets stored for
-later use. One can argue that this is not needed for \XML, because one can just
-filter all the titles and use page references, but then one also looses the
-control one normally has over such titles. For instance it can be that some
-titles are rendered differently and for that we need to keep track of usage.
-Doing that with transformations or filtering is often more complex than leaving
-that to \TEX. As soon as the list gets typeset, the reference (\type {demo::#3})
-is used for the lookup. This is because by default the title is stored as given.
-So, as long as we make sure the \XML\ source is loaded before the table of
-contents is typeset we're ok. Later we will look into this in more detail, for
-now it's enough to know that in most cases the abstract \type {#1} reference will
-work out ok.
-
-Contrary to the style definitions this interface looks rather low level (with no
-optional arguments) and the main reason for this is that we want processing to be
-fast. So, the basic framework is:
-
-\starttyping
-\startxmlsetups xml:demo:base
- % associate setups with elements
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{demo}{xml:demo:base}
-
-% define setups for matches
-
-\xmlprocessfile{demo}{demo.xml}{}
-\stoptyping
-
-In this example we mostly just flush the content of an element and in the case of
-a section we flush explicit child elements. The \type {#1} in the example code
-represents the current element. The line:
-
-\starttyping
-\xmlsetsetup{demo}{*}{-}
-\stoptyping
-
-sets the default for each element to \quote {just ignore it}. A \type {+} would
-make the default to always flush the content. This means that at this point we
-only handle:
-
-\starttyping
-<section>
- <title>Some title</title>
- <content>
- <p>a paragraph of text</p>
- </content>
-</section>
-\stoptyping
-
-In the next section we will deal with the slightly more complex itemize and
-figure placement. At first sight all these setups may look overkill but keep in
-mind that normally the number of elements is rather limited. The complexity is
-often in the style and having access to each snippet of content is actually
-quite handy for that.
-
-\stopsection
-
-\startsection[title={alternative solutions}]
-
-Dealing with an itemize is rather simple (as long as we forget about
-attributes that control the behaviour):
-
-\starttyping
-<itemize>
- <item>first</item>
- <item>second</item>
-</itemize>
-\stoptyping
-
-First we need to add \type {itemize} to the setup assignment (unless we've used
-the wildcard \type {*}):
-
-\starttyping
-\xmlsetsetup{demo}{document|section|p|itemize}{xml:demo:*}
-\stoptyping
-
-The setup can look like:
-
-\starttyping
-\startxmlsetups xml:demo:itemize
- \startitemize
- \xmlfilter{#1}{/item/command(xml:demo:itemize:item)}
- \stopitemize
-\stopxmlsetups
-
-\startxmlsetups xml:demo:itemize:item
- \startitem
- \xmlflush{#1}
- \stopitem
-\stopxmlsetups
-\stoptyping
-
-An alternative is to map item directly:
-
-\starttyping
-\xmlsetsetup{demo}{document|section|p|itemize|item}{xml:demo:*}
-\stoptyping
-
-and use:
-
-\starttyping
-\startxmlsetups xml:demo:itemize
- \startitemize
- \xmlflush{#1}
- \stopitemize
-\stopxmlsetups
-
-\startxmlsetups xml:demo:item
- \startitem
- \xmlflush{#1}
- \stopitem
-\stopxmlsetups
-\stoptyping
-
-Sometimes, a more local solution using filters and \type {/command(...)} makes more
-sense, especially when the \type {item} tag is used for other purposes as well.
-
-Explicit flushing with \type {command} is definitely the way to go when you have
-complex products. In one of our projects we compose math school books from many
-thousands of small \XML\ files, and from one source set several products are
-typeset. Within a book sections get done differently, content gets used, ignored
-or interpreted differently depending on the kind of content, so there is a
-constant checking of attributes that drive the rendering. In that a generic setup
-for a title element makes less sense than explicit ones for each case. (We're
-talking of huge amounts of files here, including multiple images on each rendered
-page.)
-
-When using \type {command} you can pass two arguments, the first is the setup for
-the match, the second one for the miss, as in:
-
-\starttyping
-\xmlfilter{#1}{/element/command(xml:true,xml:false)}
-\stoptyping
-
-Back to the example, this leaves us with dealing with the resources, like
-figures:
-
-\starttyping
-<resource type='figure'>
- <caption>A picture of a cow.</caption>
- <content><external file="cow.pdf"/></content>
-</resource>
-\stoptyping
-
-Here we can use a more restricted match:
-
-\starttyping
-\xmlsetsetup{demo}{resource[@type='figure']}{xml:demo:figure}
-\xmlsetsetup{demo}{external}{xml:demo:*}
-\stoptyping
-
-and the definitions:
-
-\starttyping
-\startxmlsetups xml:demo:figure
- \placefigure
- {\xmlfirst{#1}{/caption}}
- {\xmlfirst{#1}{/content}}
-\stopxmlsetups
-
-\startxmlsetups xml:demo:external
- \externalfigure[\xmlatt{#1}{file}]
-\stopxmlsetups
-\stoptyping
-
-At this point it is good to notice that \type {\xmlatt{#1}{file}} is passed as it
-is: a macro call. This means that when a macro like \type {\externalfigure} uses
-the first argument frequently without first storing its value, the lookup is done
-several times. A solution for this is:
-
-\starttyping
-\startxmlsetups xml:demo:external
- \expanded{\externalfigure[\xmlatt{#1}{file}]}
-\stopxmlsetups
-\stoptyping
-
-Because the lookup is rather fast, normally there is no need to bother about this
-too much because internally \CONTEXT\ already makes sure such expansion happens
-only once.
-
-An alternative definition for placement is the following:
-
-\starttyping
-\xmlsetsetup{demo}{resource}{xml:demo:resource}
-\stoptyping
-
-with:
-
-\starttyping
-\startxmlsetups xml:demo:resource
- \placefloat
- [\xmlatt{#1}{type}]
- {\xmlfirst{#1}{/caption}}
- {\xmlfirst{#1}{/content}}
-\stopxmlsetups
-\stoptyping
-
-This way you can specify \type {table} as type too. Because you can define your
-own float types, more complex variants are also possible. In that case it makes
-sense to provide some default behaviour too:
-
-\starttyping
-\definefloat[figure-here][figure][default=here]
-\definefloat[figure-left][figure][default=left]
-\definefloat[table-here] [table] [default=here]
-\definefloat[table-left] [table] [default=left]
-
-\startxmlsetups xml:demo:resource
- \placefloat
- [\xmlattdef{#1}{type}{figure}-\xmlattdef{#1}{location}{here}]
- {\xmlfirst{#1}{/caption}}
- {\xmlfirst{#1}{/content}}
-\stopxmlsetups
-\stoptyping
-
-In this example we support two types and two locations. We default to a figure
-placed (when possible) at the current location.
-
-\stopsection
-
-\stopchapter
-
-\startchapter[title={Filtering content}]
-
-\startsection[title={\TEX\ versus \LUA}]
-
-It will not come as a surprise that we can access \XML\ files from \TEX\ as well
-as from \LUA. In fact there are two methods to deal with \XML\ in \LUA. First
-there are the low level \XML\ functions in the \type {xml} namespace. On top of
-those functions there is a set of functions in the \type {lxml} namespace that
-deals with \XML\ in a more \TEX ie way. Most of these have similar commands at
-the \TEX\ end.
-
-\startbuffer
-\startxmlsetups first:demo:one
- \xmlfilter {#1} {artist/name[text()='Randy Newman']/..
- /albums/album[position()=3]/command(first:demo:two)}
-\stopxmlsetups
-
-\startxmlsetups first:demo:two
- \blank \start \tt
- \xmldisplayverbatim{#1}
- \stop \blank
-\stopxmlsetups
-
-\xmlprocessfile{demo}{music-collection.xml}{first:demo:one}
-\stopbuffer
-
-\typebuffer
-
-This gives the following snippet of verbatim \XML\ code. The indentation is
-conform the indentation in the whole \XML\ file. \footnote {The (probably
-outdated) \XML\ file contains the collection stores on my slimserver instance.
-You can use the \type {mtxrun --script flac} to generate such files.}
-
-\doifmodeelse {atpragma} {
- \getbuffer
-} {
- \typefile{xml-mkiv-01.xml}
-}
-
-An alternative written in \LUA\ looks as follows:
-
-\startbuffer
-\blank \start \tt \startluacode
- local m = lxml.load("mine","music-collection.xml") -- m == lxml.id("mine")
- local p = "artist/name[text()='Randy Newman']/../albums/album[position()=4]"
- local l = lxml.filter(m,p) -- returns a list (with one entry)
- lxml.displayverbatim(l[1])
-\stopluacode \stop \blank
-\stopbuffer
-
-\typebuffer
-
-This produces:
-
-\doifmodeelse {atpragma} {
- \getbuffer
-} {
- \typefile{xml-mkiv-02.xml}
-}
-
-You can use both methods mixed but in practice we will use the \TEX\ commands in
-regular styles and the mixture in modules, for instance in those dealing with
-\MATHML\ and cals tables. For complex matters you can write your own finalizers
-(the last action to be taken in a match) in \LUA\ and use them at the \TEX\ end.
-
-\stopsection
-
-\startsection[title={a few details}]
-
-In \CONTEXT\ setups are a rather common variant on macros (\TEX\ commands) but
-with their own namespace. An example of a setup is:
-
-\starttyping
-\startsetup doc:print
- \setuppapersize[A4][A4]
-\stopsetup
-
-\startsetup doc:screen
- \setuppapersize[S6][S4]
-\stopsetup
-\stoptyping
-
-Given the previous definitions, later on we can say something like:
-
-\starttyping
-\doifmodeelse {paper} {
- \setup[doc:print]
-} {
- \setup[doc:screen]
-}
-\stoptyping
-
-Another example is:
-
-\starttyping
-\startsetup[doc:header]
- \marking[chapter]
- \space
- --
- \space
- \pagenumber
-\stopsetup
-\stoptyping
-
-in combination with:
-
-\starttyping
-\setupheadertexts[\setup{doc:header}]
-\stoptyping
-
-Here the advantage is that instead of ending up with an unreadable header
-definitions, we use a nicely formatted setup. An important property of setups and
-the reason why they were introduced long ago is that spaces and newlines are
-ignored in the definition. This means that we don't have to worry about so called
-spurious spaces but it also means that when we do want a space, we have to use
-the \type {\space} command.
-
-The only difference between setups and \XML\ setups is that the following ones
-get an argument (\type {#1}) that reflects the current node in the \XML\ tree.
-
-\stopsection
-
-\startsection[title={CDATA}]
-
-What to do with \type {CDATA}? There are a few methods at tle \LUA\ end for
-dealing with it but here we just mention how you can influence the rendering.
-There are four macros that play a role here:
-
-\starttyping
-\unexpanded\def\xmlcdataobeyedline {\obeyedline}
-\unexpanded\def\xmlcdataobeyedspace{\strut\obeyedspace}
-\unexpanded\def\xmlcdatabefore {\begingroup\tt}
-\unexpanded\def\xmlcdataafter {\endgroup}
-\stoptyping
-
-Technically you can overload them but beware of side effects. Normally you won't
-see much \type {CDATA} and whenever we do, it involves special data that needs
-very special treatment anyway.
-
-\stopsection
-
-\startsection[title={Entities}]
-
-As usual with any way of encoding documents you need escapes in order to encode
-the characters that are used in tagging the content, embedding comments, escaping
-special characters in strings (in programming languages), etc. In \XML\ this
-means that in order characters like \type {<} you need an escape like \type
-{&lt;} and in order then to encode an \type {&} you need \type {&amp;}.
-
-In a typesetting workflow using a programming language like \TEX, another problem
-shows up. There we have different special characters, like \type {$ $} for triggering
-math, but also the backslash, braces etc. Even one such special character is already
-enough to have yet another escaping mechanism at work.
-
-Ideally a user should not worry about these issues but it helps figuring out issues
-when you know what happens under the hood. Also it is good to know that in the
-code there are several ways to deal with these issues. Take the following document:
-
-\starttyping
-<text>
- Here we have a bit of a &lt;&mess&gt;:
-
- # &#35;
- % &#37;
- \ &#92;
- { &#123;
- | &#124;
- } &#125;
- ~ &#126;
-</text>
-\stoptyping
-
-When the file is read the \type {&lt;} entity will be replaced by \type {<} and
-the \type {&gt;} by \type {>}. The numeric entities will be replaced by the
-characters they refer to. The \type {&mess} is kind of special. We do preload
-a huge list of more or less standardized entities but \type {mess} is not in
-there. However, it is possible to have it defined in the document preamble, like:
-
-\starttyping
-<!DOCTYPE dummy SYSTEM "dummy.dtd" [
- <!ENTITY mess "what a mess" >
-]>
-\stoptyping
-
-or even this:
-
-\starttyping
-<!DOCTYPE dummy SYSTEM "dummy.dtd" [
- <!ENTITY mess "<p>what a mess</p>" >
-]>
-\stoptyping
-
-You can also define it in your document style using one of:
-
-\startxmlcmd {\cmdbasicsetup{xmlsetentity}}
- replaces entity with name \cmdinternal {cd:name} by \cmdinternal {cd:text}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmltexentity}}
- replaces entity with name \cmdinternal {cd:name} by \cmdinternal {cd:text}
- typeset under a \TEX\ regime
-\stopxmlcmd
-
-Such a definition will always have a higher priority than the one defined
-in the document. Anyway, when the document is read in all entities are
-resolved and those that need a special treatment because they map to some
-text are stored in such a way that we can roundtrip them. As a consequence,
-as soon as the content gets pushed into \TEX, we need not only to intercept
-special characters but also have to make sure that the following works:
-
-\starttyping
-\xmltexentity {tex} {\TEX}
-\stoptyping
-
-Here the backslash starts a control sequence while in regular content a
-backslash is just that: a backslash.
-
-Special characters are really special when we have to move text around
-in a \TEX\ ecosystem.
-
-\starttyping
-<text>
- <title>About #3</title>
-</text>
-\stoptyping
-
-If we map and define title as follows:
-
-\starttyping
-\startxmlsetup xml:title
- \title{\xmlflush{#1}}
-\stopxmlsetup
-\stoptyping
-
-normally something \type {\xmlflush {id::123}} will be written to the
-auxiliary file and in most cases that is quite okay, but if we have this:
-
-\starttyping
-\setuphead[title][expansion=yes]
-\stoptyping
-
-then we don't want the \type {#} to end up as hash because later on \TEX\
-can get very confused about it because it sees some argument then in a
-probably unexpected way. This is solved by escaping the hash like this:
-
-\starttyping
-About \Ux{23}3
-\stoptyping
-
-The \type {\Ux} command will convert its hexadecimal argument into a
-character. Of course one then needs to typeset such a text under a \TEX\
-character regime but that is normally the case anyway.
-
-\stopsection
-
-\stopchapter
-
-\startchapter[title={Commands}]
-
-\startsection[title={nodes and lpaths}]
-
-The amount of commands available for manipulating the \XML\ file is rather large.
-Many of the commands cooperate with the already discussed setups, a fancy name
-for a collection of macro calls either or not mixed with text.
-
-Most of the commands are just shortcuts to \LUA\ calls, which means that the real
-work is done by \LUA. In fact, what happens is that we have a continuous transfer
-of control from \TEX\ to \LUA, where \LUA\ prints back either data (like element
-content or attribute values) or just invokes a setup whereby it passes a
-reference to the node resolved conform the path expression. The invoked setup
-itself might return control to \LUA\ again, etc.
-
-This sounds complicated but examples will show what we mean here. First we
-present the whole repertoire of commands. Because users can read the source code,
-they might uncover more commands, but only the ones discussed here are official.
-The commands are grouped in categories.
-
-In the following sections \cmdinternal {cd:node} means a reference to a node:
-this can be the identifier of the root (the loaded xml tree) or a reference to a
-node in that tree (often the result of some lookup. A \cmdinternal {cd:lpath} is
-a fancy name for a path expression (as with \XSLT) but resolved by \LUA.
-
-\stopsection
-
-\startsection[title={commands}]
-
-There are a lot of commands available but you probably can ignore most of them.
-We try to be complete which means that there is for instance \type {\xmlfirst} as
-well as \type {\xmllast} but you probably never need the last one. There are also
-commands that were used when testing this interface and we see no reason to
-remove them. Some obscure ones are used in modules and after a while even I often
-forget that they exist. To give you an idea of what commands are important we
-show their use in generating the \CONTEXT\ command definitions (\type
-{x-set-11.mkiv}) per Januari 2016:
-
-\startcolumns[n=2,balance=yes]
-\starttabulate[|l|r|]
-\NC \type {\xmlall} \NC 1 \NC \NR
-\NC \type {\xmlatt} \NC 23 \NC \NR
-\NC \type {\xmlattribute} \NC 1 \NC \NR
-\NC \type {\xmlcount} \NC 1 \NC \NR
-\NC \type {\xmldoif} \NC 2 \NC \NR
-\NC \type {\xmldoifelse} \NC 1 \NC \NR
-\NC \type {\xmlfilterlist} \NC 4 \NC \NR
-\NC \type {\xmlflush} \NC 5 \NC \NR
-\NC \type {\xmlinclude} \NC 1 \NC \NR
-\NC \type {\xmlloadonly} \NC 1 \NC \NR
-\NC \type {\xmlregisterdocumentsetup} \NC 1 \NC \NR
-\NC \type {\xmlsetsetup} \NC 1 \NC \NR
-\NC \type {\xmlsetup} \NC 4 \NC \NR
-\stoptabulate
-\stopcolumns
-
-As you can see filtering, flushing and accessing attributes score high. Below we show
-the statistics of a quite complex rendering (5 variants of schoolbooks: basic book,
-answers, teachers guide, worksheets, full blown version with extensive tracing).
-
-\startcolumns[n=2,balance=yes]
-\starttabulate[|l|r|]
-\NC \type {\xmladdindex} \NC 3 \NC \NR
-\NC \type {\xmlall} \NC 5 \NC \NR
-\NC \type {\xmlappendsetup} \NC 1 \NC \NR
-\NC \type {\xmlapplyselectors} \NC 1 \NC \NR
-\NC \type {\xmlatt} \NC 40 \NC \NR
-\NC \type {\xmlattdef} \NC 9 \NC \NR
-\NC \type {\xmlattribute} \NC 10 \NC \NR
-\NC \type {\xmlbadinclusions} \NC 3 \NC \NR
-\NC \type {\xmlconcat} \NC 3 \NC \NR
-\NC \type {\xmlcount} \NC 1 \NC \NR
-\NC \type {\xmldelete} \NC 11 \NC \NR
-\NC \type {\xmldoif} \NC 39 \NC \NR
-\NC \type {\xmldoifelse} \NC 28 \NC \NR
-\NC \type {\xmldoifelsetext} \NC 13 \NC \NR
-\NC \type {\xmldoifnot} \NC 2 \NC \NR
-\NC \type {\xmldoifnotselfempty} \NC 1 \NC \NR
-\NC \type {\xmlfilter} \NC 100 \NC \NR
-\NC \type {\xmlfirst} \NC 51 \NC \NR
-\NC \type {\xmlflush} \NC 69 \NC \NR
-\NC \type {\xmlflushcontext} \NC 2 \NC \NR
-\NC \type {\xmlinclude} \NC 1 \NC \NR
-\NC \type {\xmlincludeoptions} \NC 5 \NC \NR
-\NC \type {\xmlinclusion} \NC 16 \NC \NR
-\NC \type {\xmlinjector} \NC 1 \NC \NR
-\NC \type {\xmlloaddirectives} \NC 1 \NC \NR
-\NC \type {\xmlmapvalue} \NC 4 \NC \NR
-\NC \type {\xmlmatch} \NC 1 \NC \NR
-\NC \type {\xmlprependsetup} \NC 5 \NC \NR
-\NC \type {\xmlregisterdocumentsetup} \NC 2 \NC \NR
-\NC \type {\xmlregistersetup} \NC 1 \NC \NR
-\NC \type {\xmlremapnamespace} \NC 1 \NC \NR
-\NC \type {\xmlsetfunction} \NC 2 \NC \NR
-\NC \type {\xmlsetinjectors} \NC 2 \NC \NR
-\NC \type {\xmlsetsetup} \NC 11 \NC \NR
-\NC \type {\xmlsetup} \NC 76 \NC \NR
-\NC \type {\xmlstrip} \NC 1 \NC \NR
-\NC \type {\xmlstripanywhere} \NC 1 \NC \NR
-\NC \type {\xmltag} \NC 1 \NC \NR
-\NC \type {\xmltext} \NC 53 \NC \NR
-\NC \type {\xmlvalue} \NC 2 \NC \NR
-\stoptabulate
-\stopcolumns
-
-Here many more are used but this is an exceptional case. The top is again
-dominated by filtering, flushing and attribute consulting. The list can actually
-be smaller. For instance, the \type {\xmlcount} can just as well be \type
-{\xmlfilter} with a \type {count} finalizer. There are also some special ones,
-like the injectors, that are needed for finetuning the final result.
-
-\stopsection
-
-\startsection[title={loading}]
-
-\startxmlcmd {\cmdbasicsetup{xmlloadfile}}
- loads the file \cmdinternal {cd:file} and registers it under \cmdinternal
- {cd:name} and applies either given or standard \cmdinternal
- {cd:xmlsetup} (alias: \type {\xmlload})
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlloadbuffer}}
- loads the buffer \cmdinternal {cd:buffer} and registers it under
- \cmdinternal {cd:name} and applies either given or standard
- \cmdinternal {cd:xmlsetup}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlloaddata}}
- loads \cmdinternal {cd:text} and registers it under \cmdinternal
- {cd:name} and applies either given or standard \cmdinternal
- {cd:xmlsetup}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlloadonly}}
- loads \cmdinternal {cd:text} and registers it under \cmdinternal
- {cd:name} and applies either given or standard \cmdinternal
- {cd:xmlsetup} but doesn't flush the content
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlinclude}}
- includes the file specified by attribute \cmdinternal {cd:name} of the
- element located by \cmdinternal {cd:lpath} at node \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlprocessfile}}
- registers file \cmdinternal {cd:file} as \cmdinternal {cd:name} and
- process the tree starting with \cmdinternal {cd:xmlsetup} (alias:
- \type {\xmlprocess})
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlprocessbuffer}}
- registers buffer \cmdinternal {cd:name} as \cmdinternal {cd:name} and process
- the tree starting with \cmdinternal {cd:xmlsetup}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlprocessdata}}
- registers \cmdinternal {cd:text} as \cmdinternal {cd:name} and process
- the tree starting with \cmdinternal {cd:xmlsetup}
-\stopxmlcmd
-
-The initial setup defaults to \type {xml:process} that is defined
-as follows:
-
-\starttyping
-\startsetups xml:process
- \xmlregistereddocumentsetups\xmldocument
- \xmlmain\xmldocument
-\stopsetups
-\stoptyping
-
-First we apply the setups associated with the document (including common setups)
-and then we flush the whole document. The macro \type {\xmldocument} expands to
-the current document id. There is also \type {\xmlself} which expands to the
-current node number (\type {#1} in setups).
-
-\startxmlcmd {\cmdbasicsetup{xmlmain}}
- returns the whole document
-\stopxmlcmd
-
-Normally such a flush will trigger a chain reaction of setups associated with the
-child elements.
-
-\stopsection
-
-\startsection[title={saving}]
-
-\startxmlcmd {\cmdbasicsetup{xmlsave}}
- saves the given node \cmdinternal {cd:node} in the file \cmdinternal {cd:file}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmltofile}}
- saves the match of \cmdinternal {cd:lpath} in the file \cmdinternal {cd:file}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmltobuffer}}
- saves the match of \cmdinternal {cd:lpath} in the buffer \cmdinternal {cd:buffer}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmltobufferverbose}}
- saves the match of \cmdinternal {cd:lpath} verbatim in the buffer \cmdinternal
- {cd:buffer}
-\stopxmlcmd
-
-% \startxmlcmd {\cmdbasicsetup{xmltoparameters}}
-% converts the match of \cmdinternal {cd:lpath} to key|/|values (for tracing)
-% \stopxmlcmd
-
-The next command is only needed when you have messed with the tree using
-\LUA\ code.
-
-\startxmlcmd {\cmdbasicsetup{xmladdindex}}
- (re)indexes a tree
-\stopxmlcmd
-
-The following macros are only used in special situations and are not really meant
-for users.
-
-\startxmlcmd {\cmdbasicsetup{xmlraw}}
- flush the content if \cmdinternal {cd:node} with original entities
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{startxmlraw}}
- flush the wrapped content with original entities
-\stopxmlcmd
-
-\stopsection
-
-\startsection[title={flushing data}]
-
-When we flush an element, the associated \XML\ setups are expanded. The most
-straightforward way to flush an element is the following. Keep in mind that the
-returned values itself can trigger setups and therefore flushes.
-
-\startxmlcmd {\cmdbasicsetup{xmlflush}}
- returns all nodes under \cmdinternal {cd:node}
-\stopxmlcmd
-
-You can restrict flushing by using commands that accept a specification.
-
-\startxmlcmd {\cmdbasicsetup{xmltext}}
- returns the text of the matching \cmdinternal {cd:lpath} under \cmdinternal
- {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlpure}}
- returns the text of the matching \cmdinternal {cd:lpath} under \cmdinternal
- {cd:node} without \type {\Ux} escaped special \TEX\ characters
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlflushtext}}
- returns the text of the \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlflushpure}}
- returns the text of the \cmdinternal {cd:node} without \type {\Ux} escaped
- special \TEX\ characters
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlnonspace}}
- returns the text of the matching \cmdinternal {cd:lpath} under \cmdinternal
- {cd:node} without embedded spaces
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlall}}
- returns all nodes under \cmdinternal {cd:node} that matches \cmdinternal
- {cd:lpath}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmllastmatch}}
- returns all nodes found in the last match
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlfirst}}
- returns the first node under \cmdinternal {cd:node} that matches \cmdinternal
- {cd:lpath}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmllast}}
- returns the last node under \cmdinternal {cd:node} that matches \cmdinternal
- {cd:lpath}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlfilter}}
- at a match of \cmdinternal {cd:lpath} a given filter \type {filter} is applied
- and the result is returned
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlsnippet}}
- returns the \cmdinternal {cd:number}\high{th} element under \cmdinternal
- {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlposition}}
- returns the \cmdinternal {cd:number}\high{th} match of \cmdinternal
- {cd:lpath} at node \cmdinternal {cd:node}; a negative number starts at the
- end (alias: \type {\xmlindex})
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlelement}}
- returns the \cmdinternal {cd:number}\high{th} child of node \cmdinternal {cd:node};
- a negative number starts at the end
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlpos}}
- returns the index (position) in the parent node of \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlconcat}}
- returns the sequence of nodes that match \cmdinternal {cd:lpath} at
- \cmdinternal {cd:node} whereby \cmdinternal {cd:text} is put between each
- match
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlconcatrange}}
- returns the \cmdinternal {cd:first}\high {th} upto \cmdinternal
- {cd:last}\high {th} of nodes that match \cmdinternal {cd:lpath} at
- \cmdinternal {cd:node} whereby \cmdinternal {cd:text} is put between each
- match
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlcommand}}
- apply the given \cmdinternal {cd:xmlsetup} to each match of \cmdinternal
- {cd:lpath} at node \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlstrip}}
- remove leading and trailing spaces from nodes under \cmdinternal {cd:node}
- that match \cmdinternal {cd:lpath}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlstripped}}
- remove leading and trailing spaces from nodes under \cmdinternal {cd:node}
- that match \cmdinternal {cd:lpath} and return the content afterwards
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlstripnolines}}
- remove leading and trailing spaces as well as collapse embedded spaces
- from nodes under \cmdinternal {cd:node} that match \cmdinternal {cd:lpath}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlstrippednolines}}
- remove leading and trailing spaces as well as collapse embedded spaces from
- nodes under \cmdinternal {cd:node} that match \cmdinternal {cd:lpath} and
- return the content afterwards
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlverbatim}}
- flushes the content verbatim code (without any wrapping, i.e. no fonts
- are selected and such)
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlinlineverbatim}}
- return the content of the node as inline verbatim code; no further
- interpretation (expansion) takes place and spaces are honoured; it uses the
- following wrapper
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{startxmlinlineverbatim}}
- wraps inline verbatim mode using the environment specified (a prefix \type
- {xml:} is added to the environment name)
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldisplayverbatim}}
- return the content of the node as display verbatim code; no further
- interpretation (expansion) takes place and leading and trailing spaces and
- newlines are treated special; it uses the following wrapper
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{startxmldisplayverbatim}}
- wraps the content in display verbatim using the environment specified (a prefix
- \type {xml:} is added to the environment name)
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlprettyprint}}
- pretty print (with colors) the node \cmdinternal {cd:node}; use the \CONTEXT\
- \SCITE\ lexers when available (\type {\usemodule [scite]})
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlflushspacewise}}
- flush node \cmdinternal {cd:node} obeying spaces and newlines
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlflushlinewise}}
- flush node \cmdinternal {cd:node} obeying newlines
-\stopxmlcmd
-
-\stopsection
-
-\startsection[title={information}]
-
-The following commands return strings. Normally these are used in tests.
-
-\startxmlcmd {\cmdbasicsetup{xmlname}}
- returns the complete name (including namespace prefix) of the
- given \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlnamespace}}
- returns the namespace of the given \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmltag}}
- returns the tag of the element, without namespace prefix
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlcount}}
- returns the number of matches of \cmdinternal {cd:lpath} at node \cmdinternal
- {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlatt}}
- returns the value of attribute \cmdinternal {cd:name} or empty if no such
- attribute exists
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlattdef}}
- returns the value of attribute \cmdinternal {cd:name} or \cmdinternal
- {cd:string} if no such attribute exists
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlrefatt}}
- returns the value of attribute \cmdinternal {cd:name} or empty if no such
- attribute exists; a leading \type {#} is removed (nicer for tex)
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlchainatt}}
- returns the value of attribute \cmdinternal {cd:name} or empty if no such
- attribute exists; backtracks till a match is found
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlchainattdef}}
- returns the value of attribute \cmdinternal {cd:name} or \cmdinternal
- {cd:string} if no such attribute exists; backtracks till a match is found
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlattribute}}
- finds a first match for \cmdinternal {cd:lpath} at \cmdinternal {cd:node} and
- returns the value of attribute \cmdinternal {cd:name} or empty if no such
- attribute exists
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlattributedef}}
- finds a first match for \cmdinternal {cd:lpath} at \cmdinternal {cd:node} and
- returns the value of attribute \cmdinternal {cd:name} or \cmdinternal
- {cd:text} if no such attribute exists
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmllastatt}}
- returns the last attribute found (this avoids a lookup)
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlsetatt}}
- set the value of attribute \cmdinternal {cd:name}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlsetattribute}}
- set the value of attribute \cmdinternal {cd:name} for each match of \cmdinternal
- {cd:lpath}
-\stopxmlcmd
-
-\stopsection
-
-\startsection[title={manipulation}]
-
-You can use \LUA\ code to manipulate the tree and it makes no sense to duplicate
-this in \TEX. In the future we might provide an interface to some of this
-functionality. Keep in mind that manipuating the tree might have side effects as
-we maintain several indices into the tree that also needs to be updated then.
-
-\stopsection
-
-\startsection[title={integration}]
-
-If you write a module that deals with \XML, for instance processing cals tables,
-then you need ways to control specific behaviour. For instance, you might want to
-add a background to the table. Such directives are collected in \XML\ files and
-can be loaded on demand.
-
-\startxmlcmd {\cmdbasicsetup{xmlloaddirectives}}
- loads \CONTEXT\ directives from \cmdinternal {cd:file} that will get
- interpreted when processing documents
-\stopxmlcmd
-
-A directives definition file looks as follows:
-
-\starttyping
-<?xml version="1.0" standalone="yes"?>
-
-<directives>
- <directive attribute='id' value="100"
- setup="cdx:100"/>
- <directive attribute='id' value="101"
- setup="cdx:101"/>
- <directive attribute='cdx' value="colors" element="cals:table"
- setup="cdx:cals:table:colors"/>
- <directive attribute='cdx' value="vertical" element="cals:table"
- setup="cdx:cals:table:vertical"/>
- <directive attribute='cdx' value="noframe" element="cals:table"
- setup="cdx:cals:table:noframe"/>
- <directive attribute='cdx' value="*" element="cals:table"
- setup="cdx:cals:table:*"/>
-</directives>
-\stoptyping
-
-Examples of usage can be found in \type {x-cals.mkiv}. The directive is triggered
-by an attribute. Instead of a setup you can specify a setup to be applied before
-and after the node gets flushed.
-
-\startxmlcmd {\cmdbasicsetup{xmldirectives}}
- apply the setups directive associated with the node
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldirectivesbefore}}
- apply the before directives associated with the node
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldirectivesafter}}
- apply the after directives associated with the node
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlinstalldirective}}
- defines a directive that hooks into a handler
-\stopxmlcmd
-
-Normally a directive will be put in the \XML\ file, for instance as:
-
-\starttyping
-<?context-mathml-directive minus reduction yes ?>
-\stoptyping
-
-Here the \type {mathml} is the general class of directives and \type {minus} a
-subclass, in our case a specific element.
-
-\stopsection
-
-\startsection[title={setups}]
-
-The basic building blocks of \XML\ processing are setups. These are just
-collections of macros that are expanded. These setups get one argument passed
-(\type {#1}):
-
-\starttyping
-\startxmlsetups somedoc:somesetup
- \xmlflush{#1}
-\stopxmlsetups
-\stoptyping
-
-This argument is normally a number that internally refers to a specific node in
-the \XML\ tree. The user should see it as an abstract reference and not depend on
-its numeric property. Just think of it as \quote {the current node}. You can (and
-probably will) call such setups using:
-
-\startxmlcmd {\cmdbasicsetup{xmlsetup}}
- expands setup \cmdinternal {cd:setup} and pass \cmdinternal {cd:node} as
- argument
-\stopxmlcmd
-
-However, in most cases the setups are associated to specific elements,
-something that users of \XSLT\ might recognize as templates.
-
-\startxmlcmd {\cmdbasicsetup{xmlsetfunction}}
- associates function \cmdinternal {cd:luafunction} to the elements in
- namespace \cmdinternal {cd:name} that match \cmdinternal {cd:lpath}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlsetsetup}}
- associates setups \cmdinternal {cd:setup} (\TEX\ code) with the matching
- nodes of \cmdinternal {cd:lpath} or root \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlprependsetup}}
- pushes \cmdinternal {cd:setup} to the front of global list of setups
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlappendsetup}}
- adds \cmdinternal {cd:setup} to the global list of setups to be applied
- (alias: \type{\xmlregistersetup})
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlbeforesetup}}
- pushes \cmdinternal {cd:setup} into the global list of setups; the
- last setup is the position
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlaftersetup}}
- adds \cmdinternal {cd:setup} to the global list of setups; the last setup
- is the position
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlremovesetup}}
- removes \cmdinternal {cd:setup} from the global list of setups
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlprependdocumentsetup}}
- pushes \cmdinternal {cd:setup} to the front of list of setups to be applied
- to \cmdinternal {cd:name}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlappenddocumentsetup}}
- adds \cmdinternal {cd:setup} to the list of setups to be applied to
- \cmdinternal {cd:name} (you can also use the alias: \type
- {\xmlregisterdocumentsetup})
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlbeforedocumentsetup}}
- pushes \cmdinternal {cd:setup} into the setups to be applied to \cmdinternal
- {cd:name}; the last setup is the position
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlafterdocumentsetup}}
- adds \cmdinternal {cd:setup} to the setups to be applied to \cmdinternal
- {cd:name}; the last setup is the position
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlremovedocumentsetup}}
- removes \cmdinternal {cd:setup} from the global list of setups to be applied
- to \cmdinternal {cd:name}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlresetsetups}}
- removes all global setups
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlresetdocumentsetups}}
- removes all setups from the \cmdinternal {cd:name} specific list of setups to
- be applied
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlflushdocumentsetups}{setup}}
- applies \cmdinternal {cd:setup} (can be a list) to \cmdinternal {cd:name}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlregisteredsetups}}
- applies all global setups to the current document
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlregistereddocumentsetups}}
- applies all document specific \cmdinternal {cd:setup} to document
- \cmdinternal {cd:name}
-\stopxmlcmd
-
-\stopsection
-
-\startsection[title={testing}]
-
-The following test macros all take a \cmdinternal {cd:node} as first argument
-and an \cmdinternal {cd:lpath} as second:
-
-\startxmlcmd {\cmdbasicsetup{xmldoif}}
- expands to \cmdinternal {cd:true} when \cmdinternal {cd:lpath} matches at
- node \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoifnot}}
- expands to \cmdinternal {cd:true} when \cmdinternal {cd:lpath} does not match
- at node \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoifelse}}
- expands to \cmdinternal {cd:true} when \cmdinternal {cd:lpath} matches at
- node \cmdinternal {cd:node} and to \cmdinternal {cd:false} otherwise
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoiftext}}
- expands to \cmdinternal {cd:true} when the node matching \cmdinternal
- {cd:lpath} at node \cmdinternal {cd:node} has some content
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoifnottext}}
- expands to \cmdinternal {cd:true} when the node matching \cmdinternal
- {cd:lpath} at node \cmdinternal {cd:node} has no content
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoifelsetext}}
- expands to \cmdinternal {cd:true} when the node matching \cmdinternal
- {cd:lpath} at node \cmdinternal {cd:node} has content and to \cmdinternal
- {cd:false} otherwise
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoifelseempty}}
- expands to \cmdinternal {cd:true} when the node matching \cmdinternal
- {cd:lpath} at node \cmdinternal {cd:node} is empty and to \cmdinternal
- {cd:false} otherwise
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoifelseselfempty}}
- expands to \cmdinternal {cd:true} when the node is empty and to \cmdinternal
- {cd:false} otherwise
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoifselfempty}}
- expands to \cmdinternal {cd:true} when \cmdinternal {cd:node} is empty
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoifnotselfempty}}
- expands to \cmdinternal {cd:true} when \cmdinternal {cd:node} is not empty
-\stopxmlcmd
-
-\stopsection
-
-\startsection[title={initialization}]
-
-The general setup command (not to be confused with setups) that deals with the
-\MKIV\ tree handler is \type {\setupxml}. There are currently only a few options.
-
-\cmdfullsetup{setupxml}
-
-When you set \type {default} to \cmdinternal {cd:text} elements with no setup
-assigned will end up as text. When set to \type {hidden} such elements will be
-hidden. You can apply the default yourself using:
-
-\startxmlcmd {\cmdbasicsetup{xmldefaulttotext}}
- presets the tree with root \cmdinternal {cd:node} to the handlers set up with
- \type {\setupxml} option \cmdinternal{default}
-\stopxmlcmd
-
-You can set \type {compress} to \type {yes} in which case comment is stripped
-from the tree when the file is read.
-
-\startxmlcmd {\cmdbasicsetup{xmlregisterns}}
- associates an internal namespace (like \type {mml}) with one given in the
- document as \URL\ (like mathml)
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlremapname}}
- changes the namespace and tag of the matching elements
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlremapnamespace}}
- replaces all references to the given namespace to a new one (applied
- recursively)
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlchecknamespace}}
- sets the namespace of the matching elements unless a namespace is already set
-\stopxmlcmd
-
-\stopsection
-
-\startsection[title={helpers}]
-
-Often an attribute will determine the rendering and this may result in many
-tests. Especially when we have multiple attributes that control the output such
-tests can become rather extensive and redundant because one gets $n\times m$ or
-more such tests.
-
-Therefore we have a convenient way to map attributes onto for instance strings or
-commands.
-
-\startxmlcmd {\cmdbasicsetup{xmlmapvalue}}
- associate a \cmdinternal {cd:text} with a \cmdinternal {cd:category} and
- \cmdinternal {cd:name} (alias: \type{\xmlmapval})
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlvalue}}
- expand the value associated with a \cmdinternal {cd:category} and
- \cmdinternal {cd:name} and if not resolved, expand to the \cmdinternal
- {cd:text} (alias: \type{\xmlval})
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmldoifelsevalue}}
- associate a \cmdinternal {cd:text} with a \cmdinternal {cd:category} and
- \cmdinternal {cd:name}
-\stopxmlcmd
-
-This is used as follows. We define a couple of mappings in the same category:
-
-\starttyping
-\xmlmapvalue{emph}{bold} {\bf}
-\xmlmapvalue{emph}{italic}{\it}
-\stoptyping
-
-Assuming that we have associated the following setup with the \type {emph}
-element, we can say (with \type {#1} being the current element):
-
-\starttyping
-\startxmlsetups demo:emph
- \begingroup
- \xmlvalue{emph}{\xmlatt{#1}{type}}{}
- \endgroup
-\stopxmlsetups
-\stoptyping
-
-In this case we have no default. The \type {type} attribute triggers the actions,
-as in:
-
-\starttyping
-normal <emph type='bold'>bold</emph> normal
-\stoptyping
-
-This mechanism is not really bound to elements and attributes so you can use this
-mechanism for other purposes as well.
-
-\stopsection
-
-\startsection[title={Parameters}]
-
-\startbuffer[test]
-<something whatever="alpha">
- <what>
- beta
- </what>
-</something>
-\stopbuffer
-
-\startbuffer
-\startxmlsetups xml:mysetups
- \xmlsetsetup{\xmldocument}{*}{xml:*}
-\stopxmlsetups
-
-\xmlregistersetup{xml:mysetups}
-
-\startxmlsetups xml:something
- parameter : \xmlpar {#1}{whatever}\par
- attribute : \xmlatt {#1}{whatever}\par
- text : \xmlfirst {#1}{what} \par
- \xmlsetpar{#1}{whatever}{gamma}
- parameter : \xmlpar {#1}{whatever}\par
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:what
- what: \xmlflush{#1}\par
- parameter : \xmlparam{#1}{..}{whatever}\par
-\stopxmlsetups
-
-\xmlprocessbuffer{main}{test}{}
-\stopbuffer
-
-Say that we have this \XML\ blob:
-
-\typebuffer[test]
-
-With:
-
-\typebuffer
-
-we get:
-
-\getbuffer
-
-Parameters are stored with a node.
-
-\startxmlcmd {\cmdbasicsetup{xmlpar}}
- returns the value of parameter \cmdinternal {cd:name} or empty if no such
- parameter exists
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlparam}}
- finds a first match for \cmdinternal {cd:lpath} at \cmdinternal {cd:node} and
- returns the value of parameter \cmdinternal {cd:name} or empty if no such
- parameter exists
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmllastpar}}
- returns the last parameter found (this avoids a lookup)
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlsetpar}}
- set the value of parameter \cmdinternal {cd:name}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlsetparam}}
- set the value of parameter \cmdinternal {cd:name} for each match of \cmdinternal
- {cd:lpath}
-\stopxmlcmd
-
-\stopsection
-
-\stopchapter
-
-\startchapter[title={Expressions and filters}]
-
-\startsection[title={path expressions}]
-
-In the previous chapters we used \cmdinternal {cd:lpath} expressions, which are a variant
-on \type {xpath} expressions as in \XSLT\ but in this case more geared towards
-usage in \TEX. This mechanisms will be extended when demands are there.
-
-A path is a sequence of matches. A simple path expression is:
-
-\starttyping
-a/b/c/d
-\stoptyping
-
-Here each \type {/} goes one level deeper. We can go backwards in a lookup with
-\type {..}:
-
-\starttyping
-a/b/../d
-\stoptyping
-
-We can also combine lookups, as in:
-
-\starttyping
-a/(b|c)/d
-\stoptyping
-
-A negated lookup is preceded by a \type {!}:
-
-\starttyping
-a/(b|c)/!d
-\stoptyping
-
-A wildcard is specified with a \type {*}:
-
-\starttyping
-a/(b|c)/!d/e/*/f
-\stoptyping
-
-In addition to these tag based lookups we can use attributes:
-
-\starttyping
-a/(b|c)/!d/e/*/f[@type=whatever]
-\stoptyping
-
-An \type {@} as first character means that we are dealing with an attribute.
-Within the square brackets there can be boolean expressions:
-
-\starttyping
-a/(b|c)/!d/e/*/f[@type=whatever and @id>100]
-\stoptyping
-
-You can use functions as in:
-
-\starttyping
-a/(b|c)/!d/e/*/f[something(text()) == "oeps"]
-\stoptyping
-
-There are a couple of predefined functions:
-
-\starttabulate[|l|l|p|]
-\NC \type{rootposition} \type{order} \NC number \NC the index of the matched root element (kind of special) \NC \NR
-\NC \type{position} \NC number \NC the current index of the matched element in the match list \NC \NR
-\NC \type{match} \NC number \NC the current index of the matched element sub list with the same parent \NC \NR
-\NC \type{first} \NC number \NC \NC \NR
-\NC \type{last} \NC number \NC \NC \NR
-\NC \type{index} \NC number \NC the current index of the matched element in its parent list \NC \NR
-\NC \type{firstindex} \NC number \NC \NC \NR
-\NC \type{lastindex} \NC number \NC \NC \NR
-\NC \type{element} \NC number \NC the element's index \NC \NR
-\NC \type{firstelement} \NC number \NC \NC \NR
-\NC \type{lastelement} \NC number \NC \NC \NR
-\NC \type{text} \NC string \NC the textual representation of the matched element \NC \NR
-\NC \type{content} \NC table \NC the node of the matched element \NC \NR
-\NC \type{name} \NC string \NC the full name of the matched element: namespace and tag \NC \NR
-\NC \type{namespace} \type{ns} \NC string \NC the namespace of the matched element \NC \NR
-\NC \type{tag} \NC string \NC the tag of the matched element \NC \NR
-\NC \type{attribute} \NC string \NC the value of the attribute with the given name of the matched element \NC \NR
-\stoptabulate
-
-There are fundamental differences between \type {position}, \type {match} and
-\type {index}. Each step results in a new list of matches. The \type {position}
-is the index in this new (possibly intermediate) list. The \type {match} is also
-an index in this list but related to the specific match of element names. The
-\type {index} refers to the location in the parent element.
-
-Say that we have:
-
-\starttyping
-<collection>
- <resources>
- <manual>
- <screen>.1.</screen>
- <paper>.1.</paper>
- </manual>
- <manual>
- <paper>.2.</paper>
- <screen>.2.</screen>
- </manual>
- <resources>
- <resources>
- <manual>
- <screen>.3.</screen>
- <paper>.3.</paper>
- </manual>
- <resources>
-<collection>
-\stoptyping
-
-The following then applies:
-
-\starttabulate[|l|l|]
-\NC \type {collection/resources/manual[position()==1]/paper} \NC \type{.1.} \NC \NR
-\NC \type {collection/resources/manual[match()==1]/paper} \NC \type{.1.} \type{.3.} \NC \NR
-\NC \type {collection/resources/manual/paper[index()==1]} \NC \type{.2.} \NC \NR
-\stoptabulate
-
-In most cases the \type {position} test is more restrictive than the \type
-{match} test.
-
-You can pass your own functions too. Such functions are defined in the the \type
-{xml.expressions} namespace. We have defined a few shortcuts:
-
-\starttabulate[|l|l|]
-\NC \type {find(str,pattern)} \NC \type{string.find} \NC \NR
-\NC \type {contains(str)} \NC \type{string.find} \NC \NR
-\NC \type {oneof(str,...)} \NC is \type{str} in list \NC \NR
-\NC \type {upper(str)} \NC \type{characters.upper} \NC \NR
-\NC \type {lower(str)} \NC \type{characters.lower} \NC \NR
-\NC \type {number(str)} \NC \type{tonumber} \NC \NR
-\NC \type {boolean(str)} \NC \type{toboolean} \NC \NR
-\NC \type {idstring(str)} \NC removes leading hash \NC \NR
-\NC \type {name(index)} \NC full tag name \NC \NR
-\NC \type {tag(index)} \NC tag name \NC \NR
-\NC \type {namespace(index)} \NC namespace of tag \NC \NR
-\NC \type {text(index)} \NC content \NC \NR
-\NC \type {error(str)} \NC quit and show error \NC \NR
-\NC \type {quit()} \NC quit \NC \NR
-\NC \type {print()} \NC print message \NC \NR
-\NC \type {count(pattern)} \NC number of matches \NC \NR
-\NC \type {child(pattern)} \NC take child that matches \NC \NR
-\stoptabulate
-
-
-You can also use normal \LUA\ functions as long as you make sure that you pass
-the right arguments. There are a few predefined variables available inside such
-functions.
-
-\starttabulate[|Tl|l|p|]
-\NC \type{list} \NC table \NC the list of matches \NC \NR
-\NC \type{l} \NC number \NC the current index in the list of matches \NC \NR
-\NC \type{ll} \NC element \NC the current element that matched \NC \NR
-\NC \type{order} \NC number \NC the position of the root of the path \NC \NR
-\stoptabulate
-
-The given expression between \type {[]} is converted to a \LUA\ expression so you
-can use the usual operators:
-
-\starttyping
-== ~= <= >= < > not and or ()
-\stoptyping
-
-In addition, \type {=} equals \type {==} and \type {!=} is the same as \type
-{~=}. If you mess up the expression, you quite likely get a \LUA\ error message.
-
-\stopsection
-
-\startsection[title={css selectors}]
-
-\startbuffer[selector-001]
-<?xml version="1.0" ?>
-
-<a>
- <b class="one">b.one</b>
- <b class="two">b.two</b>
- <b class="one two">b.one.two</b>
- <b class="three">b.three</b>
- <b id="first">b#first</b>
- <c>c</c>
- <d>d e</d>
- <e>d e</e>
- <e>d e e</e>
- <d>d f</d>
- <f foo="bar">@foo = bar</f>
- <f bar="foo">@bar = foo</f>
- <f bar="foo1">@bar = foo1</f>
- <f bar="foo2">@bar = foo2</f>
- <f bar="foo3">@bar = foo3</f>
- <f bar="foo+4">@bar = foo+4</f>
- <g>g</g>
- <g><gg><d>g gg d</d></gg></g>
- <g><gg><f>g gg f</f></gg></g>
- <g><gg><f class="one">g gg f.one</f></gg></g>
- <g>g</g>
- <g><gg><f class="two">g gg f.two</f></gg></g>
- <g><gg><f class="three">g gg f.three</f></gg></g>
- <g><f class="one">g f.one</f></g>
- <g><f class="three">g f.three</f></g>
- <h whatever="four five six">@whatever = four five six</h>
-</a>
-\stopbuffer
-
-\xmlloadbuffer{selector-001}{selector-001}
-
-\startxmlsetups xml:selector:demo
- \advance\scratchcounter\plusone
- \inleftmargin{\the\scratchcounter}\ignorespaces\xmlverbatim{#1}\par
-\stopxmlsetups
-
-\unexpanded\def\showCSSdemo#1#2%
- {\blank
- \textrule{\tttf#2}
- \startlines
- \dontcomplain
- \tttf \obeyspaces
- \scratchcounter\zerocount
- \xmlcommand{#1}{#2}{xml:selector:demo}
- \stoplines
- \blank}
-
-The \CSS\ approach to filtering is a bit different from the path based one and is
-supported too. In fact, you can combine both methods. Depending on what you
-select, the \CSS\ one can be a little bit faster too. It has the advantage that
-one can select more in one go but at the same time looks a bit less attractive.
-This method was added just to show that it can be done but might be useful too. A
-selector is given between curly braces (after all \CSS\ uses them and they have no
-function yet in the parser.
-
-\starttyping
-\xmlall{#1}{{foo bar .whatever, bar foo .whatever}}
-\stoptyping
-
-The following methods are supported:
-
-\starttabulate[|T||]
-\NC element \NC all tags element \NC \NR
-\NC element-1 > element-2 \NC all tags element-2 with parent tag element-1 \NC \NR
-\NC element-1 + element-2 \NC all tags element-2 preceded by tag element-1 \NC \NR
-\NC element-1 ~ element-2 \NC all tags element-2 preceded by tag element-1 \NC \NR
-\NC element-1 element-2 \NC all tags element-2 inside tag element-1 \NC \NR
-\NC [attribute] \NC has attribute \NC \NR
-\NC [attribute=value] \NC attribute equals value\NC \NR
-\NC [attribute\lettertilde =value] \NC attribute contains value (space is separator) \NC \NR
-\NC [attribute\letterhat ="value"] \NC attribute starts with value \NC \NR
-\NC [attribute\letterdollar="value"] \NC attribute ends with value \NC \NR
-\NC [attribute*="value"] \NC attribute contains value \NC \NR
-\NC .class \NC has class \NC \NR
-\NC \letterhash id \NC has id \NC \NR
-\NC :nth-child(n) \NC the child at index n \NC \NR
-\NC :nth-last-child(n) \NC the child at index n from the end \NC \NR
-\NC :first-child \NC the first child \NC \NR
-\NC :last-child \NC the last child \NC \NR
-\NC :nth-of-type(n) \NC the match at index n \NC \NR
-\NC :nth-last-of-type(n) \NC the match at index n from the end \NC \NR
-\NC :first-of-type \NC the first match \NC \NR
-\NC :last-of-type \NC the last match \NC \NR
-\NC :only-of-type \NC the only match or nothing \NC \NR
-\NC :only-child \NC the only child or nothing \NC \NR
-\NC :empty \NC only when empty \NC \NR
-\NC :root \NC the whole tree \NC \NR
-\stoptabulate
-
-The next pages show some examples. For that we use the demo file:
-
-\typebuffer[selector-001]
-
-The class and id selectors often only make sense in \HTML\ like documents but they
-are supported nevertheless. They are after all just shortcuts for filtering by
-attribute. The class filtering is special in the sense that it checks for a class
-in a list of classes given in an attribute.
-
-\showCSSdemo{selector-001}{{.one}}
-\showCSSdemo{selector-001}{{.one, .two}}
-\showCSSdemo{selector-001}{{.one, .two, \letterhash first}}
-
-Attributes can be filtered by presence, value, partial value and such. Quotes are
-optional but we advice to use them.
-
-\showCSSdemo{selector-001}{{[foo], [bar=foo]}}
-\showCSSdemo{selector-001}{{[bar\lettertilde=foo]}}
-\showCSSdemo{selector-001}{{[bar\letterhat="foo"]}}
-\showCSSdemo{selector-001}{{[whatever\lettertilde="five"]}}
-
-You can of course combine the methods as in:
-
-\showCSSdemo{selector-001}{{g f .one, g f .three}}
-\showCSSdemo{selector-001}{{g > f .one, g > f .three}}
-\showCSSdemo{selector-001}{{d + e}}
-\showCSSdemo{selector-001}{{d ~ e}}
-\showCSSdemo{selector-001}{{d ~ e, g f .one, g f .three}}
-
-You can also negate the result by using \type {:not} on a simple expression:
-
-\showCSSdemo{selector-001}{{:not([whatever\lettertilde="five"])}}
-\showCSSdemo{selector-001}{{:not(d)}}
-
-The child and match selectors are also supported:
-
-\showCSSdemo{selector-001}{{a:nth-child(3)}}
-\showCSSdemo{selector-001}{{a:nth-last-child(3)}}
-\showCSSdemo{selector-001}{{g:nth-of-type(3)}}
-\showCSSdemo{selector-001}{{g:nth-last-of-type(3)}}
-\showCSSdemo{selector-001}{{a:first-child}}
-\showCSSdemo{selector-001}{{a:last-child}}
-\showCSSdemo{selector-001}{{e:first-of-type}}
-\showCSSdemo{selector-001}{{gg d:only-of-type}}
-
-Instead of numbers you can also give the \type {an} and \type {an+b} formulas
-as well as the \type {odd} and \type {even} keywords:
-
-\showCSSdemo{selector-001}{{a:nth-child(even)}}
-\showCSSdemo{selector-001}{{a:nth-child(odd)}}
-\showCSSdemo{selector-001}{{a:nth-child(3n+1)}}
-\showCSSdemo{selector-001}{{a:nth-child(2n+3)}}
-
-There are a few special cases:
-
-\showCSSdemo{selector-001}{{g:empty}}
-\showCSSdemo{selector-001}{{g:root}}
-\showCSSdemo{selector-001}{{*}}
-
-Combining the \CSS\ methods with the regular ones is possible:
-
-\showCSSdemo{selector-001}{{g gg f .one}}
-\showCSSdemo{selector-001}{g/gg/f[@class='one']}
-\showCSSdemo{selector-001}{g/{gg f .one}}
-
-\startbuffer[selector-002]
-<?xml version="1.0" ?>
-
-<document>
- <title class="one" >title 1</title>
- <title class="two" >title 2</title>
- <title class="one" >title 3</title>
- <title class="three">title 4</title>
-</document>
-\stopbuffer
-
-The next examples we use this file:
-
-\typebuffer[selector-002]
-
-\xmlloadbuffer{selector-002}{selector-002}
-
-When we filter from this (not too well structured) tree we can use both
-methods to achieve the same:
-
-\showCSSdemo{selector-002}{{document title .one, document title .three}}
-
-\showCSSdemo{selector-002}{/document/title[(@class='one') or (@class='three')]}
-
-However, imagine this file:
-
-\startbuffer[selector-003]
-<?xml version="1.0" ?>
-
-<document>
- <title class="one">title 1</title>
- <subtitle class="sub">title 1.1</subtitle>
- <title class="two">title 2</title>
- <subtitle class="sub">title 2.1</subtitle>
- <title class="one">title 3</title>
- <subtitle class="sub">title 3.1</subtitle>
- <title class="two">title 4</title>
- <subtitle class="sub">title 4.1</subtitle>
-</document>
-\stopbuffer
-
-\typebuffer[selector-003]
-
-\xmlloadbuffer{selector-003}{selector-003}
-
-The next filter in easier with the \CSS\ selector methods because these accumulate
-independent (simple) expressions:
-
-\showCSSdemo{selector-003}{{document title .one + subtitle, document title .two + subtitle}}
-
-Watch how we get an output in the document order. Because we render a sequential document
-a combined filter will trigger a sorting pass.
-
-\stopsection
-
-\startsection[title={functions as filters}]
-
-At the \LUA\ end a whole \cmdinternal {cd:lpath} expression results in a (set of) node(s)
-with its environment, but that is hardly usable in \TEX. Think of code like:
-
-\starttyping
-for e in xml.collected(xml.load('text.xml'),"title") do
- -- e = the element that matched
-end
-\stoptyping
-
-The older variant is still supported but you can best use the previous variant.
-
-\starttyping
-for r, d, k in xml.elements(xml.load('text.xml'),"title") do
- -- r = root of the title element
- -- d = data table
- -- k = index in data table
-end
-\stoptyping
-
-Here \type {d[k]} points to the \type {title} element and in this case all titles
-in the tree pass by. In practice this kind of code is encapsulated in function
-calls, like those returning elements one by one, or returning the first or last
-match. The result is then fed back into \TEX, possibly after being altered by an
-associated setup. We've seen the wrappers to such functions already in a previous
-chapter.
-
-In addition to the previously discussed expressions, one can add so called
-filters to the expression, for instance:
-
-\starttyping
-a/(b|c)/!d/e/text()
-\stoptyping
-
-In a filter, the last part of the \cmdinternal {cd:lpath} expression is a
-function call. The previous example returns the text of each element \type {e}
-that results from matching the expression. When running \TEX\ the following
-functions are available. Some are also available when using pure \LUA. In \TEX\
-you can often use one of the macros like \type {\xmlfirst} instead of a \type
-{\xmlfilter} with finalizer \type {first()}. The filter can be somewhat faster
-but that is hardly noticeable.
-
-\starttabulate[|l|l|p|]
-\NC \type {context()} \NC string \NC the serialized text with \TEX\ catcode regime \NC \NR
-%NC \type {ctxtext()} \NC string \NC \NC \NR
-\NC \type {function()} \NC string \NC depends on the function \NC \NR
-%
-\NC \type {name()} \NC string \NC the (remapped) namespace \NC \NR
-\NC \type {tag()} \NC string \NC the name of the element \NC \NR
-\NC \type {tags()} \NC list \NC the names of the element \NC \NR
-%
-\NC \type {text()} \NC string \NC the serialized text \NC \NR
-\NC \type {upper()} \NC string \NC the serialized text uppercased \NC \NR
-\NC \type {lower()} \NC string \NC the serialized text lowercased \NC \NR
-\NC \type {stripped()} \NC string \NC the serialized text stripped \NC \NR
-\NC \type {lettered()} \NC string \NC the serialized text only letters (cf. \UNICODE) \NC \NR
-%
-\NC \type {count()} \NC number \NC the number of matches \NC \NR
-\NC \type {index()} \NC number \NC the matched index in the current path \NC \NR
-\NC \type {match()} \NC number \NC the matched index in the preceding path \NC \NR
-%
-%NC \type {lowerall()} \NC string \NC \NC \NR
-%NC \type {upperall()} \NC string \NC \NC \NR
-%
-\NC \type {attribute(name)} \NC content \NC returns the attribute with the given name \NC \NR
-\NC \type {chainattribute(name)} \NC content \NC sidem, but backtracks till one is found \NC \NR
-\NC \type {command(name)} \NC content \NC expands the setup with the given name for each found element \NC \NR
-\NC \type {position(n)} \NC content \NC processes the \type {n}\high{th} instance of the found element \NC \NR
-\NC \type {all()} \NC content \NC processes all instances of the found element \NC \NR
-%NC \type {default} \NC content \NC all \NC \NR
-\NC \type {reverse()} \NC content \NC idem in reverse order \NC \NR
-\NC \type {first()} \NC content \NC processes the first instance of the found element \NC \NR
-\NC \type {last()} \NC content \NC processes the last instance of the found element \NC \NR
-\NC \type {concat(...)} \NC content \NC concatinates the match \NC \NC \NR
-\NC \type {concatrange(from,to,...)} \NC content \NC concatinates a range of matches \NC \NC \NR
-\stoptabulate
-
-The extra arguments of the concatinators are: \type {separator} (string), \type
-{lastseparator} (string) and \type {textonly} (a boolean).
-
-These filters are in fact \LUA\ functions which means that if needed more of them
-can be added. Indeed this happens in some of the \XML\ related \MKIV\ modules,
-for instance in the \MATHML\ processor.
-
-\stopsection
-
-\startsection[title={example}]
-
-The number of commands is rather large and if you want to avoid them this is
-often possible. Take for instance:
-
-\starttyping
-\xmlall{#1}{/a/b[position()>3]}
-\stoptyping
-
-Alternatively you can use:
-
-\starttyping
-\xmlfilter{#1}{/a/b[position()>3]/all()}
-\stoptyping
-
-and actually this is also faster as internally it avoids a function call. Of
-course in practice this is hardly measurable.
-
-In previous examples we've already seen quite some expressions, and it might be
-good to point out that the syntax is modelled after \XSLT\ but is not quite the
-same. The reason is that we started with a rather minimal system and have already
-styles in use that depend on compatibility.
-
-\starttyping
-namespace:// axis node(set) [expr 1]..[expr n] / ... / filter
-\stoptyping
-
-When we are inside a \CONTEXT\ run, the namespace is \type {tex}. Hoewever, if
-you want not to print back to \TEX\ you need to be more explicit. Say that we
-typeset examns and have a (not that logical) structure like:
-
-\starttyping
-<question>
- <text>...</text>
- <answer>
- <item>one</item>
- <item>two</item>
- <item>three</item>
- </answer>
- <alternative>
- <condition>true</condition>
- <score>1</score>
- </alternative>
- <alternative>
- <condition>false</condition>
- <score>0</score>
- </alternative>
- <alternative>
- <condition>true</condition>
- <score>2</score>
- </alternative>
-</question>
-\stoptyping
-
-Say that we typeset the questions with:
-
-\starttyping
-\startxmlsetups question
- \blank
- score: \xmlfunction{#1}{totalscore}
- \blank
- \xmlfirst{#1}{text}
- \startitemize
- \xmlfilter{#1}{/answer/item/command(answer:item)}
- \stopitemize
- \endgraf
- \blank
-\stopxmlsetups
-\stoptyping
-
-Each item in the answer results in a call to:
-
-\starttyping
-\startxmlsetups answer:item
- \startitem
- \xmlflush{#1}
- \endgraf
- \xmlfilter{#1}{../../alternative[position()=rootposition()]/
- condition/command(answer:condition)}
- \stopitem
-\stopxmlsetups
-\stoptyping
-
-\starttyping
-\startxmlsetups answer:condition
- \endgraf
- condition: \xmlflush{#1}
- \endgraf
-\stopxmlsetups
-\stoptyping
-
-Now, there are two rather special filters here. The first one involves
-calculating the total score. As we look forward we use a function to deal with
-this.
-
-\starttyping
-\startluacode
-function xml.functions.totalscore(root)
- local score = 0
- for e in xml.collected(root,"/alternative") do
- score = score + xml.filter(e,"xml:///score/number()") or 0
- end
- tex.write(score)
-end
-\stopluacode
-\stoptyping
-
-Watch how we use the namespace to keep the results at the \LUA\ end.
-
-The second special trick shown here is to limit a match using the current
-position of the root (\type {#}) match.
-
-As you can see, a path expression can be more than just filtering a few nodes. At
-the end of this manual you will find a bunch of examples.
-
-\stopsection
-
-\startsection[title={tables}]
-
-If you want to know how the internal \XML\ tables look you can print such a
-table:
-
-\starttyping
-print(table.serialize(e))
-\stoptyping
-
-This produces for instance:
-
-% s = xml.convert("<document><demo label='whatever'>some text</demo></document>")
-% print(table.serialize(xml.filter(s,"demo")[1]))
-
-\starttyping
-t={
- ["at"]={
- ["label"]="whatever",
- },
- ["dt"]={ "some text" },
- ["ns"]="",
- ["rn"]="",
- ["tg"]="demo",
-}
-\stoptyping
-
-The \type {rn} entry is the renamed namespace (when renaming is applied). If you
-see tags like \type {@pi@} this means that we don't have an element, but (in this
-case) a processing instruction.
-
-\starttabulate[|l|p|]
-\NC \type {@rt@} \NC the root element \NC \NR
-\NC \type {@dd@} \NC document definition \NC \NR
-\NC \type {@cm@} \NC comment, like \type {<!-- whatever -->} \NC \NR
-\NC \type {@cd@} \NC so called \type {CDATA} \NC \NR
-\NC \type {@pi@} \NC processing instruction, like \type {<?whatever we want ?>} \NC \NR
-\stoptabulate
-
-There are many ways to deal with the content, but in the perspective of \TEX\
-only a few matter.
-
-\starttabulate[|l|p|]
-\NC \type {xml.sprint(e)} \NC print the content to \TEX\ and apply setups if needed \NC \NR
-\NC \type {xml.tprint(e)} \NC print the content to \TEX\ (serialize elements verbose) \NC \NR
-\NC \type {xml.cprint(e)} \NC print the content to \TEX\ (used for special content) \NC \NR
-\stoptabulate
-
-Keep in mind that anything low level that you uncover is not part of the official
-interface unless mentioned in this manual.
-
-\stopsection
-
-\stopchapter
-
-\startchapter[title={Tips and tricks}]
-
-\startsection[title={tracing}]
-
-It can be hard to debug code as much happens kind of behind the screens.
-Therefore we have a couple of tracing options. Of course you can typeset some
-status information, using for instance:
-
-\startxmlcmd {\cmdbasicsetup{xmlshow}}
- typeset the tree given by \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlinfo}}
- typeset the name in the element given by \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlpath}}
- returns the complete path (including namespace prefix and index) of the
- given \cmdinternal {cd:node}
-\stopxmlcmd
-
-\startbuffer[demo]
-<?xml version "1.0"?>
-<document>
- <section>
- <content>
- <p>first</p>
- <p><b>second</b></p>
- </content>
- </section>
- <section>
- <content>
- <p><b>third</b></p>
- <p>fourth</p>
- </content>
- </section>
-</document>
-\stopbuffer
-
-Say that we have the following \XML:
-
-\typebuffer[demo]
-
-and the next definitions:
-
-\startbuffer
-\startxmlsetups xml:demo:base
- \xmlsetsetup{#1}{p|b}{xml:demo:*}
-\stopxmlsetups
-
-\startxmlsetups xml:demo:p
- \xmlflush{#1}
- \par
-\stopxmlsetups
-
-\startxmlsetups xml:demo:b
- \par
- \xmlpath{#1} : \xmlflush{#1}
- \par
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{example-10}{xml:demo:base}
-
-\xmlprocessbuffer{example-10}{demo}{}
-\stopbuffer
-
-\typebuffer
-
-This will give us:
-
-\blank \startpacked \getbuffer \stoppacked \blank
-
-If you use \type {\xmlshow} you will get a complete subtree which can
-be handy for tracing but can also lead to large documents.
-
-We also have a bunch of trackers that can be enabled, like:
-
-\starttyping
-\enabletrackers[xml.show,xml.parse]
-\stoptyping
-
-The full list (currently) is:
-
-\starttabulate[|lT|p|]
-\NC xml.entities \NC show what entities are seen and replaced \NC \NR
-\NC xml.path \NC show the result of parsing an lpath expression \NC \NR
-\NC xml.parse \NC show stepwise resolving of expressions \NC \NR
-\NC xml.profile \NC report all parsed lpath expressions (in the log) \NC \NR
-\NC xml.remap \NC show what namespaces are remapped \NC \NR
-\NC lxml.access \NC report errors with respect to resolving (symbolic) nodes \NC \NR
-\NC lxml.comments \NC show the comments that are encountered (if at all) \NC \NR
-\NC lxml.loading \NC show what files are loaded and converted \NC \NR
-\NC lxml.setups \NC show what setups are being associated to elements \NC \NR
-\stoptabulate
-
-In one of our workflows we produce books from \XML\ where the (educational)
-content is organized in many small files. Each book has about 5~chapters and each
-chapter is made of sections that contain text, exercises, resources, etc.\ and so
-the document is assembled from thousands of files (don't worry, runtime inclusion
-is pretty fast). In order to see where in the sources content resides we can
-trace the filename.
-
-\startxmlcmd {\cmdbasicsetup{xmlinclusion}}
- returns the file where the node comes from
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlinclusions}}
- returns the list of files where the node comes from
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlbadinclusions}}
- returns a list of files that were not included due to some problem
-\stopxmlcmd
-
-Of course you have to make sure that these names end up somewhere visible, for
-instance in the margin.
-
-\stopsection
-
-\startsection[title={expansion}]
-
-For novice users the concept of expansion might sound frightening and to some
-extend it is. However, it is important enough to spend some words on it here.
-
-It is good to realize that most setups are sort of immediate. When one setup is
-issued, it can call another one and so on. Normally you won't notice that but
-there are cases where that can be a problem. In \TEX\ you can define a macro,
-take for instance:
-
-\starttyping
-\startxmlsetups xml:foo
- \def\foobar{\xmlfirst{#1}{/bar}}
-\stopxmlsetups
-\stoptyping
-
-you store the reference top node \type {bar} in \type {\foobar} maybe for later use. In
-this case the content is not yet fetched, it will be done when \type {\foobar} is
-called.
-
-\starttyping
-\startxmlsetups xml:foo
- \edef\foobar{\xmlfirst{#1}{/bar}}
-\stopxmlsetups
-\stoptyping
-
-Here the content of \type {bar} becomes the body of the macro. But what if
-\type {bar} itself contains elements that also contain elements. When there
-is a setup for \type {bar} it will be triggered and so on.
-
-When that setup looks like:
-
-\starttyping
-\startxmlsetups xml:bar
- \def\barfoo{\xmlflush{#1}}
-\stopxmlsetups
-\stoptyping
-
-Here we get something like:
-
-\starttyping
-\foobar => {\def\barfoo{...}}
-\stoptyping
-
-When \type {\barfoo} is not defined we get an error and when it is known and expands
-to something weird we might also get an error.
-
-Especially when you don't know what content can show up, this can result in errors
-when an expansion fails, for example because some macro being used is not defined.
-To prevent this we can define a macro:
-
-\starttyping
-\starttexdefinition unexpanded xml:bar:macro #1
- \def\barfoo{\xmlflush{#1}}
-\stoptexdefinition
-
-\startxmlsetups xml:bar
- \texdefinition{xml:bar:macro}{#1}
-\stopxmlsetups
-\stoptyping
-
-The setup \type {xml:bar} will still expand but the replacement text now is just the
-call to the macro, think of:
-
-\starttyping
-\foobar => {\texdefinition{xml:bar:macro}{#1}}
-\stoptyping
-
-But this is often not needed, most \CONTEXT\ commands can handle the expansions
-quite well but it's good to know that there is a way out. So, now to some
-examples. Imagine that we have an \XML\ file that looks as follows:
-
-\starttyping
-<?xml version='1.0' ?>
-<demo>
- <chapter>
- <title>Some <em>short</em> title</title>
- <content>
- zeta
- <index>
- <key>zeta</key>
- <content>zeta again</content>
- </index>
- alpha
- <index>
- <key>alpha</key>
- <content>alpha <em>again</em></content>
- </index>
- gamma
- <index>
- <key>gamma</key>
- <content>gamma</content>
- </index>
- beta
- <index>
- <key>beta</key>
- <content>beta</content>
- </index>
- delta
- <index>
- <key>delta</key>
- <content>delta</content>
- </index>
- done!
- </content>
- </chapter>
-</demo>
-\stoptyping
-
-There are a few structure related elements here: a chapter (with its list entry)
-and some index entries. Both are multipass related and therefore travel around.
-This means that when we let data end up in the auxiliary file, we need to make
-sure that we end up with either expanded data (i.e.\ no references to the \XML\
-tree) or with robust forward and backward references to elements in the tree.
-
-Here we discuss three approaches (and more may show up later): pushing \XML\ into
-the auxiliary file and using references to elements either or not with an
-associated setup. We control the variants with a switch.
-
-\starttyping
-\newcount\TestMode
-
-\TestMode=0 % expansion=xml
-\TestMode=1 % expansion=yes, index, setup
-\TestMode=2 % expansion=yes
-\stoptyping
-
-We apply a couple of setups:
-
-\starttyping
-\startxmlsetups xml:mysetups
- \xmlsetsetup{\xmldocument}{demo|index|content|chapter|title|em}{xml:*}
-\stopxmlsetups
-
-\xmlregistersetup{xml:mysetups}
-\stoptyping
-
-The main document is processed with:
-
-\starttyping
-\startxmlsetups xml:demo
- \xmlflush{#1}
- \subject{contents}
- \placelist[chapter][criterium=all]
- \subject{index}
- \placeregister[index][criterium=all]
- \page % else buffer is forgotten when placing header
-\stopxmlsetups
-\stoptyping
-
-First we show three alternative ways to deal with the chapter. The first case
-expands the \XML\ reference so that we have an \XML\ stream in the auxiliary
-file. This stream is processed as a small independent subfile when needed. The
-second case registers a reference to the current element (\type {#1}). This means
-that we have access to all data of this element, like attributes, title and
-content. What happens depends on the given setup. The third variant does the same
-but here the setup is part of the reference.
-
-\starttyping
-\startxmlsetups xml:chapter
- \ifcase \TestMode
- % xml code travels around
- \setuphead[chapter][expansion=xml]
- \startchapter[title=eh: \xmltext{#1}{title}]
- \xmlfirst{#1}{content}
- \stopchapter
- \or
- % index is used for access via setup
- \setuphead[chapter][expansion=yes,xmlsetup=xml:title:flush]
- \startchapter[title=\xmlgetindex{#1}]
- \xmlfirst{#1}{content}
- \stopchapter
- \or
- % tex call to xml using index is used
- \setuphead[chapter][expansion=yes]
- \startchapter[title=hm: \xmlreference{#1}{xml:title:flush}]
- \xmlfirst{#1}{content}
- \stopchapter
- \fi
-\stopxmlsetups
-
-\startxmlsetups xml:title:flush
- \xmltext{#1}{title}
-\stopxmlsetups
-\stoptyping
-
-We need to deal with emphasis and the content of the chapter.
-
-\starttyping
-\startxmlsetups xml:em
- \begingroup\em\xmlflush{#1}\endgroup
-\stopxmlsetups
-
-\startxmlsetups xml:content
- \xmlflush{#1}
-\stopxmlsetups
-\stoptyping
-
-A similar approach is followed with the index entries. Watch how we use the
-numbered entries variant (in this case we could also have used just \type
-{entries} and \type {keys}).
-
-\starttyping
-\startxmlsetups xml:index
- \ifcase \TestMode
- \setupregister[index][expansion=xml,xmlsetup=]
- \setstructurepageregister
- [index]
- [entries:1=\xmlfirst{#1}{content},
- keys:1=\xmltext{#1}{key}]
- \or
- \setupregister[index][expansion=yes,xmlsetup=xml:index:flush]
- \setstructurepageregister
- [index]
- [entries:1=\xmlgetindex{#1},
- keys:1=\xmltext{#1}{key}]
- \or
- \setupregister[index][expansion=yes,xmlsetup=]
- \setstructurepageregister
- [index]
- [entries:1=\xmlreference{#1}{xml:index:flush},
- keys:1=\xmltext{#1}{key}]
- \fi
-\stopxmlsetups
-
-\startxmlsetups xml:index:flush
- \xmlfirst{#1}{content}
-\stopxmlsetups
-\stoptyping
-
-Instead of this flush, you can use the predefined setup \type {xml:flush}
-unless it is overloaded by you.
-
-The file is processed by:
-
-\starttyping
-\starttext
- \xmlprocessfile{main}{test.xml}{}
-\stoptext
-\stoptyping
-
-We don't show the result here. If you're curious what the output is, you can test
-it yourself. In that case it also makes sense to peek into the \type {test.tuc}
-file to see how the information travels around. The \type {metadata} fields carry
-information about how to process the data.
-
-The first case, the \XML\ expansion one, is somewhat special in the sense that
-internally we use small pseudo files. You can control the rendering by tweaking
-the following setups:
-
-\starttyping
-\startxmlsetups xml:ctx:sectionentry
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:ctx:registerentry
- \xmlflush{#1}
-\stopxmlsetups
-\stoptyping
-
-{\em When these methods work out okay the other structural elements will be
-dealt with in a similar way.}
-
-\stopsection
-
-\startsection[title={special cases}]
-
-Normally the content will be flushed under a special (so called) catcode regime.
-This means that characters that have a special meaning in \TEX\ will have no such
-meaning in an \XML\ file. If you want content to be treated as \TEX\ code, you can
-use one of the following:
-
-\startxmlcmd {\cmdbasicsetup{xmlflushcontext}}
- flush the given \cmdinternal {cd:node} using the \TEX\ character
- interpretation scheme
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlcontext}}
- flush the match of \cmdinternal {cd:lpath} for the given \cmdinternal
- {cd:node} using the \TEX\ character interpretation scheme
-\stopxmlcmd
-
-We use this in cases like:
-
-\starttyping
-....
- \xmlsetsetup {#1} {
- tm|texformula|
- } {xml:*}
-....
-
-\startxmlsetups xml:tm
- \mathematics{\xmlflushcontext{#1}}
-\stopxmlsetups
-
-\startxmlsetups xml:texformula
- \placeformula\startformula\xmlflushcontext{#1}\stopformula
-\stopxmlsetups
-\stoptyping
-
-\stopsection
-
-\startsection[title={collecting}]
-
-Say that your document has
-
-\starttyping
-<table>
- <tr>
- <td>foo</td>
- <td>bar<td>
- </tr>
-</table>
-\stoptyping
-
-And that you need to convert that to \TEX\ speak like:
-
-\starttyping
-\bTABLE
- \bTR
- \bTD foo \eTD
- \bTD bar \eTD
- \eTR
-\eTABLE
-\stoptyping
-
-A simple mapping is:
-
-\starttyping
-\startxmlsetups xml:table
- \bTABLE \xmlflush{#1} \eTABLE
-\stopxmlsetups
-\startxmlsetups xml:tr
- \bTR \xmlflush{#1} \eTR
-\stopxmlsetups
-\startxmlsetups xml:td
- \bTD \xmlflush{#1} \eTD
-\stopxmlsetups
-\stoptyping
-
-The \type {\bTD} command is a so called delimited command which means that it
-picks up its argument by looking for an \type {\eTD}. For the simple case here
-this works quite well because the flush is inside the pair. This is not the case
-in the following variant:
-
-\starttyping
-\startxmlsetups xml:td:start
- \bTD
-\stopxmlsetups
-\startxmlsetups xml:td:stop
- \eTD
-\stopxmlsetups
-\startxmlsetups xml:td
- \xmlsetup{#1}{xml:td:start}
- \xmlflush{#1}
- \xmlsetup{#1}{xml:td:stop}
-\stopxmlsetups
-\stoptyping
-
-When for some reason \TEX\ gets confused you can revert to a mechanism that
-collects content.
-
-\starttyping
-\startxmlsetups xml:td:start
- \startcollect
- \bTD
- \stopcollect
-\stopxmlsetups
-\startxmlsetups xml:td:stop
- \startcollect
- \eTD
- \stopcollect
-\stopxmlsetups
-\startxmlsetups xml:td
- \startcollecting
- \xmlsetup{#1}{xml:td:start}
- \xmlflush{#1}
- \xmlsetup{#1}{xml:td:stop}
- \stopcollecting
-\stopxmlsetups
-\stoptyping
-
-You can even implement solutions that effectively do this:
-
-\starttyping
-\startcollecting
- \startcollect \bTABLE \stopcollect
- \startcollect \bTR \stopcollect
- \startcollect \bTD \stopcollect
- \startcollect foo\stopcollect
- \startcollect \eTD \stopcollect
- \startcollect \bTD \stopcollect
- \startcollect bar\stopcollect
- \startcollect \eTD \stopcollect
- \startcollect \eTR \stopcollect
- \startcollect \eTABLE \stopcollect
-\stopcollecting
-\stoptyping
-
-Of course you only need to go that complex when the situation demands it. Here is
-another weird one:
-
-\starttyping
-\startcollecting
- \startcollect \setupsomething[\stopcollect
- \startcollect foo=\stopcollect
- \startcollect FOO,\stopcollect
- \startcollect bar=\stopcollect
- \startcollect BAR,\stopcollect
- \startcollect ]\stopcollect
-\stopcollecting
-\stoptyping
-
-\stopsection
-
-\startsection[title={selectors and injectors}]
-
-This section describes a bit special feature, one that we needed for a project
-where we could not touch the original content but could add specific sections for
-our own purpose. Hopefully the example demonstrates its useability.
-
-\enabletrackers[lxml.selectors]
-
-\startbuffer[foo]
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?context-directive message info 1: this is a demo file ?>
-<?context-message-directive info 2: this is a demo file ?>
-
-<one>
- <two>
- <?context-select begin t1 t2 t3 ?>
- <three>
- t1 t2 t3
- <?context-directive injector crlf t1 ?>
- t1 t2 t3
- </three>
- <?context-select end ?>
- <?context-select begin t4 ?>
- <four>
- t4
- </four>
- <?context-select end ?>
- <?context-select begin t8 ?>
- <four>
- t8.0
- t8.0
- </four>
- <?context-select end ?>
- <?context-include begin t4 ?>
- <!--
- <three>
- t4.t3
- <?context-directive injector crlf t1 ?>
- t4.t3
- </three>
- -->
- <three>
- t3
- <?context-directive injector crlf t1 ?>
- t3
- </three>
- <?context-include end ?>
- <?context-select begin t8 ?>
- <four>
- t8.1
- t8.1
- </four>
- <?context-select end ?>
- <?context-select begin t8 ?>
- <four>
- t8.2
- t8.2
- </four>
- <?context-select end ?>
- <?context-select begin t4 ?>
- <four>
- t4
- t4
- </four>
- <?context-select end ?>
- <?context-directive injector page t7 t8 ?>
- foo
- <?context-directive injector blank t1 ?>
- bar
- <?context-directive injector page t7 t8 ?>
- bar
- </two>
-</one>
-\stopbuffer
-
-\typebuffer[foo]
-
-First we show how to plug in a directive. Processing instructions like the
-following are normally ignored by an \XML\ processor, unless they make sense
-to it.
-
-\starttyping
-<?context-directive message info 1: this is a demo file ?>
-<?context-message-directive info 2: this is a demo file ?>
-\stoptyping
-
-We can define a message handler as follows:
-
-\startbuffer
-\def\MyMessage#1#2#3{\writestatus{#1}{#2 #3}}
-
-\xmlinstalldirective{message}{MyMessage}
-\stopbuffer
-
-\typebuffer \getbuffer
-
-When this file is processed you will see this on the console:
-
-\starttyping
-info > 1: this is a demo file
-info > 2: this is a demo file
-\stoptyping
-
-The file has some sections that can be used or ignored. The recipe for
-obeying \type {t1} and \type {t4} is the following:
-
-\startbuffer
-\xmlsetinjectors[t1]
-\xmlsetinjectors[t4]
-
-\startxmlsetups xml:initialize
- \xmlapplyselectors{#1}
- \xmlsetsetup {#1} {
- one|two|three|four
- } {xml:*}
-\stopxmlsetups
-
-\xmlregistersetup{xml:initialize}
-
-\startxmlsetups xml:one
- [ONE \xmlflush{#1} ONE]
-\stopxmlsetups
-
-\startxmlsetups xml:two
- [TWO \xmlflush{#1} TWO]
-\stopxmlsetups
-
-\startxmlsetups xml:three
- [THREE \xmlflush{#1} THREE]
-\stopxmlsetups
-
-\startxmlsetups xml:four
- [FOUR \xmlflush{#1} FOUR]
-\stopxmlsetups
-\stopbuffer
-
-\typebuffer \getbuffer
-
-This typesets:
-
-\startnarrower
-\xmlprocessbuffer{main}{foo}{}
-\stopnarrower
-
-The include coding is kind of special: it permits adding content (in a comment)
-and ignoring the rest so that we indeed can add something without interfering
-with the original. Of course in a normal workflow such messy solutions are
-not needed, but alas, often workflows are not that clean, especially when one
-has no real control over the source.
-
-\startxmlcmd {\cmdbasicsetup{xmlsetinjectors}}
- enables a list of injectors that will be used
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlresetinjectors}}
- resets the list of injectors
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlinjector}}
- expands an injection (command); normally this one is only used
- (in some setup) or for testing
-\stopxmlcmd
-
-\startxmlcmd {\cmdbasicsetup{xmlapplyselectors}}
- analyze the tree \cmdinternal {cd:node} for marked sections that
- will be injected
-\stopxmlcmd
-
-We have some injections predefined:
-
-\starttyping
-\startsetups xml:directive:injector:page
- \page
-\stopsetups
-
-\startsetups xml:directive:injector:column
- \column
-\stopsetups
-
-\startsetups xml:directive:injector:blank
- \blank
-\stopsetups
-\stoptyping
-
-In the example we see:
-
-\starttyping
-<?context-directive injector page t7 t8 ?>
-\stoptyping
-
-When we set \type {\xmlsetinjector[t7]} a pagebreak will injected in that spot.
-Tags like \type {t7}, \type {t8} etc.\ can represent versions.
-
-\stopsection
-
-\startsection[title=preprocessing]
-
-% local match = lpeg.match
-% local replacer = lpeg.replacer("BAD TITLE:","<bold>BAD TITLE:</bold>")
-%
-% function lxml.preprocessor(data,settings)
-% return match(replacer,data)
-% end
-
-\startbuffer[pre-code]
-\startluacode
- function lxml.preprocessor(data,settings)
- return string.find(data,"BAD TITLE:")
- and string.gsub(data,"BAD TITLE:","<bold>BAD TITLE:</bold>")
- or data
- end
-\stopluacode
-\stopbuffer
-
-\startbuffer[pre-xml]
-\startxmlsetups pre:demo:initialize
- \xmlsetsetup{#1}{*}{pre:demo:*}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{pre:demo}{pre:demo:initialize}
-
-\startxmlsetups pre:demo:root
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups pre:demo:bold
- \begingroup\bf\xmlflush{#1}\endgroup
-\stopxmlsetups
-
-\starttext
- \xmlprocessbuffer{pre:demo}{demo}{}
-\stoptext
-\stopbuffer
-
-Say that you have the following \XML\ setup:
-
-\typebuffer[pre-xml]
-
-and that (such things happen) the input looks like this:
-
-\startbuffer[demo]
-<root>
-BAD TITLE: crap crap crap ...
-
-BAD TITLE: crap crap crap ...
-</root>
-\stopbuffer
-
-\typebuffer[demo]
-
-You can then clean up these \type {BAD TITLE}'s as follows:
-
-\typebuffer[pre-code]
-
-and get as result:
-
-\start \getbuffer[pre-code,pre-xml] \stop
-
-The preprocessor function gets as second argument the current settings, an d
-the field \type {currentresource} can be used to limit the actions to
-specific resources, in our case it's \type {buffer: demo}. Afterwards you can
-reset the proprocessor with:
-
-\startluacode
-lxml.preprocessor = nil
-\stopluacode
-
-Future versions might give some more control over preprocessors. For now consider
-it to be a quick hack.
-
-\stopsection
-
-\stopchapter
-
-\startchapter[title={Lookups using lpaths}]
-
-\startsection[title={introduction}]
-
-There is not that much system in the following examples. They resulted from tests
-with different documents. The current implementation evolved out of the
-experimental code. For instance, I decided to add the multiple expressions in row
-handling after a few email exchanges with Jean|-|Michel Huffen.
-
-One of the main differences between the way \XSLT\ resolves a path and our way is
-the anchor. Take:
-
-\starttyping
-/something
-something
-\stoptyping
-
-The first one anchors in the current (!) element so it will only consider direct
-children. The second one does a deep lookup and looks at the descendants as well.
-Furthermore we have a few extra shortcuts like \type {**} in \type {a/**/b} which
-represents all descendants.
-
-The expressions (between square brackets) has to be valid \LUA\ and some
-preprocessing is done to resolve the built in functions. So, you might use code
-like:
-
-\starttyping
-my_lpeg_expression:match(text()) == "whatever"
-\stoptyping
-
-given that \type {my_lpeg_expression} is known. In the examples below we use the
-visualizer to show the steps. Some are shown more than once as part of a set.
-
-\stopsection
-
-\startsection[title={special cases}]
-
-\xmllshow{}
-\xmllshow{*}
-\xmllshow{.}
-\xmllshow{/}
-
-\stopsection
-
-\startsection[title={wildcards}]
-
-\xmllshow{*}
-\xmllshow{*:*}
-\xmllshow{/*}
-\xmllshow{/*:*}
-\xmllshow{*/*}
-\xmllshow{*:*/*:*}
-
-\xmllshow{a/*}
-\xmllshow{a/*:*}
-\xmllshow{/a/*}
-\xmllshow{/a/*:*}
-
-\xmllshow{/*}
-\xmllshow{/**}
-\xmllshow{/***}
-
-\stopsection
-
-\startsection[title={multiple steps}]
-
-\xmllshow{answer}
-\xmllshow{answer/test/*}
-\xmllshow{answer/test/child::}
-\xmllshow{answer/*}
-\xmllshow{answer/*[tag()='p' and position()=1 and text()!='']}
-
-\stopsection
-
-\startsection[title={pitfals}]
-
-\xmllshow{[oneof(lower(@encoding),'tex','context','ctx')]}
-\xmllshow{.[oneof(lower(@encoding),'tex','context','ctx')]}
-
-\stopsection
-
-\startsection[title={more special cases}]
-
-\xmllshow{**}
-\xmllshow{*}
-\xmllshow{..}
-\xmllshow{.}
-\xmllshow{//}
-\xmllshow{/}
-
-\xmllshow{**/}
-\xmllshow{**/*}
-\xmllshow{**/.}
-\xmllshow{**//}
-
-\xmllshow{*/}
-\xmllshow{*/*}
-\xmllshow{*/.}
-\xmllshow{*//}
-
-\xmllshow{/**/}
-\xmllshow{/**/*}
-\xmllshow{/**/.}
-\xmllshow{/**//}
-
-\xmllshow{/*/}
-\xmllshow{/*/*}
-\xmllshow{/*/.}
-\xmllshow{/*//}
-
-\xmllshow{./}
-\xmllshow{./*}
-\xmllshow{./.}
-\xmllshow{.//}
-
-\xmllshow{../}
-\xmllshow{../*}
-\xmllshow{../.}
-\xmllshow{..//}
-
-\stopsection
-
-\startsection[title={more wildcards}]
-
-\xmllshow{one//two}
-\xmllshow{one/*/two}
-\xmllshow{one/**/two}
-\xmllshow{one/***/two}
-\xmllshow{one/x//two}
-\xmllshow{one//x/two}
-\xmllshow{//x/two}
-
-\stopsection
-
-\startsection[title={special axis}]
-
-\xmllshow{descendant::whocares/ancestor::whoknows}
-\xmllshow{descendant::whocares/ancestor::whoknows/parent::}
-\xmllshow{descendant::whocares/ancestor::}
-\xmllshow{child::something/child::whatever/child::whocares}
-\xmllshow{child::something/child::whatever/child::whocares|whoknows}
-\xmllshow{child::something/child::whatever/child::(whocares|whoknows)}
-\xmllshow{child::something/child::whatever/child::!(whocares|whoknows)}
-\xmllshow{child::something/child::whatever/child::(whocares)}
-\xmllshow{child::something/child::whatever/child::(whocares)[position()>2]}
-\xmllshow{child::something/child::whatever[position()>2][position()=1]}
-\xmllshow{child::something/child::whatever[whocares][whocaresnot]}
-\xmllshow{child::something/child::whatever[whocares][not(whocaresnot)]}
-\xmllshow{child::something/child::whatever/self::whatever}
-
-There is also \type {last-match::} that starts with the last found set of nodes.
-This can save some run time when you do lots of tests combined with a same check
-afterwards. There is however one pitfall: you never know what is done with that
-last match in the setup that gets called nested. Take the following example:
-
-\starttyping
-\startbuffer[test]
-<something>
- <crap> <crapa> <crapb> <crapc> <crapd>
- <crape>
- done 1
- </crape>
- </crapd> </crapc> </crapb> </crapa>
- <crap> <crapa> <crapb> <crapc> <crapd>
- <crape>
- done 2
- </crape>
- </crapd> </crapc> </crapb> </crapa>
- <crap> <crapa> <crapb> <crapc> <crapd>
- <crape>
- done 3
- </crape>
- </crapd> </crapc> </crapb> </crapa>
-</something>
-\stopbuffer
-\stoptyping
-
-One way to filter the content is this:
-
-\starttyping
-\xmldoif {#1} {/crap/crapa/crapb/crapc/crapd/crape} {
- some action
-}
-\stoptyping
-
-It is not unlikely that you will do something like this:
-
-\starttyping
-\xmlfirst {#1} {/crap/crapa/crapb/crapc/crapd/crape} {
- \xmlfirst{#1}{/crap/crapa/crapb/crapc/crapd/crape}
-}
-\stoptyping
-
-This means that the path is resolved twice but that can be avoided as
-follows:
-
-\starttyping
-\xmldoif{#1}{/crap/crapa/crapb/crapc/crapd/crape}{
- \xmlfirst{#1}{last-match::}
-}
-\stoptyping
-
-But the next is now guaranteed to work:
-
-\starttyping
-\xmldoif{#1}{/crap/crapa/crapb/crapc/crapd/crape}{
- \xmlfirst{#1}{last-match::}
- \xmllast{#1}{last-match::}
-}
-\stoptyping
-
-Because the first one can have done some lookup the last match can be replaced
-and the second call will give unexpected results. You can overcome this with:
-
-\starttyping
-\xmldoif{#1}{/crap/crapa/crapb/crapc/crapd/crape}{
- \xmlpushmatch
- \xmlfirst{#1}{last-match::}
- \xmlpopmatch
-}
-\stoptyping
-
-Does it pay off? Here are some timings of a 10.000 times text and lookup
-like the previous (on a decent Januari 2016 laptop):
-
-\starttabulate[|r|l|]
-\NC 0.239 \NC \type {\xmldoif {...} {...}} \NC \NR
-\NC 0.292 \NC \type {\xmlfirst {...} {...}} \NC \NR
-\NC 0.538 \NC \type {\xmldoif {...} {...} + \xmlfirst {...} {...}} \NC \NR
-\NC 0.338 \NC \type {\xmldoif {...} {...} + \xmlfirst {...} {last-match::}} \NC \NR
-\NC 0.349 \NC \type {+ \xmldoif {...} {...} + \xmlfirst {...} {last-match::}-} \NC \NR
-\stoptabulate
-
-So, pushing and popping (the last row) is a bit slower than not doing that but it
-is still much faster than not using \type {last-match::} at all. As a shortcut
-you can use \type {=}, as in:
-
-\starttyping
-\xmlfirst{#1}{=}
-\stoptyping
-
-You can even do this:
-
-\starttyping
-\xmlall{#1}{last-match::/text()}
-\stoptyping
-
-or
-
-\starttyping
-\xmlall{#1}{=/text()}
-\stoptyping
-
-
-\stopsection
-
-\startsection[title={some more examples}]
-
-\xmllshow{/something/whatever}
-\xmllshow{something/whatever}
-\xmllshow{/**/whocares}
-\xmllshow{whoknows/whocares}
-\xmllshow{whoknows}
-\xmllshow{whocares[contains(text(),'f') or contains(text(),'g')]}
-\xmllshow{whocares/first()}
-\xmllshow{whocares/last()}
-\xmllshow{whatever/all()}
-\xmllshow{whocares/position(2)}
-\xmllshow{whocares/position(-2)}
-\xmllshow{whocares[1]}
-\xmllshow{whocares[-1]}
-\xmllshow{whocares[2]}
-\xmllshow{whocares[-2]}
-\xmllshow{whatever[3]/attribute(id)}
-\xmllshow{whatever[2]/attribute('id')}
-\xmllshow{whatever[3]/text()}
-\xmllshow{/whocares/first()}
-\xmllshow{/whocares/last()}
-
-\xmllshow{xml://whatever/all()}
-\xmllshow{whatever/all()}
-\xmllshow{//whocares}
-\xmllshow{..[2]}
-\xmllshow{../*[2]}
-
-\xmllshow{/(whocares|whocaresnot)}
-\xmllshow{/!(whocares|whocaresnot)}
-\xmllshow{/!whocares}
-
-\xmllshow{/interface/command/command(xml:setups:register)}
-\xmllshow{/interface/command[@name='xxx']/command(xml:setups:typeset)}
-\xmllshow{/arguments/*}
-\xmllshow{/sequence/first()}
-\xmllshow{/arguments/text()}
-\xmllshow{/sequence/variable/first()}
-\xmllshow{/interface/define[@name='xxx']/first()}
-\xmllshow{/parameter/command(xml:setups:parameter:measure)}
-
-\xmllshow{/(*:library|figurelibrary)/*:figure/*:label}
-\xmllshow{/(*:library|figurelibrary)/figure/*:label}
-\xmllshow{/(*:library|figurelibrary)/figure/label}
-\xmllshow{/(*:library|figurelibrary)/figure:*/label}
-
-\xmlshow {whatever//br[tag(1)='br']}
-
-\stopsection
-
-\stopchapter
-
-\startchapter[title=Examples]
-
-\startsection[title=attribute chains]
-
-In \CSS, when an attribute is not present, the parent element is checked, and when
-not found again, the lookup follows the chain till a match is found or the root is
-reached. The following example demonstrates how such a chain lookup works.
-
-\startbuffer[test]
-<something mine="1" test="one" more="alpha">
- <whatever mine="2" test="two">
- <whocares mine="3">
- <!-- this is a test -->
- </whocares>
- </whatever>
-</something>
-\stopbuffer
-
-\typebuffer[test]
-
-We apply the following setups to this tree:
-
-\startbuffer[setups]
-\startxmlsetups xml:common
- [
- \xmlchainatt{#1}{mine},
- \xmlchainatt{#1}{test},
- \xmlchainatt{#1}{more},
- \xmlchainatt{#1}{none}
- ]\par
-\stopxmlsetups
-
-\startxmlsetups xml:something
- something: \xmlsetup{#1}{xml:common}
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:whatever
- whatever: \xmlsetup{#1}{xml:common}
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:whocares
- whocares: \xmlsetup{#1}{xml:common}
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:mysetups
- \xmlsetsetup{#1}{something|whatever|whocares}{xml:*}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{example-1}{xml:mysetups}
-
-\xmlprocessbuffer{example-1}{test}{}
-\stopbuffer
-
-\typebuffer[setups]
-
-This gives:
-
-\start
- \getbuffer[setups]
-\stop
-
-\stopsection
-
-\startsection[title=conditional setups]
-
-Say that we have this code:
-
-\starttyping
-\xmldoifelse {#1} {/what[@a='1']} {
- \xmlfilter {#1} {/what/command('xml:yes')}
-} {
- \xmlfilter {#1} {/what/command('xml:nop')}
-}
-\stoptyping
-
-Here we first determine if there is a child \type {what} with attribute \type {a}
-set to \type {1}. Depending on the outcome again we check the child nodes for
-being named \type {what}. A faster solution which also takes less code is this:
-
-\starttyping
-\xmlfilter {#1} {/what[@a='1']/command('xml:yes','xml:nop')}
-\stoptyping
-
-\stopsection
-
-\startsection[title=manipulating]
-
-Assume that we have the following \XML\ data:
-
-\startbuffer[test]
-<A>
- <B>right</B>
- <B>wrong</B>
-</A>
-\stopbuffer
-
-\typebuffer[test]
-
-But, instead of \type {right} we want to see \type {okay}. We can do that with a
-finalizer:
-
-\startbuffer
-\startluacode
-local rehash = {
- ["right"] = "okay",
-}
-
-function xml.finalizers.tex.Okayed(collected,what)
- for i=1,#collected do
- if what == "all" then
- local str = xml.text(collected[i])
- context(rehash[str] or str)
- else
- context(str)
- end
- end
-end
-\stopluacode
-\stopbuffer
-
-\typebuffer \getbuffer
-
-\startbuffer
-\startxmlsetups xml:A
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:B
- (It's \xmlfilter{#1}{./Okayed("all")})
-\stopxmlsetups
-
-\startxmlsetups xml:testsetups
- \xmlsetsetup{#1}{A|B}{xml:*}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{example-2}{xml:testsetups}
-\xmlprocessbuffer{example-2}{test}{}
-\stopbuffer
-
-\typebuffer
-
-The result is: \start \inlinebuffer \stop
-
-\stopsection
-
-\startsection[title=cross referencing]
-
-A rather common way to add cross references to \XML\ files is to borrow the
-asymmetrical id's from \HTML. This means that one cannot simply use a value
-of (say) \type {href} to locate an \type {id}. The next example came up on
-the \CONTEXT\ mailing list.
-
-\startbuffer[test]
-<doc>
- <p>Text
- <a href="#fn1" class="footnoteref" id="fnref1"><sup>1</sup></a> and
- <a href="#fn2" class="footnoteref" id="fnref2"><sup>2</sup></a>
- </p>
- <div class="footnotes">
- <hr />
- <ol>
- <li id="fn1"><p>A footnote.<a href="#fnref1">↩</a></p></li>
- <li id="fn2"><p>A second footnote.<a href="#fnref2">↩</a></p></li>
- </ol>
- </div>
-</doc>
-\stopbuffer
-
-\typebuffer[test]
-
-We give two variants for dealing with such references. The first solution does
-lookups and depending on the size of the file can be somewhat inefficient.
-
-\startbuffer
-\startxmlsetups xml:doc
- \blank
- \xmlflush{#1}
- \blank
-\stopxmlsetups
-
-\startxmlsetups xml:p
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:footnote
- (variant 1)\footnote
- {\xmlfirst
- {example-3-1}
- {div[@class='footnotes']/ol/li[@id='\xmlrefatt{#1}{href}']}}
-\stopxmlsetups
-
-\startxmlsetups xml:initialize
- \xmlsetsetup{#1}{p|doc}{xml:*}
- \xmlsetsetup{#1}{a[@class='footnoteref']}{xml:footnote}
- \xmlsetsetup{#1}{div[@class='footnotes']}{xml:nothing}
-\stopxmlsetups
-
-\xmlresetdocumentsetups{*}
-\xmlregisterdocumentsetup{example-3-1}{xml:initialize}
-
-\xmlprocessbuffer{example-3-1}{test}{}
-\stopbuffer
-
-\typebuffer
-
-This will typeset two footnotes.
-
-\getbuffer
-
-The second variant collects the references so that the time spend on lookups is
-less.
-
-\startbuffer
-\startxmlsetups xml:doc
- \blank
- \xmlflush{#1}
- \blank
-\stopxmlsetups
-
-\startxmlsetups xml:p
- \xmlflush{#1}
-\stopxmlsetups
-
-\startluacode
- userdata.notes = {}
-\stopluacode
-
-\startxmlsetups xml:collectnotes
- \ctxlua{userdata.notes['\xmlrefatt{#1}{id}'] = '#1'}
-\stopxmlsetups
-
-\startxmlsetups xml:footnote
- (variant 2)\footnote
- {\xmlflush
- {\cldcontext{userdata.notes['\xmlrefatt{#1}{href}']}}}
-\stopxmlsetups
-
-\startxmlsetups xml:initialize
- \xmlsetsetup{#1}{p|doc}{xml:*}
- \xmlsetsetup{#1}{a[@class='footnoteref']}{xml:footnote}
- \xmlfilter{#1}{div[@class='footnotes']/ol/li/command(xml:collectnotes)}
- \xmlsetsetup{#1}{div[@class='footnotes']}{}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{example-3-2}{xml:initialize}
-
-\xmlprocessbuffer{example-3-2}{test}{}
-\stopbuffer
-
-\typebuffer
-
-This will again typeset two footnotes:
-
-\getbuffer
-
-\stopsection
-
-\startsection[title=mapping values]
-
-One way to process options \type {frame} in the example below is to map the
-values to values known by \CONTEXT.
-
-\startbuffer[test]
-<a>
- <nattable frame="on">
- <tr><td>#1</td><td>#2</td><td>#3</td><td>#4</td></tr>
- <tr><td>#5</td><td>#6</td><td>#7</td><td>#8</td></tr>
- </nattable>
- <nattable frame="off">
- <tr><td>#1</td><td>#2</td><td>#3</td><td>#4</td></tr>
- <tr><td>#5</td><td>#6</td><td>#7</td><td>#8</td></tr>
- </nattable>
- <nattable frame="no">
- <tr><td>#1</td><td>#2</td><td>#3</td><td>#4</td></tr>
- <tr><td>#5</td><td>#6</td><td>#7</td><td>#8</td></tr>
- </nattable>
-</a>
-\stopbuffer
-
-\typebuffer[test]
-
-\startbuffer
-\startxmlsetups xml:a
- \xmlflush{#1}
-\stopxmlsetups
-
-\xmlmapvalue {nattable:frame} {on} {on}
-\xmlmapvalue {nattable:frame} {yes} {on}
-\xmlmapvalue {nattable:frame} {off} {off}
-\xmlmapvalue {nattable:frame} {no} {off}
-
-\startxmlsetups xml:nattable
- \startplacetable[title=#1]
- \setupTABLE[frame=\xmlval{nattable:frame}{\xmlatt{#1}{frame}}{on}]%
- \bTABLE
- \xmlflush{#1}
- \eTABLE
- \stopplacetable
-\stopxmlsetups
-
-\startxmlsetups xml:tr
- \bTR
- \xmlflush{#1}
- \eTR
-\stopxmlsetups
-
-\startxmlsetups xml:td
- \bTD
- \xmlflush{#1}
- \eTD
-\stopxmlsetups
-
-\startxmlsetups xml:testsetups
- \xmlsetsetup{example-4}{a|nattable|tr|td|}{xml:*}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{example-4}{xml:testsetups}
-
-\xmlprocessbuffer{example-4}{test}{}
-\stopbuffer
-
-The \type {\xmlmapvalue} mechanism is rather efficient and involves a minimum
-of testing.
-
-\typebuffer
-
-We get:
-
-\getbuffer
-
-\stopsection
-
-\startsection[title=using \LUA]
-
-In this example we demonstrate how you can delegate rendering to \LUA. We
-will construct a so called extreme table. The input is:
-
-\startbuffer[demo]
-<?xml version="1.0" encoding="utf-8"?>
-
-<a>
- <b> <c>1</c> <d>Text</d> </b>
- <b> <c>2</c> <d>More text</d> </b>
- <b> <c>2</c> <d>Even more text</d> </b>
- <b> <c>2</c> <d>And more</d> </b>
- <b> <c>3</c> <d>And even more</d> </b>
- <b> <c>2</c> <d>The last text</d> </b>
-</a>
-\stopbuffer
-
-\typebuffer[demo]
-
-The processor code is:
-
-\startbuffer[process]
-\startxmlsetups xml:test_setups
- \xmlsetsetup{#1}{a|b|c|d}{xml:*}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{example-5}{xml:test_setups}
-
-\xmlprocessbuffer{example-5}{demo}{}
-\stopbuffer
-
-\typebuffer
-
-We color a sequence of the same titles (numbers here) differently. The first
-solution remembers the last title:
-
-\startbuffer
-\startxmlsetups xml:a
- \startembeddedxtable
- \xmlflush{#1}
- \stopembeddedxtable
-\stopxmlsetups
-
-\startxmlsetups xml:b
- \xmlfunction{#1}{test_ba}
-\stopxmlsetups
-
-\startluacode
-local lasttitle = nil
-
-function xml.functions.test_ba(t)
- local title = xml.text(t, "/c")
- local content = xml.text(t, "/d")
- context.startxrow()
- context.startxcell {
- background = "color",
- backgroundcolor = lasttitle == title and "colorone" or "colortwo",
- foregroundstyle = "bold",
- foregroundcolor = "white",
- }
- context(title)
- lasttitle = title
- context.stopxcell()
- context.startxcell()
- context(content)
- context.stopxcell()
- context.stopxrow()
-end
-\stopluacode
-\stopbuffer
-
-\typebuffer \getbuffer
-
-The \type {embeddedxtable} environment is needed because the table is picked up
-as argument.
-
-\startlinecorrection \getbuffer[process] \stoplinecorrection
-
-The second implemetation remembers what titles are already processed so here we
-can color the last one too.
-
-\startbuffer
-\startxmlsetups xml:a
- \ctxlua{xml.functions.reset_bb()}
- \startembeddedxtable
- \xmlflush{#1}
- \stopembeddedxtable
-\stopxmlsetups
-
-\startxmlsetups xml:b
- \xmlfunction{#1}{test_bb}
-\stopxmlsetups
-
-\startluacode
-local titles
-
-function xml.functions.reset_bb(t)
- titles = { }
-end
-
-function xml.functions.test_bb(t)
- local title = xml.text(t, "/c")
- local content = xml.text(t, "/d")
- context.startxrow()
- context.startxcell {
- background = "color",
- backgroundcolor = titles[title] and "colorone" or "colortwo",
- foregroundstyle = "bold",
- foregroundcolor = "white",
- }
- context(title)
- titles[title] = true
- context.stopxcell()
- context.startxcell()
- context(content)
- context.stopxcell()
- context.stopxrow()
-end
-\stopluacode
-\stopbuffer
-
-\typebuffer \getbuffer
-
-\startlinecorrection \getbuffer[process] \stoplinecorrection
-
-A solution without any state variable is given below.
-
-\startbuffer
-\startxmlsetups xml:a
- \startembeddedxtable
- \xmlflush{#1}
- \stopembeddedxtable
-\stopxmlsetups
-
-\startxmlsetups xml:b
- \xmlfunction{#1}{test_bc}
-\stopxmlsetups
-
-\startluacode
-function xml.functions.test_bc(t)
- local title = xml.text(t, "/c")
- local content = xml.text(t, "/d")
- context.startxrow()
- local okay = xml.text(t,"./preceding-sibling::/[-1]") == title
- context.startxcell {
- background = "color",
- backgroundcolor = okay and "colorone" or "colortwo",
- foregroundstyle = "bold",
- foregroundcolor = "white",
- }
- context(title)
- context.stopxcell()
- context.startxcell()
- context(content)
- context.stopxcell()
- context.stopxrow()
-end
-\stopluacode
-\stopbuffer
-
-\typebuffer \getbuffer
-
-\startlinecorrection \getbuffer[process] \stoplinecorrection
-
-Here is a solution that delegates even more to \LUA. The previous variants were
-actually not that safe with repect to special characters and didn't handle
-nested elements either but the next one does.
-
-\startbuffer[demo]
-<?xml version="1.0" encoding="utf-8"?>
-
-<a>
- <b> <c>#1</c> <d>Text</d> </b>
- <b> <c>#2</c> <d>More text</d> </b>
- <b> <c>#2</c> <d>Even more text</d> </b>
- <b> <c>#2</c> <d>And more</d> </b>
- <b> <c>#3</c> <d>And even more</d> </b>
- <b> <c>#2</c> <d>Something <i>nested</i> </d> </b>
-</a>
-\stopbuffer
-
-\typebuffer[demo]
-
-We also need to map the \type {i} element.
-
-\startbuffer
-\startxmlsetups xml:a
- \starttexcode
- \xmlfunction{#1}{test_a}
- \stoptexcode
-\stopxmlsetups
-
-\startxmlsetups xml:c
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:d
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:i
- {\em\xmlflush{#1}}
-\stopxmlsetups
-
-\startluacode
-function xml.functions.test_a(t)
- context.startxtable()
- local previous = false
- for b in xml.collected(lxml.getid(t),"/b") do
- context.startxrow()
- local current = xml.text(b,"/c")
- context.startxcell {
- background = "color",
- backgroundcolor = (previous == current) and "colorone" or "colortwo",
- foregroundstyle = "bold",
- foregroundcolor = "white",
- }
- lxml.first(b,"/c")
- context.stopxcell()
- context.startxcell()
- lxml.first(b,"/d")
- context.stopxcell()
- previous = current
- context.stopxrow()
- end
- context.stopxtable()
-end
-\stopluacode
-
-\startxmlsetups xml:test_setups
- \xmlsetsetup{#1}{a|b|c|d|i}{xml:*}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{example-5}{xml:test_setups}
-
-\xmlprocessbuffer{example-5}{demo}{}
-\stopbuffer
-
-\typebuffer
-
-\startlinecorrection \getbuffer \stoplinecorrection
-
-The question is, do we really need \LUA ? Often we don't, apart maybe from an
-occasional special finalizer. A pure \TEX\ solution is given next:
-
-\startbuffer
-\startxmlsetups xml:a
- \glet\MyPreviousTitle\empty
- \glet\MyCurrentTitle \empty
- \startembeddedxtable
- \xmlflush{#1}
- \stopembeddedxtable
-\stopxmlsetups
-
-\startxmlsetups xml:b
- \startxrow
- \xmlflush{#1}
- \stopxrow
-\stopxmlsetups
-
-\startxmlsetups xml:c
- \xdef\MyCurrentTitle{\xmltext{#1}{.}}
- \doifelse {\MyPreviousTitle} {\MyCurrentTitle} {
- \startxcell
- [background=color,
- backgroundcolor=colorone,
- foregroundstyle=bold,
- foregroundcolor=white]
- } {
- \glet\MyPreviousTitle\MyCurrentTitle
- \startxcell
- [background=color,
- backgroundcolor=colortwo,
- foregroundstyle=bold,
- foregroundcolor=white]
- }
- \xmlflush{#1}
- \stopxcell
-\stopxmlsetups
-
-\startxmlsetups xml:d
- \startxcell
- \xmlflush{#1}
- \stopxcell
-\stopxmlsetups
-
-\startxmlsetups xml:i
- {\em\xmlflush{#1}}
-\stopxmlsetups
-
-\startxmlsetups xml:test_setups
- \xmlsetsetup{#1}{*}{xml:*}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{example-5}{xml:test_setups}
-
-\xmlprocessbuffer{example-5}{demo}{}
-\stopbuffer
-
-\typebuffer
-
-\startlinecorrection \getbuffer \stoplinecorrection
-
-You can even save a few lines of code:
-
-\starttyping
-\startxmlsetups xml:c
- \xdef\MyCurrentTitle{\xmltext{#1}{.}}
- \startxcell
- [background=color,
- backgroundcolor=color\ifx\MyPreviousTitle\MyCurrentTitle one\else two\fi,
- foregroundstyle=bold,
- foregroundcolor=white]
- \xmlflush{#1}
- \stopxcell
- \glet\MyPreviousTitle\MyCurrentTitle
-\stopxmlsetups
-\stoptyping
-
-Or if you prefer:
-
-\starttyping
-\startxmlsetups xml:c
- \xdef\MyCurrentTitle{\xmltext{#1}{.}}
- \doifelse {\MyPreviousTitle} {\MyCurrentTitle} {
- \xmlsetup{#1}{xml:c:one}
- } {
- \xmlsetup{#1}{xml:c:two}
- }
-\stopxmlsetups
-
-\startxmlsetups xml:c:one
- \startxcell
- [background=color,
- backgroundcolor=colorone,
- foregroundstyle=bold,
- foregroundcolor=white]
- \xmlflush{#1}
- \stopxcell
-\stopxmlsetups
-
-\startxmlsetups xml:c:two
- \startxcell
- [background=color,
- backgroundcolor=colortwo,
- foregroundstyle=bold,
- foregroundcolor=white]
- \xmlflush{#1}
- \stopxcell
- \global\let\MyPreviousTitle\MyCurrentTitle
-\stopxmlsetups
-\stoptyping
-
-These examples demonstrate that it doesn't hurt to know a little bit of \TEX\
-programming: defining macros and basic comparisons can come in handy. There are
-examples in the test suite, you can peek in the source code, you can consult
-the wiki or you can just ask on the list.
-
-\stopsection
-
-\startsection[title=last match]
-
-For the next example we use the following \XML\ input:
-
-\startbuffer[demo]
-<?xml version "1.0"?>
-<document>
- <section id="1">
- <content>
- <p>first</p>
- <p>second</p>
- </content>
- </section>
- <section id="2">
- <content>
- <p>third</p>
- <p>fourth</p>
- </content>
- </section>
-</document>
-\stopbuffer
-
-\typebuffer[demo]
-
-If you check if some element is present and then act accordingly, you can
-end up with doing the same lookup twice. Although it might sound inefficient,
-in practice it's often not measureable.
-
-\startbuffer
-\startxmlsetups xml:demo:document
- \type{\xmlall{#1}{/section[@id='2']/content/p}}\par
- \xmldoif{#1}{/section[@id='2']/content/p} {
- \xmlall{#1}{/section[@id='2']/content/p}
- }
- \type{\xmllastmatch}\par
- \xmldoif{#1}{/section[@id='2']/content/p} {
- \xmllastmatch
- }
- \type{\xmlall{#1}{last-match::}}\par
- \xmldoif{#1}{/section[@id='2']/content/p} {
- \xmlall{#1}{last-match::}
- }
- \type{\xmlfilter{#1}{last-match::/command(xml:demo:p)}}\par
- \xmldoif{#1}{/section[@id='2']/content/p} {
- \xmlfilter{#1}{last-match::/command(xml:demo:p)}
- }
-\stopxmlsetups
-
-\startxmlsetups xml:demo:p
- \quad\xmlflush{#1}\endgraf
-\stopxmlsetups
-
-\startxmlsetups xml:demo:base
- \xmlsetsetup{#1}{document|p}{xml:demo:*}
-\stopxmlsetups
-
-\xmlregisterdocumentsetup{example-6}{xml:demo:base}
-
-\xmlprocessbuffer{example-6}{demo}{}
-\stopbuffer
-
-\typebuffer
-
-In the second check we just flush the last match, so effective we do an \type
-{\xmlall} here. The third and fourth alternatives demonstrate how we can use
-\type {last-match} as axis. The gain is 10\% or more on the lookup but of course
-typesetting often takes relatively more time than the lookup.
-
-\startpacked
-\getbuffer
-\stoppacked
-
-\stopsection
-
-\startsection[title=Finalizers]
-
-The \XML\ parser is also available outside \TEX. Here is an example of its usage.
-We pipe the result to \TEX\ but you can do with \type {t} whatever you like.
-
-\startbuffer
-local x = xml.load("manual-demo-1.xml")
-local t = { }
-
-for c in xml.collected(x,"//*") do
- if not c.special and not t[c.tg] then
- t[c.tg] = true
- end
-end
-
-context.tocontext(table.sortedkeys(t))
-\stopbuffer
-
-\typebuffer
-
-This returns:
-
-\ctxluabuffer
-
-We can wrap this in a finalizer:
-
-\startbuffer
-xml.finalizers.taglist = function(collected)
- local t = { }
- for i=1,#collected do
- local c = collected[i]
- if not c.special then
- local tg = c.tg
- if tg and not t[tg] then
- t[tg] = true
- end
- end
- end
- return table.sortedkeys(t)
-end
-\stopbuffer
-
-\typebuffer
-
-Or in a more extensive one:
-
-\startbuffer
-xml.finalizers.taglist = function(collected,parenttoo)
- local t = { }
- for i=1,#collected do
- local c = collected[i]
- if not c.special then
- local tg = c.tg
- if tg and not t[tg] then
- t[tg] = true
- end
- if parenttoo then
- local p = c.__p__
- if p and not p.special then
- local tg = p.tg .. ":" .. tg
- if tg and not t[tg] then
- t[tg] = true
- end
- end
- end
- end
- end
- return table.sortedkeys(t)
-end
-\stopbuffer
-
-\typebuffer \ctxluabuffer
-
-Usage is as follows:
-
-\startbuffer
-local x = xml.load("manual-demo-1.xml")
-local t = xml.applylpath(x,"//*/taglist()")
-
-context.tocontext(t)
-\stopbuffer
-
-\typebuffer
-
-And indeed we get:
-
-\ctxluabuffer
-
-But we can also say:
-
-\startbuffer
-local x = xml.load("manual-demo-1.xml")
-local t = xml.applylpath(x,"//*/taglist(true)")
-
-context.tocontext(t)
-\stopbuffer
-
-\typebuffer
-
-Now we get:
-
-\ctxluabuffer
-
-\startsection[title=Pure xml]
-
-One might wonder how a \TEX\ macro package would look like when backslashes,
-dollars and percent signs would have no special meaning. In fact, it would be
-rather useless as interpreting commands are triggered by such characters. Any
-formatting or coding system needs such characters. Take \XML: angle brackets and
-ampersands are really special. So, no matter what system we use, we do have to
-deal with the (common) case where these characters need to be sees as they are.
-Normally escaping is the solution.
-
-The \CONTEXT\ interface for \XML\ suffers from this as well. You really don't
-want to know how many tricks are used for dealing with special characters and
-entities: there are several ways these travel through the system and it is
-possible to adapt and cheat. Especially roundtripped data (via tuc file) puts
-some demands on the system because when ts \XML\ can become \TEX\ and vise versa.
-The next example (derived from a mail on the list) demonstrates this:
-
-\starttyping
-\startbuffer[demo]
-<doc>
- <pre><code>\ConTeXt\ is great</code></pre>
-
- <pre><code>but you need to know some tricks</code></pre>
-</doc>
-\stopbuffer
-
-\startxmlsetups xml:initialize
- \xmlsetsetup{#1}{doc|p|code}{xml:*}
- \xmlsetsetup{#1}{pre/code}{xml:pre:code}
-\stopxmlsetups
-
-\xmlregistersetup{xml:initialize}
-
-\startxmlsetups xml:doc
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:pre:code
- no solution
- \comment[symbol=Key, location=inmargin,color=yellow]{\xmlflush{#1}}
- \par
- solution one \begingroup
- \expandUx
- \comment[symbol=Key, location=inmargin,color=yellow]{\xmlflush{#1}}
- \endgroup
- \par
- solution two
- \comment[symbol=Key, location=inmargin,color=yellow]{\xmlpure{#1}}
- \par
- \xmlprettyprint{#1}{tex}
-\stopxmlsetups
-
-\xmlprocessbuffer{main}{demo}{}
-\stoptyping
-
-The first comment (an interactive feature of \PDF\ comes out as:
-
-\starttyping
-\Ux {5C}ConTeXt\Ux {5C} is great
-\stoptyping
-
-The second and third comment are okay. It's one of the reasons why we have \type
-{\xmlpure}.
-
-\stopsection
-
-\stopchapter
-
+ \component xml-mkiv-converter
+ \component xml-mkiv-filtering
+ \component xml-mkiv-commands
+ \component xml-mkiv-expressions
+ \component xml-mkiv-tricks
+ \component xml-mkiv-lookups
+ \component xml-mkiv-examples
\stopbodymatter
\stoptext
diff --git a/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex b/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex
index 827ad3fcc..1b878e5cb 100644
--- a/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex
+++ b/doc/context/sources/general/manuals/xtables/xtables-mkiv.tex
@@ -1250,6 +1250,101 @@ you're lucky.
\stopsection
+\startsection[title={Swapping}]
+
+The next two examples demonstrate a feature added for Taco, who wanted to input
+vertical instead of horizontal. It's a bit of a hack but it works okay for
+simple cases. We assume these settings:
+
+\startbuffer[settings]
+\setupxtable[one] [foregroundcolor=darkred]
+\setupxtable[two] [foregroundcolor=darkgreen]
+\setupxtable[three][foregroundcolor=darkblue]
+\setupxtable[four] [foregroundcolor=darkorange]
+\stopbuffer
+
+\startbuffer[demo-1]
+\startxtable[frame=on]
+ \startxcolumn[one]
+ \startxcell A1 \stopxcell
+ \startxcell B1 \stopxcell
+ \startxcell C1 \stopxcell
+ \startxcell D1 \stopxcell
+ \startxcell E1 \stopxcell
+ \stopxcolumn
+ \startxcolumn[two]
+ \startxcell A2 \stopxcell
+ \startxcell B2 \stopxcell
+ \startxcell C2 \stopxcell
+ \startxcell D2 \stopxcell
+ \startxcell E2 \stopxcell
+ \stopxcolumn
+ \startxcolumn[three]
+ \startxcell A3 \stopxcell
+ \startxcell B3 \stopxcell
+ \startxcell C3 \stopxcell
+ \startxcell D3 \stopxcell
+ \startxcell E3 \stopxcell
+ \stopxcolumn
+ \startxcolumn[four]
+ \startxcell A4 \stopxcell
+ \startxcell B4 \stopxcell
+ \startxcell C4 \stopxcell
+ \startxcell D4 \stopxcell
+ \startxcell E4 \stopxcell
+ \stopxcolumn
+\stopxtable
+\stopbuffer
+
+\startbuffer[demo-2]
+\startxtable[frame=on]
+ \startxcolumn[one]
+ \startxcell A \stopxcell
+ \startxcell B \stopxcell
+ \startxcell C \stopxcell
+ \startxcell D \stopxcell
+ \startxcell E \stopxcell
+ \stopxcolumn
+ \startxcolumn[two]
+ \startxcell A \stopxcell
+ \startxcell[ny=2] BC \stopxcell
+ \startxcell[ny=2] DE \stopxcell
+ \stopxcolumn
+ \startxcolumn[three]
+ \startxcell A \stopxcell
+ \startxcell[ny=4] BCDE \stopxcell
+ \stopxcolumn
+ \startxcolumn[four]
+ \startxcell A \stopxcell
+ \startxcell B \stopxcell
+ \startxcell[ny=2] CD \stopxcell
+ \startxcell E \stopxcell
+ \stopxcolumn
+\stopxtable
+\stopbuffer
+
+\typebuffer[settings]
+
+The first example has no spans:
+
+\typebuffer[demo-1]
+
+while the second one has:
+
+\typebuffer[demo-2]
+
+The results are shown in \in {figure} [fig:swapped].
+
+\startplacefigure[title={Entering columns instead of rows.},reference=fig:swapped]
+ \getbuffer[settings]
+ \startcombination
+ {\getbuffer[demo-1]} {no spans}
+ {\getbuffer[demo-2]} {some spans}
+ \stopcombination
+\stopplacefigure
+
+\stopsection
+
\startsection[title={Examples}]
On the following pages we show some examples of (experimental) features. For this
diff --git a/metapost/context/base/mpii/mp-text.mpii b/metapost/context/base/mpii/mp-text.mpii
index 5f96f6788..b7787a42d 100644
--- a/metapost/context/base/mpii/mp-text.mpii
+++ b/metapost/context/base/mpii/mp-text.mpii
@@ -56,12 +56,11 @@ boolean hobbiestextext ; hobbiestextext := false ;
% enddef ;
vardef textext@#(expr txt) =
- save _s_ ; string _s_ ;
interim labeloffset := textextoffset ;
noftexpictures := noftexpictures + 1 ;
if string txt :
if hobbiestextext : % the tex.mp method as fallback (see tex.mp)
- write _s_ & "btex " & txt & " etex" to "mptextmp.mp" ;
+ write "btex " & txt & " etex" to "mptextmp.mp" ;
write EOF to "mptextmp.mp" ;
scantokens "input mptextmp"
else :
diff --git a/metapost/context/base/mpiv/metafun.mpiv b/metapost/context/base/mpiv/metafun.mpiv
index 818fd7c56..fa43d3460 100644
--- a/metapost/context/base/mpiv/metafun.mpiv
+++ b/metapost/context/base/mpiv/metafun.mpiv
@@ -38,6 +38,7 @@ input "mp-func.mpiv" ; % under construction
input "mp-node.mpiv" ; % relatively small so preloaded
input "mp-apos.mpiv" ;
input "mp-abck.mpiv" ;
+input "mp-blob.mpiv" ;
string metafunversion ; metafunversion =
"metafun iv" & " " &
diff --git a/metapost/context/base/mpiv/minifun.mpiv b/metapost/context/base/mpiv/minifun.mpiv
new file mode 100644
index 000000000..6d877fddb
--- /dev/null
+++ b/metapost/context/base/mpiv/minifun.mpiv
@@ -0,0 +1,45 @@
+%D \module
+%D [ file=minifun.mp,
+%D version=2018.06.02,
+%D title=\CONTEXT\ \METAPOST\ graphics,
+%D subtitle=format generation file,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is a minimal \METAFUN\ instance which can be handy for isolated
+%D subruns.
+
+prologues := 0 ;
+mpprocset := 1 ;
+
+input "mp-base.mpiv" ;
+input "mp-tool.mpiv" ;
+input "mp-mlib.mpiv" ;
+input "mp-luas.mpiv" ;
+input "mp-page.mpiv" ;
+
+string minifunversion ; minifunversion =
+ "minifun iv" & " " &
+ decimal year & "-" &
+ decimal month & "-" &
+ decimal day & " " &
+ if ((time div 60) < 10) : "0" & fi
+ decimal (time div 60) & ":" &
+ if ((time-(time div 60)*60) < 10) : "0" & fi
+ decimal (time-(time div 60)*60) ;
+
+let normalend = end ;
+
+if known mplib :
+ def end = ; message "" ; message minifunversion ; message "" ; endinput ; enddef ;
+ def bye = ; message "" ; message minifunversion ; message "" ; endinput ; enddef ;
+else :
+ def end = ; message "" ; message minifunversion ; message "" ; normalend ; enddef ;
+fi ;
+
+% dump ; % obsolete in mplib
diff --git a/metapost/context/base/mpiv/mp-asnc.mpiv b/metapost/context/base/mpiv/mp-asnc.mpiv
index fba182a64..2eb409124 100644
--- a/metapost/context/base/mpiv/mp-asnc.mpiv
+++ b/metapost/context/base/mpiv/mp-asnc.mpiv
@@ -15,163 +15,103 @@ if known context_asnc : endinput ; fi ;
boolean context_asnc ; context_asnc := true ;
-% will be replaced
-
-numeric sync_n[], sync_p[][], sync_w[][], sync_h[][], sync_d[][], sync_t[][] ;
-pair sync_xy[][] ; color sync_c[][] ;
-
-def ResetSyncTasks =
- path SyncPaths[] ; numeric SyncTasks[], NOfSyncPaths, CurrentSyncClass ;
- NOfSyncPaths := CurrentSyncClass := 0 ;
- if unknown SyncLeftOffset : numeric SyncLeftOffset ; SyncLeftOffset := 0 ; fi ;
- if unknown SyncWidth : numeric SyncWidth ; SyncWidth := 0 ; fi ;
- if unknown SyncThreshold : numeric SyncThreshold ; SyncThreshold := LineHeight ; fi ;
- if unknown SyncColor : color SyncColor ; SyncColor := .5white ; fi ;
- if (SyncLeftOffset = 0) and (SyncWidth = 0) :
- SyncWidth := if known TextWidth : TextWidth else : -1cm fi ;
+%D This is a rather old mechanism that we once needed in an actually nice
+%D design. Those were the times that processing a rather complex xml file
+%D with pdftex into a 400 page document took 45 minutes (a few runs) while
+%D nowadays with luatex and mkiv we express runtime in seconds.
+%D
+%D The logic is mostly the same but some work is delegated to Lua so that
+%D we save memory and also run faster. As this was not really a used module
+%D the interface also was upgraded. As we know the bottlenecks in mp we also
+%D work around it a bit.
+
+numeric mfun_sync_count ;
+numeric mfun_sync_page ;
+
+vardef StartSync(expr n) =
+ numeric CurrentSyncClass ; CurrentSyncClass := n ;
+ numeric SyncHOffset ; SyncHOffset := 0 ;
+ numeric SyncVOffset ; SyncVOffset := 0 ;
+ numeric SyncWidth ; SyncWidth := 0 ;
+ path SyncPaths[] ;
+ numeric SyncTasks[] ;
+ numeric SyncKinds[] ;
+ %
+ mfun_sync_page := RealPageNumber ;
+ mfun_sync_count := 0 ;
+enddef ;
+
+def StopSync =
+ % maybe some cleanup
+enddef ;
+
+vardef CollectSyncDataPage =
+ mfun_sync_count := lua.mp.sync_collect(CurrentSyncClass,mfun_sync_page) ;
+enddef ;
+
+vardef CollectSyncDataRegion(expr region) =
+ mfun_sync_count := lua.mp.sync_collect(CurrentSyncClass,mfun_sync_page,region) ;
+enddef ;
+
+vardef MakeSyncPaths =
+ if mfun_sync_count > 0 :
+ save k, t, b ;
+ save l ; l := SyncHOffset ;
+ save r ; r := SyncHOffset + SyncWidth ;
+ save y ; y := lua.mp.sync_get_y() + SyncVOffset ;
+ for i=1 upto mfun_sync_count :
+ k := lua.mp.sync_get_kind(i) ;
+ t := lua.mp.sync_get_top(i) - y ;
+ b := lua.mp.sync_get_bottom(i) - y ;
+ SyncPaths[i] = ((l,t) -- (r,t) -- (r,b) -- (l,b) -- cycle) ;
+ SyncTasks[i] = lua.mp.sync_get_task(i) ;
+ SyncKinds[i] = k ;
+ endfor ;
fi ;
enddef ;
-ResetSyncTasks ;
+% Extend to the top of the text area.
-vardef SyncBox(expr n, i, leftoffset, width, topoffset, bottomoffset) =
- save o ; pair o ; o := (xpart llcorner PlainTextArea,ypart sync_xy[n][i]) ;
- o shifted (leftoffset,sync_h[n][i]+topoffset) --
- o shifted (width+leftoffset,sync_h[n][i]+topoffset) --
- o shifted (width+leftoffset,bottomoffset) --
- o shifted (leftoffset,bottomoffset) -- cycle
+vardef ExtendSyncPaths =
+ mfun_sync_count := lua.mp.sync_extend() ;
enddef ;
-def SetSyncColor(expr n, i, c) =
- sync_c[n][i] := c ;
+% Clip to the text area.
+
+vardef PruneSyncPaths =
+ mfun_sync_count := lua.mp.sync_prune() ;
enddef ;
-def SetSyncThreshold(expr n, i, th) =
- sync_th[n][i] := th ;
+% Remove duplicate tasks
+
+vardef CollapseSyncPaths =
+ mfun_sync_count := lua.mp.sync_collapse() ;
enddef ;
-vardef TheSyncColor(expr n, i) =
- if known sync_c[n][i] : sync_c[n][i] else : SyncColor fi
+def SetSyncColor(expr n, i, c) =
+ lua.mp.sync_set_color(n,i,c) ;
enddef ;
-vardef TheSyncThreshold(expr n, i) =
- if known sync_th[n][i] : sync_th[n][i] else : SyncThreshold fi
+vardef TheSyncColor(expr n, i) =
+ lua.mp.sync_get_color(n,i)
enddef ;
-vardef PrepareSyncTasks(expr n, collapse, extendtop, prestartnext) =
- ResetSyncTasks ;
- if known sync_n[n] :
- CurrentSyncClass := n ;
- save ok, l, d ; boolean ok ; ok := false ; NOfSyncPaths := l := 0 ;
- for i=1 upto sync_n[n] :
- if RealPageNumber > sync_p[n][i] :
- l := i ;
- elseif RealPageNumber = sync_p[n][i] :
- NOfSyncPaths := NOfSyncPaths + 1 ;
- if not ok :
- if i>1 :
- if sync_t[n][i-1] = sync_t[n][i] :
- SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ;
- SyncTasks[NOfSyncPaths] := i ;
- else :
- SyncPaths[NOfSyncPaths] := SyncBox(n, i-1, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ;
- SyncTasks[NOfSyncPaths] := i-1 ;
- NOfSyncPaths := NOfSyncPaths + 1 ;
- SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ;
- SyncTasks[NOfSyncPaths] := i ;
- fi ;
- else :
- SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ;
- SyncTasks[NOfSyncPaths] := i ;
- fi ;
- else :
- SyncPaths[NOfSyncPaths] := SyncBox(n, i, SyncLeftOffset, SyncWidth, 0, -PaperHeight) ;
- SyncTasks[NOfSyncPaths] := i ;
- fi ;
- ok := true ;
- fi ;
- endfor ;
- if (NOfSyncPaths = 0) and (l > 0) :
- NOfSyncPaths := 1 ;
- SyncPaths[NOfSyncPaths] := SyncBox(n, l, SyncLeftOffset, SyncWidth, PaperHeight, -PaperHeight) ;
- SyncTasks[NOfSyncPaths] := l ;
- fi ;
- if NOfSyncPaths > 0 :
- for i = 1 upto NOfSyncPaths-1 :
- SyncPaths[i] := topboundary SyncPaths[i] -- reverse topboundary SyncPaths[i+1] -- cycle ;
- endfor ;
- if unknown SyncThresholdMethod :
- numeric SyncThresholdMethod ; SyncThresholdMethod := 2 ;
- fi ;
- if extendtop :
- if SyncThresholdMethod = 1 :
- if NOfSyncPaths>1 :
- d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[2]]) ;
- if (SyncTasks[2]>1) and (d > 0pt) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[2]])) and (sync_p[n][SyncTasks[2]] = RealPageNumber) :
- SyncPaths[2] := SyncPaths[2] topenlarged PaperHeight ;
- fi ;
- fi ;
- else :
- for i = 1 upto NOfSyncPaths :
- d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[i]]) ;
- if (d > 0) and (d <= TheSyncThreshold(n,sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[i]] = RealPageNumber) :
- SyncPaths[i] := SyncPaths[i] topenlarged PaperHeight ;
- fi ;
- endfor ;
- fi ;
- fi ;
- if prestartnext :
- if NOfSyncPaths>1 :
- if SyncTasks[NOfSyncPaths] < sync_n[n] : % there is a next one
- d := ypart (ulcorner PlainTextArea - sync_xy[n][SyncTasks[NOfSyncPaths]+1]) ;
- if (d > 0) and (d <= TheSyncThreshold(n, sync_t[n][SyncTasks[i]])) and (sync_p[n][SyncTasks[NOfSyncPaths]+1] = RealPageNumber+1) :
- SyncPaths[NOfSyncPaths+1] :=
- (xpart ulcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) --
- (xpart urcorner SyncPaths[NOfSyncPaths],ypart llcorner PlainTextArea) --
- lrcorner SyncPaths[NOfSyncPaths] --
- llcorner SyncPaths[NOfSyncPaths] -- cycle ;
- SyncTasks[NOfSyncPaths+1] := SyncTasks[NOfSyncPaths]+1 ;
- NOfSyncPaths := NOfSyncPaths + 1 ;
- fi ;
- fi ;
- fi ;
- else :
- if NOfSyncPaths>1 :
- d := ypart (sync_xy[n][SyncTasks[NOfSyncPaths]] - llcorner PlainTextArea) ;
- if (d < TheSyncThreshold(n, SyncTasks[NOfSyncPaths])) :
- NOfSyncPaths := NOfSyncPaths - 1 ;
- SyncPaths[NOfSyncPaths] := SyncPaths[NOfSyncPaths] bottomenlarged PaperHeight ;
- fi ;
- fi ;
- fi ;
- if (NOfSyncPaths>1) and collapse :
- save j ; numeric j ; j := 1 ;
- for i = 2 upto NOfSyncPaths :
- if sync_t[n][SyncTasks[i]] = sync_t[n][SyncTasks[j]] :
- SyncPaths[j] := boundingbox image (draw SyncPaths[i] ; draw SyncPaths[j] ; ) ;
- SyncTasks[j] := SyncTasks[i] ;
- else :
- j := j + 1 ;
- SyncPaths[j] := SyncPaths[i] ;
- SyncTasks[j] := SyncTasks[i] ;
- fi ;
- endfor ;
- NOfSyncPaths := j ;
- fi ;
- fi ;
- fi ;
+vardef SyncPathColor(expr i) =
+ lua.mp.sync_get_color(CurrentSyncClass,SyncTasks[i])
enddef ;
-def SyncTask(expr n) =
- if known SyncTasks[n] : SyncTasks[n] else : 0 fi
+def DrawSyncPaths =
+ for i=1 upto NOfSyncPaths :
+ draw SyncPaths[i] withcolor SyncPathColor(i) ;
+ endfor ;
enddef ;
-def FlushSyncTasks =
- for i = 1 upto NOfSyncPaths :
- ProcessSyncTask(SyncPaths[i], TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]])) ;
+def FillSyncPaths =
+ for i=1 upto NOfSyncPaths :
+ fill SyncPaths[i] withcolor SyncPathColor(i) ;
endfor ;
enddef ;
-def ProcessSyncTask(expr p, c) =
- fill p withcolor c ;
+vardef NOfSyncPaths =
+ mfun_sync_count
enddef ;
diff --git a/metapost/context/base/mpiv/mp-bare.mpiv b/metapost/context/base/mpiv/mp-bare.mpiv
index c6194b1ee..8f517b268 100644
--- a/metapost/context/base/mpiv/mp-bare.mpiv
+++ b/metapost/context/base/mpiv/mp-bare.mpiv
@@ -14,75 +14,71 @@
if known context_bare : endinput ; fi ;
boolean context_bare ; context_bare := true ;
-numeric mfun_tt_w[], mfun_tt_h[], mfun_tt_d[] ;
+vardef colordecimals primary c =
+ if cmykcolor c :
+ decimal cyanpart c & ":" & decimal magentapart c & ":" & decimal yellowpart c & ":" & decimal blackpart c
+ elseif rgbcolor c :
+ decimal redpart c & ":" & decimal greenpart c & ":" & decimal bluepart c
+ else :
+ decimal c
+ fi
+enddef ;
+
+rgbcolor mfun_tt_r ;
numeric mfun_tt_n ; mfun_tt_n := 0 ;
-picture mfun_tt_p ; mfun_tt_p := nullpicture ;
picture mfun_tt_o ; mfun_tt_o := nullpicture ;
picture mfun_tt_c ; mfun_tt_c := nullpicture ;
-if unknown mfun_trial_run :
- boolean mfun_trial_run ;
- mfun_trial_run := false ;
-fi ;
-
-if unknown mfun_first_run :
- boolean mfun_first_run ;
- mfun_first_run := true ;
-fi ;
-
def mfun_reset_tex_texts =
mfun_tt_n := 0 ;
- mfun_tt_p := nullpicture ;
mfun_tt_o := nullpicture ; % redundant
mfun_tt_c := nullpicture ; % redundant
enddef ;
def mfun_flush_tex_texts =
- addto currentpicture also mfun_tt_p
-enddef ;
-
-extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ;
-extra_endfig := "mfun_flush_tex_texts ; mfun_reset_tex_texts ; " & extra_endfig ;
-
-vardef colordecimals primary c =
- if cmykcolor c :
- decimal cyanpart c & ":" & decimal magentapart c & ":" & decimal yellowpart c & ":" & decimal blackpart c
- elseif rgbcolor c :
- decimal redpart c & ":" & decimal greenpart c & ":" & decimal bluepart c
- else :
- decimal c
- fi
enddef ;
-vardef rawtextext(expr str) = % todo: avoid currentpicture
- if str = "" :
+vardef rawtextext(expr s) =
+ if s = "" :
nullpicture
else :
mfun_tt_n := mfun_tt_n + 1 ;
mfun_tt_c := nullpicture ;
- if mfun_trial_run :
- mfun_tt_o := nullpicture ;
- addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
- addto mfun_tt_c doublepath unitsquare
- withprescript "tx_number=" & decimal mfun_tt_n
- withprescript "tx_stage=trial"
- withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
- withpostscript str ;
- addto mfun_tt_p also mfun_tt_c ;
- elseif known mfun_tt_d[mfun_tt_n] :
- addto mfun_tt_c doublepath unitsquare
- xscaled mfun_tt_w[mfun_tt_n]
- yscaled (mfun_tt_h[mfun_tt_n] + mfun_tt_d[mfun_tt_n])
- shifted (0,-mfun_tt_d[mfun_tt_n])
- withprescript "tx_number=" & decimal mfun_tt_n
- withprescript "tx_stage=final" ;
- else :
- addto mfun_tt_c doublepath unitsquare ; % unitpicture
- fi ;
+ mfun_tt_o := nullpicture ;
+ addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
+ mfun_tt_r := runscript("mp.SomeText(" & decimal mfun_tt_n & "," & ditto & s & ditto & ")") ;
+ addto mfun_tt_c doublepath unitsquare
+ xscaled redpart mfun_tt_r
+ yscaled (greenpart mfun_tt_r + bluepart mfun_tt_r)
+ shifted (0,-bluepart mfun_tt_r)
+ withprescript "mf_object=text"
+ withprescript "tx_index=" & decimal mfun_tt_n
+ withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
+ ;
mfun_tt_c
fi
enddef ;
+vardef rawmadetext =
+ mfun_tt_n := mfun_tt_n + 1 ;
+ mfun_tt_c := nullpicture ;
+ mfun_tt_o := nullpicture ;
+ addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
+ mfun_tt_r := runscript("mp.MadeText(" & decimal mfun_tt_n & ")") ;
+ addto mfun_tt_c doublepath unitsquare
+ xscaled redpart mfun_tt_r
+ yscaled (greenpart mfun_tt_r + bluepart mfun_tt_r)
+ shifted (0,-bluepart mfun_tt_r)
+ withprescript "mf_object=text"
+ withprescript "tx_index=" & decimal mfun_tt_n
+ withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
+ ;
+ mfun_tt_c
+enddef ;
+
+extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ;
+extra_endfig := "mfun_flush_tex_texts ; mfun_reset_tex_texts ; " & extra_endfig ;
+
primarydef str infont name = % nasty hack
if name = "" :
rawtextext(str)
diff --git a/metapost/context/base/mpiv/mp-base.mpiv b/metapost/context/base/mpiv/mp-base.mpiv
index 0cc209302..617855473 100644
--- a/metapost/context/base/mpiv/mp-base.mpiv
+++ b/metapost/context/base/mpiv/mp-base.mpiv
@@ -201,7 +201,7 @@ let graycolor = numeric ;
% color part (will be overloaded)
def colorpart primary t =
- if colormodel t=7:
+ if colormodel t = 7:
(cyanpart t, magentapart t, yellowpart t, blackpart t)
elseif colormodel t = 5 :
(redpart t, greenpart t, bluepart t)
@@ -250,7 +250,7 @@ vardef whatever =
?
enddef ;
-% unary operators
+% unary operators (with patched round)
let abs = length ;
@@ -258,7 +258,14 @@ vardef round primary u =
if numeric u :
floor(u+.5)
elseif pair u :
- (round xpart u, round ypart u)
+ (floor(xpart u+.5), floor(ypart u+.5))
+ elseif path u :
+ % added by HH
+ for i=0 upto length u-1 :
+ round(point i of u) ..
+ controls round(postcontrol i of u) and round(precontrol i+1 of u) ..
+ endfor
+ if cycle u : cycle else : point infinity of u fi
else :
u
fi
@@ -323,53 +330,18 @@ primarydef w dotprod z =
(xpart w * xpart z + ypart w * ypart z)
enddef ;
-primarydef x**y =
- if y = 2 :
- x*x
- else :
- takepower y of x
- fi
-enddef ;
-
-def takepower expr y of x =
- if x>0 :
- mexp(y*mlog x)
- elseif (x=0) and (y>0) :
- 0
- else :
- 1
- if y = floor y :
- if y >= 0 :
- for n=1 upto y :
- *x
- endfor
- else :
- for n=-1 downto y :
- /x
- endfor
- fi
- else :
- hide(errmessage "Undefined power: " & decimal x & "**" & decimal y)
- fi
- fi
-enddef ;
-
-% for big number systems:
-%
% primarydef x**y =
-% if y = 1 :
-% x
-% elseif y = 2 :
+% if y = 2 :
% x*x
-% elseif y = 3 :
-% x*x*x
% else :
% takepower y of x
% fi
% enddef ;
-%
-% vardef takepower expr y of x =
-% if (x=0) and (y>0) :
+%
+% def takepower expr y of x =
+% if x>0 :
+% mexp(y*mlog x)
+% elseif (x=0) and (y>0) :
% 0
% else :
% 1
@@ -389,6 +361,51 @@ enddef ;
% fi
% enddef ;
+% for big number systems:
+
+primarydef x**y =
+ if y = 0 :
+ 1
+ elseif x = 0 :
+ 0
+ elseif y < 0 :
+ 1/(x**-y)
+ elseif y = 1 :
+ x
+ elseif y = 2 :
+ x*x
+ elseif y = 3 :
+ x*x*x
+ else :
+ takepower y of x
+ fi
+enddef ;
+
+def takepower expr y of x =
+ if y=0 : % isn't x**0 = 1 even if x=0 ?
+ 1
+ elseif x=0 :
+ 0
+ else :
+ if y = floor y :
+ 1
+ if y >= 0 :
+ for n=1 upto y :
+ *x
+ endfor
+ else :
+ for n=-1 downto y :
+ /x
+ endfor
+ fi
+ elseif x>0 :
+ mexp(y*mlog x)
+ else :
+ -mexp(y*mlog -x)
+ fi
+ fi
+enddef ;
+
vardef direction expr t of p =
postcontrol t of p - precontrol t of p
enddef ;
diff --git a/metapost/context/base/mpiv/mp-blob.mpiv b/metapost/context/base/mpiv/mp-blob.mpiv
new file mode 100644
index 000000000..d1fc7357b
--- /dev/null
+++ b/metapost/context/base/mpiv/mp-blob.mpiv
@@ -0,0 +1,112 @@
+%D \module
+%D [ file=mp-blob.mpiv,
+%D version=2018.04.08,
+%D title=\CONTEXT\ \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.
+
+%D This is a follow up on good old \type {meta-imp-txt}.
+
+if known context_blob : endinput ; fi ;
+
+boolean context_blob ; context_blob := true ;
+
+numeric mfun_blob_n ; mfun_blob_n := 0 ;
+picture mfun_blob_c ;
+color mfun_blob_b ;
+
+def mfun_reset_tex_blobs =
+ mfun_blob_n := 0 ;
+ mfun_blob_c := nullpicture ;
+enddef ;
+
+extra_endfig := extra_endfig & "mfun_reset_tex_blobs ; " ;
+
+vardef mfun_inject_blob(expr n) =
+ mfun_blob_c := nullpicture ;
+ mfun_blob_b := lua.mp.mf_blob_dimensions(mfun_blob_n,n) ;
+ addto mfun_blob_c doublepath unitsquare
+ xscaled redpart mfun_blob_b
+ yscaled (greenpart mfun_blob_b + bluepart mfun_blob_b)
+ shifted (0,- bluepart mfun_blob_b)
+ withprescript "mf_object=texblob"
+ withprescript "tb_blob=" & decimal lua.mp.mf_blob_index(mfun_blob_n,n) ;
+ mfun_blob_c
+enddef ;
+
+% An example of usage:
+
+newinternal followtextalternative ; followtextalternative := 1 ;
+newinternal tracingfollowtext ; tracingfollowtext := 0 ;
+newinternal autoscaleupfollowtext ; autoscaleupfollowtext := 2 ;
+newinternal autoscaledownfollowtext ; autoscaledownfollowtext := 0 ;
+
+vardef followtext(expr pth, txt) =
+ image (
+ mfun_blob_n := mfun_blob_n + 1 ;
+ lua.mp.mf_inject_blob(mfun_blob_n,txt);
+ save pat, al, at, pl, pc, wid, pos, ap, ad, pic, len, n, sc ;
+ path pat ; pat := pth ;
+ numeric al, at, pl, pc, wid, pos, len[], n, sc ;
+ pair ap, ad ;
+ picture pic[] ;
+ len[0] := 0 ;
+ n := lua.mp.mf_blob_size(mfun_blob_n) ;
+ sc := 0 ;
+ for i=1 upto n :
+ pic[i] := mfun_inject_blob(i) ;
+ pic[i] := pic[i] shifted - llcorner pic[i] ;
+ len[i] := len[i-1] + lua.mp.mf_blob_width(mfun_blob_n,i) ;
+ endfor ;
+ al := arclength pth ;
+ if al = 0 :
+ al := len[n] ;
+ pat := origin -- (al,0) ;
+ fi ;
+ if ((al < len[n]) and (autoscaleupfollowtext > 0)) or
+ ((al > len[n]) and (autoscaledownfollowtext > 0)) :
+ sc := len[n] /al ;
+ pat := pat scaled sc ;
+ al := arclength pat ;
+ fi ;
+ if followtextalternative = 1 :
+ pl := (al-len[n])/(if n>1 : (n-1) else : 1 fi) ;
+ pc := 0 ;
+ else : % centered / MP
+ pl := 0 ;
+ pc := arclength pat/2 - len[n]/2 ;
+ fi ;
+ if tracingfollowtext = 1 :
+ draw pat withpen pencircle scaled 1pt withcolor blue ;
+ fi ;
+ for i=1 upto n :
+ wid := lua.mp.mf_blob_width(mfun_blob_n,i) ;
+ pos := len[i]-wid/2 + (i-1)*pl + pc ;
+ at := arctime pos of pat ;
+ ap := point at of pat ;
+ ad := direction at of pat ;
+ pic[i] := pic[i] shifted (-wid/2,0) rotated(angle(ad)) shifted ap ;
+ draw pic[i] ;
+ if tracingfollowtext = 1 :
+ draw boundingbox pic[i] withpen pencircle scaled .25pt withcolor red ;
+ draw ap withpen pencircle scaled .50pt withcolor green ;
+ fi ;
+ endfor ;
+ if ((autoscaleupfollowtext = 2) or (autoscaledownfollowtext = 2)) and
+ (sc <> 0) and (sc <> 1):
+ currentpicture := currentpicture scaled (1/sc) ;
+ fi ;
+ if tracingfollowtext = 1 :
+ draw boundingbox currentpicture withpen pencircle scaled .25pt withcolor blue ;
+ fi ;
+ draw fullcircle scaled 100bp
+ withprescript "mf_object=followtext"
+ withprescript "ft_category=" & decimal mfun_blob_n ;
+ )
+enddef ;
diff --git a/metapost/context/base/mpiv/mp-grap.mpiv b/metapost/context/base/mpiv/mp-grap.mpiv
index e799f629c..0299c0587 100644
--- a/metapost/context/base/mpiv/mp-grap.mpiv
+++ b/metapost/context/base/mpiv/mp-grap.mpiv
@@ -266,19 +266,27 @@ enddef ;
graph_margin_fraction.low=-.07 ; % bbox fraction for default range start
graph_margin_fraction.high=1.07 ; % bbox fraction for default range stop
+%def graph_with_pen_and_color(expr q) =
+% withpen penpart q
+% withcolor
+% if colormodel q=1 :
+% false
+% elseif colormodel q=3 :
+% (greypart q)
+% elseif colormodel q=5 :
+% (redpart q, greenpart q, bluepart q)
+% elseif colormodel q=7 :
+% (cyanpart q, magentapart q, yellowpart q, blackpart q)
+% fi
+% withprescript prescriptpart q
+% withpostscript postscriptpart q
+%enddef ;
+
def graph_with_pen_and_color(expr q) =
- withpen penpart q withcolor
- if colormodel q=1 :
- false
- elseif colormodel q=3 :
- (greypart q)
- elseif colormodel q=5 :
- (redpart q, greenpart q, bluepart q)
- elseif colormodel q=7 :
- (cyanpart q, magentapart q, yellowpart q, blackpart q)
- fi
+ withproperties q
enddef ;
+
% Add picture component q to picture @# and change part p to tp,
% where p is something from q that needs coordinate transformation.
% The type of p is pair or path.
diff --git a/metapost/context/base/mpiv/mp-grph.mpiv b/metapost/context/base/mpiv/mp-grph.mpiv
index 04d4920f6..d4316eb91 100644
--- a/metapost/context/base/mpiv/mp-grph.mpiv
+++ b/metapost/context/base/mpiv/mp-grph.mpiv
@@ -65,8 +65,6 @@ enddef ;
numeric currentgraphictext ; currentgraphictext := 0 ;
-def data_mpy_file = job_name & "-mpgraph.mpy" enddef ;
-
def begingraphictextfig (expr n) =
foundpicture := n ;
scratchpicture := nullpicture ;
@@ -117,7 +115,7 @@ def mfun_load_figure (expr filename) text figureattributes =
endgroup ;
enddef ;
-% shared between old and new
+% We only use the new method now.
boolean mfun_gt_color_fill ;
boolean mfun_gt_color_draw ;
@@ -126,148 +124,12 @@ boolean mfun_gt_reverse_fill ;
boolean mfun_gt_outline_fill ;
picture mfun_gt_picture ;
-% this is the old version:
-
-def old_graphictext primary t =
- hide (
- if mfun_trial_run :
- let mfun_graphic_text = mfun_no_graphic_text ;
- else :
- let mfun_graphic_text = mfun_do_graphic_text ;
- fi
- )
- mfun_graphic_text(t)
-enddef ;
-
-def mfun_do_graphic_text (expr t) =
- % withprescript "gt_stage=final"
- begingroup ;
- save figurepicture ; picture figurepicture ;
- figurepicture := currentpicture ; currentpicture := nullpicture ;
- currentgraphictext := currentgraphictext + 1 ;
- mfun_finish_graphic_text % picks up directives
-enddef ;
-
-def mfun_no_graphic_text (expr t) text rest =
- currentgraphictext := currentgraphictext + 1 ;
- draw unitsquare
- withprescript "gt_stage=trial"
- withprescript "gt_index=" & decimal currentgraphictext
- withpostscript t
-enddef ;
-
-def mfun_finish_graphic_text text rest =
- protectgraphicmacros ; % resets currentpicture
- interim linecap := butt ; % normally rounded
- interim linejoin := mitered ; % normally rounded
- interim miterlimit := 10 ; % todo
- let normalwithshade = withshade ;
- save foundpicture, scratchpicture, str ;
- save fill, draw, withshade, reversefill, outlinefill ;
- save withfillcolor, withdrawcolor ; % quite important
- numeric foundpicture ; picture scratchpicture ; string str ;
- def draw expr p =
- % the first, naive implementation was:
- % addto scratchpicture doublepath p withpen currentpen ;
- % but it is better to turn lines into fills
- addto scratchpicture contour boundingbox
- image (addto currentpicture doublepath p withpen currentpen) ;
- enddef ;
- def fill expr p =
- addto scratchpicture contour p withpen currentpen ;
- enddef ;
- def mfun_gt_fill = enddef ; boolean mfun_gt_color_fill ; mfun_gt_color_fill := false ;
- def mfun_gt_draw = enddef ; boolean mfun_gt_color_draw ; mfun_gt_color_draw := false ;
- def mfun_gt_shade = enddef ; boolean mfun_gt_shade_fill ; mfun_gt_shade_fill := false ;
- boolean mfun_gt_reverse_fill ; mfun_gt_reverse_fill := false ;
- boolean mfun_gt_outline_fill ; mfun_gt_outline_fill := false ;
- def reversefill =
- hide(mfun_gt_reverse_fill := true )
- enddef ;
- def outlinefill =
- hide(mfun_gt_outline_fill := true )
- enddef ;
- def withshade primary c =
- hide(def mfun_gt_shade = normalwithshade c enddef ; mfun_gt_shade_fill := true )
- enddef ;
- def withfillcolor primary c =
- hide(def mfun_gt_fill = withcolor c enddef ; mfun_gt_color_fill := true )
- enddef ;
- def withdrawcolor primary c =
- hide(def mfun_gt_draw = withcolor c enddef ; mfun_gt_color_draw := true )
- enddef ;
- scratchpicture := nullpicture ;
- addto scratchpicture doublepath origin rest ; % pre-roll
- for i within scratchpicture : % Below here is a dirty tricky test!
- if (urcorner dashpart i) = origin :
- mfun_gt_outline_fill := false ;
- fi ;
- endfor ;
- scratchpicture := nullpicture ;
- readfile(data_mpy_file) ;
- scratchpicture := (scratchpicture shifted -llcorner scratchpicture) scaled (1/10) ;
- if not mfun_gt_color_draw and not mfun_gt_color_fill :
- mfun_gt_color_draw := true ;
- fi
- if mfun_gt_shade_fill :
- mfun_gt_color_draw := false ;
- mfun_gt_color_fill := false ;
- fi ;
- currentpicture := figurepicture ;
- if mfun_gt_shade_fill :
- for i within scratchpicture :
- if filled i :
- addto currentpicture contour pathpart i _op_ rest mfun_gt_shade ;
- fi ;
- endfor ;
- else :
- if mfun_gt_color_draw and not mfun_gt_reverse_fill :
- for i within scratchpicture :
- if mfun_gt_color_fill and mfun_gt_outline_fill :
- addto currentpicture doublepath pathpart i _op_ rest mfun_gt_fill dashed nullpicture ;
- fi ;
- if filled i :
- addto currentpicture doublepath pathpart i _op_ rest mfun_gt_draw ;
- fi ;
- endfor ;
- fi ;
- if mfun_gt_color_fill :
- for i within scratchpicture :
- if filled i :
- addto currentpicture contour pathpart i _op_ rest mfun_gt_fill withpen pencircle scaled 0 ;
- fi ;
- endfor ;
- fi ;
- if mfun_gt_color_draw and mfun_gt_reverse_fill :
- for i within scratchpicture :
- if filled i :
- addto currentpicture doublepath pathpart i _op_ rest mfun_gt_draw ;
- fi ;
- endfor ;
- fi ;
- for i within scratchpicture :
- if stroked i :
- addto currentpicture doublepath pathpart i _op_ rest mfun_gt_draw ;
- fi ;
- endfor ;
- fi ;
- endgroup ;
-enddef ;
-
-% and this is the new one:
-
-% boolean mfun_gt_color_fill ;
-% boolean mfun_gt_color_draw ;
-% boolean mfun_gt_shade_fill ;
-% boolean mfun_gt_reverse_fill ;
-% picture mfun_gt_picture ;
-
def mfun_gt_default = % somewhat compatible
scaled 11.5
withpen pencircle scaled .1
enddef ;
-def new_graphictext primary t = % use outlinetext instead
+def graphictext primary t = % use outlinetext instead
begingroup ;
mfun_graphic_text_indeed(t)
enddef ;
@@ -310,24 +172,21 @@ def mfun_graphic_text_indeed(expr t) text rest =
draw outlinetext.f(t)(mfun_gt_shade) rest;
elseif mfun_gt_color_fill and mfun_gt_color_draw :
if mfun_gt_reverse_fill :
- draw outlinetext.r(t)(mfun_gt_default mfun_gt_fill rest)(mfun_gt_default mfun_gt_draw rest) ;
+ draw outlinetext.r(t)(mfun_gt_default mfun_gt_fill)(mfun_gt_default mfun_gt_draw) rest;
else :
- draw outlinetext.b(t)(mfun_gt_default mfun_gt_draw rest)(mfun_gt_default mfun_gt_fill rest);
+ draw outlinetext.b(t)(mfun_gt_default mfun_gt_draw)(mfun_gt_default mfun_gt_fill) rest;
fi ;
elseif mfun_gt_color_fill :
- draw outlinetext.f(t)(mfun_gt_default mfun_gt_fill rest) ;
+ draw outlinetext.f(t)(mfun_gt_default mfun_gt_fill) rest;
elseif mfun_gt_color_draw :
- draw outlinetext.d(t)(mfun_gt_default mfun_gt_draw rest) ;
+ draw outlinetext.d(t)(mfun_gt_default mfun_gt_draw) rest ;
else :
- draw outlinetext.d(t)(mfun_gt_default rest) ;
+ draw outlinetext.d(t)(mfun_gt_default) rest ;
fi ;
%
endgroup ;
enddef ;
-let graphictext = old_graphictext ;
-%%% graphictext = new_graphictext ; % more than 10 times faster
-
% example
%
% beginfig (1) ;
diff --git a/metapost/context/base/mpiv/mp-luas.mpiv b/metapost/context/base/mpiv/mp-luas.mpiv
index d35701ec6..e5cfe0371 100644
--- a/metapost/context/base/mpiv/mp-luas.mpiv
+++ b/metapost/context/base/mpiv/mp-luas.mpiv
@@ -49,41 +49,95 @@ boolean context_luas ; context_luas := true ;
%
% Fourth variant:
-string mfun_lua_bs ; mfun_lua_bs := "[[" ;
-string mfun_lua_es ; mfun_lua_es := "]]" ;
+string mfun_lua_bs ; mfun_lua_bs := "[===[" ;
+string mfun_lua_es ; mfun_lua_es := "]===]" ;
vardef mlib_luas_luacall(text t) =
runscript("" for s = t :
if string s :
& s
+ % & mfun_lua_bs & s & mfun_lua_es
elseif numeric s :
& decimal s
elseif boolean s :
& if s : "true" else : "false" fi
+ elseif pair s :
+ & mfun_pair_to_table(s)
+ elseif path s :
+ & mfun_path_to_table(s)
+ elseif rgbcolor s :
+ & mfun_rgb_to_table(s)
+ elseif cmykcolor s :
+ & mfun_cmyk_to_table(s)
else :
& ditto & tostring(s) & ditto
fi endfor
)
enddef ;
+% vardef mlib_luas_lualist(expr c)(text t) =
+% save b ; boolean b ; b := false ;
+% runscript(c & "(" for s = t :
+% if b :
+% & ","
+% else :
+% hide(b := true)
+% fi
+% if string s :
+% % & ditto & s & ditto
+% & mfun_lua_bs & s & mfun_lua_es
+% elseif numeric s :
+% & decimal s
+% elseif boolean s :
+% & if s : "true" else : "false" fi
+% elseif pair s :
+% & mfun_pair_to_table(s)
+% elseif path s :
+% & mfun_path_to_table(s)
+% elseif rgbcolor s :
+% & mfun_rgb_to_table(s)
+% elseif cmykcolor s :
+% & mfun_cmyk_to_table(s)
+% else :
+% & ditto & tostring(s) & ditto
+% fi endfor & ")"
+% )
+% enddef ;
+
+newinternal mfun_luas_b ;
+
+def mlib_luas_luadone =
+ exitif numeric begingroup mfun_luas_b := 1 ; endgroup ;
+enddef ;
+
vardef mlib_luas_lualist(expr c)(text t) =
- save b ; boolean b ; b := false ;
- runscript(c & "(" for s = t :
- if b :
- & ","
+ interim mfun_luas_b := 0 ;
+ runscript(c & for s = t :
+ if mfun_luas_b = 0 :
+ "("
+ % hide(mfun_luas_b := 1)
+ mlib_luas_luadone
else :
- hide(b := true)
+ ","
fi
+ &
if string s :
- % & ditto & s & ditto
- & mfun_lua_bs & s & mfun_lua_es
+ mfun_lua_bs & s & mfun_lua_es
elseif numeric s :
- & decimal s
+ decimal s
elseif boolean s :
- & if s : "true" else : "false" fi
+ if s : "true" else : "false" fi
+ elseif pair s :
+ mfun_pair_to_table(s)
+ elseif path s :
+ mfun_path_to_table(s)
+ elseif rgbcolor s :
+ mfun_rgb_to_table(s)
+ elseif cmykcolor s :
+ mfun_cmyk_to_table(s)
else :
- & ditto & tostring(s) & ditto
- fi endfor & ")"
+ ditto & tostring(s) & ditto
+ fi & endfor if mfun_luas_b = 0 : "()" else : ")" fi
)
enddef ;
@@ -107,9 +161,14 @@ vardef MP@#(text t) =
enddef ;
def message expr t =
- if t <> "" : lua.mp.report(t) fi ;
+ lua.mp.report(tostring(t)) ;
enddef ;
+% Modes:
+
+vardef texmode (expr s) = lua.mp("mode", s) enddef ;
+vardef systemmode(expr s) = lua.mp("systemmode",s) enddef ;
+
% A few helpers
vardef isarray suffix a = lua.mp.isarray (str a) enddef ;
@@ -118,19 +177,15 @@ vardef dimension suffix a = lua.mp.dimension(str a) enddef ;
% More access
-def getdimen(expr k) = lua.mp._get_dimen_(k) enddef ;
-def getcount(expr k) = lua.mp._get_count_(k) enddef ;
-def gettoks (expr k) = lua.mp._get_toks_ (k) enddef ;
-def setdimen(expr k, v) = lua.mp._set_dimen_(k,v) enddef ;
-def setcount(expr k, v) = lua.mp._set_count_(k,v) enddef ;
-def settoks (expr k, v) = lua.mp._set_toks_ (k,v) enddef ;
+vardef getmacro(expr k) = lua.mp._get_macro_(k) enddef ;
+vardef getdimen(expr k) = lua.mp._get_dimen_(k) enddef ;
+vardef getcount(expr k) = lua.mp._get_count_(k) enddef ;
+vardef gettoks (expr k) = lua.mp._get_toks_ (k) enddef ;
-% vardef getdimen(expr k) = save getdimen ; lua.mp.getdimen(k) enddef ;
-% vardef getcount(expr k) = save getcount ; lua.mp.getcount(k) enddef ;
-% vardef gettoks (expr k) = save gettoks ; lua.mp.gettoks (k) enddef ;
-% vardef setdimen(expr k,v) = save setdimen ; lua.mp.setdimen(k,v) enddef ;
-% vardef setcount(expr k,v) = save setcount ; lua.mp.setcount(k,v) enddef ;
-% vardef settoks (expr k,v) = save settoks ; lua.mp.settoks (k,v) enddef ;
+def setmacro(expr k,v) = lua.mp._set_macro_(k,v) enddef ;
+def setdimen(expr k,v) = lua.mp._set_dimen_(k,v) enddef ;
+def setcount(expr k,v) = lua.mp._set_count_(k,v) enddef ;
+def settoks (expr k,v) = lua.mp._set_toks_ (k,v) enddef ;
vardef positionpath (expr name) = lua.mp.positionpath (name) enddef ;
vardef positioncurve (expr name) = lua.mp.positioncurve (name) enddef ;
@@ -154,6 +209,43 @@ vardef positionatanchor(expr name) =
currentpicture := currentpicture shifted - positionxy(name) ;
enddef ;
-
vardef texvar(expr name) = lua.mp.texvar(name) enddef ;
vardef texstr(expr name) = lua.mp.texstr(name) enddef ;
+
+%D New experimental feature for Alan-The-Number-Cruncher:
+
+% \startMPcode{doublefun}
+% path p ; p := (
+% for i=1 upto 20000 :
+% origin randomized 10000 ..
+% endfor cycle
+% ) xysized (TextWidth,TextHeight) ;
+% draw for i inpath p:
+% pointof i .. controls (leftof i) and (rightof i) ..
+% endfor cycle ;
+% \stopMPcode
+
+% def inpath suffix p =
+% = 1 step 1 until lua.mp.mf_path_length(str p)
+% enddef ;
+
+% def inpath suffix p =
+% % = 1 step 1 until lua.mp.mf_path_length(str p)
+% = 1 step 1 until (begingroup save n ; n := lua.mp.mf_path_length(str p) ; if n = 0 : 1 else : n fi endgroup)
+% enddef ;
+
+def inpath suffix p = % permits p[0]
+ = 1 step 1 until
+ begingroup
+ save mfun_inpath_r,mfun_inpath_n ; path mfun_inpath_r ;
+ mfun_inpath_r = p ;
+ mfun_inpath_n := lua.mp.mf_path_length(str mfun_inpath_r) ;
+ if mfun_inpath_n = 0 : 1 else : mfun_inpath_n fi
+ endgroup
+enddef ;
+
+vardef pointof primary i = lua.mp.mf_path_point(i) enddef ;
+vardef leftof primary i = lua.mp.mf_path_left (i) enddef ;
+vardef rightof primary i = lua.mp.mf_path_right(i) enddef ;
+
+extra_endfig := extra_endfig & " lua.mp.mf_path_reset() ; " ;
diff --git a/metapost/context/base/mpiv/mp-mlib.mpiv b/metapost/context/base/mpiv/mp-mlib.mpiv
index 115fe63ae..131796757 100644
--- a/metapost/context/base/mpiv/mp-mlib.mpiv
+++ b/metapost/context/base/mpiv/mp-mlib.mpiv
@@ -16,6 +16,18 @@ if known context_mlib : endinput ; fi ;
boolean context_mlib ; context_mlib := true ;
+numeric LUATEXFUNCTIONALITY ; LUATEXFUNCTIONALITY := runscript("mp.print(LUATEXFUNCTIONALITY)") ;
+
+%D Objects:
+
+vardef isobject expr p =
+ if picture p :
+ lua.mp.isobject(prescriptpart p)
+ else :
+ false
+ fi
+enddef ;
+
%D Color and transparency
%D
%D Separable:
@@ -60,16 +72,16 @@ def namedcolor expr n =
withprescript "sp_name=" & n
enddef ;
-% def spotcolor(expr n, v) =
+% def mfun_spotcolor(expr n, v) =
% 1
-% withprescript "sp_type=spot"
+% withprescript "sp_type=xspot"
% withprescript "sp_name=" & n
% withprescript "sp_value=" & (if numeric v : decimal v else : v fi)
% enddef ;
-%
-% def multitonecolor(expr name, fractions, components, value) =
+
+% def mfun_multispotcolor(expr name, fractions, components, value) =
% 1
-% withprescript "sp_type=multitone"
+% withprescript "sp_type=multispot"
% withprescript "sp_name=" & name
% withprescript "sp_fractions=" & decimal fractions
% withprescript "sp_components=" & components
@@ -79,10 +91,12 @@ enddef ;
def spotcolor(expr name, v) =
(1)
withprescript "sp_type=spot"
- withprescript "sp_name=" & name
+ withprescript "sp_name=" & name
withprescript "sp_value=" & colordecimals v
enddef ;
+% In this case a mixed color will be calculated:
+
def multitonecolor(expr name)(text t) =
(1)
withprescript "sp_type=multitone"
@@ -92,7 +106,7 @@ enddef ;
def transparent(expr a, t)(text c) = % use withtransparency instead
(1) % this permits withcolor x intoshade y
- withprescript "tr_alternative=" & decimal transparency_alternative_to_number(a)
+ withprescript "tr_alternative=" & decimal transparency_alternative_to_number(a)
withprescript "tr_transparency=" & decimal t
withcolor c
enddef ;
@@ -174,72 +188,52 @@ extra_beginfig := extra_beginfig & "mfun_reset_tex_texts ;" ;
% flush twice: once in location in order to pick up e.g. color properties,
% and once at the end because we need to flush missing ones.
-% see mp-keep.mpiv for older code
+boolean mfun_onetime_textext ; mfun_onetime_textext := false ;
-% vardef rawtextext(expr s) = % todo: avoid currentpicture
-% if s = "" :
-% nullpicture
-% else :
-% mfun_tt_n := mfun_tt_n + 1 ;
-% mfun_tt_c := nullpicture ;
-% if mfun_trial_run :
-% mfun_tt_o := nullpicture ;
-% addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
-% addto mfun_tt_c doublepath unitsquare
-% withprescript "tx_number=" & decimal mfun_tt_n
-% withprescript "tx_stage=trial"
-% withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
-% withpostscript s ;
-% addto mfun_tt_p also mfun_tt_c ;
-% elseif known mfun_tt_d[mfun_tt_n] :
-% addto mfun_tt_c doublepath unitsquare
-% xscaled mfun_tt_w[mfun_tt_n]
-% yscaled (mfun_tt_h[mfun_tt_n] + mfun_tt_d[mfun_tt_n])
-% shifted (0,-mfun_tt_d[mfun_tt_n])
-% withprescript "tx_number=" & decimal mfun_tt_n
-% withprescript "tx_stage=final" ;
-% else :
-% addto mfun_tt_c doublepath unitsquare ; % unitpicture
-% fi ;
-% mfun_tt_c
-% fi
-% enddef ;
+def notcached = withprescript "tx_cache=no" enddef ;
-boolean mfun_onetime_textext ; mfun_onetime_textext := false ;
+% todo: onetime
+
+rgbcolor mfun_tt_r ;
-vardef rawtextext(expr s) = % todo: avoid currentpicture
+vardef rawtextext(expr s) =
if s = "" :
- mfun_onetime_textext := false ;
nullpicture
else :
mfun_tt_n := mfun_tt_n + 1 ;
mfun_tt_c := nullpicture ;
- if mfun_trial_run :
- mfun_tt_o := nullpicture ;
- addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
- addto mfun_tt_c doublepath unitsquare
- withprescript "tx_number=" & decimal mfun_tt_n
- withprescript "tx_stage=trial"
- withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
- withpostscript s ;
- if not mfun_onetime_textext :
- addto mfun_tt_p also mfun_tt_c
- withprescript "tx_global=yes" ;
- fi ;
- else :
- mfun_tt_b := lua.mp.tt_dimensions(mfun_tt_n) ;
- addto mfun_tt_c doublepath unitsquare
- xscaled redpart mfun_tt_b
- yscaled (greenpart mfun_tt_b + bluepart mfun_tt_b)
- shifted (0,- bluepart mfun_tt_b)
- withprescript "tx_number=" & decimal mfun_tt_n
- withprescript "tx_stage=final" ;
- fi ;
- mfun_onetime_textext := false ;
+ mfun_tt_o := nullpicture ;
+ addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
+ mfun_tt_r := lua.mp.mf_some_text(mfun_tt_n,s) ;
+ addto mfun_tt_c doublepath unitsquare
+ xscaled wdpart mfun_tt_r
+ yscaled (htpart mfun_tt_r + dppart mfun_tt_r)
+ shifted (0,-dppart mfun_tt_r)
+ withprescript "mf_object=text"
+ withprescript "tx_index=" & decimal mfun_tt_n
+ withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
+ ;
mfun_tt_c
fi
enddef ;
+vardef rawmadetext =
+ mfun_tt_n := mfun_tt_n + 1 ;
+ mfun_tt_c := nullpicture ;
+ mfun_tt_o := nullpicture ;
+ addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
+ mfun_tt_r := lua.mp.mf_made_text(mfun_tt_n) ;
+ addto mfun_tt_c doublepath unitsquare
+ xscaled wdpart mfun_tt_r
+ yscaled (htpart mfun_tt_r + dppart mfun_tt_r)
+ shifted (0,-dppart mfun_tt_r)
+ withprescript "mf_object=text"
+ withprescript "tx_index=" & decimal mfun_tt_n
+ withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
+ ;
+ mfun_tt_c
+enddef ;
+
vardef validtexbox(expr category, name) =
if category == "" :
false
@@ -255,11 +249,12 @@ enddef ;
vardef rawtexbox(expr category, name) =
mfun_tt_c := nullpicture ;
if validtexbox(category,name) :
- mfun_tt_b := lua.mp.tb_dimensions(category, name) ;
+ mfun_tt_b := lua.mp.mf_tb_dimensions(category, name) ;
addto mfun_tt_c doublepath unitsquare
- xscaled redpart mfun_tt_b
- yscaled (greenpart mfun_tt_b + bluepart mfun_tt_b)
- shifted (0,- bluepart mfun_tt_b)
+ xscaled wdpart mfun_tt_b
+ yscaled (htpart mfun_tt_b + dppart mfun_tt_b)
+ shifted (0,- dppart mfun_tt_b)
+ withprescript "mf_object=box"
withprescript "bx_category=" & if numeric category : decimal fi category
withprescript "bx_name=" & if numeric name : decimal fi name ;
fi
@@ -368,13 +363,25 @@ vardef installlabel@# (expr type, x, y, offset) =
numeric labyf @# ; labyf @# := y ;
enddef ;
+vardef mfun_labshift@#(expr p) =
+ (mfun_labxf@#*lrcorner p +
+ mfun_labyf@#*ulcorner p +
+ (1-mfun_labxf@#-mfun_labyf@#)*llcorner p)
+enddef ;
+
+vardef mfun_picshift@#(expr p) =
+ (mfun_labxf@#*ulcorner p +
+ mfun_labyf@#*lrcorner p +
+ (1-mfun_labxf@#-mfun_labyf@#)*urcorner p)
+enddef ;
+
% we save the plain variant
vardef plain_thelabel@#(expr p,z) =
if string p :
plain_thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p) scaled defaultscale,z)
else :
- p shifted (z + labeloffset*laboff@# - (labxf@#*lrcorner p + labyf@#*ulcorner p + (1-labxf@#-labyf@#)*llcorner p))
+ p shifted (z + labeloffset*laboff@# - mfun_labshift@#(p))
fi
enddef;
@@ -403,7 +410,22 @@ enddef ;
plain_compatibility_data := plain_compatibility_data & "save label, thelabel ;" & "useplainlabels ;" ;
-% next comes own own:
+% vardef thetextext@#(expr p,z) =
+% % interim labeloffset := textextoffset ;
+% if string p :
+% thetextext@#(rawtextext(p),z)
+% elseif numeric p :
+% thetextext@#(rawtextext(decimal p),z)
+% else :
+% p
+% if (mfun_labtype@# >= 10) :
+% shifted (0,ypart center p)
+% fi
+% shifted (z + textextoffset*mfun_laboff@# - mfun_labshift@#(p))
+% fi
+% enddef ;
+
+newinternal anchortextexts ; anchortextexts := 0 ; % disabled by default
vardef thetextext@#(expr p,z) =
% interim labeloffset := textextoffset ;
@@ -411,12 +433,18 @@ vardef thetextext@#(expr p,z) =
thetextext@#(rawtextext(p),z)
elseif numeric p :
thetextext@#(rawtextext(decimal p),z)
+ elseif pair p :
+ thetextext@#(rawtextext(ddecimal p),z)
else :
- p
- if (mfun_labtype@# >= 10) :
- shifted (0,ypart center p)
- fi
- shifted (z + textextoffset*mfun_laboff@# - (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p))
+ if anchortextexts > 0 :
+ image(draw p withprescript "tx_anchor=" & ddecimal z)
+ else :
+ p
+ fi
+ if (mfun_labtype@# >= 10) :
+ shifted (0,ypart center p)
+ fi
+ shifted (z + textextoffset*mfun_laboff@# - mfun_labshift@#(p))
fi
enddef ;
@@ -433,56 +461,38 @@ enddef ;
pair mfun_tt_z ;
-vardef rawfmttext(text t) = % todo: avoid currentpicture
+vardef rawfmttext(text t) =
mfun_tt_n := mfun_tt_n + 1 ;
mfun_tt_c := nullpicture ;
- if mfun_trial_run :
- mfun_tt_o := nullpicture ;
- addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
- addto mfun_tt_c doublepath unitsquare
- withprescript "tx_number=" & decimal mfun_tt_n
- withprescript "tx_stage=trial"
- withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
- % begin of fmt specific
- withprescript "tx_type=format"
- for s = t :
- if string s : withpostscript "s:" & s
- elseif numeric s : withpostscript "n:" & decimal s
- elseif boolean s : withpostscript "b:" & if s : "true" else : "false" fi
- elseif pair s : hide(mfun_tt_z := s ; )
- fi
- endfor ;
- % end of fmt specific
- if not mfun_onetime_textext :
- addto mfun_tt_p also mfun_tt_c
- withprescript "tx_global=yes" ;
- fi ;
- else :
- mfun_tt_b := lua.mp.tt_dimensions(mfun_tt_n) ;
- addto mfun_tt_c doublepath unitsquare
- xscaled redpart mfun_tt_b
- yscaled (greenpart mfun_tt_b + bluepart mfun_tt_b)
- shifted (0,- bluepart mfun_tt_b)
- withprescript "tx_number=" & decimal mfun_tt_n
- withprescript "tx_stage=final" ;
- % begin of fmt specific
- for s = t :
- if pair s : mfun_tt_z := s ; fi
- endfor ;
- % end of fmt specific
- fi ;
- mfun_onetime_textext := false ;
+ mfun_tt_o := nullpicture ;
+ addto mfun_tt_o doublepath origin _op_ ; % save drawoptions
+ mfun_tt_r := lua.mp.mf_formatted_text(mfun_tt_n,t) ;
+ addto mfun_tt_c doublepath unitsquare
+ xscaled wdpart mfun_tt_r
+ yscaled (htpart mfun_tt_r + dppart mfun_tt_r)
+ shifted (0,-dppart mfun_tt_r)
+ withprescript "mf_object=text"
+ withprescript "tx_index=" & decimal mfun_tt_n
+ withprescript "tx_color=" & colordecimals colorpart mfun_tt_o
+ ;
+ for s = t :
+ if pair s : mfun_tt_z := s ; fi
+ endfor ;
mfun_tt_c
enddef ;
vardef thefmttext@#(text t) =
- mfun_tt_z := origin ;
+ mfun_tt_z := origin ; % initialization
save p ; picture p ; p := rawfmttext(t) ;
- p
+ if anchortextexts > 0 :
+ image(draw p withprescript "tx_anchor=" & ddecimal mfun_tt_z)
+ else :
+ p
+ fi
if (mfun_labtype@# >= 10) :
shifted (0,ypart center p)
fi
- shifted (mfun_tt_z + textextoffset*mfun_laboff@# - (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p))
+ shifted (mfun_tt_z + textextoffset*mfun_laboff@# - mfun_labshift@#(p))
enddef ;
vardef fmttext@#(text t) = % no draw here
@@ -504,18 +514,44 @@ vardef thetexbox@#(expr category, name, z) =
if (mfun_labtype@# >= 10) :
shifted (0,ypart center p)
fi
- shifted (z + textextoffset*mfun_laboff@# - (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p))
+ shifted (z + textextoffset*mfun_laboff@# - mfun_labshift@#(p))
enddef ;
vardef texbox@#(expr category, name) = % no draw here
thetexbox@#(category,name,origin)
enddef ;
+% vardef thelabel@#(expr p,z) =
+% if string p :
+% thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p) scaled defaultscale,z)
+% else :
+% p shifted (z + labeloffset*mfun_laboff@# - (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p))
+% fi
+% enddef;
+
+vardef theoffset@#(expr z) =
+ if pair z :
+ z
+ elseif path z :
+ if mfun_laboff@# = origin :
+ center z
+ else :
+ ((center z)-- mfun_picshift@#(z)) intersectionpoint (z if not cycle z: --cycle fi)
+ fi
+ else : % picture
+ mfun_picshift@#(z)
+ fi
+enddef;
+
vardef thelabel@#(expr p,z) =
if string p :
thelabel@#(rawtextext("\definedfont[" & defaultfont & "]" & p) scaled defaultscale,z)
+ elseif numeric p :
+ thelabel@#(decimal p,z)
+ elseif pair p :
+ thelabel@#("(" & decimal(xpart p) & "," & decimal(ypart p) & ")",z)
else :
- p shifted (z + labeloffset*mfun_laboff@# - (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p))
+ p shifted (theoffset@#(z) + labeloffset*mfun_laboff@# - mfun_labshift@#(p))
fi
enddef;
@@ -528,7 +564,7 @@ vardef anchored@#(expr p, z) = % beware: no "+ mfun_laboff@#" here (never!)
if (mfun_labtype@# >= 10) :
shifted (0,ypart center p)
fi
- shifted (z + (mfun_labxf@#*lrcorner p + mfun_labyf@#*ulcorner p + (1-mfun_labxf@#-mfun_labyf@#)*llcorner p))
+ shifted (z + mfun_labshift@#(p))
enddef ;
let normalinfont = infont ;
@@ -984,18 +1020,16 @@ def withmask primary filename =
withprescript "fg_mask=" & filename
enddef ;
-def externalfigure primary filename =
- if false :
- rawtextext("\externalfigure[" & filename & "]")
- else :
- image (
- addto currentpicture doublepath unitsquare
- withprescript "fg_name=" & filename ;
- )
-% unitsquare
-% withpen pencircle scaled 0
-% withprescript "fg_name=" & filename
- fi
+vardef externalfigure primary filename =
+ mfun_tt_c := nullpicture ;
+ mfun_tt_r := lua.mp.mf_external_figure(filename) ;
+ addto mfun_tt_c doublepath unitsquare
+ xscaled wdpart mfun_tt_r
+ yscaled htpart mfun_tt_r
+ withprescript "mf_object=figure"
+ withprescript "fg_name=" & filename ;
+ ;
+ mfun_tt_c
enddef ;
def figure primary filename =
@@ -1015,101 +1049,85 @@ enddef ;
numeric currentoutlinetext ; currentoutlinetext := 0 ;
-vardef mfun_do_outline_text_flush (expr kind, n, x, y) (text t) =
+vardef mfun_do_outline_text_flush (expr kind, n, x, y, c) (text t) =
if kind = "f" :
- mfun_do_outline_text_f (n, x, y) (t)
+ mfun_do_outline_text_f (n, x, y, c) (t)
elseif kind = "d" :
- mfun_do_outline_text_d (n, x, y) (t)
+ mfun_do_outline_text_d (n, x, y, c) (t)
elseif kind = "b" :
- mfun_do_outline_text_b (n, x, y) (t)
+ mfun_do_outline_text_b (n, x, y, c) (t)
elseif kind = "r" :
- mfun_do_outline_text_r (n, x, y) (t)
+ mfun_do_outline_text_r (n, x, y, c) (t)
elseif kind = "p" :
- mfun_do_outline_text_p (n, x, y) (t)
+ mfun_do_outline_text_p (n, x, y, c) (t)
elseif kind = "u" :
- mfun_do_outline_text_u (n, x, y) (t)
+ mfun_do_outline_text_u (n, x, y, c) (t)
else :
- mfun_do_outline_text_n (n, x, y) (t)
+ mfun_do_outline_text_n (n, x, y, c) (t)
fi ;
enddef ;
vardef mfun_do_outline_rule_flush (expr kind, x, y, w, h) =
- mfun_do_outline_text_flush (kind, 1, x, y) (fullsquare xyscaled(w,h))
+ mfun_do_outline_text_flush (kind, 1, x, y, "") (fullsquare xyscaled(w,h))
enddef ;
numeric mfun_do_outline_n ; mfun_do_outline_n := 0 ;
-vardef mfun_do_outline_text_f (expr n, x, y) (text t) =
+vardef mfun_do_outline_text_f (expr n, x, y, c) (text t) =
mfun_do_outline_n := 0 ;
for i=t :
mfun_do_outline_n := mfun_do_outline_n + 1 ;
- if mfun_do_outline_n = n :
- fill i shifted(x,y) mfun_do_outline_options_f withpen pencircle scaled 0
- else :
- nofill i shifted(x,y)
- fi ;
+ if mfun_do_outline_n = n : fill else : nofill fi (i shifted(x,y)) mfun_do_outline_options_f withpen pencircle scaled 0 withprescript c ;
endfor ;
enddef ;
-vardef mfun_do_outline_text_u (expr n, x, y) (text t) =
+vardef mfun_do_outline_text_u (expr n, x, y, c) (text t) =
mfun_do_outline_n := 0 ;
for i=t :
mfun_do_outline_n := mfun_do_outline_n + 1 ;
- if mfun_do_outline_n = n :
- fillup i shifted(x,y) mfun_do_outline_options_f
- else :
- nofill i shifted(x,y)
- fi ;
+ if mfun_do_outline_n = n : fillup else : nofill fi (i shifted(x,y)) mfun_do_outline_options_f withprescript c ;
endfor ;
enddef ;
-vardef mfun_do_outline_text_d (expr n, x, y) (text t) =
+vardef mfun_do_outline_text_d (expr n, x, y, c) (text t) =
for i=t :
draw i shifted(x,y) mfun_do_outline_options_d ;
endfor ;
enddef ;
-vardef mfun_do_outline_text_p (expr n, x, y) (text t) =
+vardef mfun_do_outline_text_p (expr n, x, y, c) (text t) =
for i=t :
- draw i shifted(x,y) ;
+ draw i shifted(x,y) withprescript c ;
endfor ;
enddef ;
-vardef mfun_do_outline_text_b (expr n, x, y) (text t) =
+vardef mfun_do_outline_text_b (expr n, x, y, c) (text t) =
mfun_do_outline_n := 0 ;
for i=t :
mfun_do_outline_n := mfun_do_outline_n + 1 ;
- if mfun_do_outline_n = n :
- fill i shifted(x,y) mfun_do_outline_options_f
- else :
- nofill i shifted(x,y)
- fi ;
+ if mfun_do_outline_n = n : fill else : nofill fi (i shifted(x,y)) mfun_do_outline_options_f ;
endfor ;
for i=t :
draw i shifted(x,y) mfun_do_outline_options_d ;
endfor ;
enddef ;
-vardef mfun_do_outline_text_r (expr n, x, y) (text t) =
+vardef mfun_do_outline_text_r (expr n, x, y, c) (text t) =
mfun_do_outline_n := 0 ;
for i=t :
draw i shifted(x,y) mfun_do_outline_options_d ;
endfor ;
for i=t :
mfun_do_outline_n := mfun_do_outline_n + 1 ;
- if mfun_do_outline_n = n :
- fill i shifted(x,y) mfun_do_outline_options_f
- else :
- nofill i shifted(x,y)
- fi ;
+ if mfun_do_outline_n = n : fill else : nofill fi (i shifted(x,y)) mfun_do_outline_options_f;
endfor ;
enddef ;
-vardef mfun_do_outline_text_n (expr n, x, y) (text t) =
+vardef mfun_do_outline_text_n (expr n, x, y, c) (text t) =
mfun_do_outline_n := 0 ;
for i=t :
mfun_do_outline_n := mfun_do_outline_n + 1 ;
- if mfun_do_outline_n = n : fill else : nofill fi i shifted(x,y) ;
+ if mfun_do_outline_n = n : fill else : nofill fi (i shifted(x,y)) ;
endfor ;
enddef ;
@@ -1146,6 +1164,39 @@ def mfun_do_outline_options_d = enddef ;
def mfun_do_outline_options_f = enddef ;
def mfun_do_outline_options_r = enddef ;
+def outlinetexttopath(text o, p, n) =
+ scantokens("numeric " & str n & ";") ;
+ scantokens("path " & str p & "[];") ;
+ n := 0 ;
+ for i within o : p[incr(n)] := pathpart i ; endfor ;
+enddef ;
+
+def filloutlinetext(expr o) =
+ draw image (
+ save n, m ; numeric n, m ; n := m := 0 ;
+ for i within o :
+ n := n + 1 ;
+ endfor ;
+ for i within o :
+ m := m + 1 ;
+ if n = m :
+ eofill
+ else :
+ nofill
+ fi pathpart i ;
+ endfor ;
+ )
+enddef ;
+
+def drawoutlinetext(expr o) =
+ draw image (
+ % nicer for properties
+ for i within o :
+ draw pathpart i ;
+ endfor ;
+ )
+enddef ;
+
vardef outlinetext@# (expr t) text rest =
save kind ; string kind ; kind := str @# ;
currentoutlinetext := currentoutlinetext + 1 ;
@@ -1153,32 +1204,25 @@ vardef outlinetext@# (expr t) text rest =
def mfun_do_outline_options_f = enddef ;
def mfun_do_outline_options_r = enddef ;
image ( normaldraw image (
- if mfun_trial_run :
- % lua.mp.report("set outline text",currentoutlinetext);
- normaldraw unitsquare
- withprescript "ot_stage=trial"
- withprescript "ot_index=" & decimal currentoutlinetext
- withprescript "ot_kind=" & kind
- withpostscript t ;
+ % lua.mp.report("set outline text",currentoutlinetext);
+ lua.mp.mf_outline_text(currentoutlinetext,t,kind) ;
+ % lua.mp.report("get outline text",currentoutlinetext);
+ if kind = "f" :
+ mfun_do_outline_text_set_f rest ;
+ elseif kind = "d" :
+ mfun_do_outline_text_set_d rest ;
+ elseif kind = "b" :
+ mfun_do_outline_text_set_b rest ;
+ elseif kind = "u" :
+ mfun_do_outline_text_set_f rest ;
+ elseif kind = "r" :
+ mfun_do_outline_text_set_r rest ;
+ elseif kind = "p" :
+ mfun_do_outline_text_set_p ;
else :
- % lua.mp.report("get outline text",currentoutlinetext);
- if kind = "f" :
- mfun_do_outline_text_set_f rest ;
- elseif kind = "d" :
- mfun_do_outline_text_set_d rest ;
- elseif kind = "b" :
- mfun_do_outline_text_set_b rest ;
- elseif kind = "u" :
- mfun_do_outline_text_set_f rest ;
- elseif kind = "r" :
- mfun_do_outline_text_set_r rest ;
- elseif kind = "p" :
- mfun_do_outline_text_set_p ;
- else :
- mfun_do_outline_text_set_n rest ;
- fi ;
- lua.mp.get_outline_text(currentoutlinetext) ;
+ mfun_do_outline_text_set_n rest ;
fi ;
+ lua.mp.mf_get_outline_text(currentoutlinetext) ;
) mfun_do_outline_options_r ; )
enddef ;
@@ -1209,7 +1253,6 @@ vardef rule(expr wd,ht,dp) =
image (fill (0,-dp)--(wd,-dp)--(wd,ht)--(0,ht)--cycle)
enddef ;
-
% Housekeeping
extra_beginfig := extra_beginfig & "currentgraphictext := 0 ; " ;
@@ -1254,9 +1297,9 @@ def withproperties expr p =
withcolor (cyanpart p,magentapart p,yellowpart p,blackpart p)
fi
withpen penpart p
- % if dashpart p <> nullpicture : % fails
+ if length (dashpart p) > 0 :
dashed dashpart p
- % fi
+ fi
withprescript prescriptpart p
withpostscript postscriptpart p
enddef ;
@@ -1357,7 +1400,42 @@ vardef mfun_cmykcolor_to_string(expr c) =
decimal blackpart c
enddef ;
-vardef mfun_greycolor_to_string(expr n) =
+vardef mfun_pair_to_table(expr p) =
+ "{" & decimal xpart p &
+ "," & decimal ypart p &
+ "}"
+enddef ;
+
+vardef mfun_point_to_table(expr p,i) =
+ "{" & decimal xpart (point i of p) &
+ "," & decimal ypart (point i of p) &
+ "," & decimal xpart (precontrol i of p) &
+ "," & decimal ypart (precontrol i of p) &
+ "," & decimal xpart (postcontrol i of p) &
+ "," & decimal ypart (postcontrol i of p) &
+ "}"
+enddef ;
+
+vardef mfun_path_to_table(expr p) =
+ "{" & mfun_point_to_table(p,0) for i=1 upto length(p) : & "," & mfun_point_to_table(p,i) endfor & "}"
+enddef ;
+
+vardef mfun_rgb_to_table(expr c) =
+ "{" & decimal redpart c &
+ "," & decimal greenpart c &
+ "," & decimal bluepart c &
+ "}"
+enddef ;
+
+vardef mfun_cmyk_to_table(expr c) =
+ "{" & decimal cyanpart c &
+ "," & decimal magentapart c &
+ "," & decimal yellowpart c &
+ "," & decimal blackpart c &
+ "}"
+enddef ;
+
+vardef mfun_grey_to_string(expr n) =
decimal n
enddef ;
@@ -1568,8 +1646,8 @@ enddef ;
vardef strfmt(expr f, x) = "\MPgraphformat{" & escaped_format(f) & "}{" & mfun_tagged_string(x) & "}" enddef ;
vardef varfmt(expr f, x) = "\MPformatted{" & escaped_format(f) & "}{" & mfun_tagged_string(x) & "}" enddef ;
-vardef format (expr f, x) = textext(strfmt(f, x)) enddef ;
-vardef formatted(expr f, x) = textext(varfmt(f, x)) enddef ;
+vardef format@# (expr f, x) = textext@#(strfmt(f, x)) enddef ;
+vardef formatted@#(expr f, x) = textext@#(varfmt(f, x)) enddef ;
% could be this (something to discuss with alan as it involves graph):
%
@@ -1596,12 +1674,15 @@ def nofill text t = fill t withpostscript "collect" enddef ;
% so we can do: withcolor "red"
-vardef resolvedcolor primary s =
- % lua.mp.namedcolor(s) % conflicts with macro namedcolor
- % lua.mp.NamedColor(s) % okay but, can also be
- % lua.mp("NamedColor",s) % which gives expansion mess
+% We do a low level runscript:
+%
+% lua.mp.namedcolor(s) % conflicts with macro namedcolor
+% lua.mp.mf_named_color(s) % okay but, can also be
+% lua.mp("mf_named_color",s) % which gives expansion mess
+
+def resolvedcolor primary s = % no vardef
if string s :
- runscript("mp.NamedColor('" & s & "')") % faster anyway
+ runscript("mp.mf_named_color('" & s & "')") % faster anyway
else :
s
fi
@@ -1614,6 +1695,10 @@ def comment expr str =
special "metapost.comment[[" & str & "]]" ;
enddef ;
+vardef report(text t) =
+ lua.mp.report(t)
+enddef ;
+
% This overloads a dummy:
vardef uniquelist(suffix list) =
diff --git a/metapost/context/base/mpiv/mp-node.mpiv b/metapost/context/base/mpiv/mp-node.mpiv
index 79391220b..5829558e6 100644
--- a/metapost/context/base/mpiv/mp-node.mpiv
+++ b/metapost/context/base/mpiv/mp-node.mpiv
@@ -53,6 +53,8 @@ vardef makenode@#(text t) =
for a = t :
if (path a) or (unknown a) :
mfun_makenode@#(t,)
+ elseif (string a) and (length(a) = 0) :
+ mfun_makenode@#(t,)
else :
mfun_makenode@#(nodepath, t,)
fi
@@ -64,6 +66,8 @@ vardef node@#(text t) =
for a = t :
if (path a) or (unknown a) :
mfun_node@#(t,)
+ elseif (string a) and (length(a) = 0) :
+ mfun_node@#(t,)
else :
mfun_node@#(nodepath, t,)
fi
@@ -75,6 +79,8 @@ vardef nodeboundingpoint@#(text t) =
for a = t :
if (path a) or (unknown a) :
mfun_nodeboundingpoint@#(t)
+ elseif (string a) and (length(a) = 0) :
+ mfun_nodeboundingpoint@#(t)
else :
mfun_nodeboundingpoint@#(nodepath,a)
fi
@@ -231,7 +237,7 @@ vardef betweennodes@#(suffix p)(expr f)(suffix q)(text s) =
for a = s :
if unknown t :
t = a ;
- nodeboundingpoint@#(q,t) + nodeboundingpoint@#(p,f)
+ mfun_nodeboundingpoint@#(q,t) + mfun_nodeboundingpoint@#(p,f)
else :
+ relative@#(a)
fi
diff --git a/metapost/context/base/mpiv/mp-page.mpiv b/metapost/context/base/mpiv/mp-page.mpiv
index 6e93bdaae..eba66a005 100644
--- a/metapost/context/base/mpiv/mp-page.mpiv
+++ b/metapost/context/base/mpiv/mp-page.mpiv
@@ -188,6 +188,8 @@ fi ;
string CurrentLayout ; CurrentLayout := "default" ;
+% runscript("mp.PaperHeight()") % way faster of course
+
vardef PaperHeight = lua.mp.PaperHeight () enddef ;
vardef PaperWidth = lua.mp.PaperWidth () enddef ;
vardef PrintPaperHeight = lua.mp.PrintPaperHeight () enddef ;
@@ -319,8 +321,9 @@ vardef OverlayHeight = lua.mp.OverlayHeight () enddef ;
vardef OverlayDepth = lua.mp.OverlayDepth () enddef ;
vardef OverlayLineWidth = lua.mp.OverlayLineWidth() enddef ;
vardef OverlayOffset = lua.mp.OverlayOffset () enddef ;
+vardef OverlayRegion = lua.mp.OverlayRegion () enddef ;
-vardef defaultcolormodel = lua.mp.defaultcolormodel() enddef ;
+vardef defaultcolormodel = lua.mp.mf_default_color_model() enddef ;
% def OverlayLineColor = lua.mp.OverlayLineColor() enddef ;
% def OverlayColor = lua.mp.OverlayColor () enddef ;
diff --git a/metapost/context/base/mpiv/mp-tool.mpiv b/metapost/context/base/mpiv/mp-tool.mpiv
index 75706e09b..2cdb5fb39 100644
--- a/metapost/context/base/mpiv/mp-tool.mpiv
+++ b/metapost/context/base/mpiv/mp-tool.mpiv
@@ -17,6 +17,8 @@ boolean context_tool ; context_tool := true ;
let @## = @# ;
+let noexpand = quote ;
+
%D New, version number testing:
%D
%D \starttyping
@@ -242,19 +244,19 @@ boolean savingdata ; savingdata := false ;
boolean savingdatadone ; savingdatadone := false ;
def savedata expr txt =
- lua.mp.save_data(txt);
+ lua.mp.mf_save_data(txt);
enddef ;
def startsavingdata =
- lua.mp.start_saving_data();
+ lua.mp.mf_start_saving_data();
enddef ;
def stopsavingdata =
- lua.mp.stop_saving_data() ;
+ lua.mp.mf_stop_saving_data() ;
enddef ;
def finishsavingdata =
- lua.mp.finish_saving_data() ;
+ lua.mp.mf_finish_saving_data() ;
enddef ;
%D Instead of a keystroke eating save and allocation
@@ -302,7 +304,7 @@ def newpair text v = forsuffixes i=v : save i ; pair i ; endfor ; endd
%D set_inner_boundingbox p
%D \stoptyping
-path mfun_boundingbox_stack ;
+path mfun_boundingbox_stack[] ;
numeric mfun_boundingbox_stack_depth ;
mfun_boundingbox_stack_depth := 0 ;
@@ -314,7 +316,7 @@ enddef ;
def popboundingbox text p =
setbounds p to mfun_boundingbox_stack[mfun_boundingbox_stack_depth] ;
- mfun_boundingbox_stack[mfun_boundingbox_stack_depth] := origin ;
+ mfun_boundingbox_stack[mfun_boundingbox_stack_depth] := origin -- cycle ;
mfun_boundingbox_stack_depth := mfun_boundingbox_stack_depth - 1 ;
enddef ;
@@ -323,7 +325,7 @@ let pop_boundingbox = popboundingbox ; % downward compatible
vardef boundingbox primary p =
if (path p) or (picture p) :
- llcorner p -- lrcorner p -- urcorner p -- ulcorner p
+ llcorner p -- lrcorner p -- urcorner p -- ulcorner p
else :
origin
fi -- cycle
@@ -395,6 +397,14 @@ vardef boundingpoint@#(expr p) =
fi
enddef ;
+def mirrored primary a =
+ a scaled -1
+enddef ;
+
+primarydef a mirroredabout b =
+ (a shifted -b) scaled -1 shifted b
+enddef ;
+
%D Some missing functions can be implemented rather straightforward (thanks to
%D Taco and others):
@@ -2881,13 +2891,15 @@ enddef ;
% This could be standard mplib 2 behaviour:
+% vardef rcomponent expr p = if rgbcolor p : redpart elseif cmykcolor p : 1 - cyanpart fi p enddef ;
+
vardef rcomponent expr p = if rgbcolor p : redpart p elseif cmykcolor p : 1 - cyanpart p else : p fi enddef ;
vardef gcomponent expr p = if rgbcolor p : greenpart p elseif cmykcolor p : 1 - magentapart p else : p fi enddef ;
vardef bcomponent expr p = if rgbcolor p : bluepart p elseif cmykcolor p : 1 - yellowpart p else : p fi enddef ;
vardef ccomponent expr p = if cmykcolor p : cyanpart p elseif rgbcolor p : 1 - redpart p else : p fi enddef ;
vardef mcomponent expr p = if cmykcolor p : magentapart p elseif rgbcolor p : 1 - greenpart p else : p fi enddef ;
vardef ycomponent expr p = if cmykcolor p : yellowpart p elseif rgbcolor p : 1 - bluepart p else : p fi enddef ;
-vardef bcomponent expr p = if cmykcolor p : blackpart p elseif rgbcolor p : 0 else : p fi enddef ;
+vardef kcomponent expr p = if cmykcolor p : blackpart p elseif rgbcolor p : 0 else : p fi enddef ;
% draw image (...) ... ; % prescripts prepended to first, postscripts appended to last
% draw decorated (...) ... ; % prescripts prepended to each, postscripts appended to each
@@ -3405,8 +3417,7 @@ primarydef p crossingunder q =
a := hold[hold] ; hold := hold - 1 ;
fi
if i = crossingnumbermax :
- message("crossingunder reached maximum " & decimal i &
- " intersections.");
+ message("crossingunder reached maximum " & decimal i & " intersections.");
fi
endfor
@@ -3554,3 +3565,40 @@ enddef ;
vardef tocycle(suffix p)(text t) =
topath(p,t) t cycle
enddef ;
+
+% reimplemented to support paths and pictures
+
+def drawdot expr p =
+ if pair p :
+ addto currentpicture doublepath p
+ withpen currentpen _op_
+ elseif path p :
+ draw image (
+ for i=0 upto length p :
+ addto currentpicture doublepath point i of p
+ withpen currentpen _op_ ;
+ endfor ;
+ )
+ elseif picture p :
+ draw image (
+ save pp ; path pp ;
+ for i within p :
+ if stroked i or filled i :
+ pp := pathpart i ;
+ for j=0 upto length pp :
+ addto currentpicture doublepath point j of pp
+ withpen currentpen _op_ ;
+ endfor ;
+ fi ;
+ endfor ;
+ )
+ fi
+enddef ;
+
+% vardef textlength(text t) =
+% save n ; n := 0 ;
+% for i = t :
+% n := n + 1 ;
+% endfor;
+% n
+% enddef;
diff --git a/metapost/context/base/mpiv/mp-tres.mpiv b/metapost/context/base/mpiv/mp-tres.mpiv
index 335670a98..c331d71af 100644
--- a/metapost/context/base/mpiv/mp-tres.mpiv
+++ b/metapost/context/base/mpiv/mp-tres.mpiv
@@ -96,14 +96,14 @@ primarydef p XYZscaled q =
(q*Xpart p,q*Ypart p,q*Zpart p)
enddef ;
-vardef projection expr t =
- if triplet t :
+vardef projection primary t =
+ (if triplet t :
(Xpart t, Ypart t) transformed Txy shifted (0,Zpart t)
- elseif pair t :
+ elseif pair t :
t transformed Txy
- else :
+ else :
origin transformed Txy
- fi
+ fi)
enddef ;
%D This overloads the plain macro \type {abs} (being \type {length}):
@@ -166,6 +166,59 @@ vardef draw_vector@# (expr v, s) text t =
fi
enddef ;
+%D Transform a (2D) path to a 3D plane
+
+def XYpath primary p =
+ (for i=0 upto (length p) if cycle p: -1 fi :
+ if i>0 : .. fi
+ projection (xpart point i of p,
+ ypart point i of p,
+ 0)
+ ..controls
+ projection (xpart postcontrol i of p,
+ ypart postcontrol i of p,
+ 0)
+ and
+ projection (xpart precontrol (i+1) of p,
+ ypart precontrol (i+1) of p,
+ 0)
+ endfor if cycle p: ..cycle fi)
+enddef ;
+
+def XZpath primary p =
+ (for i=0 upto (length p) if cycle p: -1 fi :
+ if i>0 : .. fi
+ projection (xpart point i of p,
+ 0,
+ ypart point i of p)
+ ..controls
+ projection (xpart postcontrol i of p,
+ 0,
+ ypart postcontrol i of p)
+ and
+ projection (xpart precontrol (i+1) of p,
+ 0,
+ ypart precontrol (i+1) of p)
+ endfor if cycle p: ..cycle fi)
+enddef ;
+
+def YZpath primary p =
+ (for i=0 upto (length p) if cycle p: -1 fi :
+ if i>0 : .. fi
+ projection (0,
+ xpart point i of p,
+ ypart point i of p)
+ ..controls
+ projection (0,
+ xpart postcontrol i of p,
+ ypart postcontrol i of p)
+ and
+ projection (0,
+ xpart precontrol (i+1) of p,
+ ypart precontrol (i+1) of p)
+ endfor if cycle p: ..cycle fi)
+enddef ;
+
%D Some constants...
triplet Origin, Xunitvector, Yunitvector, Zunitvector ;
diff --git a/scripts/context/lua/mtx-colors.lua b/scripts/context/lua/mtx-colors.lua
index 7dd1b4ac4..1c3f8cf82 100644
--- a/scripts/context/lua/mtx-colors.lua
+++ b/scripts/context/lua/mtx-colors.lua
@@ -61,7 +61,14 @@ function scripts.colors.table()
end
end
else
- report("no file(s) given" )
+ local files = resolvers.findfiles("*.icc")
+ if #files > 0 then
+ for i=1,#files do
+ report(files[i])
+ end
+ else
+ report("no file(s) given" )
+ end
end
end
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index f380dc6ff..0288d686c 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -40,49 +40,49 @@ local application = logs.application {
}
-- local luatexflags = {
--- ["8bit"] = true, -- ignored, input is assumed to be in UTF-8 encoding
--- ["default-translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
--- ["translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
--- ["etex"] = true, -- ignored, the etex extensions are always active
--- ["parse-first-line"] = true, -- ignored, enable parsing of the first line of the input file
--- ["no-parse-first-line"] = true, -- ignored, disable parsing of the first line of the input file
+-- ["8bit"] = true, -- ignored, input is assumed to be in UTF-8 encoding
+-- ["default-translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
+-- ["translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
+-- ["etex"] = true, -- ignored, the etex extensions are always active
+-- ["parse-first-line"] = true, -- ignored, enable parsing of the first line of the input file
+-- ["no-parse-first-line"] = true, -- ignored, disable parsing of the first line of the input file
--
--- ["credits"] = true, -- display credits and exit
--- ["debug-format"] = true, -- enable format debugging
--- ["disable-write18"] = true, -- disable \write18{SHELL COMMAND}
--- ["draftmode"] = true, -- switch on draft mode (generates no output PDF)
--- ["enable-write18"] = true, -- enable \write18{SHELL COMMAND}
--- ["file-line-error"] = true, -- enable file:line:error style messages
--- ["file-line-error-style"] = true, -- aliases of --file-line-error
--- ["no-file-line-error"] = true, -- disable file:line:error style messages
--- ["no-file-line-error-style"] = true, -- aliases of --no-file-line-error
--- ["fmt"] = true, -- load the format file FORMAT
--- ["halt-on-error"] = true, -- stop processing at the first error
--- ["help"] = true, -- display help and exit
--- ["ini"] = true, -- be iniluatex, for dumping formats
--- ["interaction"] = true, -- set interaction mode (STRING=batchmode/nonstopmode/scrollmode/errorstopmode)
--- ["jobname"] = true, -- set the job name to STRING
--- ["kpathsea-debug"] = true, -- set path searching debugging flags according to the bits of NUMBER
--- ["lua"] = true, -- load and execute a lua initialization script
--- ["mktex"] = true, -- enable mktexFMT generation (FMT=tex/tfm)
--- ["no-mktex"] = true, -- disable mktexFMT generation (FMT=tex/tfm)
--- ["nosocket"] = true, -- disable the lua socket library
--- ["output-comment"] = true, -- use STRING for DVI file comment instead of date (no effect for PDF)
--- ["output-directory"] = true, -- use existing DIR as the directory to write files in
--- ["output-format"] = true, -- use FORMAT for job output; FORMAT is 'dvi' or 'pdf'
--- ["progname"] = true, -- set the program name to STRING
--- ["recorder"] = true, -- enable filename recorder
--- ["safer"] = true, -- disable easily exploitable lua commands
--- ["shell-escape"] = true, -- enable \write18{SHELL COMMAND}
--- ["no-shell-escape"] = true, -- disable \write18{SHELL COMMAND}
--- ["shell-restricted"] = true, -- restrict \write18 to a list of commands given in texmf.cnf
--- ["nodates"] = true, -- no production dates in pdf file
--- ["trailerid"] = true, -- alternative trailer id
--- ["synctex"] = true, -- enable synctex
--- ["version"] = true, -- display version and exit
--- ["luaonly"] = true, -- run a lua file, then exit
--- ["luaconly"] = true, -- byte-compile a lua file, then exit
--- ["jiton"] = false,
+-- ["credits"] = true, -- display credits and exit
+-- ["debug-format"] = true, -- enable format debugging
+-- ["disable-write18"] = true, -- disable \write18{SHELL COMMAND}
+-- ["draftmode"] = true, -- switch on draft mode (generates no output PDF)
+-- ["enable-write18"] = true, -- enable \write18{SHELL COMMAND}
+-- ["file-line-error"] = true, -- enable file:line:error style messages
+-- ["file-line-error-style"] = true, -- aliases of --file-line-error
+-- ["no-file-line-error"] = true, -- disable file:line:error style messages
+-- ["no-file-line-error-style"] = true, -- aliases of --no-file-line-error
+-- ["fmt"] = true, -- load the format file FORMAT
+-- ["halt-on-error"] = true, -- stop processing at the first error
+-- ["help"] = true, -- display help and exit
+-- ["ini"] = true, -- be iniluatex, for dumping formats
+-- ["interaction"] = true, -- set interaction mode (STRING=batchmode/nonstopmode/scrollmode/errorstopmode)
+-- ["jobname"] = true, -- set the job name to STRING
+-- ["kpathsea-debug"] = true, -- set path searching debugging flags according to the bits of NUMBER
+-- ["lua"] = true, -- load and execute a lua initialization script
+-- ["mktex"] = true, -- enable mktexFMT generation (FMT=tex/tfm)
+-- ["no-mktex"] = true, -- disable mktexFMT generation (FMT=tex/tfm)
+-- ["nosocket"] = true, -- disable the lua socket library
+-- ["output-comment"] = true, -- use STRING for DVI file comment instead of date (no effect for PDF)
+-- ["output-directory"] = true, -- use existing DIR as the directory to write files in
+-- ["output-format"] = true, -- use FORMAT for job output; FORMAT is 'dvi' or 'pdf'
+-- ["progname"] = true, -- set the program name to STRING
+-- ["recorder"] = true, -- enable filename recorder
+-- ["safer"] = true, -- disable easily exploitable lua commands
+-- ["shell-escape"] = true, -- enable \write18{SHELL COMMAND}
+-- ["no-shell-escape"] = true, -- disable \write18{SHELL COMMAND}
+-- ["shell-restricted"] = true, -- restrict \write18 to a list of commands given in texmf.cnf
+-- ["nodates"] = true, -- no production dates in pdf file
+-- ["trailerid"] = true, -- alternative trailer id
+-- ["synctex"] = true, -- enable synctex
+-- ["version"] = true, -- display version and exit
+-- ["luaonly"] = true, -- run a lua file, then exit
+-- ["luaconly"] = true, -- byte-compile a lua file, then exit
+-- ["jiton"] = false, -- not supported (makes no sense, slower)
-- }
local report = application.report
@@ -95,12 +95,15 @@ scripts.context = scripts.context or { }
if jit then -- already luajittex
setargument("engine","luajittex")
setargument("jit",nil)
-elseif getargument("jit") or getargument("jiton") then -- relaunch luajittex
- -- bonus shortcut, we assume than --jit also indicates the engine
+elseif getargument("jit") then -- relaunch luajittex
+ -- bonus shortcut, we assume that --jit also indicates the engine
-- although --jit and --engine=luajittex are independent
setargument("engine","luajittex")
end
+-- -- The way we use stubs will change in a bit in 2019 (mtxrun and context). We also normalize
+-- -- the platforms to use a similar approach to this.
+
local engine_new = file.nameonly(getargument("engine") or directives.value("system.engine"))
local engine_old = file.nameonly(environment.ownbin)
@@ -111,15 +114,15 @@ local function restart(engine_old,engine_new)
os.exit(result == 0 and 0 or 1)
end
-if getargument("redirected") then
- setargument("engine",engine_old) -- later on we need this
-elseif engine_new == engine_old then
- setargument("engine",engine_new) -- later on we need this
-elseif environment.validengines[engine_new] and engine_new ~= environment.basicengines[engine_old] then
- restart(engine_old,engine_new)
-else
- setargument("engine",engine_new) -- later on we need this
-end
+-- if getargument("redirected") then
+-- setargument("engine",engine_old) -- later on we need this
+-- elseif engine_new == engine_old then
+-- setargument("engine",engine_new) -- later on we need this
+-- elseif environment.validengines[engine_new] and engine_new ~= environment.basicengines[engine_old] then
+-- restart(engine_old,engine_new)
+-- else
+-- setargument("engine",engine_new) -- later on we need this
+-- end
-- so far
@@ -433,6 +436,7 @@ end
local pdfview -- delayed
local function pdf_open(name,method)
+ statistics.starttiming("pdfview")
pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
pdfview.setmethod(method)
report(pdfview.status())
@@ -441,9 +445,12 @@ local function pdf_open(name,method)
pdfname = name .. ".pdf" -- agressive
end
pdfview.open(pdfname)
+ statistics.stoptiming("pdfview")
+ report("pdfview overhead: %s seconds",statistics.elapsedtime("pdfview"))
end
local function pdf_close(name,method)
+ statistics.starttiming("pdfview")
pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
pdfview.setmethod(method)
local pdfname = filenewsuffix(name,"pdf")
@@ -452,6 +459,7 @@ local function pdf_close(name,method)
end
pdfname = name .. ".pdf" -- agressive
pdfview.close(pdfname)
+ statistics.stoptiming("pdfview")
end
-- result file handling
@@ -596,7 +604,7 @@ function scripts.context.run(ctxdata,filename)
local a_nofile = getargument("nofile")
local a_engine = getargument("engine")
--
- local files = environment.files or { }
+ local files = environment.filenames or { }
--
local filelist, mainfile
--
@@ -651,7 +659,6 @@ function scripts.context.run(ctxdata,filename)
local a_backend = getargument("backend")
local a_arrange = getargument("arrange")
local a_noarrange = getargument("noarrange")
- local a_jiton = getargument("jiton")
local a_jithash = getargument("jithash")
local a_texformat = getargument("texformat")
local a_keeptuc = getargument("keeptuc")
@@ -665,11 +672,11 @@ function scripts.context.run(ctxdata,filename)
-- side effects (so no bug reports please) .. we provide --sandbox that
-- does similar things but tries to ensure that context works as expected
- local a_safer = getargument("safer")
-
- if a_safer then
- report("warning: using the luatex safer options, processing is not guaranteed")
- end
+ -- local a_safer = getargument("safer")
+ --
+ -- if a_safer then
+ -- report("warning: using the luatex safer options, processing is not guaranteed")
+ -- end
--
a_batchmode = (a_batchmode and "batchmode") or (a_nonstopmode and "nonstopmode") or (a_scrollmode and "scrollmode") or nil
@@ -688,7 +695,7 @@ function scripts.context.run(ctxdata,filename)
--
if pathname == "" and not a_global and filename ~= usedfiles.nop then
filename = "./" .. filename
- if not validfile(filename) then
+ if not validfile(filename) and not validfile(filename..".tex") then
report("warning: no (local) file %a, proceeding",filename)
end
end
@@ -709,7 +716,6 @@ function scripts.context.run(ctxdata,filename)
formatfile, scriptfile = resolvers.locateformat(formatname)
end
--
- a_jiton = (a_jiton or toboolean(analysis.jiton,true)) and true or nil
a_jithash = validstring(a_jithash or analysis.jithash) or nil
--
if not formatfile or not scriptfile then
@@ -795,6 +801,7 @@ function scripts.context.run(ctxdata,filename)
ctx = validstring(ctxname),
export = a_export and true or nil,
nocompression = a_nocompression and true or nil,
+ texmfbinpath = os.selfdir,
}
--
for k, v in next, environment.arguments do
@@ -809,14 +816,13 @@ function scripts.context.run(ctxdata,filename)
local l_flags = {
["interaction"] = a_batchmode,
-- ["synctex"] = false, -- context has its own way
- ["no-parse-first-line"] = true, -- obsolete
- ["safer"] = a_safer, -- better use --sandbox
+ -- ["no-parse-first-line"] = true, -- obsolete
+ -- ["safer"] = a_safer, -- better use --sandbox
-- ["no-mktex"] = true,
-- ["file-line-error-style"] = true,
["fmt"] = formatfile,
["lua"] = scriptfile,
["jobname"] = jobname,
- ["jiton"] = a_jiton,
["jithash"] = a_jithash,
}
--
@@ -1185,9 +1191,9 @@ function scripts.context.make(name)
if not getargument("fast") then -- as in texexec
scripts.context.generate()
end
- local list = (name and { name }) or (environment.files[1] and environment.files) or defaultformats
+ local list = (name and { name }) or (environment.filenames[1] and environment.filenames) or defaultformats
local engine = getargument("engine") or "luatex"
- if getargument("jit") or getargument("jiton") then
+ if getargument("jit") then
engine = "luajittex"
end
for i=1,#list do
@@ -1205,7 +1211,7 @@ end
function scripts.context.ctx()
local ctxdata = ctxrunner.new()
- ctxdata.jobname = environment.files[1]
+ ctxdata.jobname = environment.filenames[1]
ctxrunner.checkfile(ctxdata,getargument("ctx"))
ctxrunner.checkflags(ctxdata)
scripts.context.run(ctxdata)
@@ -1213,7 +1219,7 @@ end
function scripts.context.autoctx()
local ctxdata = nil
- local files = environment.files
+ local files = environment.filenames
local firstfile = #files > 0 and files[1]
if firstfile then
local suffix = filesuffix(firstfile)
@@ -1248,7 +1254,7 @@ end
-- local loaded = false
--
-- function scripts.context.metapost()
--- local filename = environment.files[1] or ""
+-- local filename = environment.filenames[1] or ""
-- if not loaded then
-- dofile(resolvers.findfile("mlib-run.lua"))
-- loaded = true
@@ -1265,7 +1271,7 @@ end
-- local jobname = "mtx-context-metapost"
-- local tempname = fileaddsuffix(jobname,"tex")
-- io.savedata(tempname,format(template,"metafun",filename))
--- environment.files[1] = tempname
+-- environment.filenames[1] = tempname
-- setargument("result",resultname)
-- setargument("once",true)
-- scripts.context.run()
@@ -1583,7 +1589,7 @@ end
-- updating (often one will use mtx-update instead)
function scripts.context.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
local zipname = "cont-tmf.zip"
@@ -1792,14 +1798,14 @@ elseif getargument("expert") then
elseif getargument("showmodules") or getargument("modules") then
scripts.context.modules()
elseif getargument("showextras") or getargument("extras") then
- scripts.context.extras(environment.files[1] or getargument("extras"))
+ scripts.context.extras(environment.filenames[1] or getargument("extras"))
elseif getargument("extra") then
scripts.context.extra()
elseif getargument("exporthelp") then
- -- application.export(getargument("exporthelp"),environment.files[1])
+ -- application.export(getargument("exporthelp"),environment.filenames[1])
application.export()
elseif getargument("help") then
- if environment.files[1] == "extras" then
+ if environment.filenames[1] == "extras" then
scripts.context.extras()
else
application.help("basic")
@@ -1810,7 +1816,7 @@ elseif getargument("showdirectives") or getargument("directives") == true then
scripts.context.directives()
elseif getargument("showlogcategories") then
scripts.context.logcategories()
-elseif environment.files[1] or getargument("nofile") then
+elseif environment.filenames[1] or getargument("nofile") then
scripts.context.timed(scripts.context.autoctx)
elseif getargument("pipe") then
scripts.context.timed(scripts.context.pipe)
diff --git a/scripts/context/lua/mtx-context.xml b/scripts/context/lua/mtx-context.xml
index 9003b549a..8c21eaa8c 100644
--- a/scripts/context/lua/mtx-context.xml
+++ b/scripts/context/lua/mtx-context.xml
@@ -70,6 +70,9 @@
<flag name="silent" value="list">
<short>disable logcatgories (show list with <ref name="showlogcategories"/>)</short>
</flag>
+ <flag name="strip">
+ <short>strip Lua code (only meant for production where no errors are expected)</short>
+ </flag>
<flag name="errors" value="list">
<short>show errors at the end of a run, quit when in list (also when <ref name="--silent"/>)</short>
</flag>
@@ -187,6 +190,9 @@
<flag name="keeplog">
<short>keep previous log files (jobname-log-[run].tmp)</short>
</flag>
+ <flag name="lmtx">
+ <short>force lmtx mode (when available)</short>
+ </flag>
</subcategory>
<subcategory>
<flag name="extra=name">
diff --git a/scripts/context/lua/mtx-evohome.lua b/scripts/context/lua/mtx-evohome.lua
index 7fd8612ec..83f87abdf 100644
--- a/scripts/context/lua/mtx-evohome.lua
+++ b/scripts/context/lua/mtx-evohome.lua
@@ -24,6 +24,7 @@ local helpinfo = [[
<category name="basic">
<subcategory>
<flag name="collect"><short>collect data from device</short></flag>
+ <flag name="update"><short>update data from device</short></flag>
<flag name="presets"><short>file with authenciation data</short></flag>
<flag name="auto"><short>fetch temperature data every hour</short></flag>
<flag name="port"><short>server port when running the service, default: 8068</short></flag>
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index 9b23f55c4..5fab67082 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -16,7 +16,7 @@ local lower = string.lower
local concat = table.concat
local write_nl = texio.write_nl
-local otlversion = 3.103
+local otlversion = 3.106
local helpinfo = [[
<?xml version="1.0"?>
diff --git a/scripts/context/lua/mtx-metatex.lua b/scripts/context/lua/mtx-metatex.lua
deleted file mode 100644
index 455ecbd52..000000000
--- a/scripts/context/lua/mtx-metatex.lua
+++ /dev/null
@@ -1,80 +0,0 @@
-if not modules then modules = { } end modules ['mtx-metatex'] = {
- version = 1.001,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files"
-}
-
--- future versions will deal with specific variants of metatex
-
-local helpinfo = [[
-<?xml version="1.0"?>
-<application>
- <metadata>
- <entry name="name">mtx-metatex</entry>
- <entry name="detail">MetaTeX Process Management</entry>
- <entry name="version">0.10</entry>
- </metadata>
- <flags>
- <category name="basic">
- <subcategory>
- <flag name="run"><short>process (one or more) files (default action)</short></flag>
- <flag name="make"><short>create metatex format(s)</short></flag>
- </subcategory>
- </category>
- </flags>
-</application>
-]]
-
-local application = logs.application {
- name = "mtx-metatex",
- banner = "MetaTeX Process Management 0.10",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-
-scripts = scripts or { }
-scripts.metatex = scripts.metatex or { }
-
--- metatex
-
-function scripts.metatex.make()
- environment.make_format("metatex")
-end
-
-function scripts.metatex.run(ctxdata,filename)
- local filename = environment.files[1] or ""
- if filename ~= "" then
- local formatfile, scriptfile = resolvers.locateformat("metatex")
- if formatfile and scriptfile then
- local command = string.format("luatex --fmt=%s --lua=%s %s",
- string.quote(formatfile), string.quote(scriptfile), string.quote(filename))
- report("running command: %s",command)
- os.spawn(command)
- elseif formatname then
- report("error, no format found with name: %s",formatname)
- else
- report("error, no format found (provide formatname or interface)")
- end
- end
-end
-
-function scripts.metatex.timed(action)
- statistics.timed(action)
-end
-
-if environment.argument("run") then
- scripts.metatex.timed(scripts.metatex.run)
-elseif environment.argument("make") then
- scripts.metatex.timed(scripts.metatex.make)
-elseif environment.argument("help") then
- logs.help(messages.help,false)
-elseif environment.argument("exporthelp") then
- application.export(environment.argument("exporthelp"),environment.files[1])
-elseif environment.files[1] then
- scripts.metatex.timed(scripts.metatex.run)
-else
- application.help()
-end
diff --git a/scripts/context/lua/mtx-package.lua b/scripts/context/lua/mtx-package.lua
index 23da30bf2..cf60a444e 100644
--- a/scripts/context/lua/mtx-package.lua
+++ b/scripts/context/lua/mtx-package.lua
@@ -69,8 +69,25 @@ function scripts.package.merge_luatex_files(name)
end
end
end
- report("saving %q",newname)
- io.savedata(newname,table.concat(collected))
+ collected = table.concat(collected)
+ if environment.argument("stripcontext") then
+ local stripped = 0
+ local eol = lpeg.patterns.eol
+ local space = lpeg.patterns.space^0
+ local start = eol * lpeg.P("if context then") * space * eol
+ local stop = eol * (lpeg.P("else") + lpeg.P("end")) * space * eol
+ local noppes = function()
+ stripped = stripped + 1
+ return "\n--removed\n"
+ end
+ local pattern = lpeg.Cs((start * ((1-stop)^1/noppes) * stop + lpeg.P(1))^0)
+ collected = lpeg.match(pattern,collected)
+ if stripped > 0 then
+ report("%i context specific sections stripped",stripped)
+ end
+ end
+ report("saving %q (%i bytes)",newname,#collected)
+ io.savedata(newname,collected)
end
end
end
diff --git a/scripts/context/lua/mtx-patterns.lua b/scripts/context/lua/mtx-patterns.lua
index d16912e4f..4eb571117 100644
--- a/scripts/context/lua/mtx-patterns.lua
+++ b/scripts/context/lua/mtx-patterns.lua
@@ -691,6 +691,7 @@ end
-- mtxrun --script pattern --check hyph-*.tex
-- mtxrun --script pattern --check --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns
-- mtxrun --script pattern --convert --path=c:/data/develop/svn-hyphen/trunk/hyph-utf8/tex/generic/hyph-utf8/patterns/tex --destination=e:/tmp/patterns
+-- mtxrun --script pattern --convert --path=c:/data/repositories/tex-hyphen/hyph-utf8/tex/generic/hyph-utf8/patterns/tex --destination=e:/tmp/patterns
--
-- use this call:
--
diff --git a/scripts/context/lua/mtx-pdf.lua b/scripts/context/lua/mtx-pdf.lua
index 371b7f319..2e73fa841 100644
--- a/scripts/context/lua/mtx-pdf.lua
+++ b/scripts/context/lua/mtx-pdf.lua
@@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['mtx-pdf'] = {
}
local tonumber = tonumber
-local format, gmatch = string.format, string.gmatch
+local format, gmatch, gsub = string.format, string.gmatch, string.gsub
local utfchar = utf.char
local concat = table.concat
local setmetatableindex, sortedhash, sortedkeys = table.setmetatableindex, table.sortedhash, table.sortedkeys
@@ -25,8 +25,13 @@ local helpinfo = [[
<subcategory>
<flag name="info"><short>show some info about the given file</short></flag>
<flag name="metadata"><short>show metadata xml blob</short></flag>
+ <flag name="pretty"><short>replace newlines in metadata</short></flag>
<flag name="fonts"><short>show used fonts (<ref name="detail)"/></short></flag>
- <flag name="linearize"><short>linearize given file</short></flag>
+ </subcategory>
+ <subcategory>
+ <example><command>mtxrun --script pdf --info foo.pdf</command></example>
+ <example><command>mtxrun --script pdf --metadata foo.pdf</command></example>
+ <example><command>mtxrun --script pdf --metadata --pretty foo.pdf</command></example>
</subcategory>
</category>
</flags>
@@ -41,11 +46,17 @@ local application = logs.application {
local report = application.report
-dofile(resolvers.findfile("lpdf-epd.lua","tex"))
+if pdfe then
+ dofile(resolvers.findfile("lpdf-pde.lua","tex"))
+else
+ dofile(resolvers.findfile("lpdf-epd.lua","tex"))
+end
scripts = scripts or { }
scripts.pdf = scripts.pdf or { }
+local details = environment.argument("detail") or environment.argument("details")
+
local function loadpdffile(filename)
if not filename or filename == "" then
report("no filename given")
@@ -64,60 +75,134 @@ end
function scripts.pdf.info(filename)
local pdffile = loadpdffile(filename)
if pdffile then
- local catalog = pdffile.Catalog
- local info = pdffile.Info
- local pages = pdffile.pages
- local nofpages = pages.n -- no # yet. will be in 5.2
+ local catalog = pdffile.Catalog
+ local info = pdffile.Info
+ local pages = pdffile.pages
+ local nofpages = pdffile.nofpages
+
+ local unset = "<unset>"
- report("filename > %s",filename)
- report("pdf version > %s",catalog.Version)
- report("number of pages > %s",nofpages)
- report("title > %s",info.Title)
- report("creator > %s",info.Creator)
- report("producer > %s",info.Producer)
- report("creation date > %s",info.CreationDate)
- report("modification date > %s",info.ModDate)
+ report("%-17s > %s","filename", filename)
+ report("%-17s > %s","pdf version", catalog.Version or unset)
+ report("%-17s > %s","major version", pdffile.majorversion or unset)
+ report("%-17s > %s","minor version", pdffile.minorversion or unset)
+ report("%-17s > %s","number of pages", nofpages or 0)
+ report("%-17s > %s","title", info.Title or unset)
+ report("%-17s > %s","creator", info.Creator or unset)
+ report("%-17s > %s","producer", info.Producer or unset)
+ report("%-17s > %s","creation date", info.CreationDate or unset)
+ report("%-17s > %s","modification date", info.ModDate or unset)
- local width, height, start
- for i=1, nofpages do
- local page = pages[i]
- local bbox = page.CropBox or page.MediaBox
- local w, h = bbox[4]-bbox[2],bbox[3]-bbox[1]
- if w ~= width or h ~= height then
- if start then
- report("cropbox > pages: %s-%s, width: %s, height: %s",start,i-1,width,height)
+ local function somebox(what)
+ local box = string.lower(what)
+ local width, height, start
+ for i=1, nofpages do
+ local page = pages[i]
+ local bbox = page[what] or page.MediaBox or { 0, 0, 0, 0 }
+ local w, h = bbox[4]-bbox[2],bbox[3]-bbox[1]
+ if w ~= width or h ~= height then
+ if start then
+ report("%-17s > pages: %s-%s, width: %s, height: %s",box,start,i-1,width,height)
+ end
+ width, height, start = w, h, i
end
- width, height, start = w, h, i
end
+ report("%-17s > pages: %s-%s, width: %s, height: %s",box,start,nofpages,width,height)
end
- report("cropbox > pages: %s-%s, width: %s, height: %s",start,nofpages,width,height)
+
+ if details then
+ somebox("MediaBox")
+ somebox("ArtBox")
+ somebox("BleedBox")
+ somebox("CropBox")
+ somebox("TrimBox")
+ else
+ somebox("CropBox")
+ end
+
+ -- if details then
+ local annotations = 0
+ for i=1, nofpages do
+ local page = pages[i]
+ local a = page.Annots
+ if a then
+ annotations = annotations + #a
+ end
+ end
+ if annotations > 0 then
+ report("%-17s > %s", "annotations",annotations)
+ end
+ -- end
+
+ -- if details then
+ local d = pdffile.destinations
+ local k = d and sortedkeys(d)
+ if k and #k > 0 then
+ report("%-17s > %s", "destinations",#k)
+ end
+ local d = pdffile.javascripts
+ local k = d and sortedkeys(d)
+ if k and #k > 0 then
+ report("%-17s > %s", "javascripts",#k)
+ end
+ local d = pdffile.widgets
+ if d and #d > 0 then
+ report("%-17s > %s", "widgets",#d)
+ end
+ local d = pdffile.embeddedfiles
+ local k = d and sortedkeys(d)
+ if k and #k > 0 then
+ report("%-17s > %s", "embeddedfiles",#k)
+ end
+ -- end
+
end
end
-function scripts.pdf.metadata(filename)
+function scripts.pdf.metadata(filename,pretty)
local pdffile = loadpdffile(filename)
if pdffile then
local catalog = pdffile.Catalog
local metadata = catalog.Metadata
if metadata then
- report("metadata > \n\n%s\n",metadata())
+ metadata = metadata()
+ if pretty then
+ metadata = gsub(metadata,"\r","\n")
+ end
+ report("metadata > \n\n%s\n",metadata)
else
report("no metadata")
end
end
end
+local expanded = lpdf.epdf.expanded
+
local function getfonts(pdffile)
local usedfonts = { }
- for i=1,pdffile.pages.n do
- local page = pdffile.pages[i]
- local fontlist = page.Resources.Font
- if fontlist then
- for k, v in next, lpdf.epdf.expand(fontlist) do
- usedfonts[k] = lpdf.epdf.expand(v)
+
+ local function collect(where,tag)
+ local resources = where.Resources
+ if resources then
+ local fontlist = resources.Font
+ if fontlist then
+ for k, v in expanded(fontlist) do
+ usedfonts[tag and (tag .. "." .. k) or k] = v
+ end
+ end
+ local objects = resources.XObject
+ if objects then
+ for k, v in expanded(objects) do
+ collect(v,tag and (tag .. "." .. k) or k)
+ end
end
end
end
+
+ for i=1,pdffile.nofpages do
+ collect(pdffile.pages[i])
+ end
+
return usedfonts
end
@@ -125,7 +210,8 @@ local function getunicodes(font)
local cid = font.ToUnicode
if cid then
cid = cid()
- local counts = { }
+ local counts = { }
+ local indices = { }
-- for s in gmatch(cid,"begincodespacerange%s*(.-)%s*endcodespacerange") do
-- for a, b in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do
-- print(a,b)
@@ -141,18 +227,20 @@ local function getunicodes(font)
for i=first,last do
local c = i + offset
counts[c] = counts[c] + 1
+ indices[i] = true
end
end
end
for s in gmatch(cid,"beginbfchar%s*(.-)%s*endbfchar") do
for old, new in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do
+ indices[tonumber(old,16)] = true
for n in gmatch(new,"....") do
local c = tonumber(n,16)
counts[c] = counts[c] + 1
end
end
end
- return counts
+ return counts, indices
end
end
@@ -161,49 +249,93 @@ function scripts.pdf.fonts(filename)
if pdffile then
local usedfonts = getfonts(pdffile)
local found = { }
+ local common = table.setmetatableindex("table")
for k, v in table.sortedhash(usedfonts) do
- local counts = getunicodes(v)
- local codes = { }
- local chars = { }
- local freqs = { }
+ local basefont = v.BaseFont
+ local encoding = v.Encoding
+ local subtype = v.Subtype
+ local unicode = v.ToUnicode
+ local counts,
+ indices = getunicodes(v)
+ local codes = { }
+ local chars = { }
+ local freqs = { }
+ local names = { }
if counts then
codes = sortedkeys(counts)
for i=1,#codes do
local k = codes[i]
- local c = utfchar(k)
- chars[i] = c
- freqs[i] = format("U+%05X %s %s",k,counts[k] > 1 and "+" or " ", c)
+ if k > 32 then
+ local c = utfchar(k)
+ chars[i] = c
+ freqs[i] = format("U+%05X %s %s",k,counts[k] > 1 and "+" or " ", c)
+ else
+ freqs[i] = format("U+%05X %s --",k,counts[k] > 1 and "+" or " ")
+ end
+ end
+ if basefont and unicode then
+ local b = gsub(basefont,"^.*%+","")
+ local c = common[b]
+ for k in next, indices do
+ c[k] = true
+ end
end
for i=1,#codes do
codes[i] = format("U+%05X",codes[i])
end
end
+ local d = encoding and encoding.Differences
+ if d then
+ for i=1,#d do
+ local di = d[i]
+ if type(di) == "string" then
+ names[#names+1] = di
+ end
+ end
+ end
found[k] = {
- basefont = v.BaseFont or "no basefont",
- encoding = v.Encoding or "no encoding",
- subtype = v.Subtype or "no subtype",
- unicode = v.ToUnicode and "unicode" or "no unicode",
+ basefont = basefont or "no basefont",
+ encoding = (d and "custom n=" .. #d) or "no encoding",
+ subtype = subtype or "no subtype",
+ unicode = tounicode and "unicode" or "no vector",
chars = chars,
codes = codes,
freqs = freqs,
+ names = names,
}
end
- if environment.argument("detail") then
+ if details then
for k, v in sortedhash(found) do
- report("id : %s",k)
- report("basefont : %s",v.basefont)
- report("encoding : %s",v.encoding)
- report("subtype : %s",v.subtype)
- report("unicode : %s",v.unicode)
- report("characters : %s", concat(v.chars," "))
- report("codepoints : %s", concat(v.codes," "))
+ report("id : %s", k)
+ report("basefont : %s", v.basefont)
+ report("encoding : % t", v.names)
+ report("subtype : %s", v.subtype)
+ report("unicode : %s", v.unicode)
+ if #v.chars > 0 then
+ report("characters : % t", v.chars)
+ end
+ if #v.codes > 0 then
+ report("codepoints : % t", v.codes)
+ end
+ report("")
+ end
+ for k, v in sortedhash(common) do
+ report("basefont : %s",k)
+ report("indices : % t", sortedkeys(v))
report("")
end
else
- local results = { { "id", "basefont", "encoding", "subtype", "unicode", "characters" } }
+ local haschar = false
for k, v in sortedhash(found) do
- results[#results+1] = { k, v.basefont, v.encoding, v.subtype, v.unicode, concat(v.chars," ") }
+ if #v.chars > 0 then
+ haschar = true
+ break
+ end
+ end
+ local results = { { "id", "basefont", "encoding", "subtype", "unicode", haschar and "characters" or nil } }
+ for k, v in sortedhash(found) do
+ results[#results+1] = { k, v.basefont, v.encoding, v.subtype, v.unicode, haschar and concat(v.chars," ") or nil }
end
utilities.formatters.formatcolumns(results)
report(results[1])
@@ -216,46 +348,6 @@ function scripts.pdf.fonts(filename)
end
end
--- this is a quick hack ... proof of concept .. will change (derived from luigi's example) ...
--- i will make a ctx wrapper
-
-local qpdf -- just call qpdf, no need for a lib here
-
-function scripts.pdf.linearize(filename)
- qpdf = qpdf or swiglib("qpdf.core")
- local oldfile = filename or environment.files[1]
- if not oldfile then
- return
- end
- file.addsuffix(oldfile,"pdf")
- if not lfs.isfile(oldfile) then
- return
- end
- local newfile = environment.files[2]
- if not newfile or file.removesuffix(oldfile) == file.removesuffix(newfile)then
- newfile = file.addsuffix(file.removesuffix(oldfile) .. "-linearized","pdf")
- end
- local password = environment.arguments.password
- local instance = qpdf.qpdf_init()
- if bit32.band(qpdf.qpdf_read(instance,oldfile,password),qpdf.QPDF_ERRORS) ~= 0 then
- report("unable to open input file")
- elseif bit32.band(qpdf.qpdf_init_write(instance,newfile),qpdf.QPDF_ERRORS) ~= 0 then
- report("unable to open output file")
- else
- report("linearizing %a into %a",oldfile,newfile)
- qpdf.qpdf_set_static_ID(instance,qpdf.QPDF_TRUE)
- qpdf.qpdf_set_linearization(instance,qpdf.QPDF_TRUE)
- qpdf.qpdf_write(instance)
- end
- while qpdf.qpdf_more_warnings(instance) ~= 0 do
- report("warning: %s",qpdf.qpdf_get_error_full_text(instance,qpdf.qpdf_next_warning(qpdf)))
- end
- if qpdf.qpdf_has_error(instance) ~= 0 then
- report("error: %s",qpdf.qpdf_get_error_full_text(instance,qpdf.qpdf_get_error(qpdf)))
- end
- qpdf.qpdf_cleanup_p(instance)
-end
-
-- scripts.pdf.info("e:/tmp/oeps.pdf")
-- scripts.pdf.metadata("e:/tmp/oeps.pdf")
-- scripts.pdf.fonts("e:/tmp/oeps.pdf")
@@ -268,11 +360,9 @@ if filename == "" then
elseif environment.argument("info") then
scripts.pdf.info(filename)
elseif environment.argument("metadata") then
- scripts.pdf.metadata(filename)
+ scripts.pdf.metadata(filename,environment.argument("pretty"))
elseif environment.argument("fonts") then
scripts.pdf.fonts(filename)
-elseif environment.argument("linearize") then
- scripts.pdf.linearize(filename)
elseif environment.argument("exporthelp") then
application.export(environment.argument("exporthelp"),filename)
else
diff --git a/scripts/context/lua/mtx-server.lua b/scripts/context/lua/mtx-server.lua
index 448b20ac5..4f7b9b591 100644
--- a/scripts/context/lua/mtx-server.lua
+++ b/scripts/context/lua/mtx-server.lua
@@ -48,8 +48,6 @@ local gettime = os.gettimeofday or os.clock
scripts = scripts or { }
scripts.webserver = scripts.webserver or { }
-dofile(resolvers.findfile("luat-soc.lua","tex"))
-
local socket = socket or require("socket")
----- http = http or require("socket.http") -- not needed
diff --git a/scripts/context/lua/mtx-tools.lua b/scripts/context/lua/mtx-tools.lua
index 69064c640..146c46f36 100644
--- a/scripts/context/lua/mtx-tools.lua
+++ b/scripts/context/lua/mtx-tools.lua
@@ -103,12 +103,18 @@ function scripts.tools.downcase()
local basename = file.basename(name)
if lower(basename) ~= basename then
n = n + 1
+ local low = lower(name)
+ if n == 1 then
+ report()
+ end
+ report("%a renamed to %a",name,low)
if force then
- os.rename(name,lower(name))
+ os.rename(name,low)
end
end
end)
if n > 0 then
+ report()
if force then
report("%s files renamed",n)
else
diff --git a/scripts/context/lua/mtx-unicode.lua b/scripts/context/lua/mtx-unicode.lua
index 7d59bd1ca..fd6576646 100644
--- a/scripts/context/lua/mtx-unicode.lua
+++ b/scripts/context/lua/mtx-unicode.lua
@@ -14,9 +14,54 @@ if not modules then modules = { } end modules ['mtx-unicode'] = {
--
-- e:/tex-context/tex/texmf-local/data/unicode/blocks.txt
--
--- last checked:
+-- curl -o arabicshaping.txt http://www.unicode.org/Public/UNIDATA/ArabicShaping.txt
+-- curl -o bidibrackets.txt http://www.unicode.org/Public/UNIDATA/BidiBrackets.txt
+-- curl -o bidicharactertest.txt http://www.unicode.org/Public/UNIDATA/BidiCharacterTest.txt
+-- curl -o bidimirroring.txt http://www.unicode.org/Public/UNIDATA/BidiMirroring.txt
+-- curl -o biditest.txt http://www.unicode.org/Public/UNIDATA/BidiTest.txt
+-- curl -o blocks.txt http://www.unicode.org/Public/UNIDATA/Blocks.txt
+-- curl -o cjkradicals.txt http://www.unicode.org/Public/UNIDATA/CJKRadicals.txt
+-- curl -o casefolding.txt http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
+-- curl -o compositionexclusions.txt http://www.unicode.org/Public/UNIDATA/CompositionExclusions.txt
+-- curl -o derivedage.txt http://www.unicode.org/Public/UNIDATA/DerivedAge.txt
+-- curl -o derivedcoreproperties.txt http://www.unicode.org/Public/UNIDATA/DerivedCoreProperties.txt
+-- curl -o derivednormalizationprops.txt http://www.unicode.org/Public/UNIDATA/DerivedNormalizationProps.txt
+-- curl -o eastasianwidth.txt http://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt
+-- curl -o emojisources.txt http://www.unicode.org/Public/UNIDATA/EmojiSources.txt
+-- curl -o hangulsyllabletype.txt http://www.unicode.org/Public/UNIDATA/HangulSyllableType.txt
+-- curl -o index.txt http://www.unicode.org/Public/UNIDATA/Index.txt
+-- curl -o indicpositionalcategory.txt http://www.unicode.org/Public/UNIDATA/IndicPositionalCategory.txt
+-- curl -o indicsyllabiccategory.txt http://www.unicode.org/Public/UNIDATA/IndicSyllabicCategory.txt
+-- curl -o jamo.txt http://www.unicode.org/Public/UNIDATA/Jamo.txt
+-- curl -o linebreak.txt http://www.unicode.org/Public/UNIDATA/LineBreak.txt
+-- curl -o namealiases.txt http://www.unicode.org/Public/UNIDATA/NameAliases.txt
+-- curl -o namedsequences.txt http://www.unicode.org/Public/UNIDATA/NamedSequences.txt
+-- curl -o namedsequencesprov.txt http://www.unicode.org/Public/UNIDATA/NamedSequencesProv.txt
+-- curl -o nameslist.html http://www.unicode.org/Public/UNIDATA/NamesList.html
+-- curl -o nameslist.txt http://www.unicode.org/Public/UNIDATA/NamesList.txt
+-- curl -o normalizationcorrections.txt http://www.unicode.org/Public/UNIDATA/NormalizationCorrections.txt
+-- curl -o normalizationtest.txt http://www.unicode.org/Public/UNIDATA/NormalizationTest.txt
+-- curl -o proplist.txt http://www.unicode.org/Public/UNIDATA/PropList.txt
+-- curl -o propertyaliases.txt http://www.unicode.org/Public/UNIDATA/PropertyAliases.txt
+-- curl -o propertyvaluealiases.txt http://www.unicode.org/Public/UNIDATA/PropertyValueAliases.txt
+-- curl -o readme.txt http://www.unicode.org/Public/UNIDATA/ReadMe.txt
+-- curl -o scriptextensions.txt http://www.unicode.org/Public/UNIDATA/ScriptExtensions.txt
+-- curl -o scripts.txt http://www.unicode.org/Public/UNIDATA/Scripts.txt
+-- curl -o specialcasing.txt http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt
+-- curl -o standardizedvariants.html http://www.unicode.org/Public/UNIDATA/StandardizedVariants.html
+-- curl -o standardizedvariants.txt http://www.unicode.org/Public/UNIDATA/StandardizedVariants.txt
+-- curl -o tangutsources.txt http://www.unicode.org/Public/UNIDATA/TangutSources.txt
+-- curl -o ucd.zip http://www.unicode.org/Public/UNIDATA/UCD.zip
+-- curl -o usourcedata.txt http://www.unicode.org/Public/UNIDATA/USourceData.txt
+-- curl -o usourceglyphs.pdf http://www.unicode.org/Public/UNIDATA/USourceGlyphs.pdf
+-- curl -o unicodedata.txt http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
+-- curl -o unihan.zip http://www.unicode.org/Public/UNIDATA/Unihan.zip
--
--- code freeze tl 2014 / unicode 7
+-- curl -o emoji-data.txt http://unicode.org/Public/emoji/11.0/emoji-data.txt
+-- curl -o emoji-sequences.txt http://unicode.org/Public/emoji/11.0/emoji-sequences.txt
+-- curl -o emoji-variation-sequences.txt http://unicode.org/Public/emoji/11.0/emoji-variation-sequences.txt
+-- curl -o emoji-zwj-sequences.txt http://unicode.org/Public/emoji/11.0/emoji-zwj-sequences.txt
+-- curl -o emoji-test.txt http://unicode.org/Public/emoji/11.0/emoji-test.txt
--
-- todo:
--
diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua
index 6663be7a2..d9deb1b36 100644
--- a/scripts/context/lua/mtx-update.lua
+++ b/scripts/context/lua/mtx-update.lua
@@ -220,6 +220,8 @@ update.platforms = {
--
["solaris-sparc"] = "solaris-sparc",
["solaris"] = "solaris-sparc",
+ --
+ ["unknown"] = "unknown",
}
local windowsplatform = {
diff --git a/scripts/context/lua/mtx-youless.lua b/scripts/context/lua/mtx-youless.lua
index 32e1bd870..ecab30580 100644
--- a/scripts/context/lua/mtx-youless.lua
+++ b/scripts/context/lua/mtx-youless.lua
@@ -54,7 +54,7 @@ local helpinfo = [[
local application = logs.application {
name = "mtx-youless",
- banner = "YouLess Fetcher 1.100",
+ banner = "YouLess Fetcher 1.10",
helpinfo = helpinfo,
}
diff --git a/scripts/context/lua/mtxlibs.lua b/scripts/context/lua/mtxlibs.lua
index f6839eb9d..94dc658f3 100644
--- a/scripts/context/lua/mtxlibs.lua
+++ b/scripts/context/lua/mtxlibs.lua
@@ -67,6 +67,7 @@ local owntree = ownpath
local ownlibs = {
+ "l-bit32.lua",
"l-lua.lua",
"l-macro.lua",
"l-sandbox.lua",
@@ -82,6 +83,7 @@ local ownlibs = {
"l-file.lua", -- limited functionality when no lfs
-- "l-gzip.lua",
"l-md5.lua", -- not loaded when no md5 library
+ "l-sha.lua", -- not loaded when no sha2 library
"l-url.lua",
"l-dir.lua", -- limited functionality when no lfs
"l-boolean.lua",
@@ -98,6 +100,19 @@ local ownlibs = {
-- "util-fmt.lua", -- no need for table formatters
-- "util-deb.lua", -- no need for debugging (and tracing)
+ "util-soc-imp-reset",
+ "util-soc-imp-socket",
+ "util-soc-imp-copas",
+ "util-soc-imp-ltn12",
+ -- "util-soc-imp-mbox",
+ "util-soc-imp-mime",
+ "util-soc-imp-url",
+ "util-soc-imp-headers",
+ "util-soc-imp-tp",
+ "util-soc-imp-http",
+ "util-soc-imp-ftp",
+ "util-soc-imp-smtp",
+
"trac-set.lua",
"trac-log.lua",
-- "trac-pro.lua", -- not relevant outside context
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 0f4767d91..569a7f2e1 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -1,16 +1,5 @@
#!/usr/bin/env texlua
--- for k, v in next, _G.string do
--- local tv = type(v)
--- if tv == "table" then
--- for kk, vv in next, v do
--- print(k,kk,vv)
--- end
--- else
--- print(tv,k,v)
--- end
--- end
-
if not modules then modules = { } end modules ['mtxrun'] = {
version = 1.001,
comment = "runner, lua replacement for texmfstart.rb",
@@ -20,25 +9,43 @@ if not modules then modules = { } end modules ['mtxrun'] = {
}
-- one can make a stub:
+
+-- mtxrun :
--
-- #!/bin/sh
-- env LUATEXDIR=/....../texmf/scripts/context/lua luatex --luaonly mtxrun.lua "$@"
+-- mtxrun.cmd :
+--
+-- @luatex --luaonly %~d0%~p0mtxrun.lua %*
+
-- filename : mtxrun.lua
-- comment : companion to context.tex
-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
-- copyright: PRAGMA ADE / ConTeXt Development Team
-- license : see context related readme files
--- This script is based on texmfstart.rb but does not use kpsewhich to
--- locate files. Although kpse is a library it never came to opening up
--- its interface to other programs (esp scripting languages) and so we
--- do it ourselves. The lua variant evolved out of an experimental ruby
--- one. Interesting is that using a scripting language instead of c does
--- not have a speed penalty. Actually the lua variant is more efficient,
--- especially when multiple calls to kpsewhich are involved. The lua
+-- This script is based on texmfstart.rb but does not use kpsewhich to locate files.
+-- Although kpse is a library it never came to opening up its interface to other
+-- programs (esp scripting languages) and so we do it ourselves. The lua variant
+-- evolved out of an experimental ruby one. Interesting is that using a scripting
+-- language instead of c does not have a speed penalty. Actually the lua variant is
+-- more efficient, especially when multiple calls to kpsewhich are involved. The lua
-- library also gives way more control.
+-- When libraries used here are updates you can run
+--
+-- mtxrun --selfmerge
+--
+-- to update the embedded code. After that you might need to run
+--
+-- mtxrun --selfupdate
+--
+-- to copy the new script (from scripts/context/lua) to location where
+-- binaries are expected. If you want to remove the embedded code you can run
+--
+-- mtxxun --selfclean
+
-- to be done / considered
--
-- support for --exec or make it default
@@ -54,16 +61,147 @@ if not modules then modules = { } end modules ['mtxrun'] = {
do -- create closure to overcome 200 locals limit
+package.loaded["l-bit32"] = package.loaded["l-bit32"] or true
+
+-- original size: 3607, stripped down to: 3009
+
+if not modules then modules={} end modules ['l-bit32']={
+ version=1.001,
+ license="the same as regular Lua",
+ source="bitwise.lua, v 1.24 2014/12/26 17:20:53 roberto",
+ comment="drop-in for bit32, adapted a bit by Hans Hagen",
+}
+if bit32 then
+elseif utf8 then
+ load ([[
+local select = select -- instead of: arg = { ... }
+bit32 = {
+ bnot = function (a)
+ return ~a & 0xFFFFFFFF
+ end,
+ band = function (x, y, z, ...)
+ if not z then
+ return ((x or -1) & (y or -1)) & 0xFFFFFFFF
+ else
+ local res = x & y & z
+ for i=1,select("#",...) do
+ res = res & select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ bor = function (x, y, z, ...)
+ if not z then
+ return ((x or 0) | (y or 0)) & 0xFFFFFFFF
+ else
+ local res = x | y | z
+ for i=1,select("#",...) do
+ res = res | select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ bxor = function (x, y, z, ...)
+ if not z then
+ return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF
+ else
+ local res = x ~ y ~ z
+ for i=1,select("#",...) do
+ res = res ~ select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ btest = function (x, y, z, ...)
+ if not z then
+ return (((x or -1) & (y or -1)) & 0xFFFFFFFF) ~= 0
+ else
+ local res = x & y & z
+ for i=1,select("#",...) do
+ res = res & select(i,...)
+ end
+ return (res & 0xFFFFFFFF) ~= 0
+ end
+ end,
+ lshift = function (a, b)
+ return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF
+ end,
+ rshift = function (a, b)
+ return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF
+ end,
+ arshift = function (a, b)
+ a = a & 0xFFFFFFFF
+ if b <= 0 or (a & 0x80000000) == 0 then
+ return (a >> b) & 0xFFFFFFFF
+ else
+ return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
+ end
+ end,
+ lrotate = function (a ,b)
+ b = b & 31
+ a = a & 0xFFFFFFFF
+ a = (a << b) | (a >> (32 - b))
+ return a & 0xFFFFFFFF
+ end,
+ rrotate = function (a, b)
+ b = -b & 31
+ a = a & 0xFFFFFFFF
+ a = (a << b) | (a >> (32 - b))
+ return a & 0xFFFFFFFF
+ end,
+ extract = function (a, f, w)
+ return (a >> f) & ~(-1 << (w or 1))
+ end,
+ replace = function (a, v, f, w)
+ local mask = ~(-1 << (w or 1))
+ return ((a & ~(mask << f)) | ((v & mask) << f)) & 0xFFFFFFFF
+ end,
+}
+ ]] ) ()
+elseif bit then
+ load ([[
+local band, bnot, rshift, lshift = bit.band, bit.bnot, bit.rshift, bit.lshift
+bit32 = {
+ arshift = bit.arshift,
+ band = band,
+ bnot = bnot,
+ bor = bit.bor,
+ bxor = bit.bxor,
+ btest = function(...)
+ return band(...) ~= 0
+ end,
+ extract = function(a,f,w)
+ return band(rshift(a,f),2^(w or 1)-1)
+ end,
+ lrotate = bit.rol,
+ lshift = lshift,
+ replace = function(a,v,f,w)
+ local mask = 2^(w or 1)-1
+ return band(a,bnot(lshift(mask,f)))+lshift(band(v,mask),f)
+ end,
+ rrotate = bit.ror,
+ rshift = rshift,
+}
+ ]] ) ()
+else
+ xpcall(function() local _,t=require("bit32") if t then bit32=t end return end,function() end)
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 6230, stripped down to: 3662
+-- original size: 6281, stripped down to: 2863
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+).*$")
@@ -71,122 +209,111 @@ 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
+ ffi.number=tonumber
end
-if not bit32 then
- bit32=require("l-bit32")
+if LUAVERSION>5.3 then
+ collectgarbage("generational")
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
end -- of closure
@@ -195,25 +322,27 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-macro"] = package.loaded["l-macro"] or true
--- original size: 8260, stripped down to: 5213
+-- original size: 10131, stripped down to: 5991
if not modules then modules={} end modules ['l-macros']={
- 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 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)
@@ -230,172 +359,214 @@ local definitions={}
local resolve
local subparser
local report_lua=function(...)
- if logs and logs.reporter then
- report_lua=logs.reporter("system","lua")
- report_lua(...)
- else
- print(format(...))
- end
-end
-resolve=C(C(name)*arguments^-1)/function(raw,s,a)
- local d=definitions[s]
- if d then
- if a then
- local n=#a
- local p=patterns[s][n]
- if p then
- local d=d[n]
- for i=1,n do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return lpegmatch(p,d,1,a) or d
- else
- return raw
- end
- else
- return d[0] or raw
- end
- elseif a then
- for i=1,#a do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return s.."("..concat(a,",")..")"
- else
- return raw
- end
-end
-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 n=0
+ if logs and logs.reporter then
+ report_lua=logs.reporter("system","lua")
+ report_lua(...)
+ else
+ print(format(...))
+ end
+end
+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
- n=#a
- local pattern=P(false)
+ local n=#a
+ local p=patterns[s][n]
+ if p then
+ local d=d[n]
for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- p[n]=pattern
+ return lpegmatch(p,d,1,a) or d
+ else
+ return raw
+ end
+ else
+ return d[0] or raw
end
- local d=definitions[k]
- if not d then
- d={ [0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
+ elseif a then
+ for i=1,#a do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ return s.."("..concat(a,",")..")"
+ else
+ return raw
+ end
end
-local register=(C(name)*spaces^0*(arguments+Cc(false))*spaces^0*C(body))/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ [0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+subparser=Cs((resolve+P(1))^1)
+local enddefine=P("#enddefine")/""
+local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ 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=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ 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 unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
- n=#a
- local p=patterns[k]
- if p then
- p[n]=false
- end
- end
- local d=definitions[k]
- if d then
- d[n]=false
+ local n=0
+ if a then
+ n=#a
+ local p=patterns[k]
+ if p then
+ p[n]=false
end
- return ""
+ end
+ local d=definitions[k]
+ if d then
+ d[n]=false
+ end
+ return ""
end
local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define" )*spaces^0/"")*register
-local undefine=(P("undefine" )*spaces^0/"")*unregister
+local define=(P("define" )*spaces^0/"")*register
+local undefine=(P("undefine" )*spaces^0/"")*unregister
local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
function macros.reset()
- definitions={}
- patterns={}
+ definitions={}
+ patterns={}
+end
+function macros.showdefinitions()
+ 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
+ return lpegmatch(parser,str) or str
end
function macros.resolving()
- return next(patterns)
-end
-local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
- return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
- return false,format("file '%s' is invalid",name)
- end
+ 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 n=lpegmatch(parser,c)
- if trace then
- if #n~=#c then
- report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
- if detail then
- report_lua()
- report_lua(n)
- report_lua()
- end
- elseif detail then
- report_lua("no macros expanded in '%s'",name)
- end
+ local f=loadfile(name)
+ os.remove(name)
+ return f
+ end
+end
+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
- if #name>30 then
- n="--[["..sub(name,-30).."]] "..n
- else
- n="--[["..name.."]] "..n
+ end
+ return load(data,name)
+end
+local function loaded(name,trace,detail)
+ local f=io.open(name,"rb")
+ if not f then
+ return false,format("file '%s' not found",name)
+ end
+ local c=f:read("*a")
+ if not c then
+ return false,format("file '%s' is invalid",name)
+ end
+ f:close()
+ local n=lpegmatch(parser,c)
+ if trace then
+ if #n~=#c then
+ report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
+ if detail then
+ report_lua()
+ report_lua(n)
+ report_lua()
+ end
+ elseif detail then
+ report_lua("no macros expanded in '%s'",name)
end
- return load(n)
+ end
+ return reload(lfs and lfs.currentdir(),name,n)
end
macros.loaded=loaded
function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.find_file(filename) or filename
- if not fullname or fullname=="" then
- return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
- return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
- code=code()
- else
- report_lua("error when loading '%s'",fullname)
- return false,message
- end
- if code==nil then
- code=false
- end
- package.loaded[fullname]=code
- return code
+ local filename=file.addsuffix(name,"lua")
+ local fullname=resolvers and resolvers.find_file(filename) or filename
+ if not fullname or fullname=="" then
+ return false
+ end
+ local codeblob=package.loaded[fullname]
+ if codeblob then
+ return codeblob
+ end
+ local code,message=loaded(fullname,macros,trace,trace)
+ if type(code)=="function" then
+ code=code()
+ else
+ report_lua("error when loading '%s'",fullname)
+ return false,message
+ end
+ if code==nil then
+ code=false
+ end
+ package.loaded[fullname]=code
+ return code
end
macros.required=required
@@ -406,14 +577,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
--- original size: 9678, stripped down to: 6688
+-- original size: 9747, stripped down to: 6313
if not modules then modules={} end modules ['l-sandbox']={
- 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 global=_G
local next=next
@@ -439,231 +610,234 @@ local trace=false
local logger=false
local blocked={}
local function report(...)
- tprint("sandbox ! "..format(...))
+ tprint("sandbox ! "..format(...))
end
sandbox.report=report
function sandbox.setreporter(r)
- report=r
- sandbox.report=r
+ report=r
+ sandbox.report=r
end
function sandbox.settrace(v)
- trace=v
+ trace=v
end
function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
+ logger=type(l)=="function" and l or false
end
local function register(func,overload,comment)
- if type(func)=="function" then
- if type(overload)=="string" then
- comment=overload
- overload=nil
- end
- local function f(...)
- if sandboxed then
- local overload=overloads[f]
- if overload then
- if logger then
- local result={ overload(func,...) }
- logger {
- comment=comments[f] or tostring(f),
- arguments={... },
- result=result[1] and true or false,
- }
- return unpack(result)
- else
- return overload(func,...)
- end
- else
- end
- else
- return func(...)
- end
- end
- if comment then
- comments[f]=comment
- if trace then
- report("registering function: %s",comment)
- end
+ if type(func)=="function" then
+ if type(overload)=="string" then
+ comment=overload
+ overload=nil
+ end
+ local function f(...)
+ if sandboxed then
+ local overload=overloads[f]
+ if overload then
+ if logger then
+ local result={ overload(func,...) }
+ logger {
+ comment=comments[f] or tostring(f),
+ arguments={... },
+ result=result[1] and true or false,
+ }
+ return unpack(result)
+ else
+ return overload(func,...)
+ end
+ else
end
- overloads[f]=overload or false
- originals[f]=func
- return f
+ else
+ return func(...)
+ end
end
+ if comment then
+ comments[f]=comment
+ if trace then
+ report("registering function: %s",comment)
+ end
+ end
+ overloads[f]=overload or false
+ originals[f]=func
+ return f
+ end
end
local function redefine(func,comment)
- if type(func)=="function" then
- skiploads[func]=comment or comments[func] or "unknown"
- if overloads[func]==false then
- overloads[func]=nil
- end
+ if type(func)=="function" then
+ skiploads[func]=comment or comments[func] or "unknown"
+ if overloads[func]==false then
+ overloads[func]=nil
end
+ end
end
sandbox.register=register
sandbox.redefine=redefine
function sandbox.original(func)
- return originals and originals[func] or func
+ return originals and originals[func] or func
end
function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
- if trace then
- report("overloading unknown function: %s",comment)
- end
- elseif type(overload)~="function" then
- if trace then
- report("overloading function with bad overload: %s",comment)
- end
- elseif overloads[func]==nil then
- if trace then
- report("function is not registered: %s",comment)
- end
- elseif skiploads[func] then
- if trace then
- report("function is not skipped: %s",comment)
- end
- else
- if trace then
- report("overloading function: %s",comment)
- end
- overloads[func]=overload
+ comment=comment or comments[func] or "?"
+ if type(func)~="function" then
+ if trace then
+ report("overloading unknown function: %s",comment)
+ end
+ elseif type(overload)~="function" then
+ if trace then
+ report("overloading function with bad overload: %s",comment)
+ end
+ elseif overloads[func]==nil then
+ if trace then
+ report("function is not registered: %s",comment)
+ end
+ elseif skiploads[func] then
+ if trace then
+ report("function is not skipped: %s",comment)
end
- return func
+ else
+ if trace then
+ report("overloading function: %s",comment)
+ end
+ overloads[func]=overload
+ end
+ return func
end
local function whatever(specification,what,target)
- if type(specification)~="table" then
- report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
- report("%s needs a category and action",what)
- elseif not sandboxed then
- target[#target+1]=specification
- elseif trace then
- report("already enabled, discarding %s",what)
- end
+ if type(specification)~="table" then
+ report("%s needs a specification",what)
+ elseif type(specification.category)~="string" or type(specification.action)~="function" then
+ report("%s needs a category and action",what)
+ elseif not sandboxed then
+ target[#target+1]=specification
+ elseif trace then
+ report("already enabled, discarding %s",what)
+ end
end
function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
+ whatever(specification,"initializer",initializers)
end
function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
+ whatever(specification,"finalizer",finalizers)
end
function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
- return nil
- elseif b then
- if trace then
- report("using blocked: %s",n)
- end
- return b
- else
- if trace then
- report("requiring: %s",name)
- end
- return requiem(name)
+ local n=gsub(name,"^.*[\\/]","")
+ local n=gsub(n,"[%.].*$","")
+ local b=blocked[n]
+ if b==false then
+ return nil
+ elseif b then
+ if trace then
+ report("using blocked: %s",n)
end
-end
-function blockrequire(name,lib)
+ return b
+ else
if trace then
- report("preventing reload of: %s",name)
+ report("requiring: %s",name)
end
- blocked[name]=lib or _G[name] or false
+ return requiem(name)
+ end
+end
+function blockrequire(name,lib)
+ if trace then
+ report("preventing reload of: %s",name)
+ end
+ blocked[name]=lib or _G[name] or false
end
function sandbox.enable()
- if not sandboxed then
- for i=1,#initializers do
- initializers[i].action()
- end
- for i=1,#finalizers do
- finalizers[i].action()
- end
- local nnot=0
- local nyes=0
- local cnot={}
- local cyes={}
- local skip={}
- for k,v in next,overloads do
- local c=comments[k]
- if v then
- if c then
- cyes[#cyes+1]=c
- else
- nyes=nyes+1
- end
- else
- if c then
- cnot[#cnot+1]=c
- else
- nnot=nnot+1
- end
- end
- end
- for k,v in next,skiploads do
- skip[#skip+1]=v
- end
- if #cyes>0 then
- sort(cyes)
- report("overloaded known: %s",concat(cyes," | "))
- end
- if nyes>0 then
- report("overloaded unknown: %s",nyes)
- end
- if #cnot>0 then
- sort(cnot)
- report("not overloaded known: %s",concat(cnot," | "))
- end
- if nnot>0 then
- report("not overloaded unknown: %s",nnot)
+ if not sandboxed then
+ debug={
+ traceback=debug.traceback,
+ }
+ for i=1,#initializers do
+ initializers[i].action()
+ end
+ for i=1,#finalizers do
+ finalizers[i].action()
+ end
+ local nnot=0
+ local nyes=0
+ local cnot={}
+ local cyes={}
+ local skip={}
+ for k,v in next,overloads do
+ local c=comments[k]
+ if v then
+ if c then
+ cyes[#cyes+1]=c
+ else
+ nyes=nyes+1
end
- if #skip>0 then
- sort(skip)
- report("not overloaded redefined: %s",concat(skip," | "))
+ else
+ if c then
+ cnot[#cnot+1]=c
+ else
+ nnot=nnot+1
end
- initializers=nil
- finalizers=nil
- originals=nil
- sandboxed=true
+ end
+ end
+ for k,v in next,skiploads do
+ skip[#skip+1]=v
+ end
+ if #cyes>0 then
+ sort(cyes)
+ report("overloaded known: %s",concat(cyes," | "))
+ end
+ if nyes>0 then
+ report("overloaded unknown: %s",nyes)
end
+ if #cnot>0 then
+ sort(cnot)
+ report("not overloaded known: %s",concat(cnot," | "))
+ end
+ if nnot>0 then
+ report("not overloaded unknown: %s",nnot)
+ end
+ if #skip>0 then
+ sort(skip)
+ report("not overloaded redefined: %s",concat(skip," | "))
+ end
+ initializers=nil
+ finalizers=nil
+ originals=nil
+ sandboxed=true
+ end
end
blockrequire("lfs",lfs)
blockrequire("io",io)
blockrequire("os",os)
blockrequire("ffi",ffi)
local function supported(library)
- local l=_G[library]
- return l
+ local l=_G[library]
+ return l
end
loadfile=register(loadfile,"loadfile")
if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen")
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
+ io.open=register(io.open,"io.open")
+ io.popen=register(io.popen,"io.popen")
+ io.lines=register(io.lines,"io.lines")
+ io.output=register(io.output,"io.output")
+ io.input=register(io.input,"io.input")
end
if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
+ os.execute=register(os.execute,"os.execute")
+ os.spawn=register(os.spawn,"os.spawn")
+ os.exec=register(os.exec,"os.exec")
+ os.rename=register(os.rename,"os.rename")
+ os.remove=register(os.remove,"os.remove")
end
if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
+ lfs.chdir=register(lfs.chdir,"lfs.chdir")
+ lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
+ lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
+ lfs.isfile=register(lfs.isfile,"lfs.isfile")
+ lfs.isdir=register(lfs.isdir,"lfs.isdir")
+ lfs.attributes=register(lfs.attributes,"lfs.attributes")
+ lfs.dir=register(lfs.dir,"lfs.dir")
+ lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
+ lfs.touch=register(lfs.touch,"lfs.touch")
+ lfs.link=register(lfs.link,"lfs.link")
+ lfs.setmode=register(lfs.setmode,"lfs.setmode")
+ lfs.readlink=register(lfs.readlink,"lfs.readlink")
+ lfs.shortname=register(lfs.shortname,"lfs.shortname")
+ lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
end
@@ -673,14 +847,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-package"] = package.loaded["l-package"] or true
--- original size: 11562, stripped down to: 8625
+-- original size: 11605, stripped down to: 8299
if not modules then modules={} end modules ['l-package']={
- 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=type
local gsub,format,find=string.gsub,string.format,string.find
@@ -688,40 +862,40 @@ local insert,remove=table.insert,table.remove
local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
local package=package
local searchers=package.searchers or package.loaders
-local filejoin=file and file.join or function(path,name) return path.."/"..name end
-local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join or function(path,name) return path.."/"..name end
+local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
local function cleanpath(path)
- return path
+ return path
end
local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
local function lualibfile(name)
- return lpegmatch(pattern,name) or name
+ return lpegmatch(pattern,name) or name
end
local offset=luarocks and 1 or 0
local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
- ["preload table"]=searchers[1+offset],
- ["path specification"]=searchers[2+offset],
- ["cpath specification"]=searchers[3+offset],
- ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
- "already loaded",
- "preload table",
- "qualified path",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
- }
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+ ["preload table"]=searchers[1+offset],
+ ["path specification"]=searchers[2+offset],
+ ["cpath specification"]=searchers[3+offset],
+ ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+ "already loaded",
+ "preload table",
+ "qualified path",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
}
package.helpers=helpers
local methods=helpers.methods
@@ -737,253 +911,256 @@ local nofextralib=-1
local nofpathlua=-1
local nofpathlib=-1
local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
- for i=1,nofpaths do
- helpers.report("using %s path %i: %s",what,i,paths[i])
- end
- else
- helpers.report("no %s paths defined",what)
+ local nofpaths=#paths
+ if nofpaths>0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
end
- return nofpaths
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
end
local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
- nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
+ if helpers.trace and #extraluapaths~=nofextralua then
+ nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
end
local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
- nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
+ if helpers.trace and #extralibpaths~=nofextralib then
+ nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
end
local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
- luapaths=file.splitpath(luapath,";")
- oldluapath=luapath
- nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
- nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+ luapaths=file.splitpath(luapath,";")
+ oldluapath=luapath
+ nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+ nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
end
local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
- libpaths=file.splitpath(libpath,";")
- oldlibpath=libpath
- nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
- nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+ libpaths=file.splitpath(libpath,";")
+ oldlibpath=libpath
+ nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+ nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
end
package.luapaths=getluapaths
package.libpaths=getlibpaths
package.extraluapaths=getextraluapaths
package.extralibpaths=getextralibpaths
local hashes={
- lua={},
- lib={},
+ lua={},
+ lib={},
}
local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
- local path=cleanpath(path)
- if not hash[path] then
- target[#target+1]=path
- hash[path]=true
- if trace then
- report("registered %s path %s: %s",tag,#target,path)
- end
- else
- if trace then
- report("duplicate %s path: %s",tag,path)
- end
- end
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+ local path=cleanpath(path)
+ if not hash[path] then
+ target[#target+1]=path
+ hash[path]=true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
end
- for p=1,#pathlist do
- local path=pathlist[p]
- if type(path)=="table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
+ end
+ for p=1,#pathlist do
+ local path=pathlist[p]
+ if type(path)=="table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
end
+ end
end
local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
- helpers.report("pushing %s path in front: %s",tag,path)
- end
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
end
local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
- if path then
- helpers.report("popping %s path from front: %s",tag,path)
- else
- helpers.report("no %s path to pop",tag)
- end
+ local path=remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
end
+ end
end
helpers.registerpath=registerpath
function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
+ registerpath("extra lua","lua",extraluapaths,...)
end
function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
+ pushpath("extra lua","lua",extraluapaths,path)
end
function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
+ poppath("extra lua","lua",extraluapaths)
end
function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
+ registerpath("extra lib","lib",extralibpaths,...)
end
function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
+ pushpath("extra lib","lib",extralibpaths,path)
end
function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
+ poppath("extra lib","lua",extralibpaths)
end
local function loadedaslib(resolved,rawname)
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
end
helpers.loadedaslib=loadedaslib
local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
- local path=paths[p]
- local resolved=filejoin(path,name)
- if trace then
- helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
- end
- if isreadable(resolved) then
- if trace then
- helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ for p=1,#paths do
+ local path=paths[p]
+ local resolved=filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbypath=loadedbypath
local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
- local trace=helpers.trace
- if trace then
- helpers.report("qualified name, identifying '%s'",what,name)
- end
- if isreadable(name) then
- if trace then
- helpers.report("qualified name, '%s' found",what,name)
- end
- return loadfile(name)
- end
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
+ end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
end
+ end
end
helpers.loadedbyname=loadedbyname
methods["already loaded"]=function(name)
- return package.loaded[name]
+ return package.loaded[name]
end
methods["preload table"]=function(name)
- return builtin["preload table"](name)
+ return builtin["preload table"](name)
end
methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
end
methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
end
methods["lib extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
end
methods["path specification"]=function(name)
- getluapaths()
- return builtin["path specification"](name)
+ getluapaths()
+ return builtin["path specification"](name)
end
methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
+ getlibpaths()
+ return builtin["cpath specification"](name)
end
methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+ return builtin["all in one fallback"](name)
end
methods["not loaded"]=function(name)
- if helpers.trace then
- helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
end
local level=0
local used={}
helpers.traceused=false
function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
- local method=sequence[i]
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
- end
- local result,rest=methods[method](name)
- if type(result)=="function" then
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
- end
- if helpers.traceused then
- used[#used+1]={ level=level,name=name }
- end
- level=level-1
- return result,rest
- end
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+ local method=sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
end
- level=level-1
- return nil
+ local result,rest=methods[method](name)
+ if type(result)=="function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1]={ level=level,name=name }
+ end
+ level=level-1
+ return result,rest
+ end
+ end
+ level=level-1
+ return nil
end
function helpers.showused()
- local n=#used
- if n>0 then
- helpers.report("%s libraries loaded:",n)
- helpers.report()
- for i=1,n do
- local u=used[i]
- helpers.report("%i %a",u.level,u.name)
- end
- helpers.report()
- end
+ local n=#used
+ if n>0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u=used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
end
function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading, name '%s', %s",name,"done")
- else
- helpers.report("unloading, name '%s', %s",name,"not loaded")
- end
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
end
- package.loaded[name]=nil
+ end
+ package.loaded[name]=nil
end
table.insert(searchers,1,helpers.loaded)
+if context then
+ package.path=""
+end
end -- of closure
@@ -992,14 +1169,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38582, stripped down to: 20518
+-- original size: 38434, stripped down to: 19310
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
@@ -1010,7 +1187,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
@@ -1033,7 +1210,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('"')
@@ -1042,9 +1219,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")
@@ -1076,7 +1253,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
@@ -1085,15 +1262,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
@@ -1150,7 +1327,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
@@ -1160,76 +1337,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("")
@@ -1239,505 +1424,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
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
+ 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
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ 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
+ 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
- pattern=(1-pattern)^0*pattern
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ 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
+ 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
- return p
+ 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
+ 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
- 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
+ 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
- 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
+ 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
- return (insensitive and make2 or make1)(tree)
+ 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
+ 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
@@ -1756,32 +1899,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
@@ -1791,14 +1949,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-function"] = package.loaded["l-function"] or true
--- original size: 361, stripped down to: 322
+-- original size: 361, stripped down to: 317
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
@@ -1810,14 +1968,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-string"] = package.loaded["l-string"] or true
--- original size: 6461, stripped down to: 3341
+-- original size: 6461, stripped down to: 3255
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
@@ -1825,25 +1983,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
@@ -1851,81 +2009,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
@@ -1935,166 +2093,172 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 40197, stripped down to: 23561
+-- original size: 41298, stripped down to: 21498
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 a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
end
- return tostring(a)<tostring(b)
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
+ end
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt={}
+ local category=0
+ local s=0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- 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)=="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
@@ -2102,907 +2266,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 n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ 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 n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ if not t then
+ t={}
+ end
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp={}
+ local ntmp=0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
+ end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
+ if not tables then
+ tables={}
+ end
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh={}
+ local h=0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- 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
+ 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
- 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 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"))
- else
- handle(format("%s{",depth))
- end
+ 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
- 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
- end
- if last>0 then
- first=1
- 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
- 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
+ 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
- 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
+ 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 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
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
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 {")
+ 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(name.."={")
+ handle(format("%s [%q]=%q,",depth,k,v))
end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
+ 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
- handle("["..name.."]={")
+ do_serialize(v,k,depth,level+1)
end
- elseif tname=="boolean" then
- if name then
- handle("return {")
+ 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("{")
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
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
+ 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
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
+ 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
- handle("}")
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
end
-function table.serialize(root,name,specification)
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
+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
+ 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
+ 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
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ 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)
+ 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
- f:close()
- io.flush()
+ 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
+ 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
- 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
+ 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
+ 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
- return f
+ 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
- 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
+ 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 ""
+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
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- s[i]=tostring(t[i])
+ 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 n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ 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 n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
- else
- return nothing
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
@@ -3012,14 +3213,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11823, stripped down to: 6945
+-- original size: 11823, stripped down to: 6325
if not modules then modules={} end modules ['l-io']={
- 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 io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -3027,334 +3228,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 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
- f:close()
- flush()
+ if data then
+ g:write(data)
+ end
+ 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
+ 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
+ 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
+ [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
@@ -3364,14 +3565,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5645, stripped down to: 2253
+-- original size: 5720, stripped down to: 2176
if not modules then modules={} end modules ['l-number']={
- 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 tostring,tonumber=tostring,tonumber
local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -3381,99 +3582,107 @@ local floor=math.floor
number=number or {}
local number=number
if bit32 then
- local bextract=bit32.extract
- local t={
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m)
- local n=32
- for i=0,31 do
- local v=bextract(b,i)
- local k=32-i
- if v==1 then
- n=k
- t[k]="1"
- else
- t[k]="0"
- end
- end
- if m then
- m=33-m*8
- if m<1 then
- m=1
- end
- return concat(t,"",m)
- elseif n<8 then
- return concat(t)
- elseif n<16 then
- return concat(t,"",9)
- elseif n<24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
+ local bextract=bit32.extract
+ local t={
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ }
+ 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=w-i
+ if v==1 then
+ n=k
+ t[k]="1"
+ else
+ t[k]="0"
+ end
+ end
+ 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,"",1,m)
+ elseif n<8 then
+ return concat(t)
+ elseif n<16 then
+ return concat(t,"",9)
+ elseif n<24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
end
+ end
else
- function number.tobitstring(n,m)
- if n>0 then
- local t={}
- while n>0 do
- insert(t,1,n%2>0 and 1 or 0)
- n=floor(n/2)
- end
- local nn=8-#t%8
- if nn>0 and nn<8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m=m*8-#t
- if m>0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
+ function number.tobitstring(n,m)
+ if n>0 then
+ local t={}
+ while n>0 do
+ insert(t,1,n%2>0 and 1 or 0)
+ n=floor(n/2)
+ end
+ local nn=8-#t%8
+ if nn>0 and nn<8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m=m*8-#t
+ if m>0 then
+ insert(t,1,rep("0",m))
end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
end
+ end
end
function number.valid(str,default)
- return tonumber(str) or default or nil
+ return tonumber(str) or default or nil
end
function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
- return s
- else
- return "0"..s
- end
+ local s=format("%X",n)
+ if #s%2==0 then
+ return s
+ else
+ return "0"..s
+ end
end
function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
- return 100
- elseif d<-100 then
- return -100
- else
- return d
- end
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+ return 100
+ elseif d<-100 then
+ return -100
+ else
+ return d
+ end
end
function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
- return 255
- elseif b<-255 then
- return -255
- else
- return b
- end
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+ return 255
+ elseif b<-255 then
+ return -255
+ else
+ return b
+ end
+end
+function number.idiv(i,d)
+ return floor(i/d)
end
@@ -3483,14 +3692,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-set"] = package.loaded["l-set"] or true
--- original size: 1923, stripped down to: 1133
+-- original size: 1923, stripped down to: 1044
if not modules then modules={} end modules ['l-set']={
- 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"
}
set=set or {}
local nums={}
@@ -3499,54 +3708,54 @@ local concat=table.concat
local next,type=next,type
set.create=table.tohash
function set.tonumber(t)
- if next(t) then
- local s=""
- for k,v in next,t do
- if v then
- s=s.." "..k
- end
- end
- local n=nums[s]
- if not n then
- n=#tabs+1
- tabs[n]=t
- nums[s]=n
- end
- return n
- else
- return 0
+ if next(t) then
+ local s=""
+ for k,v in next,t do
+ if v then
+ s=s.." "..k
+ end
end
+ local n=nums[s]
+ if not n then
+ n=#tabs+1
+ tabs[n]=t
+ nums[s]=n
+ end
+ return n
+ else
+ return 0
+ end
end
function set.totable(n)
- if n==0 then
- return {}
- else
- return tabs[n] or {}
- end
+ if n==0 then
+ return {}
+ else
+ return tabs[n] or {}
+ end
end
function set.tolist(n)
- if n==0 or not tabs[n] then
- return ""
- else
- local t,n={},0
- for k,v in next,tabs[n] do
- if v then
- n=n+1
- t[n]=k
- end
- end
- return concat(t," ")
+ if n==0 or not tabs[n] then
+ return ""
+ else
+ local t,n={},0
+ for k,v in next,tabs[n] do
+ if v then
+ n=n+1
+ t[n]=k
+ end
end
+ return concat(t," ")
+ end
end
function set.contains(n,s)
- if type(n)=="table" then
- return n[s]
- elseif n==0 then
- return false
- else
- local t=tabs[n]
- return t and t[s]
- end
+ if type(n)=="table" then
+ return n[s]
+ elseif n==0 then
+ return false
+ else
+ local t=tabs[n]
+ return t and t[s]
+ end
end
@@ -3556,14 +3765,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 16268, stripped down to: 9246
+-- original size: 19347, stripped down to: 10258
if not modules then modules={} end modules ['l-os']={
- 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 os=os
local date,time=os.date,os.time
@@ -3571,357 +3780,434 @@ local find,format,gsub,upper,gmatch=string.find,string.format,string.gsub,string
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
-math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
-randomseed(math.initialseed)
-if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
- local osgetenv=os.getenv
- local ossetenv=os.setenv
- local osenv=os.env local _=osenv.PATH
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- if type(v)=="table" then
- v=concat(v,";")
- end
- ossetenv(K,v)
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
+do
+ local selfdir=os.selfdir
+ if selfdir=="" then
+ selfdir=nil
+ end
+ if not selfdir then
+ if arg then
+ for i=1,#arg do
+ local a=arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir=gsub(a,"^.-=","")
+ break
end
- else
- local ossetenv=os.setenv
- local osgetenv=os.getenv
- local osenv={}
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
+ 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
+ local attributes=lfs.attributes
+ isfile=function(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+ end
+ else
+ local open=io.open
+ isfile=function(name)
+ local f=open(name)
+ if f then
+ f:close()
+ return true
end
+ end
end
- local function __index(t,k)
- return os.getenv(k)
- end
- local function __newindex(t,k,v)
- os.setenv(k,v)
+ for p in gmatch(path,patt) do
+ if isfile(p.."/"..name) then
+ selfdir=p
+ break
+ end
end
- os.env={}
- setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
+ os.selfdir=selfdir or "."
+ end
+end
+math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
+randomseed(math.initialseed)
+if not os.__getenv__ then
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+ local osgetenv=os.getenv
+ local ossetenv=os.setenv
+ local osenv=os.env local _=osenv.PATH
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ if type(v)=="table" then
+ v=concat(v,";")
+ end
+ ossetenv(K,v)
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ else
+ local ossetenv=os.setenv
+ local osgetenv=os.getenv
+ local osenv={}
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+ os.env={}
+ setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
local execute=os.execute
local iopopen=io.popen
local function resultof(command)
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- else
- return ""
- end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
end
os.resultof=resultof
function os.pipeto(command)
- return iopopen(command,"w")
+ return iopopen(command,"w")
end
if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
- io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+ io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
end
os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
end
local launchers={
- windows="start %s",
- macosx="open %s",
- unix="$BROWSER %s &> /dev/null &",
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
}
function os.launch(str)
- execute(format(launchers[os.name] or launchers.unix,str))
+ execute(format(launchers[os.name] or launchers.unix,str))
end
if not os.times then
- function os.times()
- return {
- utime=os.gettimeofday(),
- stime=0,
- cutime=0,
- cstime=0,
- }
- end
+ function os.times()
+ return {
+ utime=os.gettimeofday(),
+ stime=0,
+ cutime=0,
+ cstime=0,
+ }
+ end
end
local gettimeofday=os.gettimeofday or os.clock
os.gettimeofday=gettimeofday
local startuptime=gettimeofday()
function os.runtime()
- return gettimeofday()-startuptime
+ return gettimeofday()-startuptime
end
local resolvers=os.resolvers or {}
os.resolvers=resolvers
setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil
+ local r=resolvers[k]
+ return r and r(t,k) or nil
end })
local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
if platform~="" then
- os.platform=platform
+ os.platform=platform
elseif os.type=="windows" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("PROCESSOR_ARCHITECTURE") or ""
- if find(architecture,"AMD64",1,true) then
- platform="win64"
- else
- platform="mswin"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform=""
+ if find(architecture,"AMD64",1,true) then
+ platform="win64"
+ else
+ platform="mswin"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="linux" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- if find(architecture,"x86_64",1,true) then
- platform="linux-64"
- elseif find(architecture,"ppc",1,true) then
- platform="linux-ppc"
- else
- platform="linux"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ 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
+ 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=musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="macosx" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("echo $HOSTTYPE") or ""
- if architecture=="" then
- platform="osx-intel"
- elseif find(architecture,"i386",1,true) then
- platform="osx-intel"
- elseif find(architecture,"x86_64",1,true) then
- platform="osx-64"
- else
- platform="osx-ppc"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=resultof("echo $HOSTTYPE") or ""
+ local platform=""
+ if architecture=="" then
+ platform="osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform="osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform="osx-64"
+ else
+ platform="osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="sunos" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("uname -m") or ""
- if find(architecture,"sparc",1,true) then
- platform="solaris-sparc"
- else
- platform="solaris-intel"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"sparc",1,true) then
+ platform="solaris-sparc"
+ else
+ platform="solaris-intel"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="freebsd" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("uname -m") or ""
- if find(architecture,"amd64",1,true) then
- platform="freebsd-amd64"
- else
- platform="freebsd"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"amd64",1,true) then
+ platform="freebsd-amd64"
+ else
+ platform="freebsd"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- if find(architecture,"x86_64",1,true) then
- platform="kfreebsd-amd64"
- else
- platform="kfreebsd-i386"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"x86_64",1,true) then
+ platform="kfreebsd-amd64"
+ else
+ platform="kfreebsd-i386"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
else
- function resolvers.platform(t,k)
- local platform="linux"
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local platform="linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
end
os.newline=name=="windows" and "\013\010" or "\010"
function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
end
local t={ 8,9,"a","b" }
function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
- random(0xFFFF),random(0xFFFF),
- random(0x0FFF),
- t[ceil(random(4))] or 8,random(0x0FFF),
- random(0xFFFF),
- random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
end
local d
function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
- if delta then
- if d>0 then
- return format("+%02i:00",d)
- else
- return format("-%02i:00",-d)
- end
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d>0 then
+ return format("+%02i:00",d)
else
- return 1
+ return format("-%02i:00",-d)
end
+ else
+ return 1
+ end
end
local timeformat=format("%%s%s",os.timezone(true))
local dateformat="!%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
end
local dateformat="%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=date(dateformat,t)
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=date(dateformat,t)
+ end
+ return lastdate
end
function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
+ local t=tonumber(t)
+ if t and t>0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
end
local memory={}
local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
- local suffix=file.suffix(filename)
- local suffixes=suffix=="" and os.binsuffixes or { suffix }
- for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local df=file.join(directory,filename)
- for i=1,#suffixes do
- local dfs=file.addsuffix(df,suffixes[i])
- if io.exists(dfs) then
- fullname=dfs
- break
- end
- end
- end
- if not fullname then
- fullname=false
+ local fullname=memory[filename]
+ if fullname==nil then
+ local suffix=file.suffix(filename)
+ local suffixes=suffix=="" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local df=file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs=file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname=dfs
+ break
end
- memory[filename]=fullname
+ end
end
- return fullname
+ if not fullname then
+ fullname=false
+ end
+ memory[filename]=fullname
+ end
+ return fullname
end
os.which=which
os.where=which
function os.today()
- return date("!*t")
+ return date("!*t")
end
function os.now()
- return date("!%Y-%m-%d %H:%M:%S")
+ return date("!%Y-%m-%d %H:%M:%S")
end
if not os.sleep then
- local socket=socket
- function os.sleep(n)
- if not socket then
- socket=require("socket")
- end
- socket.sleep(n)
+ local socket=socket
+ function os.sleep(n)
+ if not socket then
+ socket=require("socket")
end
+ socket.sleep(n)
+ end
end
local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
+ return (year%4==0) and (year%100~=0 or year%400==0)
end
os.isleapyear=isleapyear
local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
local function nofdays(year,month)
- if not month then
- return isleapyear(year) and 365 or 364
- else
- return month==2 and isleapyear(year) and 29 or days[month]
- end
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month==2 and isleapyear(year) and 29 or days[month]
+ end
end
os.nofdays=nofdays
function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
+ return date("%w",time { year=year,month=month,day=day })+1
end
function os.validdate(year,month,day)
- if month<1 then
- month=1
- elseif month>12 then
- month=12
- end
- if day<1 then
- day=1
- else
- local max=nofdays(year,month)
- if day>max then
- day=max
- end
- end
- return year,month,day
+ if month<1 then
+ month=1
+ elseif month>12 then
+ month=12
+ end
+ if day<1 then
+ day=1
+ else
+ local max=nofdays(year,month)
+ if day>max then
+ day=max
+ end
+ 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
@@ -3931,19 +4217,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-file"] = package.loaded["l-file"] or true
--- original size: 21616, stripped down to: 10359
+-- original size: 21804, stripped down to: 9980
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
@@ -3951,24 +4237,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(".")
@@ -3982,27 +4266,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
@@ -4011,7 +4295,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)
@@ -4027,142 +4311,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)
- else
- return "",str
- end
+ 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 {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ 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
+ 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)
@@ -4172,30 +4456,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)
- 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
- else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
- end
+ 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
+ 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
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
@@ -4205,56 +4489,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
+ n=n-1
end
- 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)
@@ -4262,26 +4546,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("://")
@@ -4290,40 +4574,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
+ 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
- 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
+ if l<0 then
+ return false
end
- return true
+ end
+ return true
+end
+local symlinkattributes=lfs.symlinkattributes
+function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
end
@@ -4333,51 +4621,51 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
--- original size: 1211, stripped down to: 1002
+-- original size: 1211, stripped down to: 951
if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not gzip then
- return
+ return
end
local suffix,suffixes=file.suffix,file.suffixes
function gzip.load(filename)
- local f=io.open(filename,"rb")
- if not f then
- elseif suffix(filename)=="gz" then
- f:close()
- local g=gzip.open(filename,"rb")
- if g then
- local str=g:read("*all")
- g:close()
- return str
- end
- else
- local str=f:read("*all")
- f:close()
- return str
- end
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+ f:close()
+ local g=gzip.open(filename,"rb")
+ if g then
+ local str=g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str=f:read("*all")
+ f:close()
+ return str
+ end
end
function gzip.save(filename,data)
- if suffix(filename)~="gz" then
- filename=filename..".gz"
- end
- local f=io.open(filename,"wb")
- if f then
- local s=zlib.compress(data or "",9,nil,15+16)
- f:write(s)
- f:close()
- return #s
- end
+ if suffix(filename)~="gz" then
+ filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+ local s=zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
end
function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
end
@@ -4387,87 +4675,119 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-md5"] = package.loaded["l-md5"] or true
--- original size: 3309, stripped down to: 2314
+-- original size: 3309, stripped down to: 2218
if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not md5 then
- md5=optionalrequire("md5")
+ md5=optionalrequire("md5")
end
if not md5 then
- md5={
- sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
- sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
+ md5={
+ sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
end
local md5,file=md5,file
local gsub=string.gsub
do
- local patterns=lpeg and lpeg.patterns
- if patterns then
- local bytestoHEX=patterns.bytestoHEX
- local bytestohex=patterns.bytestohex
- local bytestodec=patterns.bytestodec
- local lpegmatch=lpeg.match
- local md5sum=md5.sum
- if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
- if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
- if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
- md5.sumhexa=md5.hex
- md5.sumHEXA=md5.HEX
- end
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+ local bytestoHEX=patterns.bytestoHEX
+ local bytestohex=patterns.bytestohex
+ local bytestodec=patterns.bytestodec
+ local lpegmatch=lpeg.match
+ local md5sum=md5.sum
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+ md5.sumhexa=md5.hex
+ md5.sumHEXA=md5.HEX
+ end
end
function file.needsupdating(oldname,newname,threshold)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime=lfs.attributes(newname,"modification")
- if not newtime then
- return true
- elseif newtime>=oldtime then
- return false
- elseif oldtime-newtime<(threshold or 1) then
- return false
- else
- return true
- end
- else
- return false
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime=lfs.attributes(newname,"modification")
+ if not newtime then
+ return true
+ elseif newtime>=oldtime then
+ return false
+ elseif oldtime-newtime<(threshold or 1) then
+ return false
+ else
+ return true
+ end
+ else
+ return false
+ end
end
file.needs_updating=file.needsupdating
function file.syncmtimes(oldname,newname)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
end
function file.checksum(name)
- if md5 then
- local data=io.loaddata(name)
- if data then
- return md5.HEX(data)
- end
+ if md5 then
+ local data=io.loaddata(name)
+ if data then
+ return md5.HEX(data)
end
- return nil
+ end
+ return nil
end
function file.loadchecksum(name)
- if md5 then
- local data=io.loaddata(name..".md5")
- return data and (gsub(data,"%s",""))
- end
- return nil
+ if md5 then
+ local data=io.loaddata(name..".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
end
function file.savechecksum(name,checksum)
- if not checksum then checksum=file.checksum(name) end
- if checksum then
- io.savedata(name..".md5",checksum)
- return checksum
- end
- return nil
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+ io.savedata(name..".md5",checksum)
+ return checksum
+ end
+ return nil
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["l-sha"] = package.loaded["l-sha"] or true
+
+-- original size: 1085, stripped down to: 969
+
+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
@@ -4477,14 +4797,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 14755, stripped down to: 7236
+-- original size: 14755, stripped down to: 6981
if not modules then modules={} end modules ['l-url']={
- 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 char,format,byte=string.char,string.format,string.byte
local concat=table.concat
@@ -4497,14 +4817,14 @@ local url=url
local unescapes={}
local escapes={}
setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
end })
setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
end })
local colon=P(":")
local qmark=P("?")
@@ -4523,21 +4843,21 @@ local escaped=(plus/" ")+escapedchar
local noslash=P("/")/""
local plustospace=P("+")/" "
local decoder=Cs((
- plustospace+escapedchar+P("\r\n")/"\n"+P(1)
- )^0 )
+ plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+ )^0 )
local encoder=Cs((
- R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
- )^0 )
+ R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+ )^0 )
lpegpatterns.urldecoder=decoder
lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1- qmark-hash))^0)
-local querystr=Cs(((1- hash))^0)
-local fragmentstr=Cs((escaped+(1- endofstring))^0)
+local pathstr=Cs((escaped+(1- qmark-hash))^0)
+local querystr=Cs(((1- hash))^0)
+local fragmentstr=Cs((escaped+(1- endofstring))^0)
local scheme=schemestr*colon+nothing
local authority=slash*slash*authoritystr+nothing
local path=slash*pathstr+nothing
@@ -4555,19 +4875,19 @@ lpegpatterns.urlescaper=escaper
lpegpatterns.urlunescaper=unescaper
lpegpatterns.urlgetcleaner=getcleaner
function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
+ return lpegmatch(getcleaner,str)
end
local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
end
local isscheme=schemestr*colon*slash*slash
local function hasscheme(str)
- if str then
- local scheme=lpegmatch(isscheme,str)
- return scheme~="" and scheme or false
- else
- return false
- end
+ if str then
+ local scheme=lpegmatch(isscheme,str)
+ return scheme~="" and scheme or false
+ else
+ return false
+ end
end
local rootletter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4577,161 +4897,161 @@ local barswapper=replacer("|",":")
local backslashswapper=replacer("\\","/")
local equal=P("=")
local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal )^0)
local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
},rawset)
local userpart=(1-atsign-colon)^1
local serverpart=(1-colon)^1
local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
local function hashed(str)
- if not str or str=="" then
- return {
- scheme="invalid",
- original=str,
- }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
- rawscheme=detailed[1]
- rawquery=detailed[4]
- somescheme=rawscheme~=""
- somequery=rawquery~=""
- end
- if not somescheme and not somequery then
- return {
- scheme="file",
- authority="",
- path=str,
- query="",
- fragment="",
- original=str,
- noscheme=true,
- filename=str,
- }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename
- local username
- local password
- local host
- local port
- if authority~="" then
- username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
- filename=path
- elseif path=="" then
- filename=""
- else
- filename=authority.."/"..path
- end
+ if not str or str=="" then
return {
- scheme=rawscheme,
- authority=authority,
- path=path,
- query=lpegmatch(unescaper,rawquery),
- queries=lpegmatch(splitquery,rawquery),
- fragment=detailed[5],
- original=str,
- noscheme=false,
- filename=filename,
- host=host,
- port=port,
+ scheme="invalid",
+ original=str,
}
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+ rawscheme=detailed[1]
+ rawquery=detailed[4]
+ somescheme=rawscheme~=""
+ somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme="file",
+ authority="",
+ path=str,
+ query="",
+ fragment="",
+ original=str,
+ noscheme=true,
+ filename=str,
+ }
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename
+ local username
+ local password
+ local host
+ local port
+ if authority~="" then
+ username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+ filename=path
+ elseif path=="" then
+ filename=""
+ else
+ filename=authority.."/"..path
+ end
+ return {
+ scheme=rawscheme,
+ authority=authority,
+ path=path,
+ query=lpegmatch(unescaper,rawquery),
+ queries=lpegmatch(splitquery,rawquery),
+ fragment=detailed[5],
+ original=str,
+ noscheme=false,
+ filename=filename,
+ host=host,
+ port=port,
+ }
end
url.split=split
url.hasscheme=hasscheme
url.hashed=hashed
function url.addscheme(str,scheme)
- if hasscheme(str) then
- return str
- elseif not scheme then
- return "file:///"..str
- else
- return scheme..":///"..str
- end
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///"..str
+ else
+ return scheme..":///"..str
+ end
end
function url.construct(hash)
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
- r=r+1;result[r]=lpegmatch(escaper,scheme)
- r=r+1;result[r]="://"
- end
- if authority and authority~="" then
- r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
- r=r+1;result[r]="/"
- r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
- local done=false
- for k,v in sortedhash(queries) do
- r=r+1;result[r]=done and "&" or "?"
- r=r+1;result[r]=lpegmatch(escaper,k)
- r=r+1;result[r]="="
- r=r+1;result[r]=lpegmatch(escaper,v)
- done=true
- end
- end
- if fragment and fragment~="" then
- r=r+1;result[r]="#"
- r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+ r=r+1;result[r]=lpegmatch(escaper,scheme)
+ r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+ r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+ r=r+1;result[r]="/"
+ r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+ local done=false
+ for k,v in sortedhash(queries) do
+ r=r+1;result[r]=done and "&" or "?"
+ r=r+1;result[r]=lpegmatch(escaper,k)
+ r=r+1;result[r]="="
+ r=r+1;result[r]=lpegmatch(escaper,v)
+ done=true
+ end
+ end
+ if fragment and fragment~="" then
+ r=r+1;result[r]="#"
+ r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
end
local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
end
local function escapestring(str)
- return lpegmatch(escaper,str)
+ return lpegmatch(escaper,str)
end
url.escape=escapestring
function url.query(str)
- if type(str)=="string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
+ if type(str)=="string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
end
function url.toquery(data)
- local td=type(data)
- if td=="string" then
- return #str and escape(data) or nil
- elseif td=="table" then
- if next(data) then
- local t={}
- for k,v in next,data do
- t[#t+1]=format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
- end
- else
+ local td=type(data)
+ if td=="string" then
+ return #str and escape(data) or nil
+ elseif td=="table" then
+ if next(data) then
+ local t={}
+ for k,v in next,data do
+ t[#t+1]=format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
end
+ else
+ end
end
local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
function url.barepath(path)
- if not path or path=="" then
- return ""
- else
- return lpegmatch(pattern,path)
- end
+ if not path or path=="" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
end
@@ -4741,14 +5061,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 17703, stripped down to: 11691
+-- original size: 18002, stripped down to: 10681
if not modules then modules={} end modules ['l-dir']={
- 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,select=type,select
local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -4760,471 +5080,478 @@ local dir=dir
local lfs=lfs
local attributes=lfs.attributes
local walkdir=lfs.dir
-local isdir=lfs.isdir
+local isdir=lfs.isdir
local isfile=lfs.isfile
local currentdir=lfs.currentdir
local chdir=lfs.chdir
local mkdir=lfs.mkdir
local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
- if lpegmatch(tricky,name) then
- return attributes(name,"mode")=="directory"
- else
- return attributes(name.."/.","mode")=="directory"
- end
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode")=="directory"
+ else
+ return attributes(name.."/.","mode")=="directory"
end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
else
- isdir=function(name)
- return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ isdir=function(name)
+ return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
end
function dir.current()
- return (gsub(currentdir(),"\\","/"))
+ return (gsub(currentdir(),"\\","/"))
end
local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- action(full)
- end
- elseif recurse and mode=="directory" then
- if not dirs then
- dirs={ full }
- else
- dirs[#dirs+1]=full
- end
- end
- end
- end
- if dirs then
- for i=1,#dirs do
- glob_pattern_function(dirs[i],patt,recurse,action)
- end
+ if isdir(path) then
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ for name in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ action(full)
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
end
+ end
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
end
+ end
end
local function glob_pattern_table(path,patt,recurse,result)
- if not result then
- result={}
- end
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- result[#result+1]=full
- end
- elseif recurse and mode=="directory" then
- if not dirs then
- dirs={ full }
- else
- dirs[#dirs+1]=full
- end
- end
- end
- end
+ if not result then
+ result={}
+ end
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,a in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ noffiles=noffiles+1
+ result[noffiles]=full
+ end
+ elseif recurse and mode=="directory" then
if dirs then
- for i=1,#dirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
end
+ end
end
- return result
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
+ end
+ end
+ return result
end
local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
- patt=false
- end
- if kind=="function" then
- return glob_pattern_function(path,patt,recurse,method)
- elseif kind=="table" then
- return glob_pattern_table(path,patt,recurse,method)
- else
- return glob_pattern_table(path,patt,recurse,{})
- end
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+ patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
end
dir.globpattern=globpattern
local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
- ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
- else
- ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
- end
- if ok and type(scanner)=="function" then
- if not find(path,"/$") then
- path=path..'/'
- end
- for name in scanner,first do
- if name=="." then
- elseif name==".." then
- else
- local full=path..name
- local attr=attributes(full)
- local mode=attr.mode
- if mode=='file' then
- if find(full,patt) then
- result[name]=attr
- end
- elseif recurse and mode=="directory" then
- attr.list=collectpattern(full,patt,recurse)
- result[name]=attr
- end
- end
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+ ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
+ else
+ ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
+ end
+ if ok and type(scanner)=="function" then
+ if not find(path,"/$") then
+ path=path..'/'
+ end
+ for name in scanner,first do
+ if name=="." then
+ elseif name==".." then
+ else
+ local full=path..name
+ local attr=attributes(full)
+ local mode=attr.mode
+ if mode=='file' then
+ if find(full,patt) then
+ result[name]=attr
+ end
+ elseif recurse and mode=="directory" then
+ attr.list=collectpattern(full,patt,recurse)
+ result[name]=attr
end
+ end
end
- return result
+ end
+ return result
end
dir.collectpattern=collectpattern
local separator,pattern
if onwindows then
- local slash=S("/\\")/"/"
- pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
- }
+ local slash=S("/\\")/"/"
+ pattern={
+ [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+ [3]=Cs(P(1)^0)
+ }
else
- pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
- }
+ pattern={
+ [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ [2]=C(((1-S("*?/"))^0*P("/"))^0),
+ [3]=C(P(1)^0)
+ }
end
local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
)^0 )
local function glob(str,t)
- if type(t)=="function" then
- if type(str)=="table" then
- for s=1,#str do
- glob(str[s],t)
- end
- elseif isfile(str) then
- t(str)
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- globpattern(start,result,recurse,t)
- end
- end
+ if type(t)=="function" then
+ if type(str)=="table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str)=="table" then
+ local t=t or {}
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1]=str
+ return t
+ else
+ return { str }
+ end
else
- if type(str)=="table" then
- local t=t or {}
- for s=1,#str do
- glob(str[s],t)
- end
- return t
- elseif isfile(str) then
- if t then
- t[#t+1]=str
- return t
- else
- return { str }
- end
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- return globpattern(start,result,recurse,t)
- else
- return {}
- end
- end
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ return globpattern(start,result,recurse,t)
+ else
+ return {}
+ end
end
+ end
end
dir.glob=glob
local function globfiles(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if recurse then
- globfiles(path.."/"..name,recurse,func,files)
- end
- elseif mode=="file" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if recurse then
+ globfiles(path.."/"..name,recurse,func,files)
+ end
+ elseif mode=="file" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
end
+ end
end
- return files
+ end
+ return files
end
dir.globfiles=globfiles
local function globdirs(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- if recurse then
- globdirs(path.."/"..name,recurse,func,files)
- end
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ if recurse then
+ globdirs(path.."/"..name,recurse,func,files)
+ end
end
+ end
end
- return files
+ end
+ return files
end
dir.globdirs=globdirs
function dir.ls(pattern)
- return concat(glob(pattern),"\n")
+ return concat(glob(pattern),"\n")
end
local make_indeed=true
if onwindows then
- function dir.mkdirs(...)
- local n=select("#",...)
- local str
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s=="" then
+ elseif str=="" then
+ str=s
else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s=="" then
- elseif str=="" then
- str=s
- else
- str=str.."/"..s
- end
- end
+ str=str.."/"..s
end
- local pth=""
- local drive=false
- local first,middle,last=match(str,"^(//)(//*)(.*)$")
- if first then
+ end
+ end
+ local pth=""
+ local drive=false
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ else
+ first,last=match(str,"^(//)/*(.-)$")
+ if first then
+ middle,last=match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth="//"..middle
else
- first,last=match(str,"^(//)/*(.-)$")
- if first then
- middle,last=match(str,"([^/]+)/+(.-)$")
- if middle then
- pth="//"..middle
- else
- pth="//"..last
- last=""
- end
- else
- first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth,drive=first..middle,true
- else
- middle,last=match(str,"^(/*)(.-)$")
- if not middle then
- last=str
- end
- end
- end
+ pth="//"..last
+ last=""
end
- for s in gmatch(last,"[^/]+") do
- if pth=="" then
- pth=s
- elseif drive then
- pth,drive=pth..s,false
- else
- pth=pth.."/"..s
- end
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
+ else
+ first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth,drive=first..middle,true
+ else
+ middle,last=match(str,"^(/*)(.-)$")
+ if not middle then
+ last=str
+ end
end
- return pth,(isdir(pth)==true)
+ end
end
+ for s in gmatch(last,"[^/]+") do
+ if pth=="" then
+ pth=s
+ elseif drive then
+ pth,drive=pth..s,false
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
else
- function dir.mkdirs(...)
- local n=select("#",...)
- local str,pth
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s and s~="" then
- if str~="" then
- str=str.."/"..s
- else
- str=s
- end
- end
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str,pth
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s and s~="" then
+ if str~="" then
+ str=str.."/"..s
+ else
+ str=s
+ end
end
- str=gsub(str,"/+","/")
- if find(str,"^/") then
- pth="/"
- for s in gmatch(str,"[^/]+") do
- local first=(pth=="/")
- if first then
- pth=pth..s
- else
- pth=pth.."/"..s
- end
- if make_indeed and not first and not isdir(pth) then
- mkdir(pth)
- end
- end
+ end
+ end
+ str=gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth="/"
+ for s in gmatch(str,"[^/]+") do
+ local first=(pth=="/")
+ if first then
+ pth=pth..s
else
- pth="."
- for s in gmatch(str,"[^/]+") do
- pth=pth.."/"..s
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
+ pth=pth.."/"..s
end
- return pth,(isdir(pth)==true)
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth="."
+ for s in gmatch(str,"[^/]+") do
+ pth=pth.."/"..s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
end
+ return pth,(isdir(pth)==true)
+ end
end
dir.makedirs=dir.mkdirs
do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
- local xcurrentdir=dir.current
- function dir.expandname(str)
- local first,nothing,last=match(str,"^(//)(//*)(.*)$")
- if first then
- first=xcurrentdir().."/"
- end
- if not first then
- first,last=match(str,"^(//)/*(.*)$")
- end
- if not first then
- first,last=match(str,"^([a-zA-Z]:)(.*)$")
- if first and not find(last,"^/") then
- local d=currentdir()
- if chdir(first) then
- first=xcurrentdir()
- end
- chdir(d)
- end
- end
- if not first then
- first,last=xcurrentdir(),str
- end
- last=gsub(last,"//","/")
- last=gsub(last,"/%./","/")
- last=gsub(last,"^/*","")
- first=gsub(first,"/*$","")
- if last=="" or last=="." then
- return first
- else
- return first.."/"..last
- end
- end
- else
- function dir.expandname(str)
- if not find(str,"^/") then
- str=currentdir().."/"..str
- end
- str=gsub(str,"//","/")
- str=gsub(str,"/%./","/")
- str=gsub(str,"(.)/%.$","%1")
- return str
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+ local xcurrentdir=dir.current
+ function dir.expandname(str)
+ local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ first=xcurrentdir().."/"
+ end
+ if not first then
+ first,last=match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first,last=match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d=currentdir()
+ if chdir(first) then
+ first=xcurrentdir()
+ end
+ chdir(d)
end
+ end
+ if not first then
+ first,last=xcurrentdir(),str
+ end
+ last=gsub(last,"//","/")
+ last=gsub(last,"/%./","/")
+ last=gsub(last,"^/*","")
+ first=gsub(first,"/*$","")
+ if last=="" or last=="." then
+ return first
+ else
+ return first.."/"..last
+ end
end
+ else
+ function dir.expandname(str)
+ if not find(str,"^/") then
+ str=currentdir().."/"..str
+ end
+ str=gsub(str,"//","/")
+ str=gsub(str,"/%./","/")
+ str=gsub(str,"(.)/%.$","%1")
+ return str
+ end
+ end
end
file.expandname=dir.expandname
local stack={}
function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" then
- chdir(newdir)
- return newdir
- else
- return curdir
- end
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" then
+ chdir(newdir)
+ return newdir
+ else
+ return curdir
+ end
end
function dir.pop()
- local d=remove(stack)
- if d then
- chdir(d)
- end
- return d
+ local d=remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
end
local function found(...)
- for i=1,select("#",...) do
- local path=select(i,...)
- local kind=type(path)
- if kind=="string" then
- if isdir(path) then
- return path
- end
- elseif kind=="table" then
- local path=found(unpack(path))
- if path then
- return path
- end
- end
+ for i=1,select("#",...) do
+ local path=select(i,...)
+ local kind=type(path)
+ if kind=="string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind=="table" then
+ local path=found(unpack(path))
+ if path then
+ return path
+ end
end
+ end
end
dir.found=found
@@ -5235,69 +5562,69 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
--- original size: 1850, stripped down to: 1568
+-- original size: 1850, stripped down to: 1498
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
@@ -5307,18 +5634,24 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 40036, stripped down to: 17837
+-- original size: 41047, stripped down to: 17171
if not modules then modules={} end modules ['l-unicode']={
- 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"
}
-utf=utf or (unicode and unicode.utf8) or {}
-utf.characters=utf.characters or string.utfcharacters
-utf.values=utf.values or string.utfvalues
+utf=utf or {}
+unicode=nil
+if not string.utfcharacters then
+ local gmatch=string.gmatch
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
+end
+utf.characters=string.utfcharacters
local type=type
local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch
local concat=table.concat
@@ -5329,345 +5662,340 @@ local tabletopattern=lpeg.utfchartabletopattern
local bytepairs=string.bytepairs
local finder=lpeg.finder
local replacer=lpeg.replacer
-local utfvalues=utf.values
-local utfgmatch=utf.gmatch
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 }
-end
if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+ local char=string.char
+ if bit32 then
+ local rshift=bit32.rshift
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+rshift(n,6),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+rshift(n,12),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+rshift(n,18),
+ 0x80+(rshift(n,12)%0x40),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
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
+ 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
end
+ end
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
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
end
+ end
end
local utfchar,utfbyte=utf.char,utf.byte
function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
+ return data and lpegmatch(p_utftype,data) or "unknown"
end
local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
)
patterns.toentities=toentities
function utf.toentities(str)
- return lpegmatch(toentities,str)
+ 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 )
+ 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
+ return lpegmatch(pattern,s) or s
end
local validatedutf=Cs (
- (
- patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
- )^0
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
)
patterns.validatedutf=validatedutf
function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
+ 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
+ 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
+ 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
- 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
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
end
- local function slide_two(s,p)
- n=n+1
- if n==first then
- b=p
- else
- return true
- end
+ if n>=last then
+ e=p-1
+ else
+ return p
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
+ 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_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(p_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
- 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)
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
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)
+ 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
+ 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)
+ 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
- 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
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
end
- elseif variant=="function" then
- if option=="pattern" then
- return Cs((p_utf8char/mapping+p_utf8char)^0)
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
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
+ return lpegmatch(pattern,str)
end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8character/mapping+p_utf8character)^0)
else
- return function(str)
- return str or ""
+ local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
end
+ end,pattern
end
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
+ else
return function(str)
- return lpegmatch(r,str)
+ return str or ""
end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
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
+ 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
end
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
function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
+ return lpegmatch(utflinesplitter,str or "")
end
function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
end
function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
+ return lpegmatch(utfcharsplitter_raw,str)
end
function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
end
local utf16_to_utf8_be,utf16_to_utf8_le
local utf32_to_utf8_be,utf32_to_utf8_le
@@ -5681,36 +6009,36 @@ local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_n
local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
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
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ 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
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 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
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))
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
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))
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
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)
@@ -5721,88 +6049,88 @@ 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
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ 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
+ 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
- return t
+ end
+ return t
end
utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -5813,189 +6141,225 @@ 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
+ 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
+ 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
+ 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
+ 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
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
+ 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
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
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
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
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
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
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
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
+ (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 " ")
+ return lpegmatch(pattern,str,1,separator or " ")
end
function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
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
-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
+ 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
end
-if not utf.characters then
- function utf.characters(str)
- return gmatch(str,".[\128-\191]*")
+do
+ local p_nany=p_utf8character/""
+ 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
- string.utfcharacters=utf.characters
+ end
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
+if not string.utfvalues then
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(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
- string.utfvalues=utf.values
+ end
end
+utf.values=string.utfvalues
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
+ 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
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 extract=bit32.extract
+ local char=string.char
+ function utf.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
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
+ 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
- return s
+ end
+ return s
+end
+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)
+ 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
+ end
+ if 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 p_utf8byte/f
+ end
+ end
end
@@ -6005,93 +6369,93 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-math"] = package.loaded["l-math"] or true
--- original size: 2555, stripped down to: 1900
+-- original size: 2555, stripped down to: 1831
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)<floor(n)
- end
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
@@ -6101,14 +6465,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 38734, stripped down to: 22142
+-- original size: 43539, stripped down to: 21641
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"
+ 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 {}
@@ -6121,624 +6485,657 @@ 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 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
if not number then number={} end
-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 ptf=1/65536
+local bpf=(7200/7227)/65536
local function points(n)
- n=tonumber(n)
- return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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)
+ return lpegmatch(pattern,str)
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
+ 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
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((
+ 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
+ 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)
+ extra,start=0,position
+ end+anything
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
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 space=spacer^0
-local nospace=space/""
+ 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-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 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,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["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
+ return str and lpegmatch(striplinepatterns[how],str) or str
+end
+function strings.collapse(str)
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return 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)..'"')
+ 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).."'")
+ 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]",
+ "[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
+ 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
+ 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))*(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==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
if sep1==true then
- return lpegmatch(splitter,s,1,".",",")
+ return lpegmatch(splitter,n,1,".",",")
elseif sep1=="." then
- return lpegmatch(splitter,s,1,sep1,sep2 or ",")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
elseif sep1=="," then
- return lpegmatch(splitter,s,1,sep1,sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ 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
- )
+ 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
+ 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 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
- 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))
+ 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
- return tostring(n)
+ 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
+ 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
+ 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 #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
%s
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,
+}
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ 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)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
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
+ 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 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
+ 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 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ 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)
+ 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
+ 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
+ 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
+ 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
+ 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)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ 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
+ 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
+ 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)
+ 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)
+ 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()
+ 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(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))
+ 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")
@@ -6750,160 +7147,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("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
-patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
+patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+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
@@ -6913,14 +7306,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 27741, stripped down to: 17085
+-- original size: 28772, stripped down to: 16111
if not modules then modules={} end modules ['util-tab']={
- 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"
}
utilities=utilities or {}
utilities.tables=utilities.tables or {}
@@ -6935,219 +7328,220 @@ local formatters=string.formatters
local utftoeight=utf.toeight
local splitter=lpeg.tsplitat(".")
function utilities.tables.definetable(target,nofirst,nolast)
- local composed,t=nil,{}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
- local name=snippets[i]
- if composed then
- composed=composed.."."..name
- t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
- else
- composed=name
- if not nofirst then
- t[#t+1]=formatters["%s = %s or { }"](composed,composed)
- end
- end
- end
+ local composed=nil
+ local t={}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+ local name=snippets[i]
if composed then
- if nolast then
- composed=composed.."."..snippets[#snippets]
- end
- return concat(t,"\n"),composed
+ composed=composed.."."..name
+ t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
else
- return "",target
+ composed=name
+ if not nofirst then
+ t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+ end
+ end
+ end
+ if composed then
+ if nolast then
+ composed=composed.."."..snippets[#snippets]
end
+ return concat(t,"\n"),composed
+ else
+ return "",target
+ end
end
function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
- local li=select(i,...)
- local tl=t[li]
- if not tl then
- tl={}
- t[li]=tl
- end
- t=tl
- end
- return t
+ local t=_G
+ for i=1,select("#",...) do
+ local li=select(i,...)
+ local tl=t[li]
+ if not tl then
+ tl={}
+ t[li]=tl
+ end
+ t=tl
+ end
+ return t
end
function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t=t[name]
+ if not t then
+ return
end
- return t
+ end
+ return t
end
function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
- local name=names[i]
- t[name]=t[name] or {}
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name=names[i]
+ t[name]=t[name] or {}
+ t=t[name]
+ if not t then
+ return
end
- t[names[#names]]=v
+ end
+ t[names[#names]]=v
end
function tables.removevalue(t,value)
- if value then
- for i=1,#t do
- if t[i]==value then
- remove(t,i)
- end
- end
+ if value then
+ for i=1,#t do
+ if t[i]==value then
+ remove(t,i)
+ end
end
+ end
end
function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
- for i=1,#t do
- if t[i]==oldvalue then
- t[i]=newvalue
- end
- end
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i]==oldvalue then
+ t[i]=newvalue
+ end
end
+ end
end
function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i,extra)
+ return
end
- insert(t,1,extra)
+ end
+ insert(t,1,extra)
end
function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i+1,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i+1,extra)
+ return
end
- insert(t,#t+1,extra)
+ end
+ insert(t,#t+1,extra)
end
local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
function table.tocsv(t,specification)
- if t and #t>0 then
- local result={}
- local r={}
- specification=specification or {}
- local fields=specification.fields
- if type(fields)~="string" then
- fields=sortedkeys(t[1])
- end
- local separator=specification.separator or ","
- local noffields=#fields
- if specification.preamble==true then
- for f=1,noffields do
- r[f]=lpegmatch(escape,tostring(fields[f]))
- end
- result[1]=concat(r,separator)
- end
- for i=1,#t do
- local ti=t[i]
- for f=1,noffields do
- local field=ti[fields[f]]
- if type(field)=="string" then
- r[f]=lpegmatch(escape,field)
- else
- r[f]=tostring(field)
- end
- end
- result[i+1]=concat(r,separator)
+ if t and #t>0 then
+ local result={}
+ local r={}
+ specification=specification or {}
+ local fields=specification.fields
+ if type(fields)~="string" then
+ fields=sortedkeys(t[1])
+ end
+ local separator=specification.separator or ","
+ local noffields=#fields
+ if specification.preamble==true then
+ for f=1,noffields do
+ r[f]=lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1]=concat(r,separator)
+ end
+ for i=1,#t do
+ local ti=t[i]
+ for f=1,noffields do
+ local field=ti[fields[f]]
+ if type(field)=="string" then
+ r[f]=lpegmatch(escape,field)
+ else
+ r[f]=tostring(field)
end
- return concat(result,"\n")
- else
- return ""
+ end
+ result[i+1]=concat(r,separator)
end
+ return concat(result,"\n")
+ else
+ return ""
+ end
end
local nspaces=utilities.strings.newrepeater(" ")
local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
- local s=nspaces[d]
- local tk=type(k)
- local tv=type(v)
- if tv=="table" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</entry>"](s,k)
- else
- r=r+1 result[r]=formatters["%s<%s>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</%s>"](s,k)
- end
- elseif tv=="string" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
- end
- elseif tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
- end
+ local r=#result
+ for k,v in sortedpairs(t) do
+ local s=nspaces[d]
+ local tk=type(k)
+ local tv=type(v)
+ if tv=="table" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</entry>"](s,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</%s>"](s,k)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
end
+ end
end
function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
- toxml(t,indent,result,spaces)
- else
- toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+ toxml(t,indent,result,spaces)
+ else
+ toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
end
function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
- protect=true
- capsule={}
- end
+ if type(capsule)~="table" then
+ protect=true
+ capsule={}
+ end
+ for key,value in next,core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key]=value
+ end
+ end
+ if protect then
for key,value in next,core do
+ core[key]=nil
+ end
+ setmetatable(core,{
+ __index=capsule,
+ __newindex=function(t,key,value)
if capsule[key] then
- print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
- os.exit()
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
else
- capsule[key]=value
+ rawset(t,key,value)
end
- end
- if protect then
- for key,value in next,core do
- core[key]=nil
- end
- setmetatable(core,{
- __index=capsule,
- __newindex=function(t,key,value)
- if capsule[key] then
- print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
- os.exit()
- else
- rawset(t,key,value)
- end
- end
- } )
- end
+ end
+ } )
+ end
end
local f_hashed_string=formatters["[%q]=%q,"]
local f_hashed_number=formatters["[%q]=%s,"]
@@ -7161,157 +7555,157 @@ local f_ordered_string=formatters["%q,"]
local f_ordered_number=formatters["%s,"]
local f_ordered_boolean=formatters["%l,"]
function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- for i=0,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
- end
- end
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ for i=0,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
- end
- end
- else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
- end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ else
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_hashed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_hashed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_hashed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
- return r
+ end
end
- return concat(fastserialize(t,true))
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
- if not str or str=="" then
- return
- end
- local code=load(str)
- if not code then
- return
- end
- code=code()
- if not code then
- return
- end
- return code
+ if not str or str=="" then
+ return
+ end
+ local code=load(str)
+ if not code then
+ return
+ end
+ code=code()
+ if not code then
+ return
+ end
+ return code
end
function table.load(filename,loader)
- if filename then
- local t=(loader or io.loaddata)(filename)
- if t and t~="" then
- local t=utftoeight(t)
- t=load(t)
- if type(t)=="function" then
- t=t()
- if type(t)=="table" then
- return t
- end
- end
+ if filename then
+ local t=(loader or io.loaddata)(filename)
+ if t and t~="" then
+ local t=utftoeight(t)
+ t=load(t)
+ if type(t)=="function" then
+ t=t()
+ if type(t)=="table" then
+ return t
end
+ end
end
+ end
end
function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...))
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...))
end
local f_key_value=formatters["%s=%q"]
local f_add_table=formatters[" {%t},\n"]
local f_return_table=formatters["return {\n%t}"]
local function slowdrop(t)
- local r={}
- local l={}
- for i=1,#t do
- local ti=t[i]
- local j=0
- for k,v in next,ti do
- j=j+1
- l[j]=f_key_value(k,v)
- end
- r[i]=f_add_table(l)
- end
- return f_return_table(r)
+ local r={}
+ local l={}
+ for i=1,#t do
+ local ti=t[i]
+ local j=0
+ for k,v in next,ti do
+ j=j+1
+ l[j]=f_key_value(k,v)
+ end
+ r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
end
local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
- local ti=t[i]
- m=m+1 r[m]=" {"
- for k,v in next,ti do
- m=m+1 r[m]=f_key_value(k,v)
- end
- m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+ local ti=t[i]
+ m=m+1 r[m]=" {"
+ for k,v in next,ti do
+ m=m+1 r[m]=f_key_value(k,v)
+ end
+ m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
end
function table.drop(t,slow)
- if #t==0 then
- return "return { }"
- elseif slow==true then
- return slowdrop(t)
- else
- return fastdrop(t)
- end
+ if #t==0 then
+ return "return { }"
+ elseif slow==true then
+ return slowdrop(t)
+ else
+ return fastdrop(t)
+ end
end
local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)
- if not t then
- t={}
- else
- local zero=rawget(t,0)
- for i=zero and 0 or 1,#t do
- local ti=t[i]
- if ti then
- local i=tostring(i)
- t[i]=ti
- t[ti]=i
- end
- end
+function table.twowaymapper(t)
+ if not t then
+ t={}
+ else
+ local zero=rawget(t,0)
+ for i=zero and 0 or 1,#t do
+ local ti=t[i]
+ if ti then
+ local i=tostring(i)
+ t[i]=ti
+ t[ti]=i
+ end
end
- setmetatable(t,selfmapper)
- return t
+ end
+ setmetatable(t,selfmapper)
+ return t
end
local f_start_key_idx=formatters["%w{"]
local f_start_key_num=formatters["%w[%s]={"]
@@ -7349,187 +7743,223 @@ local spaces=utilities.strings.newrepeater(" ")
local original_serialize=table.serialize
local is_simple_table=table.is_simple_table
local function serialize(root,name,specification)
- if type(specification)=="table" then
- return original_serialize(root,name,specification)
- end
- local t
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- n=n+1
- if indexed then
- t[n]=f_start_key_idx(depth)
+ if type(specification)=="table" then
+ return original_serialize(root,name,specification)
+ end
+ local t
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ n=n+1
+ if indexed then
+ t[n]=f_start_key_idx(depth)
+ else
+ local tn=type(name)
+ if tn=="number" then
+ t[n]=f_start_key_num(depth,name)
+ elseif tn=="string" then
+ t[n]=f_start_key_str(depth,name)
+ elseif tn=="boolean" then
+ t[n]=f_start_key_boo(depth,name)
+ else
+ t[n]=f_start_key_nop(depth)
+ end
+ end
+ depth=depth+1
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ 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
+ 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 first and tk=="number" and k<=last and k>=first then
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v)==nil then
+ n=n+1 t[n]=f_val_not(depth)
else
- local tn=type(name)
- if tn=="number" then
- t[n]=f_start_key_num(depth,name)
- elseif tn=="string" then
- t[n]=f_start_key_str(depth,name)
- elseif tn=="boolean" then
- t[n]=f_start_key_boo(depth,name)
- else
- t[n]=f_start_key_nop(depth)
- end
- end
- depth=depth+1
- end
- if root and next(root)~=nil then
- local first=nil
- local last=0
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
end
- if last>0 then
- first=1
+ elseif tv=="boolean" then
+ n=n+1 t[n]=f_val_boo(depth,v)
+ elseif unknown then
+ n=n+1 t[n]=f_val_str(depth,tostring(v))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_not(depth,k)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_not(depth,k)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
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 first and tk=="number" and k<=last and k>=first then
- if tv=="number" then
- n=n+1 t[n]=f_val_num(depth,v)
- elseif tv=="string" then
- n=n+1 t[n]=f_val_str(depth,v)
- elseif tv=="table" then
- if next(v)==nil then
- n=n+1 t[n]=f_val_not(depth)
- else
- local st=is_simple_table(v)
- if st then
- n=n+1 t[n]=f_val_seq(depth,st)
- else
- do_serialize(v,k,depth,level+1,true)
- end
- end
- elseif tv=="boolean" then
- n=n+1 t[n]=f_val_boo(depth,v)
- elseif unknown then
- n=n+1 t[n]=f_val_str(depth,tostring(v))
- end
- elseif tv=="number" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_num(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_num(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
- end
- elseif tv=="string" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_not(depth,k)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_not(depth,k)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_not(depth,k)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
- end
- else
- local st=is_simple_table(v)
- if not st then
- do_serialize(v,k,depth,level+1)
- elseif tk=="number" then
- n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
- end
- end
- elseif tv=="boolean" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
- end
- else
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
- end
- end
+ else
+ local st=is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
end
- end
- if level>0 then
- n=n+1 t[n]=f_stop(depth-1)
- end
- end
- local tname=type(name)
- if tname=="string" then
- if name=="return" then
- t={ f_table_return() }
- else
- t={ f_table_name(name) }
- end
- elseif tname=="number" then
- t={ f_table_entry(name) }
- elseif tname=="boolean" then
- if name then
- t={ f_table_return() }
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+ end
else
- t={ f_table_direct() }
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
end
+ end
+ end
+ if level>0 then
+ n=n+1 t[n]=f_stop(depth-1)
+ end
+ end
+ local tname=type(name)
+ if tname=="string" then
+ if name=="return" then
+ t={ f_table_return() }
else
- t={ f_table_name("t") }
+ t={ f_table_name(name) }
end
- if root then
- if 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
- local st=is_simple_table(root)
- if st then
- return t[1]..f_fin_seq(st)
- else
- do_serialize(root,name,1,0)
- end
- end
+ elseif tname=="number" then
+ t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+ if name then
+ t={ f_table_return() }
+ else
+ t={ f_table_direct() }
+ end
+ else
+ t={ f_table_name("t") }
+ end
+ if root then
+ if 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
+ local st=is_simple_table(root)
+ if st then
+ return t[1]..f_fin_seq(st)
+ else
+ do_serialize(root,name,1,0)
+ end
end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
end
table.serialize=serialize
if setinspector then
- setinspector("table",function(v)
- if type(v)=="table" then
- print(serialize(v,"table",{ metacheck=false }))
- return true
- end
- end)
+ setinspector("table",function(v)
+ if type(v)=="table" then
+ print(serialize(v,"table",{ metacheck=false }))
+ return true
+ end
+ end)
+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
@@ -7539,15 +7969,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 7787, stripped down to: 5858
+-- original size: 8607, stripped down to: 6727
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 {}
@@ -7555,251 +7986,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
@@ -7809,338 +8269,412 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 8716, stripped down to: 6754
+-- original size: 11065, stripped down to: 8209
if not modules then modules={} end modules ['util-sac']={
- 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 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)
+ 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()
end
function streams.size(f)
- return f and f[3] or 0
+ return f and f[3] or 0
end
function streams.setposition(f,i)
- if f[4] then
- if i<=0 then
- f[2]=1
- else
- f[2]=i+1
- end
+ if f[4] then
+ if i<=0 then
+ f[2]=1
else
- if i<=1 then
- f[2]=1
- else
- f[2]=i
- end
+ f[2]=i+1
end
-end
-function streams.getposition(f)
- if f[4] then
- return f[2]-1
+ else
+ if i<=1 then
+ f[2]=1
else
- return f[2]
+ f[2]=i
end
+ end
+end
+function streams.getposition(f)
+ if f[4] then
+ return f[2]-1
+ else
+ return f[2]
+ end
end
function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
- return sub(f[1],b,e)
- else
- return byte(f[1],b,e)
- end
+ local b=f[2]
+ local e=b+n-1
+ if chars then
+ return sub(f[1],b,e)
+ else
+ return byte(f[1],b,e)
+ end
end
function streams.skip(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
+ local i=f[2]
+ f[2]=i+1
+ return byte(f[1],i)
end
function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return byte(f[1],i,j-1)
end
function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return { byte(f[1],i,j-1) }
end
function streams.skipbytes(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
+ local i=f[2]
+ f[2]=i+1
+ return sub(f[1],i,i)
end
function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
-end
-function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return sub(f[1],i,j-1)
+end
+function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ local n=byte(f[1],i)
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-streams.readcardinal1=streams.readbyte
+streams.readcardinal1=streams.readbyte
streams.readcardinal=streams.readcardinal1
streams.readinteger=streams.readinteger1
function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readcardinal2LE(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ 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 streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local d,c,b,a=byte(f[1],i,j)
+ 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 streams.readfixed2(f)
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function streams.readfixed4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
- else
- return (0x100*a+b )+(0x100*c+d)/0x10000
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
end
-function streams.readfixed2(f)
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function streams.read2dot14(f)
local i=f[2]
local j=i+1
f[2]=j+1
local a,b=byte(f[1],i,j)
if a>=0x80 then
- return (a-0x100)+b/0x100
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
else
- return (a )+b/0x100
- end
-end
-if extract then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- 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 n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
+ f[2]=f[2]+2*(n or 1)
end
function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
+ f[2]=f[2]+4*(n or 1)
end
if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
- local i=f[2]
- f[2]=i+1
- return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
- local i=f[2]
- f[2]=i+2
- return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
- local i=f[2]
- f[2]=i+3
- return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
- local i=f[2]
- f[2]=i+4
- return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
- local i=f[2]
- f[2]=i+2
- return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
- local i=f[2]
- f[2]=i+3
- return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
- local i=f[2]
- f[2]=i+4
- return readinteger4(f[1],i)
- end
- function streams.read2dot4(f)
- local i=f[2]
- f[2]=i+2
- return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytes(f[1],i,n)
+ local readcardinal1=sio.readcardinal1
+ local readcardinal2=sio.readcardinal2
+ local readcardinal3=sio.readcardinal3
+ local readcardinal4=sio.readcardinal4
+ local readinteger1=sio.readinteger1
+ local readinteger2=sio.readinteger2
+ local readinteger3=sio.readinteger3
+ local readinteger4=sio.readinteger4
+ local readfixed2=sio.readfixed2
+ local readfixed4=sio.readfixed4
+ local read2dot14=sio.read2dot14
+ local readbytes=sio.readbytes
+ local readbytetable=sio.readbytetable
+ function streams.readcardinal1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readcardinal1(f[1],i)
+ end
+ function streams.readcardinal2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readcardinal2(f[1],i)
+ end
+ function streams.readcardinal3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readcardinal3(f[1],i)
+ end
+ function streams.readcardinal4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readcardinal4(f[1],i)
+ end
+ function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readinteger1(f[1],i)
+ end
+ function streams.readinteger2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readinteger2(f[1],i)
+ end
+ function streams.readinteger3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readinteger3(f[1],i)
+ end
+ function streams.readinteger4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readinteger4(f[1],i)
+ end
+ function streams.read2dot4(f)
+ local i=f[2]
+ f[2]=i+2
+ return read2dot4(f[1],i)
+ end
+ function streams.readbytes(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function streams.readbytetable(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytetable(f[1],i,n)
+ return readbytes(f[1],i,n)
+ end
+ function streams.readbytetable(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readbytetable(f[1],i,n)
+ end
+ streams.readbyte=streams.readcardinal1
+ streams.readsignedbyte=streams.readinteger1
+ streams.readcardinal=streams.readcardinal1
+ 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
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
+ 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
@@ -8150,156 +8684,168 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sto"] = package.loaded["util-sto"] or true
--- original size: 6449, stripped down to: 3069
+-- original size: 6661, stripped down to: 3074
if not modules then modules={} end modules ['util-sto']={
- 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 setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
utilities=utilities or {}
utilities.storage=utilities.storage or {}
local storage=utilities.storage
function storage.mark(t)
- if not t then
- print("\nfatal error: storage cannot be marked\n")
- os.exit()
- return
- end
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
+ local m=getmetatable(t)
+ return m and m.__storage__
end
function storage.checked(t)
- if not t then
- report("\nfatal error: storage has not been allocated\n")
- os.exit()
- return
- end
- return t
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
end
function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
- m.__index=nil
- initialize()
- return data[k]
- end
- setmetatable(data,m)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+ m.__index=nil
+ initialize()
+ return data[k]
+ end
+ setmetatable(data,m)
end
local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
+ t[k]=k
+ return k
end }
function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
-end
-local function f_empty () return "" end
-local function f_self (t,k) t[k]=k return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0 return 0 end
-local function f_ignore() end
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
+end
+local function f_empty () return "" end
+local function f_self (t,k) t[k]=k return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0 return 0 end
+local function f_ignore() end
local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
}
function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- else
- setmetatable(t,{ __index=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ else
+ setmetatable(t,{ __index=i })
+ end
+ return t
end
local f_index={
- ["ignore"]=f_ignore,
+ ["ignore"]=f_ignore,
}
function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__newindex=i
- else
- setmetatable(t,{ __newindex=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__newindex=i
+ else
+ setmetatable(t,{ __newindex=i })
+ end
+ return t
end
function table.setmetatablecall(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
- m.__call=f
- else
- setmetatable(t,{ __call=f })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__call=f
+ else
+ setmetatable(t,{ __call=f })
+ end
+ return t
end
function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- m.__newindex=n
- m.__call=c
- else
- setmetatable(t,{
- __index=i,
- __newindex=n,
- __call=c,
- })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ m.__newindex=n
+ m.__call=c
+ else
+ setmetatable(t,{
+ __index=i,
+ __newindex=n,
+ __call=c,
+ })
+ end
+ return t
end
function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m[key]=value
- return t
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m[key]=value
+ return t
end
function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
+ local m=getmetatable(t)
+ 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
@@ -8309,14 +8855,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 22956, stripped down to: 16106
+-- original size: 23460, stripped down to: 15834
if not modules then modules={} end modules ['util-prs']={
- 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 lpeg,table,string=lpeg,table,string
local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -8338,6 +8884,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("}")
@@ -8357,8 +8904,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -8366,311 +8913,329 @@ local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
local spaces=space^0
local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces
+lpegpatterns.nestedbraces=nestedbraces
lpegpatterns.nestedparents=nestedparents
-lpegpatterns.nested=nestedbraces
+lpegpatterns.nested=nestedbraces
lpegpatterns.argument=argument
lpegpatterns.content=content
-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("")))
local hash={}
local function set(key,value)
- hash[key]=value
+ hash[key]=value
end
local pattern_a_s=(pattern_a/set)^1
local pattern_b_s=(pattern_b/set)^1
local pattern_c_s=(pattern_c/set)^1
+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
- return (pattern_c/set)^1
- elseif how=="tolerant" then
- return (pattern_b/set)^1
- else
- return (pattern_a/set)^1
- end
+ if how=="strict" then
+ return (pattern_c/set)^1
+ elseif how=="tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
end
function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_a_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_a_s,str)
+ return hash
+ 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 {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_b_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
- return nil
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- elseif str and str~="" then
- hash=existing or {}
- lpegmatch(pattern_c_s,str)
- return next(hash) and hash
+ if not str or str=="" then
+ return nil
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
end
+ elseif str and str~="" then
+ hash=existing or {}
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
end
local separator=comma*space^0
-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 pattern=spaces*Ct(value*(separator*value)^0)
patterns.settings_to_array=pattern
function parsers.settings_to_array(str,strict)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- elseif strict then
- if find(str,"{",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
- elseif find(str,",",1,true) then
- return lpegmatch(pattern,str)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
else
- return { str }
+ return { str }
end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
end
function parsers.settings_to_numbers(str)
- if not str or str=="" then
- return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
- str=lpegmatch(pattern,str)
- else
- return { tonumber(str) }
- end
- for i=1,#str do
- str[i]=tonumber(str[i])
- end
- return str
-end
-local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
+ if not str or str=="" then
+ return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+ str=lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i]=tonumber(str[i])
+ end
+ return str
+end
+local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache_a={}
local cache_b={}
function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
- symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
- local symbols=S(symbol)
- local separator=space^0*symbols*space^0
- local value=P(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
- pattern=spaces*withvalue*(separator*withvalue)^0
- cache_b[symbol]=pattern
- else
- pattern=spaces*Ct(value*(separator*value)^0)
- cache_a[symbol]=pattern
- end
- end
- return pattern
+ if not symbol then
+ symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols=S(symbol)
+ local separator=space^0*symbols*space^0
+ 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
+ pattern=spaces*withvalue*(separator*withvalue)^0
+ cache_b[symbol]=pattern
+ else
+ pattern=spaces*Ct(value*(separator*value)^0)
+ cache_a[symbol]=pattern
+ end
+ end
+ return pattern
end
local pattern_a=parsers.groupedsplitat(",",false)
local pattern_b=parsers.groupedsplitat(",",true)
function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_a,str)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_a,str)
+ end
end
function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_b,str,1,action)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
end
local function set(t,v)
- t[#t+1]=v
+ t[#t+1]=v
end
local value=P(Carg(1)*value)/set
local pattern=value*(separator*value)^0*Carg(1)
function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
+ return lpegmatch(pattern,str,nil,t)
end
function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
- local t,tn,s={},0,sortedkeys(h)
- omit=omit and tohash(omit)
- for i=1,#s do
- local key=s[i]
- if not omit or not omit[key] then
- local value=h[key]
- if type(value)=="boolean" then
- if yes and no then
- if value then
- tn=tn+1
- t[tn]=key..'='..yes
- elseif not strict then
- tn=tn+1
- t[tn]=key..'='..no
- end
- elseif value or not strict then
- tn=tn+1
- t[tn]=key..'='..tostring(value)
- end
- else
- tn=tn+1
- t[tn]=key..'='..value
- end
- end
+ if h then
+ local t={}
+ local tn=0
+ local s=sortedkeys(h)
+ omit=omit and tohash(omit)
+ for i=1,#s do
+ local key=s[i]
+ if not omit or not omit[key] then
+ local value=h[key]
+ if type(value)=="boolean" then
+ if yes and no then
+ if value then
+ tn=tn+1
+ t[tn]=key..'='..yes
+ elseif not strict then
+ tn=tn+1
+ t[tn]=key..'='..no
+ end
+ elseif value or not strict then
+ tn=tn+1
+ t[tn]=key..'='..tostring(value)
+ end
+ else
+ tn=tn+1
+ t[tn]=key..'='..value
end
- return concat(t,separator or ",")
- else
- return ""
+ end
end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
end
function parsers.array_to_string(a,separator)
- if a then
- return concat(a,separator or ",")
- else
- return ""
- end
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
end
local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
function utilities.parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
+ return str and lpegmatch(pattern,str) or {}
end
hashes.settings_to_set=table.setmetatableindex(function(t,k)
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
end)
getmetatable(hashes.settings_to_set).__mode="kv"
function parsers.simple_hash_to_string(h,separator)
- local t,tn={},0
- for k,v in sortedhash(h) do
- if v then
- tn=tn+1
- t[tn]=k
- end
+ local t={}
+ local tn=0
+ for k,v in sortedhash(h) do
+ if v then
+ tn=tn+1
+ t[tn]=k
end
- return concat(t,separator or ",")
+ end
+ return concat(t,separator or ",")
end
local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
local splitter=setting^1
function utilities.parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
end
local splitter=lpeg.tsplitat(" ")
function utilities.parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
+ return str and lpegmatch(splitter,str) or {}
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
local pattern_a=spaces*Ct(value*(separator*value)^0)
local function repeater(n,str)
- if not n then
- return str
+ if not n then
+ return str
+ else
+ local s=lpegmatch(pattern_a,str)
+ if n==1 then
+ return unpack(s)
else
- local s=lpegmatch(pattern_a,str)
- if n==1 then
- return unpack(s)
- else
- local t,tn={},0
- for i=1,n do
- for j=1,#s do
- tn=tn+1
- t[tn]=s[j]
- end
- end
- return unpack(t)
+ local t={}
+ local tn=0
+ for i=1,n do
+ for j=1,#s do
+ tn=tn+1
+ t[tn]=s[j]
end
+ end
+ return unpack(t)
end
+ end
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
local pattern_b=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_with_repeat(str,expand)
- if expand then
- return lpegmatch(pattern_b,str) or {}
- else
- return lpegmatch(pattern_a,str) or {}
- end
+ if expand then
+ return lpegmatch(pattern_b,str) or {}
+ else
+ return lpegmatch(pattern_a,str) or {}
+ end
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
local pattern=Ct((space+value)^0)
function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
- sc={}
- self[class]=sc
- if parentclass then
- local sp=self[parentclass]
- if not sp then
- sp={}
- self[parentclass]=sp
- end
- setmetatableindex(sc,sp)
- end
+ local sc=self[class]
+ if not sc then
+ sc={}
+ self[class]=sc
+ if parentclass then
+ local sp=self[parentclass]
+ if not sp then
+ sp={}
+ self[parentclass]=sp
+ end
+ setmetatableindex(sc,sp)
end
- parsers.settings_to_hash(settings,sc)
+ end
+ parsers.settings_to_hash(settings,sc)
end
function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
+ return gmatch(str,"[^, ]+")
end
local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
}
lpegpatterns.splitthousands=pattern
function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local optionalwhitespace=whitespace^0
lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -8684,75 +9249,75 @@ local key=C((1-equal)^1)
local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
function parsers.keq_to_hash(str)
- if str and str~="" then
- return lpegmatch(pattern,str)
- else
- return {}
- end
+ if str and str~="" then
+ return lpegmatch(pattern,str)
+ else
+ return {}
+ end
end
local defaultspecification={ separator=",",quote='"' }
function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
- local quotedata=nil
- for chr in gmatch(quotechar,".") do
- local quotechar=P(chr)
- local quoteword=quotechar*C((1-quotechar)^0)*quotechar
- if quotedata then
- quotedata=quotedata+quoteword
- else
- quotedata=quoteword
- end
- end
- whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
- return lpegmatch(parser,data)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+ local quotedata=nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar=P(chr)
+ local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+ if quotedata then
+ quotedata=quotedata+quoteword
+ else
+ quotedata=quoteword
+ end
end
+ whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
end
function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=P(specification.quote)
- local dquotechar=quotechar*quotechar
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=P(specification.quote)
+ local dquotechar=quotechar*quotechar
/specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
- if getheader then
- local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(headeryes,data,position)
- return data,header
- else
- return lpegmatch(headernop,data)
- end
- end
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header,position=lpegmatch(headerline,data)
+ local data=lpegmatch(headeryes,data,position)
+ return data,header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
end
local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
- for i=first,n or first do
- action(i)
- end
- elseif last then
- for i=first,last do
- action(i)
- end
- else
- action(first)
+ if not first then
+ elseif last==true then
+ for i=first,n or first do
+ action(i)
end
+ elseif last then
+ for i=first,last do
+ action(i)
+ end
+ else
+ action(first)
+ end
end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
@@ -8760,89 +9325,89 @@ local endofstring=lpegpatterns.endofstring
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
- if type(n)=="function" then
- lpegmatch(stepper,str,1,false,n or print)
- else
- lpegmatch(stepper,str,1,n,action or print)
- end
+ if type(n)=="function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
end
local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
patterns.unittotex=pattern
function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
end
local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache={}
local spaces=lpegpatterns.space^0
local dummy=function() end
setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
end)
local commalistiterator=cache[","]
function utilities.parsers.iterator(str,separator)
- local n=#str
- if n==0 then
- return dummy
- else
- local pattern=separator and cache[separator] or commalistiterator
- local p=1
- return function()
- if p<=n then
- local s,e=lpegmatch(pattern,str,p)
- if e then
- p=e
- return s
- end
- end
+ local n=#str
+ if n==0 then
+ return dummy
+ else
+ local pattern=separator and cache[separator] or commalistiterator
+ local p=1
+ return function()
+ if p<=n then
+ local s,e=lpegmatch(pattern,str,p)
+ if e then
+ p=e
+ return s
end
+ end
end
+ end
end
local function initialize(t,name)
- local source=t[name]
- if source then
- local result={}
- for k,v in next,t[name] do
- result[k]=v
- end
- return result
- else
- return {}
+ local source=t[name]
+ if source then
+ local result={}
+ for k,v in next,t[name] do
+ result[k]=v
end
+ return result
+ else
+ return {}
+ end
end
local function fetch(t,name)
- return t[name] or {}
+ return t[name] or {}
end
local function process(result,more)
- for k,v in next,more do
- result[k]=v
- end
- return result
+ for k,v in next,more do
+ result[k]=v
+ end
+ return result
end
local name=C((1-S(", "))^1)
local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
local merge=Cf(parser,process)
function utilities.parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
+ return lpegmatch(merge,list,1,hash)
end
function utilities.parsers.runtime(time)
- if not time then
- time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
+ if not time then
+ time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
end
local spacing=whitespace^0
local apply=P("->")
@@ -8850,11 +9415,11 @@ local method=C((1-apply)^1)
local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
function utilities.parsers.splitmethod(str,default)
- if str then
- return lpegmatch(pattern,str,1,default or false)
- else
- return default or false,""
- end
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false,""
+ end
end
@@ -8864,14 +9429,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
--- original size: 2274, stripped down to: 1781
+-- original size: 2541, stripped down to: 1624
if not modules then modules={} end modules ['util-fmt']={
- 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"
}
utilities=utilities or {}
utilities.formatters=utilities.formatters or {}
@@ -8882,61 +9447,2887 @@ local strip=string.strip
local lpegmatch=lpeg.match
local stripper=lpeg.patterns.stripzeros
function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
+ return lpegmatch(stripper,str)
end
function formatters.formatcolumns(result,between)
- if result and #result>0 then
- between=between or " "
- local widths,numbers={},{}
- local first=result[1]
- local n=#first
- for i=1,n do
- widths[i]=0
+ if result and #result>0 then
+ between=between or " "
+ local widths,numbers={},{}
+ local first=result[1]
+ local n=#first
+ for i=1,n do
+ widths[i]=0
+ end
+ for i=1,#result do
+ local r=result[i]
+ for j=1,n do
+ local rj=r[j]
+ local tj=type(rj)
+ if tj=="number" then
+ numbers[j]=true
+ rj=tostring(rj)
+ elseif tj~="string" then
+ rj=tostring(rj)
+ r[j]=rj
+ end
+ local w=#rj
+ if w>widths[j] then
+ widths[j]=w
end
- for i=1,#result do
- local r=result[i]
- 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
- local w=#rj
- if w>widths[j] then
- widths[j]=w
- end
+ end
+ end
+ for i=1,n do
+ local w=widths[i]
+ if numbers[i] then
+ if w>80 then
+ widths[i]="%s"..between
+ else
+ widths[i]="%0"..w.."i"..between
+ end
+ else
+ if w>80 then
+ widths[i]="%s"..between
+ elseif w>0 then
+ widths[i]="%-"..w.."s"..between
+ else
+ widths[i]="%s"
+ end
+ end
+ end
+ local template=strip(concat(widths))
+ for i=1,#result do
+ local str=format(template,unpack(result[i]))
+ result[i]=strip(str)
+ end
+ end
+ return result
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true
+
+-- original size: 374, stripped down to: 282
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
+
+-- original size: 4870, stripped down to: 3527
+
+
+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
+ 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
+ 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
+package.loaded["socket"]=socket
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
+
+-- original size: 25844, stripped down to: 14821
+
+
+local socket=socket or require("socket")
+local ssl=ssl or nil
+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
+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
+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
+ 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
- for i=1,n do
- local w=widths[i]
- if numbers[i] then
- if w>80 then
- widths[i]="%s"..between
- else
- widths[i]="%0"..w.."i"..between
- end
- else
- if w>80 then
- widths[i]="%s"..between
- elseif w>0 then
- widths[i]="%-"..w.."s"..between
- else
- widths[i]="%s"
- end
+ }
+ } )
+ return set
+end
+local _sleeping={
+ times={},
+ cos={},
+ lethargy={},
+ insert=function()
+ end,
+ remove=function()
+ end,
+ push=function(self,sleeptime,co)
+ if not co then
+ return
+ end
+ if sleeptime<0 then
+ 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=
+ 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=
+ 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
- local template=strip(concat(widths))
- for i=1,#result do
- local str=format(template,unpack(result[i]))
- result[i]=strip(str)
+ end
+}
+local _servers=newset()
+local _reading=newset()
+local _writing=newset()
+local _reading_log={}
+local _writing_log={}
+local _is_timeout={
+ timeout=true,
+ wantread=true,
+ wantwrite=true,
+}
+local function isTCP(socket)
+ return not find(tostring(socket),"^udp")
+end
+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
+local function copasreceivefrom(client,size)
+ local s,err,port
+ if not size or size==0 then
+ size=UDP_DATAGRAM_MAX
+ end
+ repeat
+ 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
+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
+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)
+ 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
+local function copassendto(client,data,ip,port)
+ repeat
+ local s,err=client:sendto(data,ip,port)
+ 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
+local function copasconnect(skt,host,port)
+ skt:settimeout(0)
+ local ret,err,tried_more_than_once
+ repeat
+ ret,err=skt:connect (host,port)
+ if ret or (err~="timeout" and err~="Operation already in progress") then
+ 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
+local function copasdohandshake(skt,sslt)
+ 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
+local function copasflush(client)
+end
+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
+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,
+ 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,
+ bind=function(self,...)
+ return self.socket:bind(...)
+ end,
+ 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,
+ 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,
+}
+local _skt_mt_udp_index={
+ 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,
+ setpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ setsockname=function(self,...)
+ return self.socket:setsockname(...)
+ end,
+ 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
+local function wrap(skt,sslt)
+ if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
+ return skt
+ 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
+function copas.handler(handler,sslparams)
+ return function (skt,...)
+ skt=wrap(skt)
+ if sslparams then
+ skt:dohandshake(sslparams)
+ end
+ return handler(skt,...)
+ end
+end
+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
+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
+ if skt and copas.autoclose and isTCP(skt) then
+ skt:close()
+ end
+ _errhandlers[co]=nil
+ end
+end
+local function _accept(input,handler)
+ local client=input:accept()
+ if client then
+ client:settimeout(0)
+ local co=createcoroutine(handler)
+ _doTick (co,client)
+ end
+ return client
+end
+local function _tickRead(skt)
+ _doTick(_reading:pop(skt),skt)
+end
+local function _tickWrite(skt)
+ _doTick(_writing:pop(skt),skt)
+end
+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
+function copas.addthread(handler,...)
+ local thread=createcoroutine(function(_,...) return handler(...) end)
+ _doTick(thread,nil,...)
+ return thread
+end
+local _tasks={}
+local function addtaskRead(task)
+ task.def_tick=_tickRead
+ _tasks[task]=true
+end
+local function addtaskWrite(task)
+ task.def_tick=_tickWrite
+ _tasks[task]=true
+end
+local function tasks()
+ return next,_tasks
+end
+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)
+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)
+local _sleeping_t={
+ tick=function(self,time,...)
+ _doTick(_sleeping:pop(time),...)
+ end
+}
+function copas.sleep(sleeptime)
+ yieldcoroutine((sleeptime or 0),_sleeping)
+end
+function copas.wakeup(co)
+ _sleeping:wakeup(co)
+end
+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
+ for skt,time in next,_reading_log do
+ if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#r_evs+1
+ _reading_log[skt]=nil
+ r_evs[n]=skt
+ r_evs[skt]=n
+ end
+ end
+ 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
+local function copasfinished()
+ return not (next(_reading) or next(_writing) or _sleeping:getnext())
+end
+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
+function copas.loop(timeout)
+ copas.running=true
+ while not copasfinished() do
+ copasstep(timeout)
+ end
+ copas.running=false
+end
+package.loaded["copas"]=copas
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
+
+-- original size: 8709, stripped down to: 5411
+
+
+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,
+}
+function filter.cycle(low,ctx,extra)
+ if low then
+ return function(chunk)
+ return (low(ctx,chunk,extra))
+ end
+ end
+end
+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
- return result
+ end
+end
+local function empty()
+ return nil
+end
+function source.empty()
+ return empty
+end
+local function sourceerror(err)
+ return function()
+ return nil,err
+ end
+end
+source.error=sourceerror
+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
+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
+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
+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
+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
+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
+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
+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
+local function null()
+ return 1
+end
+function sink.null()
+ return null
+end
+local function sinkerror(err)
+ return function()
+ return nil,err
+ end
+end
+sink.error=sinkerror
+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
+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
+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
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
+
+-- original size: 2328, stripped down to: 1874
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
+
+-- original size: 6863, stripped down to: 5269
+
+
+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)
+ 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
+ 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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
+
+-- original size: 5721, stripped down to: 3754
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
+
+-- original size: 3116, stripped down to: 2533
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
+
+-- original size: 12577, stripped down to: 9577
+
+
+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
+local http={
+ TIMEOUT=60,
+ USERAGENT=socket._VERSION,
+}
+socket.http=http
+local PORT=80
+local SCHEMES={
+ http=true,
+}
+local function receiveheaders(sock,headers)
+ if not headers then
+ headers={}
+ end
+ local line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while line~="" do
+ local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
+ if not (name and value) then
+ return nil,"malformed reponse headers"
+ end
+ name=lower(name)
+ line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while find(line,"^%s") do
+ value=value..line
+ line=sock:receive()
+ if err then
+ return nil,err
+ end
+ end
+ local found=headers[name]
+ if found then
+ value=found..", "..value
+ end
+ headers[name]=value
+ end
+ return headers
+end
+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
+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
+ 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"]
+ local mode="default"
+ if encoding and encoding~="identity" then
+ mode="http-chunked"
+ elseif length then
+ mode="by-length"
+ end
+ 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
+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
+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
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
+
+-- original size: 10357, stripped down to: 8548
+
+
+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
+ 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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
+
+-- original size: 7018, stripped down to: 5883
+
+
+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
end -- of closure
@@ -8945,14 +12336,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-set"] = package.loaded["trac-set"] or true
--- original size: 13044, stripped down to: 9231
+-- original size: 13340, stripped down to: 8826
if not modules then modules={} end modules ['trac-set']={
- 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=type,next,tostring,tonumber
local concat,sortedhash=table.concat,table.sortedhash
@@ -8967,305 +12358,318 @@ utilities.setters=setters
local data={}
local trace_initialize=false
function setters.initialize(filename,name,values)
- local setter=data[name]
- if setter then
- frozen=true
- local data=setter.data
- if data then
- for key,newvalue in sortedhash(values) do
- local newvalue=is_boolean(newvalue,newvalue,true)
- local functions=data[key]
- if functions then
- local oldvalue=functions.value
- if functions.frozen then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
- end
- elseif #functions>0 and not oldvalue then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
- end
- for i=1,#functions do
- functions[i](newvalue)
- end
- functions.value=newvalue
- functions.frozen=functions.frozen or frozen
- else
- if trace_initialize then
- setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
- end
- end
- else
- functions={ default=newvalue,frozen=frozen }
- data[key]=functions
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
- end
- end
+ local setter=data[name]
+ if setter then
+ frozen=true
+ local data=setter.data
+ if data then
+ for key,newvalue in sortedhash(values) do
+ local newvalue=is_boolean(newvalue,newvalue,true)
+ local functions=data[key]
+ if functions then
+ local oldvalue=functions.value
+ if functions.frozen then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+ end
+ elseif #functions>0 and not oldvalue then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
+ end
+ for i=1,#functions do
+ functions[i](newvalue)
+ end
+ functions.value=newvalue
+ functions.frozen=functions.frozen or frozen
+ else
+ if trace_initialize then
+ setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
end
- return true
+ end
+ else
+ functions={ default=newvalue,frozen=frozen }
+ data[key]=functions
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
+ end
end
+ end
+ return true
end
+ end
end
local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
- local done=t.done
- if type(what)=="string" then
- what=settings_to_hash(what)
- end
- if type(what)~="table" then
- return
- end
- if not done then
- done={}
- t.done=done
- end
- for w,value in sortedhash(what) do
- if value=="" then
- value=newvalue
- elseif not value then
- value=false
- else
- value=is_boolean(value,value,true)
- end
- w=topattern(w,true,true)
- for name,functions in sortedhash(data) do
- if done[name] then
- elseif find(name,w) then
- done[name]=true
- for i=1,#functions do
- functions[i](value)
- end
- functions.value=value
- end
- end
+ local data=t.data
+ if not data.frozen then
+ local done=t.done
+ if type(what)=="string" then
+ what=settings_to_hash(what)
+ end
+ if type(what)~="table" then
+ return
+ end
+ if not done then
+ done={}
+ t.done=done
+ end
+ for w,value in sortedhash(what) do
+ if value=="" then
+ value=newvalue
+ elseif not value then
+ value=false
+ else
+ value=is_boolean(value,value,true)
+ end
+ w=topattern(w,true,true)
+ for name,functions in sortedhash(data) do
+ if done[name] then
+ elseif find(name,w) then
+ done[name]=true
+ for i=1,#functions do
+ functions[i](value)
+ end
+ functions.value=value
end
+ end
end
+ end
end
local function reset(t)
- local data=t.data
- if not data.frozen then
- for name,functions in sortedthash(data) do
- for i=1,#functions do
- functions[i](false)
- end
- functions.value=false
- end
+ local data=t.data
+ if not data.frozen then
+ for name,functions in sortedthash(data) do
+ for i=1,#functions do
+ functions[i](false)
+ end
+ functions.value=false
end
+ end
end
local function enable(t,what)
- set(t,what,true)
+ set(t,what,true)
end
local function disable(t,what)
- local data=t.data
- if not what or what=="" then
- t.done={}
- reset(t)
- else
- set(t,what,false)
- end
+ local data=t.data
+ if not what or what=="" then
+ t.done={}
+ reset(t)
+ else
+ set(t,what,false)
+ end
end
function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
- functions={}
- data[what]=functions
- if trace_initialize then
- t.report("defining %a",what)
- end
- end
- local default=functions.default
- for i=1,select("#",...) do
- local fnc=select(i,...)
- local typ=type(fnc)
- if typ=="string" then
- if trace_initialize then
- t.report("coupling %a to %a",what,fnc)
- end
- local s=fnc
- fnc=function(value) set(t,s,value) end
- elseif typ~="function" then
- fnc=nil
- end
- if fnc then
- functions[#functions+1]=fnc
- local value=functions.value or default
- if value~=nil then
- fnc(value)
- functions.value=value
- end
- end
+ local data=t.data
+ what=lower(what)
+ local functions=data[what]
+ if not functions then
+ functions={}
+ data[what]=functions
+ if trace_initialize then
+ t.report("defining %a",what)
+ end
+ end
+ local default=functions.default
+ for i=1,select("#",...) do
+ local fnc=select(i,...)
+ local typ=type(fnc)
+ if typ=="string" then
+ if trace_initialize then
+ t.report("coupling %a to %a",what,fnc)
+ end
+ local s=fnc
+ fnc=function(value) set(t,s,value) end
+ elseif typ~="function" then
+ fnc=nil
+ end
+ if fnc then
+ functions[#functions+1]=fnc
+ local value=functions.value or default
+ if value~=nil then
+ fnc(value)
+ functions.value=value
+ end
end
- return false
+ end
+ return false
end
function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
+ local e=t.enable
+ t.enable,t.done=enable,{}
+ enable(t,what)
+ t.enable,t.done=e,{}
end
function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
+ local e=t.disable
+ t.disable,t.done=disable,{}
+ disable(t,what)
+ t.disable,t.done=e,{}
end
function setters.reset(t)
- t.done={}
- reset(t)
+ t.done={}
+ reset(t)
end
function setters.list(t)
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
- local what=list[l]
- if find(what,"^%*") then
- system[#system+1]=what
- else
- user[#user+1]=what
- end
+ local list=table.sortedkeys(t.data)
+ local user,system={},{}
+ for l=1,#list do
+ local what=list[l]
+ if find(what,"^%*") then
+ system[#system+1]=what
+ else
+ user[#user+1]=what
end
- return user,system
+ end
+ return user,system
end
function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
- local name=list[k]
- local functions=t.data[name]
- if functions then
- local value=functions.value
- local default=functions.default
- local modules=#functions
- if default==nil then
- default="unset"
- elseif type(default)=="table" then
- default=concat(default,"|")
- else
- default=tostring(default)
- end
- if value==nil then
- value="unset"
- elseif type(value)=="table" then
- value=concat(value,"|")
- else
- value=tostring(value)
- end
- t.report(name)
- t.report(" modules : %i",modules)
- t.report(" default : %s",default)
- t.report(" value : %s",value)
- t.report()
- end
+ local list=setters.list(t)
+ t.report()
+ for k=1,#list do
+ local name=list[k]
+ local functions=t.data[name]
+ if functions then
+ local value=functions.value
+ local default=functions.default
+ local modules=#functions
+ if default==nil then
+ default="unset"
+ elseif type(default)=="table" then
+ default=concat(default,"|")
+ else
+ default=tostring(default)
+ end
+ if value==nil then
+ value="unset"
+ elseif type(value)=="table" then
+ value=concat(value,"|")
+ else
+ value=tostring(value)
+ end
+ t.report(name)
+ t.report(" modules : %i",modules)
+ t.report(" default : %s",default)
+ t.report(" value : %s",value)
+ t.report()
end
+ end
end
local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
function setters.report(setter,...)
- print(format("%-15s : %s\n",setter.name,format(...)))
+ print(format("%-15s : %s\n",setter.name,format(...)))
end
local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
+ local d=setter.data[name]
+ return d and d.default
end
local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
+ local d=setter.data[name]
+ return d and (d.value or d.default)
end
function setters.new(name)
- local setter
- setter={
- data=allocate(),
- name=name,
- report=function(...) setters.report (setter,...) end,
- enable=function(...) enable (setter,...) end,
- disable=function(...) disable (setter,...) end,
- reset=function(...) reset (setter,...) end,
- register=function(...) register(setter,...) end,
- list=function(...) list (setter,...) end,
- show=function(...) show (setter,...) end,
- default=function(...) return default (setter,...) end,
- value=function(...) return value (setter,...) end,
- }
- data[name]=setter
- return setter
+ local setter
+ setter={
+ data=allocate(),
+ name=name,
+ report=function(...) setters.report (setter,...) end,
+ enable=function(...) enable (setter,...) end,
+ disable=function(...) disable (setter,...) end,
+ reset=function(...) reset (setter,...) end,
+ register=function(...) register(setter,...) end,
+ list=function(...) list (setter,...) end,
+ show=function(...) show (setter,...) end,
+ default=function(...) return default (setter,...) end,
+ value=function(...) return value (setter,...) end,
+ }
+ data[name]=setter
+ return setter
end
trackers=setters.new("trackers")
directives=setters.new("directives")
experiments=setters.new("experiments")
-local t_enable,t_disable=trackers .enable,trackers .disable
+local t_enable,t_disable=trackers .enable,trackers .disable
local d_enable,d_disable=directives .enable,directives .disable
local e_enable,e_disable=experiments.enable,experiments.disable
-local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
-local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
+local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
+local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
function directives.enable(...)
- if trace_directives then
- directives.report("enabling: % t",{...})
- end
- d_enable(...)
+ if trace_directives then
+ directives.report("enabling: % t",{...})
+ end
+ d_enable(...)
end
function directives.disable(...)
- if trace_directives then
- directives.report("disabling: % t",{...})
- end
- d_disable(...)
+ if trace_directives then
+ directives.report("disabling: % t",{...})
+ end
+ d_disable(...)
end
function experiments.enable(...)
- if trace_experiments then
- experiments.report("enabling: % t",{...})
- end
- e_enable(...)
+ if trace_experiments then
+ experiments.report("enabling: % t",{...})
+ end
+ e_enable(...)
end
function experiments.disable(...)
- if trace_experiments then
- experiments.report("disabling: % t",{...})
- end
- e_disable(...)
+ if trace_experiments then
+ experiments.report("disabling: % t",{...})
+ end
+ e_disable(...)
end
directives.register("system.nostatistics",function(v)
- if statistics then
- statistics.enable=not v
- else
- end
+ if statistics then
+ statistics.enable=not v
+ else
+ end
end)
directives.register("system.nolibraries",function(v)
- if libraries then
- libraries=nil
- else
- end
+ if libraries then
+ libraries=nil
+ else
+ end
end)
if environment then
- local engineflags=environment.engineflags
- if engineflags then
- local list=engineflags["c:trackers"] or engineflags["trackers"]
- if type(list)=="string" then
- setters.initialize("commandline flags","trackers",settings_to_hash(list))
- end
- local list=engineflags["c:directives"] or engineflags["directives"]
- if type(list)=="string" then
- setters.initialize("commandline flags","directives",settings_to_hash(list))
- end
+ local engineflags=environment.engineflags
+ if engineflags then
+ local list=engineflags["c:trackers"] or engineflags["trackers"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","trackers",settings_to_hash(list))
end
-end
-if texconfig then
- local function set(k,v)
- v=tonumber(v)
- if v then
- texconfig[k]=v
- end
+ local list=engineflags["c:directives"] or engineflags["directives"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","directives",settings_to_hash(list))
end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v) end)
- directives.register("luatex.savesize",function(v) set("save_size",v) end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+ end
end
+if texconfig then
+ local function set(k,v)
+ v=tonumber(v)
+ if v then
+ texconfig[k]=v
+ end
+ end
+ directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
+ directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
+ directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
+ directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
+ directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
+ directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
+ directives.register("luatex.paramsize",function(v) set("param_size",v) end)
+ directives.register("luatex.savesize",function(v) set("save_size",v) end)
+ directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+end
+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,
+}
end -- of closure
@@ -9274,14 +12678,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-log"] = package.loaded["trac-log"] or true
--- original size: 32922, stripped down to: 23011
+-- original size: 32608, stripped down to: 20925
if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.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 trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,select,print=next,type,select,print
local format,gmatch,find=string.format,string.gmatch,string.find
@@ -9292,7 +12696,7 @@ local datetime=os.date
local openfile=io.open
local runningtex=tex and (tex.jobname or tex.formatname)
local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
+local write=runningtex and texio and texio.write or io.write
local setmetatableindex=table.setmetatableindex
local formatters=string.formatters
local settings_to_hash=utilities.parsers.settings_to_hash
@@ -9308,404 +12712,404 @@ webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
wiki : http://contextgarden.net
]]
formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
+ formatters,"unichr",
+ [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
)
formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
+ formatters,"chruni",
+ [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
)
local function ignore() end
setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
local report,subreport,status,settarget,setformats,settranslations
local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
if runningtex then
- if texio.setescape then
- texio.setescape(0)
- end
- if arg then
- for k,v in next,arg do
- if v=="--ansi" or v=="--c:ansi" then
- variant="ansi"
- break
- end
- end
- end
- local function useluawrites()
- local texio_write_nl=texio.write_nl
- local texio_write=texio.write
- local io_write=io.write
- write_nl=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write_nl("log",...)
- texio_write_nl("term","")
- io_write(...)
- elseif target=="log" then
- texio_write_nl("log",...)
- elseif target=="term" then
- texio_write_nl("term","")
- io_write(...)
- elseif type(target)=="number" then
- texio_write_nl(target,...)
- elseif target~="none" then
- texio_write_nl("log",target,...)
- texio_write_nl("term","")
- io_write(target,...)
- end
- end
- write=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write("log",...)
- io_write(...)
- elseif target=="log" then
- texio_write("log",...)
- elseif target=="term" then
- io_write(...)
- elseif type(target)=="number" then
- texio_write(target,...)
- elseif target~="none" then
- texio_write("log",target,...)
- io_write(target,...)
- end
- end
- texio.write=write
- texio.write_nl=write_nl
- useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="log",
- log="log",
- file="log",
- console="term",
- terminal="term",
- both="term and log",
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="none",
- log="none",
- file="none",
- console="term",
- terminal="term",
- both="term",
- },
- }
- }
- logs.flush=io.flush
- writer=function(...)
- write_nl(target,...)
- end
- newline=function()
- write_nl(target,"\n")
- end
- report=function(a,b,c,...)
- if c~=nil then
- write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,report_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,report_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- direct=function(a,b,c,...)
- if c~=nil then
- return direct_yes(translations[a],formatters[formats[b]](c,...))
- elseif b then
- return direct_yes(translations[a],formats[b])
- elseif a then
- return direct_nop(translations[a])
- else
- return ""
- end
- end
- subreport=function(a,s,b,c,...)
- if c~=nil then
- write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
- elseif a then
- write_nl(target,subreport_nop(translations[a],translations[s]))
- else
- write_nl(target,"\n")
- end
- end
- subdirect=function(a,s,b,c,...)
- if c~=nil then
- return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
- elseif b then
- return subdirect_yes(translations[a],translations[s],formats[b])
- elseif a then
- return subdirect_nop(translations[a],translations[s])
- else
- return ""
- end
+ if texio.setescape then
+ texio.setescape(0)
+ end
+ if arg then
+ for k,v in next,arg do
+ if v=="--ansi" or v=="--c:ansi" then
+ variant="ansi"
+ break
+ end
end
- status=function(a,b,c,...)
- if c~=nil then
- write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,status_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,status_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
+ end
+ local function useluawrites()
+ local texio_write_nl=texio.write_nl
+ local texio_write=texio.write
+ local io_write=io.write
+ write_nl=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write_nl("log",...)
+ texio_write_nl("term","")
+ io_write(...)
+ elseif target=="log" then
+ texio_write_nl("log",...)
+ elseif target=="term" then
+ texio_write_nl("term","")
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write_nl(target,...)
+ elseif target~="none" then
+ texio_write_nl("log",target,...)
+ texio_write_nl("term","")
+ io_write(target,...)
+ end
end
- settarget=function(askedwhereto)
- whereto=askedwhereto or whereto or "both"
- target=targets[whereto]
- if not target then
- whereto="both"
- target=targets[whereto]
- end
- if target=="term" or target=="term and log" then
- logs.flush=io.flush
- else
- logs.flush=ignore
- end
+ write=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write("log",...)
+ io_write(...)
+ elseif target=="log" then
+ texio_write("log",...)
+ elseif target=="term" then
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write(target,...)
+ elseif target~="none" then
+ texio_write("log",target,...)
+ io_write(target,...)
+ end
end
- local stack={}
- pushtarget=function(newtarget)
- insert(stack,target)
- settarget(newtarget)
+ texio.write=write
+ texio.write_nl=write_nl
+ useluawrites=ignore
+ end
+ local whereto="both"
+ local target=nil
+ local targets=nil
+ local formats=table.setmetatableindex("self")
+ local translations=table.setmetatableindex("self")
+ local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
+ local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="log",
+ log="log",
+ file="log",
+ console="term",
+ terminal="term",
+ both="term and log",
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="none",
+ log="none",
+ file="none",
+ console="term",
+ terminal="term",
+ both="term",
+ },
+ }
+ }
+ logs.flush=io.flush
+ writer=function(...)
+ write_nl(target,...)
+ end
+ newline=function()
+ write_nl(target,"\n")
+ end
+ report=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,report_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,report_nop(translations[a]))
+ else
+ write_nl(target,"\n")
end
- poptarget=function()
- if #stack>0 then
- settarget(remove(stack))
- end
+ end
+ direct=function(a,b,c,...)
+ if c~=nil then
+ return direct_yes(translations[a],formatters[formats[b]](c,...))
+ elseif b then
+ return direct_yes(translations[a],formats[b])
+ elseif a then
+ return direct_nop(translations[a])
+ else
+ return ""
end
- setformats=function(f)
- formats=f
+ end
+ subreport=function(a,s,b,c,...)
+ if c~=nil then
+ write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
+ elseif a then
+ write_nl(target,subreport_nop(translations[a],translations[s]))
+ else
+ write_nl(target,"\n")
end
- settranslations=function(t)
- translations=t
+ end
+ subdirect=function(a,s,b,c,...)
+ if c~=nil then
+ return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
+ elseif b then
+ return subdirect_yes(translations[a],translations[s],formats[b])
+ elseif a then
+ return subdirect_nop(translations[a],translations[s])
+ else
+ return ""
end
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(target,...)
- writeline(target,f(...))
- end
+ end
+ status=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,status_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,status_nop(translations[a]))
+ else
+ write_nl(target,"\n")
+ end
+ end
+ settarget=function(askedwhereto)
+ whereto=askedwhereto or whereto or "both"
+ target=targets[whereto]
+ if not target then
+ whereto="both"
+ target=targets[whereto]
+ end
+ if target=="term" or target=="term and log" then
+ logs.flush=io.flush
+ else
+ logs.flush=ignore
+ end
+ end
+ local stack={}
+ pushtarget=function(newtarget)
+ insert(stack,target)
+ settarget(newtarget)
+ end
+ poptarget=function()
+ if #stack>0 then
+ settarget(remove(stack))
+ end
+ end
+ setformats=function(f)
+ formats=f
+ end
+ settranslations=function(t)
+ translations=t
+ end
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(target,...)
+ writeline(target,f(...))
+ end
+ end
+ setformatters=function(specification)
+ local t=nil
+ local f=nil
+ local d=variants.default
+ if not specification then
+ elseif type(specification)=="table" then
+ t=specification.targets
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ t=v.targets
+ f=v.formats
+ variant=specification
+ end
end
- setformatters=function(specification)
- local t=nil
- local f=nil
- local d=variants.default
- if not specification then
- elseif type(specification)=="table" then
- t=specification.targets
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- t=v.targets
- f=v.formats
- variant=specification
- end
- end
- targets=t or d.targets
- target=targets[whereto] or target
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- direct_yes=f.direct_yes
- direct_nop=f.direct_nop
- subdirect_yes=f.subdirect_yes
- subdirect_nop=f.subdirect_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- if variant=="ansi" then
- useluawrites()
- end
- settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
+ targets=t or d.targets
+ target=targets[whereto] or target
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ direct_yes=f.direct_yes
+ direct_nop=f.direct_nop
+ subdirect_yes=f.subdirect_yes
+ subdirect_nop=f.subdirect_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ if variant=="ansi" then
+ useluawrites()
+ end
+ settarget(whereto)
+ end
+ setformatters(variant)
+ setlogfile=ignore
+ settimedlog=ignore
else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- }
- logs.flush=ignore
- writer=function(s)
- write_nl(s)
- end
- newline=function()
- write_nl("\n")
+ local report_yes,subreport_yes,status_yes
+ local report_nop,subreport_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ }
+ logs.flush=ignore
+ writer=function(s)
+ write_nl(s)
+ end
+ newline=function()
+ write_nl("\n")
+ end
+ report=function(a,b,c,...)
+ if c then
+ write_nl(report_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(report_yes(a,b))
+ elseif a then
+ write_nl(report_nop(a))
+ else
+ write_nl("")
end
- report=function(a,b,c,...)
- if c then
- write_nl(report_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(report_yes(a,b))
- elseif a then
- write_nl(report_nop(a))
- else
- write_nl("")
- end
+ end
+ subreport=function(a,sub,b,c,...)
+ if c then
+ write_nl(subreport_yes(a,sub,formatters[b](c,...)))
+ elseif b then
+ write_nl(subreport_yes(a,sub,b))
+ elseif a then
+ write_nl(subreport_nop(a,sub))
+ else
+ write_nl("")
end
- subreport=function(a,sub,b,c,...)
- if c then
- write_nl(subreport_yes(a,sub,formatters[b](c,...)))
- elseif b then
- write_nl(subreport_yes(a,sub,b))
- elseif a then
- write_nl(subreport_nop(a,sub))
- else
- write_nl("")
+ end
+ status=function(a,b,c,...)
+ if c then
+ write_nl(status_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(status_yes(a,b))
+ elseif a then
+ write_nl(status_nop(a))
+ else
+ write_nl("\n")
+ end
+ end
+ direct=ignore
+ subdirect=ignore
+ settarget=ignore
+ pushtarget=ignore
+ poptarget=ignore
+ setformats=ignore
+ settranslations=ignore
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(f(s))
+ end
+ end
+ setformatters=function(specification)
+ local f=nil
+ local d=variants.default
+ if specification then
+ if type(specification)=="table" then
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ f=v.formats
end
+ end
end
- status=function(a,b,c,...)
- if c then
- write_nl(status_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(status_yes(a,b))
- elseif a then
- write_nl(status_nop(a))
- else
- write_nl("\n")
- end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
- local writeline=write_nl
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ end
+ setformatters(variant)
+ setlogfile=function(name,keepopen)
+ if name and name~="" then
+ local localtime=os.localtime
+ local writeline=write_nl
+ if keepopen then
+ local f=io.open(name,"ab")
write_nl=function(s)
- writeline(f(s))
- end
- end
- setformatters=function(specification)
- local f=nil
- local d=variants.default
- if specification then
- if type(specification)=="table" then
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- f=v.formats
- end
- end
- end
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
- if name and name~="" then
- local localtime=os.localtime
- local writeline=write_nl
- if keepopen then
- local f=io.open(name,"ab")
- write_nl=function(s)
- writeline(s)
- f:write(localtime()," | ",s,"\n")
- end
- else
- write_nl=function(s)
- writeline(s)
- local f=io.open(name,"ab")
- f:write(localtime()," | ",s,"\n")
- f:close()
- end
- end
+ writeline(s)
+ f:write(localtime()," | ",s,"\n")
end
- setlogfile=ignore
- end
- settimedlog=function()
- local localtime=os.localtime
- local writeline=write_nl
+ else
write_nl=function(s)
- writeline(localtime().." | "..s)
+ writeline(s)
+ local f=io.open(name,"ab")
+ f:write(localtime()," | ",s,"\n")
+ f:close()
end
- settimedlog=ignore
+ end
end
+ setlogfile=ignore
+ end
+ settimedlog=function()
+ local localtime=os.localtime
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(localtime().." | "..s)
+ end
+ settimedlog=ignore
+ end
end
logs.report=report
logs.subreport=subreport
@@ -9727,198 +13131,186 @@ local data={}
local states=nil
local force=false
function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
- local state=states==true
- if not state and type(states)=="table" then
- for c,_ in next,states do
- if find(category,c) then
- state=true
- break
- end
- end
+ local logger=data[category]
+ if not logger then
+ local state=states==true
+ if not state and type(states)=="table" then
+ for c,_ in next,states do
+ if find(category,c) then
+ state=true
+ break
end
- logger={
- reporters={},
- state=state,
- }
- data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
- if subcategory then
- reporter=function(...)
- if force or not logger.state then
- subreport(category,subcategory,...)
- end
- end
- logger.reporters[subcategory]=reporter
- else
- local tag=category
- reporter=function(...)
- if force or not logger.state then
- report(category,...)
- end
- end
- logger.reporters.default=reporter
+ end
+ end
+ logger={
+ reporters={},
+ state=state,
+ }
+ data[category]=logger
+ end
+ local reporter=logger.reporters[subcategory or "default"]
+ if not reporter then
+ if subcategory then
+ reporter=function(...)
+ if force or not logger.state then
+ subreport(category,subcategory,...)
end
+ end
+ logger.reporters[subcategory]=reporter
+ else
+ local tag=category
+ reporter=function(...)
+ if force or not logger.state then
+ report(category,...)
+ end
+ end
+ logger.reporters.default=reporter
end
- return reporter
+ end
+ return reporter
end
logs.new=logs.reporter
local ctxreport=logs.writer
function logs.setmessenger(m)
- ctxreport=m
+ ctxreport=m
end
function logs.messenger(category,subcategory)
- if subcategory then
- return function(...)
- ctxreport(subdirect(category,subcategory,...))
- end
- else
- return function(...)
- ctxreport(direct(category,...))
- end
+ if subcategory then
+ return function(...)
+ ctxreport(subdirect(category,subcategory,...))
end
+ else
+ return function(...)
+ ctxreport(direct(category,...))
+ end
+ end
end
local function setblocked(category,value)
- if category==true or category=="all" then
- category,value="*",true
- elseif category==false then
- category,value="*",false
- elseif value==nil then
- value=true
- end
- if category=="*" then
- states=value
+ if category==true or category=="all" then
+ category,value="*",true
+ elseif category==false then
+ category,value="*",false
+ elseif value==nil then
+ value=true
+ end
+ if category=="*" then
+ states=value
+ for k,v in next,data do
+ v.state=value
+ end
+ else
+ alllocked=false
+ states=settings_to_hash(category,type(states)=="table" and states or nil)
+ for c in next,states do
+ local v=data[c]
+ if v then
+ v.state=value
+ else
+ c=topattern(c,true,true)
for k,v in next,data do
+ if find(k,c) then
v.state=value
+ end
end
- else
- alllocked=false
- states=settings_to_hash(category,type(states)=="table" and states or nil)
- for c in next,states do
- local v=data[c]
- if v then
- v.state=value
- else
- c=topattern(c,true,true)
- for k,v in next,data do
- if find(k,c) then
- v.state=value
- end
- end
- end
- end
+ end
end
+ end
end
function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
+ setblocked(category,value==nil and true or value)
end
function logs.enable(category)
- setblocked(category,false)
+ setblocked(category,false)
end
function logs.categories()
- return sortedkeys(data)
+ return sortedkeys(data)
end
function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
- n=n+1
- local state=v.state
- local reporters=v.reporters
- local nc=#category
- if nc>c then
- c=nc
- end
- for subcategory,_ in next,reporters do
- local ns=#subcategory
- if ns>c then
- s=ns
- end
- local m=nc+ns
- if m>max then
- max=m
- end
- end
- local subcategories=concat(sortedkeys(reporters),", ")
- if state==true then
- state="disabled"
- elseif state==false then
- state="enabled"
- else
- state="unknown"
- end
- report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ local n,c,s,max=0,0,0,0
+ for category,v in table.sortedpairs(data) do
+ n=n+1
+ local state=v.state
+ local reporters=v.reporters
+ local nc=#category
+ if nc>c then
+ c=nc
+ end
+ for subcategory,_ in next,reporters do
+ local ns=#subcategory
+ if ns>c then
+ s=ns
+ end
+ local m=nc+ns
+ if m>max then
+ max=m
+ end
+ end
+ local subcategories=concat(sortedkeys(reporters),", ")
+ if state==true then
+ state="disabled"
+ elseif state==false then
+ state="enabled"
+ else
+ state="unknown"
end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
+ report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ end
+ report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
end
local delayed_reporters={}
setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
+ local v=logs.reporter(k.name)
+ t[k]=v
+ return v
end)
function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
+ delayed_reporters[setter](...)
end
directives.register("logs.blocked",function(v)
- setblocked(v,true)
+ setblocked(v,true)
end)
directives.register("logs.target",function(v)
- settarget(v)
+ settarget(v)
end)
if tex then
- local report=logs.reporter("pages")
- local texgetcount=tex and tex.getcount
- local real,user,sub
- function logs.start_page_number()
- real=texgetcount("realpageno")
- user=texgetcount("userpageno")
- sub=texgetcount("subpageno")
- end
- local timing=false
- local starttime=nil
- local lasttime=nil
- trackers.register("pages.timing",function(v)
- starttime=os.clock()
- timing=true
- end)
- function logs.stop_page_number()
- if timing then
- local elapsed,average
- local stoptime=os.clock()
- 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)
- else
- report("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average)
- end
- 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
- end
- logs.flush()
+ local report=logs.reporter("pages")
+ local texgetcount=tex and tex.getcount
+ local real,user,sub=0,0,0
+ function logs.start_page_number()
+ real=texgetcount("realpageno")
+ user=texgetcount("userpageno")
+ sub=texgetcount("subpageno")
+ end
+ local timing=false
+ local lasttime=nil
+ trackers.register("pages.timing",function(v)
+ timing=""
+ end)
+ function logs.stop_page_number()
+ if timing then
+ local elapsed=statistics.currenttime(statistics)
+ local average,page
+ if not lasttime or real<2 then
+ average=elapsed
+ page=elapsed
+ else
+ 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
+ report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
+ end
+ logs.flush()
+ end
end
local nesting=0
local verbose=false
@@ -9942,222 +13334,222 @@ logs.help=ignore
local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
local p_newline=lpeg.patterns.newline
local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
+ Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
)^1
local function reportlines(t,str)
- if str then
- lpegmatch(linewise,str,1,t)
- end
+ if str then
+ lpegmatch(linewise,str,1,t)
+ end
end
local function reportbanner(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- t.report()
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ t.report()
+ end
end
local function reportversion(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ end
end
local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
- reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
- for i=1,select("#",...) do
- reportlines(t,t.helpinfo[select(i,...)])
- if i<n then
- t.report()
- end
- end
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="string" then
+ reportlines(t,helpinfo)
+ elseif type(helpinfo)=="table" then
+ for i=1,select("#",...) do
+ reportlines(t,t.helpinfo[select(i,...)])
+ if i<n then
+ t.report()
+ end
end
+ end
end
local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
+ t.report()
+ reportlines(t,t.moreinfo)
end
local function reportexport(t,method)
- report(t.helpinfo)
+ report(t.helpinfo)
end
local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
+ lines=reportlines,
+ banner=reportbanner,
+ version=reportversion,
+ help=reporthelp,
+ info=reportinfo,
+ export=reportexport,
}
local exporters={
}
logs.reporters=reporters
logs.exporters=exporters
function logs.application(t)
- t.name=t.name or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
- reporters.banner(t)
- reporters.help(t,...)
- reporters.info(t)
- end
- t.export=function(...)
- reporters.export(t,...)
- end
- t.identify=function()
- reporters.banner(t)
- end
- t.version=function()
- reporters.version(t)
- end
- return t
+ t.name=t.name or "unknown"
+ t.banner=t.banner
+ t.moreinfo=moreinfo
+ t.report=logs.reporter(t.name)
+ t.help=function(...)
+ reporters.banner(t)
+ reporters.help(t,...)
+ reporters.info(t)
+ end
+ t.export=function(...)
+ reporters.export(t,...)
+ end
+ t.identify=function()
+ reporters.banner(t)
+ end
+ t.version=function()
+ reporters.version(t)
+ end
+ return t
end
local f_syslog=formatters["%s %s => %s => %s => %s\r"]
function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
- local f=openfile(whereto,"a")
- if f then
- f:write(message)
- f:close()
- break
- else
- sleep(0.1)
- end
+ local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
+ for i=1,10 do
+ local f=openfile(whereto,"a")
+ if f then
+ f:write(message)
+ f:close()
+ break
+ else
+ sleep(0.1)
end
+ end
end
local report_system=logs.reporter("system","logs")
function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
- return function(...)
- report_system("function %a is obsolete, use %a",old,new)
- loadstring(old.."="..new.." return "..old)()(...)
- end
- elseif type(o)=="table" then
- local t,m={},{}
- m.__index=function(t,k)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- return o[k]
- end
- m.__newindex=function(t,k,v)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- o[k]=v
- end
- if libraries then
- libraries.obsolete[old]=t
- end
- setmetatable(t,m)
- return t
+ local o=loadstring("return "..new)()
+ if type(o)=="function" then
+ return function(...)
+ report_system("function %a is obsolete, use %a",old,new)
+ loadstring(old.."="..new.." return "..old)()(...)
+ end
+ elseif type(o)=="table" then
+ local t,m={},{}
+ m.__index=function(t,k)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ return o[k]
+ end
+ m.__newindex=function(t,k,v)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ o[k]=v
+ end
+ if libraries then
+ libraries.obsolete[old]=t
end
+ setmetatable(t,m)
+ return t
+ end
end
if utilities then
- utilities.report=report_system
+ utilities.report=report_system
end
if tex and tex.error then
- function logs.texerrormessage(...)
- tex.error(format(...),{})
- end
+ function logs.texerrormessage(...)
+ tex.error(format(...))
+ end
else
- function logs.texerrormessage(...)
- print(format(...))
- end
+ function logs.texerrormessage(...)
+ print(format(...))
+ end
end
io.stdout:setvbuf('no')
io.stderr:setvbuf('no')
if package.helpers.report then
- package.helpers.report=logs.reporter("package loader")
+ package.helpers.report=logs.reporter("package loader")
end
if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
- return loggingerrors
- end
- directives.register("logs.errors",function(v)
- loggingerrors=v
- if type(v)=="string" then
- fatalerrors=settings_to_hash(v)
- else
- fatalerrors={}
- end
- end)
- function logs.registerfinalactions(...)
- insert(finalactions,...)
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
- target=t
- state=force
- force=true
- report=type(r)=="function" and r or logs.reporter(r)
- what=w
- pushtarget(target)
+ local finalactions={}
+ local fatalerrors={}
+ local possiblefatal={}
+ local loggingerrors=false
+ function logs.loggingerrors()
+ return loggingerrors
+ end
+ directives.register("logs.errors",function(v)
+ loggingerrors=v
+ if type(v)=="string" then
+ fatalerrors=settings_to_hash(v)
+ else
+ fatalerrors={}
+ end
+ end)
+ function logs.registerfinalactions(...)
+ insert(finalactions,...)
+ end
+ local what=nil
+ local report=nil
+ local state=nil
+ local target=nil
+ local function startlogging(t,r,w,s)
+ target=t
+ state=force
+ force=true
+ report=type(r)=="function" and r or logs.reporter(r)
+ what=w
+ pushtarget(target)
+ newline()
+ if s then
+ report("start %s: %s",what,s)
+ else
+ report("start %s",what)
+ end
+ if target=="logfile" then
+ newline()
+ end
+ return report
+ end
+ local function stoplogging()
+ if target=="logfile" then
+ newline()
+ end
+ report("stop %s",what)
+ if target=="logfile" then
+ newline()
+ end
+ poptarget()
+ state=oldstate
+ end
+ function logs.startfilelogging(...)
+ return startlogging("logfile",...)
+ end
+ logs.stopfilelogging=stoplogging
+ local done=false
+ function logs.starterrorlogging(r,w,...)
+ if not done then
+ pushtarget("terminal")
+ newline()
+ logs.report("error logging","start possible issues")
+ poptarget()
+ done=true
+ end
+ if fatalerrors[w] then
+ possiblefatal[w]=true
+ end
+ return startlogging("terminal",r,w,...)
+ end
+ logs.stoperrorlogging=stoplogging
+ function logs.finalactions()
+ if #finalactions>0 then
+ for i=1,#finalactions do
+ finalactions[i]()
+ end
+ if done then
+ pushtarget("terminal")
newline()
- if s then
- report("start %s: %s",what,s)
- else
- report("start %s",what)
- end
- if target=="logfile" then
- newline()
- end
- return report
- end
- local function stoplogging()
- if target=="logfile" then
- newline()
- end
- report("stop %s",what)
- if target=="logfile" then
- newline()
- end
+ logs.report("error logging","stop possible issues")
poptarget()
- state=oldstate
- end
- function logs.startfilelogging(...)
- return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
- if not done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","start possible issues")
- poptarget()
- done=true
- end
- if fatalerrors[w] then
- possiblefatal[w]=true
- end
- return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
- if #finalactions>0 then
- for i=1,#finalactions do
- finalactions[i]()
- end
- if done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","stop possible issues")
- poptarget()
- end
- return next(possiblefatal) and sortedkeys(possiblefatal) or false
- end
+ end
+ return next(possiblefatal) and sortedkeys(possiblefatal) or false
end
+ end
end
@@ -10167,14 +13559,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
--- original size: 8097, stripped down to: 5534
+-- original size: 9072, stripped down to: 6055
if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.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 trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber,select=type,tonumber,select
local format,lower,find=string.format,string.lower,string.find
@@ -10189,161 +13581,191 @@ statistics.enable=true
statistics.threshold=0.01
local statusinfo,n,registered,timers={},0,{},{}
setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0 }
- t[k]=v
- return v
+ local v={ timing=0,loadtime=0 }
+ t[k]=v
+ return v
end)
local function hastiming(instance)
- return instance and timers[instance]
+ return instance and timers[instance]
end
local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0 }
+ timers[instance or "notimer"]={ timing=0,loadtime=0 }
end
local ticks=clock
local seconds=function(n) return n or 0 end
-local function starttiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it==0 then
- timer.starttime=ticks()
- if not timer.loadtime then
- timer.loadtime=0
- end
- end
- timer.timing=it+1
+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
+ timer.loadtime=0
+ end
+ end
+ timer.timing=it+1
end
local function stoptiming(instance)
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ local stoptime=ticks()
+ local loadtime=stoptime-starttime
+ timer.stoptime=stoptime
+ timer.loadtime=timer.loadtime+loadtime
+ timer.timing=0
+ timer.starttime=0
+ return loadtime
+ end
+ end
+ return 0
+end
+local function elapsed(instance)
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime) or 0
+ 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
- timer.timing=it-1
else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- local stoptime=ticks()
- local loadtime=stoptime-starttime
- timer.stoptime=stoptime
- timer.loadtime=timer.loadtime+loadtime
- timer.timing=0
- timer.starttime=0
- return loadtime
- end
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ return seconds(timer.loadtime+ticks()-starttime)
+ end
end
return 0
-end
-local function elapsed(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- return timer and seconds(timer.loadtime) or 0
- end
+ end
end
local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
+ return format("%0.3f",elapsed(instance))
end
local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
+ return elapsed(instance)>statistics.threshold
end
local function elapsedseconds(instance,rest)
- if elapsedindeed(instance) then
- return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
end
statistics.hastiming=hastiming
statistics.resettiming=resettiming
statistics.starttiming=starttiming
statistics.stoptiming=stoptiming
+statistics.currenttime=currenttime
statistics.elapsed=elapsed
statistics.elapsedtime=elapsedtime
statistics.elapsedindeed=elapsedindeed
statistics.elapsedseconds=elapsedseconds
function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
- local rt=registered[tag] or (#statusinfo+1)
- statusinfo[rt]={ tag,fnc }
- registered[tag]=rt
- if #tag>n then n=#tag end
- end
+ if statistics.enable and type(fnc)=="function" then
+ local rt=registered[tag] or (#statusinfo+1)
+ statusinfo[rt]={ tag,fnc }
+ registered[tag]=rt
+ if #tag>n then n=#tag end
+ end
end
local report=logs.reporter("mkiv lua stats")
function statistics.show()
- if statistics.enable then
- local register=statistics.register
- register("used platform",function()
- return format("%s, type: %s, binary subtree: %s",
- os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
- end)
- register("used engine",function()
- return format("%s version %s with functionality level %s, banner: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
- end)
- register("control sequences",function()
- return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
- end)
- register("callbacks",statistics.callbacks)
- if TEXENGINE=="luajittex" and JITSUPPORTED then
- local jitstatus=jit.status
- if jitstatus then
- local jitstatus={ jitstatus() }
- if jitstatus[1] then
- register("luajit options",concat(jitstatus," ",2))
- end
- end
- end
- register("lua properties",function()
- local hashchar=tonumber(status.luatex_hashchars)
- local hashtype=status.luatex_hashtype
- local mask=lua.mask or "ascii"
- return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
- jit and "luajit" or "lua",
- LUAVERSION,
- statistics.memused(),
- hashtype or "default",
- hashchar and 2^hashchar or "unknown",
- mask,
- mask=="utf" and "τεχ" or "tex")
- end)
- register("runtime",statistics.runtime)
- logs.newline()
- for i=1,#statusinfo do
- local s=statusinfo[i]
- local r=s[2]()
- if r then
- report("%s: %s",s[1],r)
- end
+ if statistics.enable then
+ local register=statistics.register
+ register("used platform",function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+ end)
+ register("used engine",function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+ end)
+ register("control sequences",function()
+ return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+ end)
+ register("callbacks",statistics.callbacks)
+ if TEXENGINE=="luajittex" and JITSUPPORTED then
+ local jitstatus=jit.status
+ if jitstatus then
+ local jitstatus={ jitstatus() }
+ if jitstatus[1] then
+ register("luajit options",concat(jitstatus," ",2))
end
- statistics.enable=false
+ end
end
+ register("lua properties",function()
+ local hashchar=tonumber(status.luatex_hashchars)
+ local hashtype=status.luatex_hashtype
+ local mask=lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashtype or "default",
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask=="utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline()
+ for i=1,#statusinfo do
+ local s=statusinfo[i]
+ local r=s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
+ end
+ statistics.enable=false
+ end
end
function statistics.memused()
- local round=math.round or math.floor
- return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+ local round=math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
end
starttiming(statistics)
function statistics.formatruntime(runtime)
- return format("%s seconds",runtime)
+ return format("%s seconds",runtime)
end
function statistics.runtime()
- stoptiming(statistics)
- return statistics.formatruntime(elapsedtime(statistics))
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report=logs.reporter("system")
-function statistics.timed(action)
- starttiming("run")
- action()
- stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("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
function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
- local name=select(i,...)
- local stat={}
- local func=base[name]
- setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
- base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
- statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
+ for i=1,select("#",...) do
+ local name=select(i,...)
+ local stat={}
+ local func=base[name]
+ setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+ base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
end
@@ -10353,144 +13775,144 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5841, stripped down to: 3511
+-- original size: 5841, stripped down to: 3352
if not modules then modules={} end modules ['trac-pro']={
- 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 getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
+local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
local namespaces=namespaces
local registered={}
local function report_index(k,name)
- if trace_namespaces then
- report_system("reference to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("reference to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("reference to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("reference to %a in protected namespace %a",k,name)
+ end
end
local function report_newindex(k,name)
- if trace_namespaces then
- report_system("assignment to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("assignment to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("assignment to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("assignment to %a in protected namespace %a",k,name)
+ end
end
local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
- return
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
- m={}
- setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
- if not index[k] then
- index[k]=true
- report_index(k,name)
- end
- return nil
+ local data=name=="global" and _G or _G[name]
+ if not data then
+ return
+ end
+ registered[name]=data
+ local m=getmetatable(data)
+ if not m then
+ m={}
+ setmetatable(data,m)
+ end
+ local index,newindex={},{}
+ m.__saved__index=m.__index
+ m.__no__index=function(t,k)
+ if not index[k] then
+ index[k]=true
+ report_index(k,name)
end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
- if not newindex[k] then
- newindex[k]=true
- report_newindex(k,name)
- end
- rawset(t,k,v)
+ return nil
+ end
+ m.__saved__newindex=m.__newindex
+ m.__no__newindex=function(t,k,v)
+ if not newindex[k] then
+ newindex[k]=true
+ report_newindex(k,name)
end
- m.__protection__depth=0
+ rawset(t,k,v)
+ end
+ m.__protection__depth=0
end
local function private(name)
- local data=registered[name]
+ local data=registered[name]
+ if not data then
+ data=_G[name]
if not data then
- data=_G[name]
- if not data then
- data={}
- _G[name]=data
- end
- register(name)
+ data={}
+ _G[name]=data
end
- return data
+ register(name)
+ end
+ return data
end
local function protect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
- m.__protection__depth=pd+1
- else
- m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
- m.__index,m.__newindex=m.__no__index,m.__no__newindex
- m.__protection__depth=1
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>0 then
+ m.__protection__depth=pd+1
+ else
+ m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
+ m.__index,m.__newindex=m.__no__index,m.__no__newindex
+ m.__protection__depth=1
+ end
end
local function unprotect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
- m.__protection__depth=pd-1
- else
- m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
- m.__protection__depth=0
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>1 then
+ m.__protection__depth=pd-1
+ else
+ m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
+ m.__protection__depth=0
+ end
end
local function protectall()
- for name,_ in next,registered do
- if name~="global" then
- protect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ protect(name)
end
+ end
end
local function unprotectall()
- for name,_ in next,registered do
- if name~="global" then
- unprotect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ unprotect(name)
end
+ end
end
-namespaces.register=register
-namespaces.private=private
+namespaces.register=register
+namespaces.private=private
namespaces.protect=protect
namespaces.unprotect=unprotect
namespaces.protectall=protectall
namespaces.unprotectall=unprotectall
namespaces.private("namespaces") registered={} register("global")
directives.register("system.protect",function(v)
- if v then
- protectall()
- else
- unprotectall()
- end
+ if v then
+ protectall()
+ else
+ unprotectall()
+ end
end)
directives.register("system.checkglobals",function(v)
- if v then
- report_system("enabling global namespace guard")
- protect("global")
- else
- report_system("disabling global namespace guard")
- unprotect("global")
- end
+ if v then
+ report_system("enabling global namespace guard")
+ protect("global")
+ else
+ report_system("disabling global namespace guard")
+ unprotect("global")
+ end
end)
@@ -10500,15 +13922,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lua"] = package.loaded["util-lua"] or true
--- original size: 6621, stripped down to: 4764
+-- original size: 6664, stripped down to: 4589
if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -10519,150 +13941,151 @@ local report_lua=logs.reporter("system","lua")
local report_mem=logs.reporter("system","lua memory")
local tracestripping=false
local tracememory=false
-luautilities.stripcode=true
+luautilities.stripcode=true
luautilities.alwaysstripcode=false
luautilities.nofstrippedchunks=0
luautilities.nofstrippedbytes=0
local strippedchunks={}
luautilities.strippedchunks=strippedchunks
luautilities.suffixes={
- tma="tma",
- tmc=jit and "tmb" or "tmc",
- lua="lua",
- luc=jit and "lub" or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc="tuc",
+ tma="tma",
+ tmc=jit and "tmb" or "tmc",
+ lua="lua",
+ luc=jit and "lub" or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
}
local function register(name)
- if tracestripping then
- report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
end
local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
- code=load(code)
- if code then
- code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
- if code and code~="" then
- register(name)
- io.savedata(lucfile,code)
- return true,0
- end
- else
- report_lua("fatal error %a in file %a",1,luafile)
- end
- else
- report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
-end
-function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
- macros=lua.macros
- end
- local code,message
- if macros then
- code,message=macros.loaded(fullname,true,false)
- else
- code,message=loadfile(fullname)
- end
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+ code=load(code)
if code then
- code()
- else
- report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip)=="function" then
- forcestrip=forcestrip(fullname)
- end
- if forcestrip or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
- elseif luautilities.alwaysstripcode then
+ code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code~="" then
register(name)
- return load(dump(code,true)),0
+ io.savedata(lucfile,code)
+ return true,0
+ end
else
- return code,0
+ report_lua("fatal error %a in file %a",1,luafile)
end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
+end
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ name=name or fullname
+ if macros then
+ macros=lua.macros
+ end
+ local code,message
+ if macros then
+ code,message=macros.loaded(fullname,true,false)
+ else
+ code,message=loadfile(fullname)
+ end
+ if code then
+ 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
+ forcestrip=forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.strippedloadstring(code,name,forcestrip)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.loadstring(code,name)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
end
function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
- report_lua("dumping %a into %a stripped",luafile,lucfile)
- if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
- report_lua("removing %a",luafile)
- os.remove(luafile)
- end
- end
- return done
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
end
function luautilities.loadstripped(...)
- local l=load(...)
- if l then
- return load(dump(l,true))
- end
+ local l=load(...)
+ if l then
+ return load(dump(l,true))
+ end
end
local finalizers={}
setmetatable(finalizers,{
- __gc=function(t)
- for i=1,#t do
- pcall(t[i])
- end
+ __gc=function(t)
+ for i=1,#t do
+ pcall(t[i])
end
+ end
} )
function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
+ finalizers[#finalizers+1]=f
end
function luautilities.checkmemory(previous,threshold,trace)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- local delta=current-previous
- if current-previous>checked then
- 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",
- 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",
- previous/1024,current/1024,delta/1024,threshold)
- end
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ local delta=current-previous
+ if current-previous>checked then
+ collectgarbage("collect")
+ local afterwards=collectgarbage("count")
+ if trace or tracememory then
+ 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 %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
end
- return current
+ end
+ return current
end
@@ -10672,17 +14095,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 8984, stripped down to: 6573
+-- original size: 9955, stripped down to: 6693
if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- 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 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
@@ -10700,228 +14121,266 @@ local names={}
local initialize=false
if not (FFISUPPORTED and ffi) then
elseif os.type=="windows" then
- initialize=function()
- local kernel=ffilib("kernel32","system")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
+ initialize=function()
+ local kernel=ffilib("kernel32","system")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
int QueryPerformanceFrequency(int64_t *lpFrequency);
int QueryPerformanceCounter(int64_t *lpPerformanceCount);
]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
end
- initialize=false
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
end
+ initialize=false
+ end
elseif os.type=="unix" then
- initialize=function()
- local C=ffi.C
- local tonumber=ffi.number or tonumber
- ffi.cdef [[
+ initialize=function()
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ ffi.cdef [[
/* what a mess */
typedef int clk_id_t;
typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
typedef struct timespec { long sec; long nsec; } ctx_timespec;
int clock_gettime(clk_id_t timerid, struct timespec *t);
]]
- local target=ffi.new("ctx_timespec[?]",1)
- local clock=C.CLOCK_PROCESS_CPUTIME_ID
- ticks=function ()
- C.clock_gettime(clock,target)
- return tonumber(target[0].sec*1000000000+target[0].nsec)
- end
- seconds=function(ticks)
- return ticks/1000000000
- end
- initialize=false
+ local target=ffi.new("ctx_timespec[?]",1)
+ local clock=C.CLOCK_PROCESS_CPUTIME_ID
+ ticks=function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
+ end
+ seconds=function(ticks)
+ return ticks/1000000000
end
+ initialize=false
+ end
end
setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
- local v=setmetatableindex(function(t,line)
- local v={ total=0,count=0 }
- t[line]=v
- return v
- end)
- t[source]=v
- return v
+ local v=setmetatableindex(function(t,source)
+ local v=setmetatableindex(function(t,line)
+ local v={ total=0,count=0,nesting=0 }
+ t[line]=v
+ return v
end)
- t[name]=v
+ t[source]=v
return v
+ end)
+ t[name]=v
+ return v
end)
+local getinfo=nil
+local sethook=nil
local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
- local source=f.short_src
- if not source then
- return
- end
- local line=f.linedefined or 0
- local name=f.name
- if not name then
- local what=f.what
- if what=="C" then
- name="<anonymous>"
- else
- name=f.namewhat or what or "<unknown>"
- end
- end
- local data=names[name][source][line]
- if where=="call" then
- data.count=data.count+1
- insert(data,ticks())
- elseif where=="return" then
- local t=remove(data)
- if t then
- data.total=data.total+ticks()-t
- end
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
+ end
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ 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 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
end
function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
- for source,lines in next,sources do
- for line,data in next,lines do
- local count=data.count
- if count>threshold then
- if #name>length then
- length=#name
- end
- local total=data.total
- local real=total
- if real>0 then
- real=total-(count*overhead/dummycalls)
- if real<0 then
- real=0
- end
- realtime=realtime+real
- end
- totaltime=totaltime+total
- if line<0 then
- line=0
- end
- dataset[#dataset+1]={ real,total,count,name,source,line }
- end
- end
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ local count=data.count
+ if count>threshold then
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ realtime=realtime+real
+ end
+ totaltime=totaltime+total
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
end
+ end
end
- sort(dataset,function(a,b)
- if a[1]==b[1] then
- if a[2]==b[2] then
- if a[3]==b[3] then
- if a[4]==b[4] then
- if a[5]==b[5] then
- return a[6]<b[6]
- else
- return a[5]<b[5]
- end
- else
- return a[4]<b[4]
- end
- else
- return b[3]<a[3]
- end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
else
- return b[2]<a[2]
+ return a[5]<b[5]
end
+ else
+ return a[4]<b[4]
+ end
else
- return b[1]<a[1]
+ return b[3]<a[3]
end
- end)
- if length>50 then
- length=50
- end
- local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
- for i=1,#dataset do
- local data=dataset[i]
- local real=data[1]
- local total=data[2]
- local count=data[3]
- local name=data[4]
- local source=data[5]
- local line=data[6]
- calls=calls+count
- functions=functions+1
- name=gsub(name,"%s+"," ")
- if #name>length then
- name=sub(name,1,length)
- end
- printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls : %i",calls))
- printer(format("overhead : %f",seconds(overhead/1000)))
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
+ end
+ local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
+ for i=1,#dataset do
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ calls=calls+count
+ functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
+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
- debugger.showstats(function(str) f:write(str,"\n") end,threshold)
- f:close()
- end
+ local f=io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
end
function debugger.enable()
- if nesting==0 then
- running=true
- if initialize then
- initialize()
- end
- sethook(hook,"cr")
- local function dummy() end
- local t=ticks()
- for i=1,dummycalls do
- dummy()
- end
- overhead=ticks()-t
- end
- if nesting>0 then
- nesting=nesting+1
- end
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- if nesting>0 then
- nesting=nesting-1
- end
- if nesting==0 then
- sethook()
- end
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
+ getdebug()
+ if getinfo then
local level=2
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
+ 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
+ end
end
debugger.showtraceback=showtraceback
@@ -10932,91 +14391,91 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7112, stripped down to: 3988
+-- original size: 7112, stripped down to: 3887
if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ 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.templates=utilities.templates or {}
local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
- if trace_template then
- report_template("unknown key %a",k)
- end
- return ""
+ local v=t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v=tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
else
- v=tostring(v)
- if trace_template then
- report_template("setting key %a to value %a",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t,how,recursive)
- else
- return v
- end
+ return v
end
+ end
end
local sqlescape=lpeg.replacer {
- { "'","''" },
- { "\\","\\\\" },
- { "\r\n","\\n" },
- { "\r","\\n" },
+ { "'","''" },
+ { "\\","\\\\" },
+ { "\r\n","\\n" },
+ { "\r","\\n" },
}
local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
lpegpatterns.sqlescape=sqlescape
lpegpatterns.sqlquoted=sqlquoted
local luaescape=lpegpatterns.luaescape
local escapers={
- lua=function(s)
- return lpegmatch(luaescape,s)
- end,
- sql=function(s)
- return lpegmatch(sqlescape,s)
- end,
+ lua=function(s)
+ return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlescape,s)
+ end,
}
local quotedescapers={
- lua=function(s)
- return format("%q",s)
- end,
- sql=function(s)
- return lpegmatch(sqlquoted,s)
- end,
+ lua=function(s)
+ return format("%q",s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
}
local luaescaper=escapers.lua
local quotedluaescaper=quotedescapers.lua
local function replacekeyunquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and escapers[how] or luaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replacekeyquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and quotedescapers[how] or quotedluaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
end
-local single=P("%")
+local single=P("%")
local double=P("%%")
local lquoted=P("%[")
local rquoted=P("]%")
@@ -11033,41 +14492,41 @@ local noloptional=P("%?")/''
local noroptional=P("?%")/''
local nomoptional=P(":")/''
local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
local any=P(1)
replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
local function replace(str,mapping,how,recurse)
- if mapping and str then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
end
templates.replace=replace
function templates.replacer(str,how,recurse)
- return function(mapping)
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
end
function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
end
function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping=t
- end
- for k,v in next,t do
- t[k]=replace(v,mapping,how,recurse)
- end
- return t
+ if not mapping then
+ mapping=t
+ end
+ for k,v in next,t do
+ t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
end
@@ -11077,14 +14536,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
--- original size: 20393, stripped down to: 13924
+-- original size: 20393, stripped down to: 13121
if not modules then modules={} end modules ['util-sbx']={
- 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 sandbox then require("l-sandbox") end
local next,type=next,type
@@ -11117,144 +14576,144 @@ local report=logs.reporter("sandbox")
trackers.register("sandbox",function(v) trace=v end)
sandbox.setreporter(report)
sandbox.finalizer {
- category="files",
- action=function()
- finalized=true
- end
+ category="files",
+ action=function()
+ finalized=true
+ end
}
local function registerroot(root,what)
- if finalized then
- report("roots are already finalized")
- else
- if type(root)=="table" then
- root,what=root[1],root[2]
- end
- if type(root)=="string" and root~="" then
- root=collapsepath(expandname(root))
- if what=="r" or what=="ro" or what=="readable" then
- what="read"
- elseif what=="w" or what=="wo" or what=="writable" then
- what="write"
- end
- validroots[root]=what=="write" or false
- end
+ if finalized then
+ report("roots are already finalized")
+ else
+ if type(root)=="table" then
+ root,what=root[1],root[2]
+ end
+ if type(root)=="string" and root~="" then
+ root=collapsepath(expandname(root))
+ if what=="r" or what=="ro" or what=="readable" then
+ what="read"
+ elseif what=="w" or what=="wo" or what=="writable" then
+ what="write"
+ end
+ validroots[root]=what=="write" or false
end
+ end
end
sandbox.finalizer {
- category="files",
- action=function()
+ category="files",
+ action=function()
+ if p_validroot then
+ report("roots are already initialized")
+ else
+ sandbox.registerroot(".","write")
+ for name in sortedhash(validroots) do
if p_validroot then
- report("roots are already initialized")
+ p_validroot=P(name)+p_validroot
else
- sandbox.registerroot(".","write")
- for name in sortedhash(validroots) do
- if p_validroot then
- p_validroot=P(name)+p_validroot
- else
- p_validroot=P(name)
- end
- end
- p_validroot=p_validroot/validroots
+ p_validroot=P(name)
end
+ end
+ p_validroot=p_validroot/validroots
end
+ end
}
local function registerbinary(name)
- if finalized then
- report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validbinaries then
- return
- end
- if validbinaries==true then
- validbinaries={ [name]=true }
- else
- validbinaries[name]=true
- end
- elseif name==true then
- validbinaries={}
+ if finalized then
+ report("binaries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validbinaries then
+ return
+ end
+ if validbinaries==true then
+ validbinaries={ [name]=true }
+ else
+ validbinaries[name]=true
end
+ elseif name==true then
+ validbinaries={}
+ end
end
local function registerlibrary(name)
- if finalized then
- report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validlibraries then
- return
- end
- if validlibraries==true then
- validlibraries={ [nameonly(name)]=true }
- else
- validlibraries[nameonly(name)]=true
- end
- elseif name==true then
- validlibraries={}
+ if finalized then
+ report("libraries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validlibraries then
+ return
+ end
+ if validlibraries==true then
+ validlibraries={ [nameonly(name)]=true }
+ else
+ validlibraries[nameonly(name)]=true
end
+ elseif name==true then
+ validlibraries={}
+ end
end
local p_write=S("wa") p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
+local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
local function normalized(name)
- if platform=="windows" then
- name=gsub(name,"/","\\")
- end
- return name
+ if platform=="windows" then
+ name=gsub(name,"/","\\")
+ end
+ return name
end
function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
+ return lpegmatch(p_path,name) and true or false
end
local filenamelogger=false
function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
+ filenamelogger=type(l)=="function" and l or false
end
local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
- local asked=collapsepath(expandname(name))
- local okay=lpegmatch(p_validroot,asked)
- if okay==true then
- if filenamelogger then
- filenamelogger(name,"w",asked,true)
- end
- return name
- elseif okay==false then
- if not what then
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- elseif lpegmatch(p_write,what) then
- if filenamelogger then
- filenamelogger(name,"w",asked,false)
- end
- return
- else
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- end
- elseif filenamelogger then
- filenamelogger(name,"*",name,false)
+ if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
+ local asked=collapsepath(expandname(name))
+ local okay=lpegmatch(p_validroot,asked)
+ if okay==true then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,true)
+ end
+ return name
+ elseif okay==false then
+ if not what then
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
end
- else
return name
+ elseif lpegmatch(p_write,what) then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,false)
+ end
+ return
+ else
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
+ end
+ return name
+ end
+ elseif filenamelogger then
+ filenamelogger(name,"*",name,false)
end
+ else
+ return name
+ end
end
local function readable(name,finalized)
- return validfilename(name,"r")
+ return validfilename(name,"r")
end
local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"r")
+ if valid then
+ return normalized(valid)
+ end
end
local function writeable(name,finalized)
- return validfilename(name,"w")
+ return validfilename(name,"w")
end
local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"w")
+ if valid then
+ return normalized(valid)
+ end
end
validators.readable=readable
validators.writeable=normalizedwriteable
@@ -11262,316 +14721,316 @@ validators.normalizedreadable=normalizedreadable
validators.normalizedwriteable=writeable
validators.filename=readable
table.setmetatableindex(validators,function(t,k)
- if k then
- t[k]=readable
- end
- return readable
+ if k then
+ t[k]=readable
+ end
+ return readable
end)
function validators.string(s,finalized)
- if finalized and suspicious(s) then
- return ""
- else
- return s
- end
+ if finalized and suspicious(s) then
+ return ""
+ else
+ return s
+ end
end
function validators.cache(s)
- if finalized then
- return basename(s)
- else
- return s
- end
+ if finalized then
+ return basename(s)
+ else
+ return s
+ end
end
function validators.url(s)
- if finalized and find("^file:") then
- return ""
- else
- return s
- end
+ if finalized and find("^file:") then
+ return ""
+ else
+ return s
+ end
end
local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
+ else
+ end
end
local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
- local checkedtwo=validfilename(two)
- if checkedtwo then
- return action(one,two,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ local checkedtwo=validfilename(two)
+ if checkedtwo then
+ return action(one,two,...)
else
end
+ else
+ end
end
local function iohandler(action,one,...)
- if type(one)=="string" then
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- end
- elseif one then
- return action(one,...)
- else
- return action()
+ if type(one)=="string" then
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
end
+ elseif one then
+ return action(one,...)
+ else
+ return action()
+ end
end
local osexecute=sandbox.original(os.execute)
local iopopen=sandbox.original(io.popen)
local reported={}
local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
- if variables then
- for variable,value in next,variables do
- local checker=validators[checkers[variable]]
- if checker then
- value=checker(unquoted(value),strict)
- if value then
- variables[variable]=optionalquoted(value)
- else
- report("variable %a with value %a fails the check",variable,value)
- return
- end
- else
- report("variable %a has no checker",variable)
- return
- end
- end
- for variable,default in next,defaults do
- local value=variables[variable]
- if not value or value=="" then
- local checker=validators[checkers[variable]]
- if checker then
- default=checker(unquoted(default),strict)
- if default then
- variables[variable]=optionalquoted(default)
- else
- report("variable %a with default %a fails the check",variable,default)
- return
- end
- end
- end
- end
- end
- local command=program.." "..replace(template,variables)
- if reporter then
- reporter("executing runner %a: %s",name,command)
- elseif trace then
- report("executing runner %a: %s",name,command)
- end
- return command
- elseif not reported[name] then
- report("executing program %a of runner %a is not permitted",program,name)
- reported[name]=true
- end
-end
-local runners={
- resultof=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("resultof: %s",command)
- end
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- end
- end
- end,
- execute=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("execute: %s",command)
- end
- return osexecute(command)
+ if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
+ if variables then
+ for variable,value in next,variables do
+ local checker=validators[checkers[variable]]
+ if checker then
+ value=checker(unquoted(value),strict)
+ if value then
+ variables[variable]=optionalquoted(value)
+ else
+ report("variable %a with value %a fails the check",variable,value)
+ return
+ end
+ else
+ report("variable %a has no checker",variable)
+ return
end
- end,
- pipeto=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("pipeto: %s",command)
+ end
+ for variable,default in next,defaults do
+ local value=variables[variable]
+ if not value or value=="" then
+ local checker=validators[checkers[variable]]
+ if checker then
+ default=checker(unquoted(default),strict)
+ if default then
+ variables[variable]=optionalquoted(default)
+ else
+ report("variable %a with default %a fails the check",variable,default)
+ return
end
- return iopopen(command,"w")
- end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
- local wrapped=validrunners[specification]
- inspect(table.sortedkeys(validrunners))
- if wrapped then
- return wrapped
- else
- report("unknown predefined runner %a",specification)
- return
+ end
end
+ end
end
- if type(specification)~="table" then
- report("specification should be a table (or string)")
- return
- end
- local name=specification.name
- if type(name)~="string" then
- report("invalid name, string expected",name)
- return
- end
- if validrunners[name] then
- report("invalid name, runner %a already defined")
- return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
- program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
- report("invalid runner %a specified for platform %a",name,platform)
- return
+ local command=program.." "..replace(template,variables)
+ if reporter then
+ reporter("executing runner %a: %s",name,command)
+ elseif trace then
+ report("executing runner %a: %s",name,command)
end
- local template=specification.template
- if not template then
- report("missing template for runner %a",name)
- return
+ return command
+ elseif not reported[name] then
+ report("executing program %a of runner %a is not permitted",program,name)
+ reported[name]=true
+ end
+end
+local runners={
+ resultof=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("resultof: %s",command)
+ end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ end
end
- local method=specification.method or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
- local finalized=finalized
- local wrapped=function(variables)
- return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
- end
- validrunners[name]=wrapped
- return wrapped
- else
- validrunners[name]=nil
- report("invalid method for runner %a",name)
+ end,
+ execute=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("execute: %s",command)
+ end
+ return osexecute(command)
+ end
+ end,
+ pipeto=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("pipeto: %s",command)
+ end
+ return iopopen(command,"w")
end
+ end,
+}
+function sandbox.registerrunner(specification)
+ if type(specification)=="string" then
+ local wrapped=validrunners[specification]
+ inspect(table.sortedkeys(validrunners))
+ if wrapped then
+ return wrapped
+ else
+ report("unknown predefined runner %a",specification)
+ return
+ end
+ end
+ if type(specification)~="table" then
+ report("specification should be a table (or string)")
+ return
+ end
+ local name=specification.name
+ if type(name)~="string" then
+ report("invalid name, string expected",name)
+ return
+ end
+ if validrunners[name] then
+ report("invalid name, runner %a already defined")
+ return
+ end
+ local program=specification.program
+ if type(program)=="string" then
+ elseif type(program)=="table" then
+ program=program[platform] or program.default or program.unix
+ end
+ if type(program)~="string" or program=="" then
+ report("invalid runner %a specified for platform %a",name,platform)
+ return
+ end
+ local template=specification.template
+ if not template then
+ report("missing template for runner %a",name)
+ return
+ end
+ local method=specification.method or "execute"
+ local checkers=specification.checkers or {}
+ local defaults=specification.defaults or {}
+ local runner=runners[method]
+ if runner then
+ local finalized=finalized
+ local wrapped=function(variables)
+ return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
+ end
+ validrunners[name]=wrapped
+ return wrapped
+ else
+ validrunners[name]=nil
+ report("invalid method for runner %a",name)
+ end
end
function sandbox.getrunner(name)
- return name and validrunners[name]
+ return name and validrunners[name]
end
local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
+ return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
end
local function binaryrunner(action,command,...)
- if validbinaries==false then
- report("no binaries permitted, ignoring command: %s",command)
- return
- end
- if type(command)~="string" then
- report("command should be a string")
- return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
- report("unable to filter binary from command: %s",command)
- return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
- report("binary not permitted, ignoring command: %s",command)
- return
- elseif suspicious(command) then
- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
- return
- end
- return action(command,...)
+ if validbinaries==false then
+ report("no binaries permitted, ignoring command: %s",command)
+ return
+ end
+ if type(command)~="string" then
+ report("command should be a string")
+ return
+ end
+ local program=lpegmatch(p_split,command)
+ if not program or program=="" then
+ report("unable to filter binary from command: %s",command)
+ return
+ end
+ if validbinaries==true then
+ elseif not validbinaries[program] then
+ report("binary not permitted, ignoring command: %s",command)
+ return
+ elseif suspicious(command) then
+ report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
+ return
+ end
+ return action(command,...)
end
local function dummyrunner(action,command,...)
- if type(command)=="table" then
- command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
+ if type(command)=="table" then
+ command=concat(command," ",command[0] and 0 or 1)
+ end
+ report("ignoring command: %s",command)
end
sandbox.filehandlerone=filehandlerone
sandbox.filehandlertwo=filehandlertwo
sandbox.iohandler=iohandler
function sandbox.disablerunners()
- validbinaries=false
+ validbinaries=false
end
function sandbox.disablelibraries()
- validlibraries=false
+ validlibraries=false
end
if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
- validlibraries=false
- for k,v in next,ffi do
- if k~="gc" then
- ffi[k]=nil
- end
- end
+ function sandbox.disablelibraries()
+ validlibraries=false
+ for k,v in next,ffi do
+ if k~="gc" then
+ ffi[k]=nil
+ end
end
- local fiiload=ffi.load
- if fiiload then
- local reported={}
- function ffi.load(name,...)
- if validlibraries==false then
- elseif validlibraries==true then
- return fiiload(name,...)
- elseif validlibraries[nameonly(name)] then
- return fiiload(name,...)
- else
- end
- if not reported[name] then
- report("using library %a is not permitted",name)
- reported[name]=true
- end
- return nil
- end
+ end
+ local fiiload=ffi.load
+ if fiiload then
+ local reported={}
+ function ffi.load(name,...)
+ if validlibraries==false then
+ elseif validlibraries==true then
+ return fiiload(name,...)
+ elseif validlibraries[nameonly(name)] then
+ return fiiload(name,...)
+ else
+ end
+ if not reported[name] then
+ report("using library %a is not permitted",name)
+ reported[name]=true
+ end
+ return nil
end
+ end
end
local overload=sandbox.overload
local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile")
+ overload(loadfile,filehandlerone,"loadfile")
if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
+ overload(io.open,filehandlerone,"io.open")
+ overload(io.popen,binaryrunner,"io.popen")
+ overload(io.input,iohandler,"io.input")
+ overload(io.output,iohandler,"io.output")
+ overload(io.lines,filehandlerone,"io.lines")
end
if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
+ overload(os.execute,binaryrunner,"os.execute")
+ overload(os.spawn,dummyrunner,"os.spawn")
+ overload(os.exec,dummyrunner,"os.exec")
+ overload(os.resultof,binaryrunner,"os.resultof")
+ overload(os.pipeto,binaryrunner,"os.pipeto")
+ overload(os.rename,filehandlertwo,"os.rename")
+ overload(os.remove,filehandlerone,"os.remove")
end
if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
+ overload(lfs.chdir,filehandlerone,"lfs.chdir")
+ overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
+ overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
+ overload(lfs.isfile,filehandlerone,"lfs.isfile")
+ overload(lfs.isdir,filehandlerone,"lfs.isdir")
+ overload(lfs.attributes,filehandlerone,"lfs.attributes")
+ overload(lfs.dir,filehandlerone,"lfs.dir")
+ overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
+ overload(lfs.touch,filehandlerone,"lfs.touch")
+ overload(lfs.link,filehandlertwo,"lfs.link")
+ overload(lfs.setmode,filehandlerone,"lfs.setmode")
+ overload(lfs.readlink,filehandlerone,"lfs.readlink")
+ overload(lfs.shortname,filehandlerone,"lfs.shortname")
+ overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
end
if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
+ zip.open=register(zip.open,filehandlerone,"zip.open")
end
if fontloader then
- fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
- fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
+ fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
+ fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
end
if epdf then
- epdf.open=register(epdf.open,filehandlerone,"epdf.open")
+ epdf.open=register(epdf.open,filehandlerone,"epdf.open")
end
sandbox.registerroot=registerroot
sandbox.registerbinary=registerbinary
@@ -11585,14 +15044,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
--- original size: 7757, stripped down to: 6015
+-- original size: 7819, stripped down to: 5881
if not modules then modules={} end modules ['util-mrg']={
- 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 gsub,format=string.gsub,string.format
local concat=table.concat
@@ -11620,19 +15079,19 @@ local m_report=[[
]]
local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
local function self_fake()
- return m_faked
+ return m_faked
end
local function self_nothing()
- return ""
+ return ""
end
local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
- report("unknown file %a",name)
- else
- report("inserting file %a",name)
- end
- return data or ""
+ local data=io.loaddata(name) or ""
+ if data=="" then
+ report("unknown file %a",name)
+ else
+ report("inserting file %a",name)
+ end
+ return data or ""
end
local space=patterns.space
local eol=patterns.newline
@@ -11661,98 +15120,99 @@ local mandatespacing=(eol+space)^1/""
local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
local lines=emptyline^2/"\n"
local spaces=(space*space)/" "
+local spaces=(space*space*space*space)/" "
local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
+ ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
)^1 )
local strip=Cs((emptyline^2/"\n"+1)^0)
local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
+ return lpegmatch(strip,lpegmatch(compact,data))
end
local function self_compact(data)
- local delta=0
- if merger.strip_comment then
- local before=#data
- data=lpegmatch(compact,data)
- data=lpegmatch(strip,data)
- local after=#data
- delta=before-after
- report("original size %s, compacted to %s, stripped %s",before,after,delta)
- data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
+ local delta=0
+ if merger.strip_comment then
+ local before=#data
+ data=lpegmatch(compact,data)
+ data=lpegmatch(strip,data)
+ local after=#data
+ delta=before-after
+ report("original size %s, compacted to %s, stripped %s",before,after,delta)
+ data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
+ end
+ return lpegmatch(stripreturn,data) or data,delta
end
local function self_save(name,data)
- if data~="" then
- io.savedata(name,data)
- report("saving %s with size %s",name,#data)
- end
+ if data~="" then
+ io.savedata(name,data)
+ report("saving %s with size %s",name,#data)
+ end
end
local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
+ return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
end
local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
+ local result,f,frozen,foundpath={},nil,false,nil
+ result[#result+1]="\n"
+ if type(libs)=='string' then libs={ libs } end
+ if type(list)=='string' then list={ list } end
+ for i=1,#libs do
+ local lib=libs[i]
+ for j=1,#list do
+ local pth=gsub(list[j],"\\","/")
+ report("checking library path %a",pth)
+ local name=pth.."/"..lib
+ if lfs.isfile(name) then
+ foundpath=pth
+ end
+ end
+ if foundpath then break end
+ end
+ if foundpath then
+ report("using library path %a",foundpath)
+ local right,wrong,original,stripped={},{},0,0
for i=1,#libs do
- local lib=libs[i]
- for j=1,#list do
- local pth=gsub(list[j],"\\","/")
- report("checking library path %a",pth)
- local name=pth.."/"..lib
- if lfs.isfile(name) then
- foundpath=pth
- end
- end
- if foundpath then break end
- end
- if foundpath then
- report("using library path %a",foundpath)
- local right,wrong,original,stripped={},{},0,0
- for i=1,#libs do
- local lib=libs[i]
- local fullname=foundpath.."/"..lib
- if lfs.isfile(fullname) then
- report("using library %a",fullname)
- local preloaded=file.nameonly(lib)
- local data=io.loaddata(fullname,true)
- original=original+#data
- local data,delta=self_compact(data)
- right[#right+1]=lib
- result[#result+1]=m_begin_closure
- result[#result+1]=format(m_preloaded,preloaded,preloaded)
- result[#result+1]=data
- result[#result+1]=m_end_closure
- stripped=stripped+delta
- else
- report("skipping library %a",fullname)
- wrong[#wrong+1]=lib
- end
- end
- right=#right>0 and concat(right," ") or "-"
- wrong=#wrong>0 and concat(wrong," ") or "-"
- report("used libraries: %a",right)
- report("skipped libraries: %a",wrong)
- report("original bytes: %a",original)
- report("stripped bytes: %a",stripped)
- result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
- report("no valid library path found")
+ local lib=libs[i]
+ local fullname=foundpath.."/"..lib
+ if lfs.isfile(fullname) then
+ report("using library %a",fullname)
+ local preloaded=file.nameonly(lib)
+ local data=io.loaddata(fullname,true)
+ original=original+#data
+ local data,delta=self_compact(data)
+ right[#right+1]=lib
+ result[#result+1]=m_begin_closure
+ result[#result+1]=format(m_preloaded,preloaded,preloaded)
+ result[#result+1]=data
+ result[#result+1]=m_end_closure
+ stripped=stripped+delta
+ else
+ report("skipping library %a",fullname)
+ wrong[#wrong+1]=lib
+ end
end
- return concat(result,"\n\n")
+ right=#right>0 and concat(right," ") or "-"
+ wrong=#wrong>0 and concat(wrong," ") or "-"
+ report("used libraries: %a",right)
+ report("skipped libraries: %a",wrong)
+ report("original bytes: %a",original)
+ report("stripped bytes: %a",stripped)
+ result[#result+1]=format(m_report,right,wrong,original,stripped)
+ else
+ report("no valid library path found")
+ end
+ return concat(result,"\n\n")
end
function merger.selfcreate(libs,list,target)
- if target then
- self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
+ if target then
+ self_save(target,self_swap(self_fake(),self_libs(libs,list)))
+ end
end
function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
+ self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
end
function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
+ self_save(name,self_swap(self_load(name),self_nothing()))
end
@@ -11762,14 +15222,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9400, stripped down to: 5499
+-- original size: 9738, stripped down to: 5531
if not modules then modules={} end modules ['util-env']={
- 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 allocate,mark=utilities.storage.allocate,utilities.storage.mark
local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
@@ -11781,178 +15241,193 @@ local setlocale=os.setlocale
setlocale(nil,nil)
local report=logs.reporter("system")
function os.setlocale(a,b)
- if a or b then
- if report then
- report()
- report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
- report("now on are on your own and without support. Crashes or unexpected side effects")
- report("can happen but don't bother the luatex and context developer team with it.")
- report()
- report=nil
- end
- setlocale(a,b)
- end
+ if a or b then
+ if report then
+ report()
+ report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+ report("now on are on your own and without support. Crashes or unexpected side effects")
+ report("can happen but don't bother the luatex and context developer team with it.")
+ report()
+ report=nil
+ end
+ setlocale(a,b)
+ end
end
local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
+ ["luatex"]=true,
+ ["luajittex"]=true,
}
local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
+ ["luatex"]="luatex",
+ ["texlua"]="luatex",
+ ["texluac"]="luatex",
+ ["luajittex"]="luajittex",
+ ["texluajit"]="luajittex",
}
local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
+ ["lua"]=true,
+ ["luajit"]=true,
}
environment.validengines=validengines
environment.basicengines=basicengines
if not arg then
- environment.used_as_library=true
+ environment.used_as_library=true
elseif luaengines[file.removesuffix(arg[-1])] then
elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
- arg[-1]=arg[0]
- arg[ 0]=arg[2]
- for k=3,#arg do
- arg[k-2]=arg[k]
- end
- remove(arg)
- remove(arg)
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
+ if arg[1]=="--luaonly" then
+ arg[-1]=arg[0]
+ arg[ 0]=arg[2]
+ for k=3,#arg do
+ arg[k-2]=arg[k]
+ end
+ remove(arg)
+ remove(arg)
+ else
+ end
+ local originalzero=file.basename(arg[0])
+ local specialmapping={ luatools=="base" }
+ if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
arg[0]=specialmapping[originalzero] or originalzero
insert(arg,0,"--script")
insert(arg,0,"mtxrun")
- end
+ end
end
environment.arguments=allocate()
environment.files=allocate()
environment.sortedflags=nil
function environment.initializearguments(arg)
- local arguments,files={},{}
- environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
- for index=1,#arg do
- local argument=arg[index]
- if index>0 then
- local flag,value=match(argument,"^%-+(.-)=(.-)$")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=unquoted(value or "")
- else
- flag=match(argument,"^%-+(.+)")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=true
- else
- files[#files+1]=argument
- end
- end
+ 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
+ local flag,value=match(argument,"^%-+(.-)=(.-)$")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=unquoted(value or "")
+ else
+ flag=match(argument,"^%-+(.+)")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=true
+ else
+ files[#files+1]=argument
end
+ 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
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
+ end
+ environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
end
function environment.setargument(name,value)
- environment.arguments[name]=value
+ environment.arguments[name]=value
end
function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
- return arguments[name]
- elseif partial then
- if not sortedflags then
- sortedflags=allocate(table.sortedkeys(arguments))
- for k=1,#sortedflags do
- sortedflags[k]="^"..sortedflags[k]
- end
- environment.sortedflags=sortedflags
- end
- for k=1,#sortedflags do
- local v=sortedflags[k]
- if find(name,v) then
- return arguments[sub(v,2,#v)]
- end
- end
+ local arguments,sortedflags=environment.arguments,environment.sortedflags
+ if arguments[name] then
+ return arguments[name]
+ elseif partial then
+ if not sortedflags then
+ sortedflags=allocate(table.sortedkeys(arguments))
+ for k=1,#sortedflags do
+ sortedflags[k]="^"..sortedflags[k]
+ end
+ environment.sortedflags=sortedflags
end
- return nil
+ for k=1,#sortedflags do
+ local v=sortedflags[k]
+ if find(name,v) then
+ return arguments[sub(v,2,#v)]
+ end
+ end
+ end
+ return nil
end
environment.argument=environment.getargument
function environment.splitarguments(separator)
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
- local v=originalarguments[k]
- if not done and v==separator then
- done=true
- elseif done then
- after[#after+1]=v
- else
- before[#before+1]=v
- end
+ local done,before,after=false,{},{}
+ local originalarguments=environment.originalarguments
+ for k=1,#originalarguments do
+ local v=originalarguments[k]
+ if not done and v==separator then
+ done=true
+ elseif done then
+ after[#after+1]=v
+ else
+ before[#before+1]=v
end
- return before,after
+ end
+ return before,after
end
function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
- return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
- local result={}
- for i=1,#arg do
- result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
- end
- return concat(result," ")
- else
- return ""
+ local resolveprefix=resolvers.resolve
+ arg=arg or environment.originalarguments
+ if noquote and #arg==1 then
+ return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
+ elseif #arg>0 then
+ local result={}
+ for i=1,#arg do
+ result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
end
+ return concat(result," ")
+ else
+ return ""
+ end
end
function environment.relativepath(path,root)
- if not path then
- path=""
+ if not path then
+ path=""
+ end
+ if not file.is_rootbased_path(path) then
+ if not root then
+ root=file.pathpart(environment.ownscript or environment.ownname or ".")
end
- if not file.is_rootbased_path(path) then
- if not root then
- root=file.pathpart(environment.ownscript or environment.ownname or ".")
- end
- if root=="" then
- root="."
- end
- path=root.."/"..path
+ if root=="" then
+ root="."
end
- return file.collapsepath(path,true)
+ path=root.."/"..path
+ end
+ return file.collapsepath(path,true)
end
if arg then
- local newarg,instring={},false
- for index=1,#arg do
- local argument=arg[index]
- if find(argument,"^\"") then
- newarg[#newarg+1]=gsub(argument,"^\"","")
- if not find(argument,"\"$") then
- instring=true
- end
- elseif find(argument,"\"$") then
- newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
- instring=false
- elseif instring then
- newarg[#newarg]=newarg[#newarg].." "..argument
- else
- newarg[#newarg+1]=argument
- end
- end
- for i=1,-5,-1 do
- newarg[i]=arg[i]
+ local newarg,instring={},false
+ for index=1,#arg do
+ local argument=arg[index]
+ if 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
+ 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
+ newarg[#newarg+1]=argument
end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={}
+ end
+ for i=1,-5,-1 do
+ newarg[i]=arg[i]
+ end
+ environment.initializearguments(newarg)
+ environment.originalarguments=mark(newarg)
+ environment.rawarguments=mark(arg)
+ arg={}
end
@@ -11962,17 +15437,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-env"] = package.loaded["luat-env"] or true
--- original size: 5820, stripped down to: 4155
+-- original size: 6134, stripped down to: 4118
if not modules then modules={} end modules ['luat-env']={
- 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 rawset,rawget,loadfile,assert=rawset,rawget,loadfile,assert
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+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)
local report_lua=logs.reporter("resolvers","lua")
local luautilities=utilities.lua
local luasuffixes=luautilities.suffixes
@@ -11980,133 +15456,146 @@ local texgettoks=tex and tex.gettoks
environment=environment or {}
local environment=environment
local mt={
- __index=function(_,k)
- if k=="version" then
- local version=texgettoks and texgettoks("contextversiontoks")
- if version and version~="" then
- rawset(environment,"version",version)
- return version
- else
- return "unknown"
- end
- elseif k=="kind" then
- local kind=texgettoks and texgettoks("contextkindtoks")
- if kind and kind~="" then
- rawset(environment,"kind",kind)
- return kind
- else
- return "unknown"
- end
- elseif k=="jobname" or k=="formatname" then
- local name=tex and tex[k]
- if name or name=="" then
- rawset(environment,k,name)
- return name
- else
- return "unknown"
- end
- elseif k=="outputfilename" then
- local name=environment.jobname
- rawset(environment,k,name)
- return name
- end
+ __index=function(_,k)
+ if k=="version" then
+ local version=texgettoks and texgettoks("contextversiontoks")
+ if version and version~="" then
+ rawset(environment,"version",version)
+ return version
+ else
+ return "unknown"
+ end
+ elseif k=="kind" then
+ local kind=texgettoks and texgettoks("contextkindtoks")
+ if kind and kind~="" then
+ rawset(environment,"kind",kind)
+ return kind
+ else
+ return "unknown"
+ end
+ elseif k=="jobname" or k=="formatname" then
+ local name=tex and tex[k]
+ if name or name=="" then
+ rawset(environment,k,name)
+ return name
+ else
+ return "unknown"
+ end
+ elseif k=="outputfilename" then
+ local name=environment.jobname
+ rawset(environment,k,name)
+ return name
end
+ end
}
setmetatable(environment,mt)
function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
+ return resolvers.findfile(filename,'tex')
end
function environment.luafile(filename)
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
- return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
- return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
-end
-local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
+ local resolved=resolvers.findfile(filename,'tex') or ""
+ if resolved~="" then
+ return resolved
+ end
+ resolved=resolvers.findfile(filename,'texmfscripts') or ""
+ if resolved~="" then
+ return resolved
+ end
+ return resolvers.findfile(filename,'luatexlibs') or ""
+end
+local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
local function strippable(filename)
- if stripindeed then
- local modu=modules[file.nameonly(filename)]
- return modu and modu.dataonly
- else
- return false
- end
+ if stripindeed then
+ local modu=modules[file.nameonly(filename)]
+ return modu and modu.dataonly
+ else
+ return false
+ end
end
function environment.luafilechunk(filename,silent,macros)
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
- local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
- if not silent then
- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- end
- return data
- else
- if not silent then
- report_lua("unknown file %a",filename)
- end
- return nil
+ filename=file.replacesuffix(filename,"lua")
+ local fullname=environment.luafile(filename)
+ if fullname and fullname~="" then
+ local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
+ if not silent then
+ report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+ end
+ return data
+ else
+ if not silent then
+ report_lua("unknown file %a",filename)
end
+ return nil
+ end
end
function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
- luaname=file.addsuffix(basename,luasuffixes.lua)
- lucname=file.addsuffix(basename,luasuffixes.luc)
- else
- luaname=basename
- lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
+ local lucname,luaname,chunk
+ local basename=file.removesuffix(filename)
+ if basename==filename then
+ luaname=file.addsuffix(basename,luasuffixes.lua)
+ lucname=file.addsuffix(basename,luasuffixes.luc)
+ else
+ luaname=filename
+ lucname=nil
+ end
+ local fullname=(lucname and environment.luafile(lucname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
+ end
+ chunk=loadfile(fullname)
+ end
+ if chunk then
+ chunk()
+ if version then
+ local v=version
+ if modules and modules[filename] then
+ v=modules[filename].version
+ elseif versions and versions[filename] then
+ v=versions[filename]
+ end
+ if v==version then
+ return true
+ else
if trace_locating then
- report_lua("loading %a",fullname)
+ report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
end
- chunk=loadfile(fullname)
+ environment.loadluafile(filename)
+ end
+ else
+ return true
end
- if chunk then
- assert(chunk)()
- if version then
- local v=version
- if modules and modules[filename] then
- v=modules[filename].version
- elseif versions and versions[filename] then
- v=versions[filename]
- end
- if v==version then
- return true
- else
- if trace_locating then
- report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
- end
- environment.loadluafile(filename)
- end
- else
- return true
- end
+ end
+ fullname=(luaname and environment.luafile(luaname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- if not chunk then
- if trace_locating then
- report_lua("unknown file %a",filename)
- end
- else
- assert(chunk)()
- return true
- end
+ chunk=loadfile(fullname)
+ if not chunk then
+ if trace_locating then
+ report_lua("unknown file %a",filename)
+ end
+ else
+ chunk()
+ return true
end
- return false
+ 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)
+ end,
+ __len=function(t)
+ return #environment.files
+ end,
+} )
end -- of closure
@@ -12115,16 +15604,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
--- original size: 60383, stripped down to: 38562
+-- original size: 60383, stripped down to: 35698
if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
+local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
xml=xml or {}
@@ -12142,17 +15631,17 @@ xml.xmlns=xml.xmlns or {}
local check=P(false)
local parse=check
function xml.registerns(namespace,pattern)
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
+ check=check+C(P(lower(pattern)))/namespace
+ parse=P { P(check)+1*V(1) }
end
function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
- xml.xmlns[namespace]=ns
- end
+ local ns=lpegmatch(parse,lower(url))
+ if ns and namespace~=ns then
+ xml.xmlns[namespace]=ns
+ end
end
function xml.resolvens(url)
- return lpegmatch(parse,lower(url)) or ""
+ return lpegmatch(parse,lower(url)) or ""
end
end
local nsremap,resolvens=xml.xmlns,xml.resolvens
@@ -12170,661 +15659,661 @@ local handle_dec_entity
local handle_any_entity_dtd
local handle_any_entity_text
local function preparexmlstate(settings)
- if settings then
- linenumbers=settings.linenumbers
- stack={}
- level=0
- top={}
- at={}
- mt={}
- dt={}
- nt=0
- xmlns={}
- errorstr=nil
- strip=settings.strip_cm_and_dt
- utfize=settings.utfize_entities
- resolve=settings.resolve_entities
- resolve_predefined=settings.resolve_predefined_entities
- unify_predefined=settings.unify_predefined_entities
- cleanup=settings.text_cleanup
- entities=settings.entities or {}
- currentfilename=settings.currentresource
- currentline=1
- parameters={}
- reported_at_errors={}
- dcache={}
- hcache={}
- acache={}
- if utfize==nil then
- settings.utfize_entities=true
- utfize=true
- end
- if resolve_predefined==nil then
- settings.resolve_predefined_entities=true
- resolve_predefined=true
- end
- else
- linenumbers=false
- stack=nil
- level=nil
- top=nil
- at=nil
- mt=nil
- dt=nil
- nt=nil
- xmlns=nil
- errorstr=nil
- strip=nil
- utfize=nil
- resolve=nil
- resolve_predefined=nil
- unify_predefined=nil
- cleanup=nil
- entities=nil
- parameters=nil
- reported_at_errors=nil
- dcache=nil
- hcache=nil
- acache=nil
- currentfilename=nil
- currentline=1
- end
+ if settings then
+ linenumbers=settings.linenumbers
+ stack={}
+ level=0
+ top={}
+ at={}
+ mt={}
+ dt={}
+ nt=0
+ xmlns={}
+ errorstr=nil
+ strip=settings.strip_cm_and_dt
+ utfize=settings.utfize_entities
+ resolve=settings.resolve_entities
+ resolve_predefined=settings.resolve_predefined_entities
+ unify_predefined=settings.unify_predefined_entities
+ cleanup=settings.text_cleanup
+ entities=settings.entities or {}
+ currentfilename=settings.currentresource
+ currentline=1
+ parameters={}
+ reported_at_errors={}
+ dcache={}
+ hcache={}
+ acache={}
+ if utfize==nil then
+ settings.utfize_entities=true
+ utfize=true
+ end
+ if resolve_predefined==nil then
+ settings.resolve_predefined_entities=true
+ resolve_predefined=true
+ end
+ else
+ linenumbers=false
+ stack=nil
+ level=nil
+ top=nil
+ at=nil
+ mt=nil
+ dt=nil
+ nt=nil
+ xmlns=nil
+ errorstr=nil
+ strip=nil
+ utfize=nil
+ resolve=nil
+ resolve_predefined=nil
+ unify_predefined=nil
+ cleanup=nil
+ entities=nil
+ parameters=nil
+ reported_at_errors=nil
+ dcache=nil
+ hcache=nil
+ acache=nil
+ currentfilename=nil
+ currentline=1
+ end
end
local function initialize_mt(root)
- mt={ __index=root }
+ mt={ __index=root }
end
function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
+ getmetatable(root).__index[k]=v
end
function xml.checkerror(top,toclose)
- return ""
+ return ""
end
local checkns=xml.checkns
local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
- value=cleanup(value)
- end
- if tag=="xmlns" then
- xmlns[#xmlns+1]=resolvens(value)
- at[tag]=value
- elseif namespace=="" then
- at[tag]=value
- elseif namespace=="xmlns" then
- checkns(tag,value)
- at["xmlns:"..tag]=value
- else
- at[namespace..":"..tag]=value
- end
+ if cleanup and value~="" then
+ value=cleanup(value)
+ end
+ if tag=="xmlns" then
+ xmlns[#xmlns+1]=resolvens(value)
+ at[tag]=value
+ elseif namespace=="" then
+ at[tag]=value
+ elseif namespace=="xmlns" then
+ checkns(tag,value)
+ at["xmlns:"..tag]=value
+ else
+ at[namespace..":"..tag]=value
+ end
end
local function add_empty(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- cf=currentfilename,
- cl=currentline,
- __p__=top,
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
- remove(xmlns)
- end
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ top=stack[level]
+ dt=top.dt
+ nt=#dt+1
+ local t=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=top,
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ __p__=top,
+ }
+ dt[nt]=t
+ setmetatable(t,mt)
+ if at.xmlns then
+ remove(xmlns)
+ end
+ at={}
end
local function add_begin(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- cf=currentfilename,
- cl=currentline,
- __p__=stack[level],
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ dt={}
+ top=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=stack[level],
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ __p__=stack[level],
+ }
+ setmetatable(top,mt)
+ nt=0
+ level=level+1
+ stack[level]=top
+ at={}
end
local function add_end(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
- errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- elseif toclose.tg~=tag then
- errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt
- if toclose.at.xmlns then
- remove(xmlns)
- end
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local toclose=stack[level]
+ level=level-1
+ top=stack[level]
+ if level<1 then
+ errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ elseif toclose.tg~=tag then
+ errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ end
+ dt=top.dt
+ nt=#dt+1
+ dt[nt]=toclose
+ toclose.ni=nt
+ if toclose.at.xmlns then
+ remove(xmlns)
+ end
end
local function add_text(text)
- if text=="" then
- return
- end
- if cleanup then
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..cleanup(text)
- else
- nt=nt+1
- dt[nt]=cleanup(text)
- end
- else
- nt=1
- dt[1]=cleanup(text)
- end
+ if text=="" then
+ return
+ end
+ if cleanup then
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..cleanup(text)
+ else
+ nt=nt+1
+ dt[nt]=cleanup(text)
+ end
else
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..text
- else
- nt=nt+1
- dt[nt]=text
- end
- else
- nt=1
- dt[1]=text
- end
+ nt=1
+ dt[1]=cleanup(text)
end
-end
-local function add_special(what,spacing,text)
- if spacing~="" then
+ else
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..text
+ else
nt=nt+1
- dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
+ dt[nt]=text
+ end
else
- nt=nt+1
- dt[nt]=linenumbers and {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- cf=currentfilename,
- cl=currentline,
- } or {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- }
+ nt=1
+ dt[1]=text
end
+ end
+end
+local function add_special(what,spacing,text)
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ if strip and (what=="@cm@" or what=="@dt@") then
+ else
+ nt=nt+1
+ dt[nt]=linenumbers and {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ cf=currentfilename,
+ cl=currentline,
+ } or {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ }
+ end
end
local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
+ errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
end
local function attribute_value_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute value %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute value %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
local function attribute_specification_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute specification %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute specification %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
do
- local badentity="&"
- xml.placeholders={
- unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
- unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
- unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return formatters["h:%s"](s),true
+ local badentity="&"
+ xml.placeholders={
+ unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
+ unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
+ unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
+ }
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local p_rest=(1-P(";"))^0
+ local p_many=P(1)^0
+ local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
+ xml.parsedentitylpeg=parsedentity
+ local predefined_unified={
+ [38]="&amp;",
+ [42]="&quot;",
+ [47]="&apos;",
+ [74]="&lt;",
+ [76]="&gt;",
+ }
+ local predefined_simplified={
+ [38]="&",amp="&",
+ [42]='"',quot='"',
+ [47]="'",apos="'",
+ [74]="<",lt="<",
+ [76]=">",gt=">",
+ }
+ local nofprivates=0xF0000
+ local privates_u={
+ [ [[&]] ]="&amp;",
+ [ [["]] ]="&quot;",
+ [ [[']] ]="&apos;",
+ [ [[<]] ]="&lt;",
+ [ [[>]] ]="&gt;",
+ }
+ local privates_p={
+ }
+ local privates_s={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[&]] ]="&U+26;",
+ [ [[']] ]="&U+27;",
+ [ [[<]] ]="&U+3C;",
+ [ [[>]] ]="&U+3E;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_x={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[']] ]="&U+27;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_n={
+ }
+ local escaped=utf.remapper(privates_u,"dynamic")
+ local unprivatized=utf.remapper(privates_p,"dynamic")
+ local unspecialized=utf.remapper(privates_s,"dynamic")
+ local despecialized=utf.remapper(privates_x,"dynamic")
+ xml.unprivatized=unprivatized
+ xml.unspecialized=unspecialized
+ xml.despecialized=despecialized
+ xml.escaped=escaped
+ local function unescaped(s)
+ local p=privates_n[s]
+ if not p then
+ nofprivates=nofprivates+1
+ p=utfchar(nofprivates)
+ privates_n[s]=p
+ s="&"..s..";"
+ privates_u[p]=s
+ privates_p[p]=s
+ privates_s[p]=s
+ end
+ return p
+ end
+ xml.privatetoken=unescaped
+ xml.privatecodes=privates_n
+ xml.specialcodes=privates_s
+ function xml.addspecialcode(key,value)
+ privates_s[key]=value or "&"..s..";"
+ end
+ handle_hex_entity=function(str)
+ local h=hcache[str]
+ if not h then
+ local n=tonumber(str,16)
+ h=unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ elseif utfize then
+ h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring hex entity &#x%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#x%s;",str)
end
+ h="&#x"..str..";"
+ end
+ hcache[str]=h
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return utfchar(n)
- else
- return formatters["d:%s"](s),true
- end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
- [38]="&amp;",
- [42]="&quot;",
- [47]="&apos;",
- [74]="&lt;",
- [76]="&gt;",
- }
- local predefined_simplified={
- [38]="&",amp="&",
- [42]='"',quot='"',
- [47]="'",apos="'",
- [74]="<",lt="<",
- [76]=">",gt=">",
- }
- local nofprivates=0xF0000
- local privates_u={
- [ [[&]] ]="&amp;",
- [ [["]] ]="&quot;",
- [ [[']] ]="&apos;",
- [ [[<]] ]="&lt;",
- [ [[>]] ]="&gt;",
- }
- local privates_p={
- }
- local privates_s={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[&]] ]="&U+26;",
- [ [[']] ]="&U+27;",
- [ [[<]] ]="&U+3C;",
- [ [[>]] ]="&U+3E;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_x={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[']] ]="&U+27;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_n={
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
- local p=privates_n[s]
- if not p then
- nofprivates=nofprivates+1
- p=utfchar(nofprivates)
- privates_n[s]=p
- s="&"..s..";"
- privates_u[p]=s
- privates_p[p]=s
- privates_s[p]=s
- end
- return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
- privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
- local h=hcache[str]
- if not h then
- local n=tonumber(str,16)
- h=unify_predefined and predefined_unified[n]
- if h then
- if trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- elseif utfize then
- h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring hex entity &#x%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- else
- if trace_entities then
- report_xml("found entity &#x%s;",str)
- end
- h="&#x"..str..";"
- end
- hcache[str]=h
- end
- return h
- end
- handle_dec_entity=function(str)
- local d=dcache[str]
- if not d then
- local n=tonumber(str)
- d=unify_predefined and predefined_unified[n]
- if d then
- if trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- elseif utfize then
- d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring dec entity &#%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- else
- if trace_entities then
- report_xml("found entity &#%s;",str)
- end
- d="&#"..str..";"
- end
- dcache[str]=d
+ return h
+ end
+ handle_dec_entity=function(str)
+ local d=dcache[str]
+ if not d then
+ local n=tonumber(str)
+ d=unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ elseif utfize then
+ d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring dec entity &#%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#%s;",str)
end
- return d
+ d="&#"..str..";"
+ end
+ dcache[str]=d
end
- handle_any_entity_dtd=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
+ return d
+ end
+ handle_any_entity_dtd=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
+ a=entities[str]
end
- end
- handle_any_entity_text=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(grammar_parsed_text_two,a) or a
- if type(a)=="number" then
- return ""
- else
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- end
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
end
- return a
+ a=a(str) or ""
+ end
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
end
- return a
- end
- end
- local p_rest=(1-P(";"))^1
- local spec={
- [0x23]="\\Ux{23}",
- [0x24]="\\Ux{24}",
- [0x25]="\\Ux{25}",
- [0x5C]="\\Ux{5C}",
- [0x7B]="\\Ux{7B}",
- [0x7C]="\\Ux{7C}",
- [0x7D]="\\Ux{7D}",
- [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
+ end
+ return a
+ end
+ end
+ handle_any_entity_text=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- return formatters["d:%s"](s),true
+ a=entities[str]
end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- local hash=table.setmetatableindex(function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
+ end
+ a=a(str) or ""
+ end
+ a=lpegmatch(grammar_parsed_text_two,a) or a
+ if type(a)=="number" then
+ return ""
+ else
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
+ end
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- return formatters["u:%s"](s),true
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
+ end
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
+ end
+ return a
+ end
+ end
+ local p_rest=(1-P(";"))^1
+ local spec={
+ [0x23]="\\Ux{23}",
+ [0x24]="\\Ux{24}",
+ [0x25]="\\Ux{25}",
+ [0x5C]="\\Ux{5C}",
+ [0x7B]="\\Ux{7B}",
+ [0x7C]="\\Ux{7C}",
+ [0x7D]="\\Ux{7D}",
+ [0x7E]="\\Ux{7E}",
+ }
+ local hash=table.setmetatableindex(spec,function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- xml.reparsedentitylpeg=reparsedentity
- xml.unescapedentitylpeg=unescapedentity
+ end
+ local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ local hash=table.setmetatableindex(function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
+ end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ xml.reparsedentitylpeg=reparsedentity
+ xml.unescapedentitylpeg=unescapedentity
end
local escaped=xml.escaped
local unescaped=xml.unescaped
local placeholders=xml.placeholders
local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
+ report_xml("error in entity, %a found without ending %a",str,";")
+ return str
end
local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
+ report_xml("error in parsing, unexpected %a found ",chr)
+ add_text(chr)
+ return chr
end
local function handlenewline()
- currentline=currentline+1
+ currentline=currentline+1
end
local spacetab=S(' \t')
local space=S(' \r\n\t')
@@ -12849,141 +16338,141 @@ local space_nl=spacetab+newline
local spacing_nl=Cs((space_nl)^0)
local anything_nl=newline+P(1)
local function weirdentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","weird",k,v)
+ end
+ parameters[k]=v
end
local function normalentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","normal",k,v)
+ end
+ entities[k]=v
end
local function systementity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","system",k,v)
+ end
+ entities[k]=v
end
local function publicentity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","public",k,v)
+ end
+ entities[k]=v
end
local function entityfile(pattern,k,v,n)
- if n then
- local okay,data
- if resolvers then
- okay,data=resolvers.loadbinfile(n)
- else
- data=io.loaddata(n)
- okay=data and data~=""
- end
- if okay then
- if trace_entities then
- report_xml("loading public entities %a as %a from %a",k,v,n)
- end
- lpegmatch(pattern,data)
- return
- end
+ if n then
+ local okay,data
+ if resolvers then
+ okay,data=resolvers.loadbinfile(n)
+ else
+ data=io.loaddata(n)
+ okay=data and data~=""
end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
+ if okay then
+ if trace_entities then
+ report_xml("loading public entities %a as %a from %a",k,v,n)
+ end
+ lpegmatch(pattern,data)
+ return
+ end
+ end
+ report_xml("ignoring public entities %a as %a from %a",k,v,n)
end
local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_dtd)
- local parsedentity_text=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_text)
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
- local endofattributes=slash*close+close
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
- entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
- lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
- lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1
- local somedoctype=C((somespace*(
+ local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
+ local hexentitycontent=R("AF","af","09")^1
+ local decentitycontent=R("09")^1
+ local parsedentity=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_dtd)
+ local parsedentity_text=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_text)
+ local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local text_unparsed=Cs((anything-open)^1)
+ local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
+ local somespace=(spacenewline)^1
+ local optionalspace=(spacenewline)^0
+ local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
+ local endofattributes=slash*close+close
+ local whatever=space*name*optionalspace*equal
+ local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
+ local attributevalue=value+wrongvalue
+ local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
+ local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
+ local parsedtext=text_parsed
+ local unparsedtext=text_unparsed/add_text
+ local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
+ local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
+ local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
+ local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
+ local begincomment=open*P("!--")
+ local endcomment=P("--")*close
+ local begininstruction=open*P("?")
+ local endinstruction=P("?")*close
+ local begincdata=open*P("![CDATA[")
+ local endcdata=P("]]")*close
+ local someinstruction=C((anything-endinstruction)^0)
+ local somecomment=C((anything-endcomment )^0)
+ local somecdata=C((anything-endcdata )^0)
+ local begindoctype=open*P("!DOCTYPE")
+ local enddoctype=close
+ local beginset=P("[")
+ local endset=P("]")
+ local wrdtypename=C((anything-somespace-P(";"))^1)
+ local doctypename=C((anything-somespace-close)^0)
+ local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
+ local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
+ local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
+ local normalentitytype=(doctypename*somespace*value)/normalentity
+ local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
+ local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
+ local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
+ local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
+ entityfile(entitydoctype,...)
+ end
+ local function weirdresolve(s)
+ lpegmatch(entitydoctype,parameters[s])
+ end
+ local function normalresolve(s)
+ lpegmatch(entitydoctype,entities[s])
+ end
+ local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
+ entitydoctype=entitydoctype+entityresolve
+ local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
+ local definitiondoctype=doctypename*somespace*doctypeset
+ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
+ local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
+ local simpledoctype=(anything-close)^1
+ local somedoctype=C((somespace*(
publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
- followup=V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
+ local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
+ local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
+ local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
+ local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
+ local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
+ local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
+ local trailer=space^0*(text_unparsed/set_message)^0
+ local grammar_parsed_text_one=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
+ }
+ local grammar_parsed_text_two=P { "followup",
+ followup=V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
+ }
+ local grammar_unparsed_text=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
+ }
+ return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
end
grammar_parsed_text_one_nop,
grammar_parsed_text_two_nop,
@@ -12992,576 +16481,576 @@ grammar_parsed_text_one_yes,
grammar_parsed_text_two_yes,
grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
local function _xmlconvert_(data,settings,detail)
- settings=settings or {}
- preparexmlstate(settings)
- if settings.linenumbers then
- grammar_parsed_text_one=grammar_parsed_text_one_yes
- grammar_parsed_text_two=grammar_parsed_text_two_yes
- grammar_unparsed_text=grammar_unparsed_text_yes
- else
- grammar_parsed_text_one=grammar_parsed_text_one_nop
- grammar_parsed_text_two=grammar_parsed_text_two_nop
- grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
- data=preprocessor(data,settings) or data
+ settings=settings or {}
+ preparexmlstate(settings)
+ if settings.linenumbers then
+ grammar_parsed_text_one=grammar_parsed_text_one_yes
+ grammar_parsed_text_two=grammar_parsed_text_two_yes
+ grammar_unparsed_text=grammar_unparsed_text_yes
+ else
+ grammar_parsed_text_one=grammar_parsed_text_one_nop
+ grammar_parsed_text_two=grammar_parsed_text_two_nop
+ grammar_unparsed_text=grammar_unparsed_text_nop
+ end
+ local preprocessor=settings.preprocessor
+ if data and data~="" and type(preprocessor)=="function" then
+ data=preprocessor(data,settings) or data
+ end
+ if settings.parent_root then
+ mt=getmetatable(settings.parent_root)
+ else
+ initialize_mt(top)
+ end
+ level=level+1
+ stack[level]=top
+ top.dt={}
+ dt=top.dt
+ nt=0
+ if not data or data=="" then
+ errorstr="empty xml file"
+ elseif data==true then
+ errorstr=detail or "problematic xml file"
+ elseif utfize or resolve then
+ local m=lpegmatch(grammar_parsed_text_one,data)
+ if m then
+ m=lpegmatch(grammar_parsed_text_two,data,m)
end
- if settings.parent_root then
- mt=getmetatable(settings.parent_root)
- else
- initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
- errorstr="empty xml file"
- elseif data==true then
- errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
- local m=lpegmatch(grammar_parsed_text_one,data)
- if m then
- m=lpegmatch(grammar_parsed_text_two,data,m)
- end
- if m then
- else
- errorstr="invalid xml file - parsed text"
- end
- elseif type(data)=="string" then
- if lpegmatch(grammar_unparsed_text,data) then
- errorstr=""
- else
- errorstr="invalid xml file - unparsed text"
- end
+ if m then
else
- errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
- result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
- setmetatable(result,mt)
- setmetatable(result.dt[1],mt)
- setmetatable(stack,mt)
- local errorhandler=settings.error_handler
- if errorhandler==false then
+ errorstr="invalid xml file - parsed text"
+ end
+ elseif type(data)=="string" then
+ if lpegmatch(grammar_unparsed_text,data) then
+ errorstr=""
+ else
+ errorstr="invalid xml file - unparsed text"
+ end
+ else
+ errorstr="invalid xml file - no text at all"
+ end
+ local result
+ if errorstr and errorstr~="" then
+ result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
+ setmetatable(result,mt)
+ setmetatable(result.dt[1],mt)
+ setmetatable(stack,mt)
+ local errorhandler=settings.error_handler
+ if errorhandler==false then
+ else
+ errorhandler=errorhandler or xml.errorhandler
+ if errorhandler then
+ local currentresource=settings.currentresource
+ if currentresource and currentresource~="" then
+ xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
else
- errorhandler=errorhandler or xml.errorhandler
- if errorhandler then
- local currentresource=settings.currentresource
- if currentresource and currentresource~="" then
- xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
- else
- xml.errorhandler(formatters["load error: %s"](errorstr))
- end
- end
- end
- else
- result=stack[1]
- end
- if not settings.no_root then
- result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
- setmetatable(result,mt)
- local rdt=result.dt
- for k=1,#rdt do
- local v=rdt[k]
- if type(v)=="table" and not v.special then
- result.ri=k
- v.__p__=result
- break
- end
+ xml.errorhandler(formatters["load error: %s"](errorstr))
end
+ end
end
- if errorstr and errorstr~="" then
- result.error=true
- else
- errorstr=nil
- end
- result.statistics={
- errormessage=errorstr,
- entities={
- decimals=dcache,
- hexadecimals=hcache,
- names=acache,
- intermediates=parameters,
- }
+ else
+ result=stack[1]
+ end
+ if not settings.no_root then
+ result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
+ setmetatable(result,mt)
+ local rdt=result.dt
+ for k=1,#rdt do
+ local v=rdt[k]
+ if type(v)=="table" and not v.special then
+ result.ri=k
+ v.__p__=result
+ break
+ end
+ end
+ end
+ if errorstr and errorstr~="" then
+ result.error=true
+ else
+ errorstr=nil
+ end
+ result.statistics={
+ errormessage=errorstr,
+ entities={
+ decimals=dcache,
+ hexadecimals=hcache,
+ names=acache,
+ intermediates=parameters,
}
- preparexmlstate()
- return result
+ }
+ preparexmlstate()
+ return result
end
local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
- return result
- elseif type(result)=="string" then
- return _xmlconvert_(true,settings,result)
- else
- return _xmlconvert_(true,settings)
- end
+ local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
+ if ok then
+ return result
+ elseif type(result)=="string" then
+ return _xmlconvert_(true,settings,result)
+ else
+ return _xmlconvert_(true,settings)
+ end
end
xml.convert=xmlconvert
function xml.inheritedconvert(data,xmldata)
- local settings=xmldata.settings
- if settings then
- settings.parent_root=xmldata
- end
- local xc=xmlconvert(data,settings)
- return xc
+ local settings=xmldata.settings
+ if settings then
+ settings.parent_root=xmldata
+ end
+ local xc=xmlconvert(data,settings)
+ return xc
end
function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
+ return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
end
function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
+ local ns,tg=match(tag,"^(.-):?([^:]+)$")
+ local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
+ setmetatable(t,mt)
+ return t
end
function xml.is_valid(root)
- return root and not root.error
+ return root and not root.error
end
xml.errorhandler=report_xml
function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
- local f=io.open(filename,'r')
- if f then
- data=f:read("*all")
- f:close()
- end
- elseif filename then
- data=filename:read("*all")
- end
- if settings then
- settings.currentresource=filename
- local result=xmlconvert(data,settings)
- settings.currentresource=nil
- return result
- else
- return xmlconvert(data,{ currentresource=filename })
- end
+ local data=""
+ if type(filename)=="string" then
+ local f=io.open(filename,'r')
+ if f then
+ data=f:read("*all")
+ f:close()
+ end
+ elseif filename then
+ data=filename:read("*all")
+ end
+ if settings then
+ settings.currentresource=filename
+ local result=xmlconvert(data,settings)
+ settings.currentresource=nil
+ return result
+ else
+ return xmlconvert(data,{ currentresource=filename })
+ end
end
local no_root={ no_root=true }
function xml.toxml(data)
- if type(data)=="string" then
- local root={ xmlconvert(data,no_root) }
- return (#root>1 and root) or root[1]
- else
- return data
- end
+ if type(data)=="string" then
+ local root={ xmlconvert(data,no_root) }
+ return (#root>1 and root) or root[1]
+ else
+ return data
+ end
end
local function copy(old,p)
- if old then
- local new={}
- for k,v in next,old do
- local t=type(v)=="table"
- if k=="at" then
- local t={}
- for k,v in next,v do
- t[k]=v
- end
- new[k]=t
- elseif k=="dt" then
- v.__p__=nil
- v=copy(v,new)
- new[k]=v
- v.__p__=p
- else
- new[k]=v
- end
- end
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ local t=type(v)=="table"
+ if k=="at" then
+ local t={}
+ for k,v in next,v do
+ t[k]=v
+ end
+ new[k]=t
+ elseif k=="dt" then
+ v.__p__=nil
+ v=copy(v,new)
+ new[k]=v
+ v.__p__=p
+ else
+ new[k]=v
+ end
end
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ return new
+ else
+ return {}
+ end
end
xml.copy=copy
function xml.checkbom(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
- return
- end
- end
- insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
- insert(dt,2,"\n" )
+ if root.ri then
+ local dt=root.dt
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
+ return
+ end
end
+ insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
+ insert(dt,2,"\n" )
+ end
end
local f_attribute=formatters['%s=%q']
local function verbose_element(e,handlers,escape)
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
- local n=0
- for k in next,eat do
- n=n+1
- ats[n]=k
- end
- if n==1 then
- local k=ats[1]
- ats=f_attribute(k,escaped(eat[k]))
- else
- sort(ats)
- for i=1,n do
- local k=ats[i]
- ats[i]=f_attribute(k,escaped(eat[k]))
- end
- ats=concat(ats," ")
- end
- end
- if ern and trace_entities and ern~=ens then
- ens=ern
+ local handle=handlers.handle
+ local serialize=handlers.serialize
+ local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
+ local ats=eat and next(eat) and {}
+ if ats then
+ local n=0
+ for k in next,eat do
+ n=n+1
+ ats[n]=k
end
- local n=edt and #edt
- if ens~="" then
- if n and n>0 then
- if ats then
- handle("<",ens,":",etg," ",ats,">")
- else
- handle("<",ens,":",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",ens,":",etg,">")
+ if n==1 then
+ local k=ats[1]
+ ats=f_attribute(k,escaped(eat[k]))
+ else
+ sort(ats)
+ for i=1,n do
+ local k=ats[i]
+ ats[i]=f_attribute(k,escaped(eat[k]))
+ end
+ ats=concat(ats," ")
+ end
+ end
+ if ern and trace_entities and ern~=ens then
+ ens=ern
+ end
+ local n=edt and #edt
+ if ens~="" then
+ if n and n>0 then
+ if ats then
+ handle("<",ens,":",etg," ",ats,">")
+ else
+ handle("<",ens,":",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",ens,":",etg," ",ats,"/>")
- else
- handle("<",ens,":",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",ens,":",etg,">")
else
- if n and n>0 then
- if ats then
- handle("<",etg," ",ats,">")
- else
- handle("<",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",etg,">")
+ if ats then
+ handle("<",ens,":",etg," ",ats,"/>")
+ else
+ handle("<",ens,":",etg,"/>")
+ end
+ end
+ else
+ if n and n>0 then
+ if ats then
+ handle("<",etg," ",ats,">")
+ else
+ handle("<",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",etg," ",ats,"/>")
- else
- handle("<",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",etg,">")
+ else
+ if ats then
+ handle("<",etg," ",ats,"/>")
+ else
+ handle("<",etg,"/>")
+ end
end
+ end
end
local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
+ handlers.handle("<?",e.dt[1],"?>")
end
local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
+ handlers.handle("<!--",e.dt[1],"-->")
end
local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
+ handlers.handle("<![CDATA[",e.dt[1],"]]>")
end
local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">")
+ handlers.handle("<!DOCTYPE",e.dt[1],">")
end
local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
+ handlers.serialize(e.dt,handlers)
end
local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
+ handlers.handle(escaped(e))
end
local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
- local ei=e[i]
- if type(ei)=="string" then
- functions["@tx@"](ei,handlers)
- else
- serialize(ei,handlers)
- end
+ local serialize=handlers.serialize
+ local functions=handlers.functions
+ for i=1,#e do
+ local ei=e[i]
+ if type(ei)=="string" then
+ functions["@tx@"](ei,handlers)
+ else
+ serialize(ei,handlers)
end
+ end
end
local function serialize(e,handlers,...)
- if e then
- local initialize=handlers.initialize
- local finalize=handlers.finalize
- local functions=handlers.functions
- if initialize then
- local state=initialize(...)
- if not state==true then
- return state
- end
- end
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- if finalize then
- return finalize()
- end
+ if e then
+ local initialize=handlers.initialize
+ local finalize=handlers.finalize
+ local functions=handlers.functions
+ if initialize then
+ local state=initialize(...)
+ if not state==true then
+ return state
+ end
end
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
+ end
+ if finalize then
+ return finalize()
+ end
+ end
end
local function xserialize(e,handlers)
- if e then
- local functions=handlers.functions
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
+ if e then
+ local functions=handlers.functions
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ end
end
local handlers={}
local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
- if settings then
- for k,v in next,settings do
- if type(v)=="table" then
- local tk=t[k] if not tk then tk={} t[k]=tk end
- for kk,vv in next,v do
- tk[kk]=vv
- end
- else
- t[k]=v
- end
- end
- if settings.name then
- handlers[settings.name]=t
- end
+ local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
+ if settings then
+ for k,v in next,settings do
+ if type(v)=="table" then
+ local tk=t[k] if not tk then tk={} t[k]=tk end
+ for kk,vv in next,v do
+ tk[kk]=vv
+ end
+ else
+ t[k]=v
+ end
end
- utilities.storage.mark(t)
- return t
+ if settings.name then
+ handlers[settings.name]=t
+ end
+ end
+ utilities.storage.mark(t)
+ return t
end
local nofunction=function() end
function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
+ handler.functions[name]=fnc or nofunction
end
function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
+ return handler.functions[name]
end
function xml.gethandlers(name)
- return handlers[name]
+ return handlers[name]
end
newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
- ["@dc@"]=verbose_document,
- ["@dt@"]=verbose_doctype,
- ["@rt@"]=verbose_root,
- ["@el@"]=verbose_element,
- ["@pi@"]=verbose_pi,
- ["@cm@"]=verbose_comment,
- ["@cd@"]=verbose_cdata,
- ["@tx@"]=verbose_text,
- }
+ name="verbose",
+ initialize=false,
+ finalize=false,
+ serialize=xserialize,
+ handle=print,
+ functions={
+ ["@dc@"]=verbose_document,
+ ["@dt@"]=verbose_doctype,
+ ["@rt@"]=verbose_root,
+ ["@el@"]=verbose_element,
+ ["@pi@"]=verbose_pi,
+ ["@cm@"]=verbose_comment,
+ ["@cd@"]=verbose_cdata,
+ ["@tx@"]=verbose_text,
+ }
}
local result
local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
- result=io.open(name,"wb")
- return result
- end,
- finalize=function()
- result:close()
- return true
- end,
- handle=function(...)
- result:write(...)
- end,
+ name="file",
+ initialize=function(name)
+ result=io.open(name,"wb")
+ return result
+ end,
+ finalize=function()
+ result:close()
+ return true
+ end,
+ handle=function(...)
+ result:write(...)
+ end,
}
function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
+ serialize(root,xmlfilehandler,name)
end
local result,r,threshold={},0,512
local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
- r=0
- return result
- end,
- finalize=function()
- local done=concat(result,"",1,r)
- r=0
- if r>threshold then
- result={}
- end
- return done
- end,
- handle=function(...)
- for i=1,select("#",...) do
- r=r+1
- result[r]=select(i,...)
- end
- end,
+ name="string",
+ initialize=function()
+ r=0
+ return result
+ end,
+ finalize=function()
+ local done=concat(result,"",1,r)
+ r=0
+ if r>threshold then
+ result={}
+ end
+ return done
+ end,
+ handle=function(...)
+ for i=1,select("#",...) do
+ r=r+1
+ result[r]=select(i,...)
+ end
+ end,
}
local function xmltostring(root)
- if not root then
- return ""
- elseif type(root)=="string" then
- return root
- else
- return serialize(root,xmlstringhandler) or ""
- end
+ if not root then
+ return ""
+ elseif type(root)=="string" then
+ return root
+ else
+ return serialize(root,xmlstringhandler) or ""
+ end
end
local function __tostring(root)
- return (root and xmltostring(root)) or ""
+ return (root and xmltostring(root)) or ""
end
initialize_mt=function(root)
- mt={ __tostring=__tostring,__index=root }
+ mt={ __tostring=__tostring,__index=root }
end
xml.defaulthandlers=handlers
xml.newhandlers=newhandlers
xml.serialize=serialize
xml.tostring=xmltostring
local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- xmlstring(edt[i],handle)
- end
- end
- else
- handle(e)
+ if not handle or (e.special and e.tg~="@rt@") then
+ elseif e.tg then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ xmlstring(edt[i],handle)
+ end
end
+ else
+ handle(e)
+ end
end
xml.string=xmlstring
function xml.settings(e)
- while e do
- local s=e.settings
- if s then
- return s
- else
- e=e.__p__
- end
+ while e do
+ local s=e.settings
+ if s then
+ return s
+ else
+ e=e.__p__
end
- return nil
+ end
+ return nil
end
function xml.root(e)
- local r=e
- while e do
- e=e.__p__
- if e then
- r=e
- end
+ local r=e
+ while e do
+ e=e.__p__
+ if e then
+ r=e
end
- return r
+ end
+ return r
end
function xml.parent(root)
- return root.__p__
+ return root.__p__
end
function xml.body(root)
- return root.ri and root.dt[root.ri] or root
+ return root.ri and root.dt[root.ri] or root
end
function xml.name(root)
- if not root then
- return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
- return tg
- else
- return ns..":"..tg
- end
+ if not root then
+ return ""
+ end
+ local ns=root.ns
+ local tg=root.tg
+ if ns=="" then
+ return tg
+ else
+ return ns..":"..tg
+ end
end
function xml.erase(dt,k)
- if dt then
- if k then
- dt[k]=""
- else for k=1,#dt do
- dt[1]={ "" }
- end end
- end
+ if dt then
+ if k then
+ dt[k]=""
+ else for k=1,#dt do
+ dt[1]={ "" }
+ end end
+ end
end
function xml.assign(dt,k,root)
- if dt and k then
- dt[k]=type(root)=="table" and xml.body(root) or root
- return dt[k]
- else
- return xml.body(root)
- end
+ if dt and k then
+ dt[k]=type(root)=="table" and xml.body(root) or root
+ return dt[k]
+ else
+ return xml.body(root)
+ end
end
function xml.tocdata(e,wrapper)
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
- whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
+ local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
+ if wrapper then
+ whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
+ end
+ local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
+ setmetatable(t,getmetatable(e))
+ e.dt={ t }
end
function xml.makestandalone(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" then
- local txt=v.dt[1]
- if find(txt,"xml.*version=") then
- v.dt[1]=txt.." standalone='yes'"
- break
- end
- end
+ if root.ri then
+ local dt=root.dt
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="table" and v.special and v.tg=="@pi@" then
+ local txt=v.dt[1]
+ if find(txt,"xml.*version=") then
+ v.dt[1]=txt.." standalone='yes'"
+ break
end
+ end
end
- return root
+ end
+ return root
end
function xml.kind(e)
- local dt=e and e.dt
- if dt then
- local n=#dt
- if n==1 then
- local d=dt[1]
- if d.special then
- local tg=d.tg
- if tg=="@cd@" then
- return "cdata"
- elseif tg=="@cm" then
- return "comment"
- elseif tg=="@pi@" then
- return "instruction"
- elseif tg=="@dt@" then
- return "declaration"
- end
- elseif type(d)=="string" then
- return "text"
- end
- return "element"
- elseif n>0 then
- return "mixed"
- end
+ local dt=e and e.dt
+ if dt then
+ local n=#dt
+ if n==1 then
+ local d=dt[1]
+ if d.special then
+ local tg=d.tg
+ if tg=="@cd@" then
+ return "cdata"
+ elseif tg=="@cm" then
+ return "comment"
+ elseif tg=="@pi@" then
+ return "instruction"
+ elseif tg=="@dt@" then
+ return "declaration"
+ end
+ elseif type(d)=="string" then
+ return "text"
+ end
+ return "element"
+ elseif n>0 then
+ return "mixed"
end
- return "empty"
+ end
+ return "empty"
end
@@ -13571,14 +17060,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
--- original size: 53301, stripped down to: 32477
+-- original size: 55145, stripped down to: 30992
if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local concat,remove,insert=table.concat,table.remove,table.insert
local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
@@ -13591,21 +17080,21 @@ local trace_lparse=false
local trace_lprofile=false
local report_lpath=logs.reporter("xml","lpath")
if trackers then
- trackers.register("xml.path",function(v)
- trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
- trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
- trace_lpath=v
- trace_lparse=v
- trace_lprofile=v
- end)
+ trackers.register("xml.path",function(v)
+ trace_lpath=v
+ end)
+ trackers.register("xml.parse",function(v)
+ trace_lparse=v
+ end)
+ trackers.register("xml.profile",function(v)
+ trace_lpath=v
+ trace_lparse=v
+ trace_lprofile=v
+ end)
end
local xml=xml
-local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
-local lpathcached=0 function xml.lpathcached() return lpathcached end
+local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
+local lpathcached=0 function xml.lpathcached() return lpathcached end
xml.functions=xml.functions or {}
local functions=xml.functions
xml.expressions=xml.expressions or {}
@@ -13619,216 +17108,271 @@ local xmlpatterns=lpegpatterns.xml
finalizers.xml=finalizers.xml or {}
finalizers.tex=finalizers.tex or {}
local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
- t[name]=fn
- else
- report_lpath("unknown sub finalizer %a",name)
- fn=function() end
- end
- return fn
+ local fn=finalizers[name]
+ if fn then
+ t[name]=fn
+ else
+ report_lpath("unknown sub finalizer %a",name)
+ fn=function() end
+ end
+ return fn
end
setmetatableindex(finalizers.xml,fallback)
setmetatableindex(finalizers.tex,fallback)
xml.defaultprotocol="xml"
local apply_axis={}
apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
- local ll=list[l]
- local rt=ll
- while ll do
- ll=ll.__p__
- if ll then
- rt=ll
- end
- end
- collected[l]=rt
+ local collected={}
+ for l=1,#list do
+ local ll=list[l]
+ local rt=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
+ rt=ll
+ end
end
- return collected
+ collected[l]=rt
+ end
+ return collected
end
apply_axis['self']=function(list)
- return list
+ return list
end
apply_axis['child']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local dt=ll.dt
- if dt then
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- end
- end
- ll.en=en
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ local dt=ll.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ end
end
+ ll.en=en
+ end
end
- return collected
+ end
+ return collected
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]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- c=collect(dk,collected,c)
- end
+ local dt=list.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ c=collect(dk,collected,c)
end
- list.en=en
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant']=function(list)
- local collected,c={},0
- for l=1,#list do
- c=collect(list[l],collected,c)
- end
- return collected
+ local collected={}
+ local c=0
+ for l=1,#list do
+ c=collect(list[l],collected,c)
+ end
+ return collected
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]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- c=collect(dk,collected,c)
- end
+ local dt=list.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ c=collect(dk,collected,c)
end
- list.en=en
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- if ll.special~=true then
- c=c+1
- collected[c]=ll
- end
- c=collect(ll,collected,c)
- end
- return collected
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ if ll.special~=true then
+ c=c+1
+ collected[c]=ll
+ end
+ c=collect(ll,collected,c)
+ end
+ return collected
end
apply_axis['ancestor']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ while ll do
+ ll=ll.__p__
+ if ll then
+ c=c+1
+ collected[c]=ll
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['ancestor-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ c=c+1
+ collected[c]=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
c=c+1
collected[c]=ll
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['parent']=function(list)
- local collected,c={},0
- for l=1,#list do
- local pl=list[l].__p__
- if pl then
- c=c+1
- collected[c]=pl
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local pl=list[l].__p__
+ if pl then
+ c=c+1
+ collected[c]=pl
end
- return collected
+ end
+ return collected
end
apply_axis['attribute']=function(list)
- return {}
+ return {}
end
apply_axis['namespace']=function(list)
- return {}
+ return {}
end
apply_axis['following']=function(list)
- return {}
+ return {}
end
apply_axis['preceding']=function(list)
- return {}
+ return {}
end
apply_axis['following-sibling']=function(list)
- 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
- end
- end
+ 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,#d do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['preceding-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=1,ll.ni-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=1,ll.ni-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['reverse-sibling']=function(list)
- 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
- end
- end
+ 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
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
apply_axis['auto-descendant']=apply_axis['descendant']
@@ -13836,130 +17380,147 @@ apply_axis['auto-child']=apply_axis['child']
apply_axis['auto-self']=apply_axis['self']
apply_axis['initial-child']=apply_axis['child']
local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then
- local nns,ntg=nodes[2],nodes[3]
- if not nns and not ntg then
+ local maxn=#nodes
+ if maxn==3 then
+ local nns=nodes[2]
+ local ntg=nodes[3]
+ if not nns and not ntg then
+ if directive then
+ return list
+ else
+ return {}
+ end
+ else
+ local collected={}
+ local c=0
+ local m=0
+ local p=nil
+ if not nns then
+ for l=1,#list do
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
if directive then
- return list
- else
- return {}
+ if ntg==ltg then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif ntg~=ltg then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- else
- local collected,c,m,p={},0,0,nil
- if not nns then
- for l=1,#list do
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif ntg~=ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- elseif not ntg then
- for l=1,#list do
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif lns~=nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- else
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
+ end
+ end
+ elseif not ntg then
+ for l=1,#list do
+ 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=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif lns~=nns then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- return collected
+ end
end
- else
- local collected,c,m,p={},0,0,nil
+ else
for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=false
- for n=1,maxn,3 do
- local nns,ntg=nodes[n+1],nodes[n+2]
- ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
- if ok then
- break
- end
- end
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=ltg==ntg and lns==nns
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
+ end
end
- return collected
+ end
+ return collected
end
-end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected,c={},0
- quit_expression=false
+ else
+ local collected={}
+ local c=0
+ local m=0
+ local p=nil
for l=1,#list do
- local ll=list[l]
- if expression(list,ll,l,order) then
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=false
+ for n=1,maxn,3 do
+ 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
+ end
+ end
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
c=c+1
collected[c]=ll
+ ll.mi=m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- if quit_expression then
- break
- end
+ end
end
return collected
+ end
end
-local function apply_selector(list,specification)
- if xml.applyselector then
- apply_selector=xml.applyselector
- return apply_selector(list,specification)
- else
- return list
+local quit_expression=false
+local function apply_expression(list,expression,order)
+ local collected={}
+ local c=0
+ quit_expression=false
+ for l=1,#list do
+ local ll=list[l]
+ if expression(list,ll,l,order) then
+ c=c+1
+ collected[c]=ll
+ end
+ if quit_expression then
+ break
end
+ end
+ return collected
+end
+local function apply_selector(list,specification)
+ if xml.applyselector then
+ apply_selector=xml.applyselector
+ return apply_selector(list,specification)
+ else
+ return list
+ end
end
local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
local spaces=S(" \n\r\t\f")^0
@@ -13970,24 +17531,24 @@ local lp_doequal=P("=")/"=="
local lp_or=P("|")/" or "
local lp_and=P("&")/" and "
local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
+ text="(ll.dt[1] or '')",
+ content="ll.dt",
+ name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
+ tag="ll.tg",
+ position="l",
+ firstindex="1",
+ firstelement="1",
+ first="1",
+ lastindex="(#ll.__p__.dt or 1)",
+ lastelement="(ll.__p__.en or 1)",
+ last="#list",
+ rootposition="order",
+ order="order",
+ element="(ll.ei or 1)",
+ index="(ll.ni or 1)",
+ match="(ll.mi or 1)",
+ namespace="ll.ns",
+ ns="ll.ns",
}
local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
@@ -13997,11 +17558,11 @@ local lp_fastpos=lp_fastpos_n+lp_fastpos_p
local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t)
- if expressions[t] then
- return "expr."..t.."("
- else
- return "expr.error("
- end
+ if expressions[t] then
+ return "expr."..t.."("
+ else
+ return "expr.error("
+ end
end
local lparent=P("(")
local rparent=P(")")
@@ -14014,24 +17575,24 @@ local lp_string=Cc("'")*R("az","AZ","--","__")^1*Cc("'")
local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
local cleaner
local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
- s=s and s~="" and lpegmatch(cleaner,s)
- if s and s~="" then
- return "expr."..t.."(ll,"..s..")"
- else
- return "expr."..t.."(ll)"
- end
+ if expressions[t] then
+ s=s and s~="" and lpegmatch(cleaner,s)
+ if s and s~="" then
+ return "expr."..t.."(ll,"..s..")"
else
- return "expr.error("..t..")"
+ return "expr."..t.."(ll)"
end
+ else
+ return "expr.error("..t..")"
+ end
end
local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
+ lp_child+lp_any
local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
+ lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
)
cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
+ lp_reserved+lp_number+lp_string+1 )^1 )
local template_e=[[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -14047,75 +17608,75 @@ local template_f_y=[[
local template_f_n=[[
return xml.finalizers['%s']['%s']
]]
-local register_last_match={ kind="axis",axis="last-match" }
-local register_self={ kind="axis",axis="self" }
-local register_parent={ kind="axis",axis="parent" }
-local register_descendant={ kind="axis",axis="descendant" }
-local register_child={ kind="axis",axis="child" }
+local register_last_match={ kind="axis",axis="last-match" }
+local register_self={ kind="axis",axis="self" }
+local register_parent={ kind="axis",axis="parent" }
+local register_descendant={ kind="axis",axis="descendant" }
+local register_child={ kind="axis",axis="child" }
local register_descendant_or_self={ kind="axis",axis="descendant-or-self" }
-local register_root={ kind="axis",axis="root" }
-local register_ancestor={ kind="axis",axis="ancestor" }
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
-local register_attribute={ kind="axis",axis="attribute" }
-local register_namespace={ kind="axis",axis="namespace" }
-local register_following={ kind="axis",axis="following" }
+local register_root={ kind="axis",axis="root" }
+local register_ancestor={ kind="axis",axis="ancestor" }
+local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
+local register_attribute={ kind="axis",axis="attribute" }
+local register_namespace={ kind="axis",axis="namespace" }
+local register_following={ kind="axis",axis="following" }
local register_following_sibling={ kind="axis",axis="following-sibling" }
-local register_preceding={ kind="axis",axis="preceding" }
+local register_preceding={ kind="axis",axis="preceding" }
local register_preceding_sibling={ kind="axis",axis="preceding-sibling" }
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
+local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" }
-local register_auto_descendant={ kind="axis",axis="auto-descendant" }
-local register_auto_self={ kind="axis",axis="auto-self" }
-local register_auto_child={ kind="axis",axis="auto-child" }
-local register_initial_child={ kind="axis",axis="initial-child" }
+local register_auto_descendant={ kind="axis",axis="auto-descendant" }
+local register_auto_self={ kind="axis",axis="auto-self" }
+local register_auto_child={ kind="axis",axis="auto-child" }
+local register_initial_child={ kind="axis",axis="initial-child" }
local register_all_nodes={ kind="nodes",nodetest=true,nodes={ true,false,false } }
local skip={}
local function errorrunner_e(str,cnv)
- if not skip[str] then
- report_lpath("error in expression: %s => %s",str,cnv)
- skip[str]=cnv or str
- end
- return false
+ if not skip[str] then
+ report_lpath("error in expression: %s => %s",str,cnv)
+ skip[str]=cnv or str
+ end
+ return false
end
local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
+ report_lpath("error in finalizer: %s(%s)",str,arg or "")
+ return false
end
local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
+ return { kind="nodes",nodetest=nodetest,nodes=nodes }
end
local function register_selector(specification)
- return { kind="selector",specification=specification }
+ return { kind="selector",specification=specification }
end
local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local runner=load(format(template_e,converted))
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
+ local converted=lpegmatch(converter,expression)
+ local runner=load(format(template_e,converted))
+ runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
+ return { kind="expression",expression=expression,converted=converted,evaluator=runner }
end
local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
- runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
- runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
+ local runner
+ if arguments and arguments~="" then
+ runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+ else
+ runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
+ end
+ runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
+ return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
end
local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
+ ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
+ sq="'"*(1-S("'"))^0*"'",
+ dq='"'*(1-S('"'))^0*'"',
}
local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
+ ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
+ nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
+ sq=P("'")*(1-P("'"))^0*P("'"),
+ dq=P('"')*(1-P('"'))^0*P('"'),
}
local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
+ return { kind="error",error=format("unparsed: %s",str) }
end
local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes)
local special_2=P("/")*Cc(register_auto_self)
@@ -14123,367 +17684,368 @@ local special_3=P("")*Cc(register_auto_self)
local no_nextcolon=P(-1)+#(1-P(":"))
local no_nextlparent=P(-1)+#(1-P("("))
local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
- (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
- ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
+ patterns=spaces*V("protocol")*spaces*(
+ (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
+ ),
+ protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
+ step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
+ axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
+ special=special_1+special_2+special_3,
+ initial=(P("/")*spaces*Cc(register_initial_child))^-1,
+ error=(P(1)^1)/register_error,
+ shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
+ shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
+ s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
+ s_descendant=P("**")*Cc(register_descendant),
+ s_child=P("*")*no_nextcolon*Cc(register_child),
+ s_parent=P("..")*Cc(register_parent),
+ s_self=P("." )*Cc(register_self),
+ s_root=P("^^")*Cc(register_root),
+ s_ancestor=P("^")*Cc(register_ancestor),
+ s_lastmatch=P("=")*Cc(register_last_match),
+ descendant=P("descendant::")*Cc(register_descendant),
+ child=P("child::")*Cc(register_child),
+ parent=P("parent::")*Cc(register_parent),
+ self=P("self::")*Cc(register_self),
+ root=P('root::')*Cc(register_root),
+ ancestor=P('ancestor::')*Cc(register_ancestor),
+ descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
+ ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
+ following=P('following::')*Cc(register_following),
+ following_sibling=P('following-sibling::')*Cc(register_following_sibling),
+ preceding=P('preceding::')*Cc(register_preceding),
+ preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
+ reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
+ last_match=P('last-match::')*Cc(register_last_match),
+ selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
+ nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
+ expressions=expression/register_expression,
+ letters=R("az")^1,
+ name=(1-S("/[]()|:*!"))^1,
+ negate=P("!")*Cc(false),
+ nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
+ nodetest=V("negate")+Cc(true),
+ nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
+ wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
+ nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
+ finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
}
xmlpatterns.pathparser=pathparser
local cache={}
local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
- local directive,ns,tg=set[i],set[i+1],set[i+2]
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
- return format("not(%s)",concat(t,"|"))
- else
- return concat(t,"|")
- end
+ local t={}
+ for i=1,#set,3 do
+ local directive,ns,tg=set[i],set[i+1],set[i+2]
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+ t[#t+1]=(directive and tg) or format("not(%s)",tg)
+ end
+ if nodetest==false then
+ return format("not(%s)",concat(t,"|"))
+ else
+ return concat(t,"|")
+ end
end
local function tagstostring(list)
- if #list==0 then
- return "no elements"
- else
- local t={}
- for i=1,#list do
- local li=list[i]
- local ns,tg=li.ns,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)
- end
- return concat(t," ")
+ if #list==0 then
+ return "no elements"
+ else
+ local t={}
+ for i=1,#list do
+ local li=list[i]
+ 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)
end
+ return concat(t," ")
+ end
end
xml.nodesettostring=nodesettostring
local lpath
local function lshow(parsed)
- if type(parsed)=="string" then
- parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
- table.serialize(parsed,false))
+ if type(parsed)=="string" then
+ parsed=lpath(parsed)
+ end
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+ table.serialize(parsed,false))
end
xml.lshow=lshow
local function add_comment(p,str)
- local pc=p.comment
- if not pc then
- p.comment={ str }
- else
- pc[#pc+1]=str
- end
+ local pc=p.comment
+ if not pc then
+ p.comment={ str }
+ else
+ pc[#pc+1]=str
+ end
end
lpath=function (pattern)
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
- return pattern
- else
- local parsed=cache[pattern]
- if parsed then
- lpathcached=lpathcached+1
+ lpathcalls=lpathcalls+1
+ if type(pattern)=="table" then
+ return pattern
+ else
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcached=lpathcached+1
+ else
+ parsed=lpegmatch(pathparser,pattern)
+ if parsed then
+ parsed.pattern=pattern
+ local np=#parsed
+ if np==0 then
+ parsed={ pattern=pattern,register_self,state="parsing error" }
+ report_lpath("parsing error in pattern: %s",pattern)
+ lshow(parsed)
else
- parsed=lpegmatch(pathparser,pattern)
- if parsed then
- parsed.pattern=pattern
- local np=#parsed
- if np==0 then
- parsed={ pattern=pattern,register_self,state="parsing error" }
- report_lpath("parsing error in pattern: %s",pattern)
- lshow(parsed)
- else
- local pi=parsed[1]
- if pi.axis=="auto-child" then
- if false then
- add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
- parsed[1]=register_auto_descendant_or_self
- else
- add_comment(parsed,"auto-child replaced by auto-descendant")
- parsed[1]=register_auto_descendant
- end
- elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
- add_comment(parsed,"initial-child removed")
- remove(parsed,1)
- end
- local np=#parsed
- if np>1 then
- local pnp=parsed[np]
- if pnp.kind=="nodes" and pnp.nodetest==true then
- local nodes=pnp.nodes
- if nodes[1]==true and nodes[2]==false and nodes[3]==false then
- add_comment(parsed,"redundant final wildcard filter removed")
- remove(parsed,np)
- end
- end
- end
- end
+ local pi=parsed[1]
+ if pi.axis=="auto-child" then
+ if false then
+ add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
+ parsed[1]=register_auto_descendant_or_self
else
- parsed={ pattern=pattern }
+ add_comment(parsed,"auto-child replaced by auto-descendant")
+ parsed[1]=register_auto_descendant
end
- cache[pattern]=parsed
- if trace_lparse and not trace_lprofile then
- lshow(parsed)
+ elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
+ add_comment(parsed,"initial-child removed")
+ remove(parsed,1)
+ end
+ local np=#parsed
+ if np>1 then
+ local pnp=parsed[np]
+ if pnp.kind=="nodes" and pnp.nodetest==true then
+ local nodes=pnp.nodes
+ if nodes[1]==true and nodes[2]==false and nodes[3]==false then
+ add_comment(parsed,"redundant final wildcard filter removed")
+ remove(parsed,np)
+ end
end
+ end
end
- return parsed
+ else
+ parsed={ pattern=pattern }
+ end
+ cache[pattern]=parsed
+ if trace_lparse and not trace_lprofile then
+ lshow(parsed)
+ end
end
+ return parsed
+ end
end
xml.lpath=lpath
do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil
- local keepmatch=nil
- if directives then
- directives.register("xml.path.keeplastmatch",function(v)
- keepmatch=v
- lastmatch=nil
- end)
- end
- apply_axis["last-match"]=function()
- return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
- local p=profiled[parsed.pattern]
- if p then
- p.tested=p.tested+1
- else
- p={ tested=1,matched=0,finalized=0 }
- profiled[parsed.pattern]=p
- end
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- p.matched=p.matched+1
- p.finalized=p.finalized+1
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- p.finalized=p.finalized+1
- return collected
- end
- return nil
- end
- end
- if collected then
- p.matched=p.matched+1
- end
- return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
- if trace_lparse then
- lshow(parsed)
- end
- report_lpath("collecting: %s",parsed.pattern)
- report_lpath("root tags : %s",tagstostring(list))
- report_lpath("order : %s",order or "unset")
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
- return collected
- end
- return nil
- end
- end
+ local profiled={}
+ xml.profiled=profiled
+ local lastmatch=nil
+ local keepmatch=nil
+ if directives then
+ directives.register("xml.path.keeplastmatch",function(v)
+ keepmatch=v
+ lastmatch=nil
+ end)
+ end
+ apply_axis["last-match"]=function()
+ return lastmatch or {}
+ end
+ local function profiled_apply(list,parsed,nofparsed,order)
+ local p=profiled[parsed.pattern]
+ if p then
+ p.tested=p.tested+1
+ else
+ p={ tested=1,matched=0,finalized=0 }
+ profiled[parsed.pattern]=p
+ end
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ p.matched=p.matched+1
+ p.finalized=p.finalized+1
return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- local axis=pi.axis
- if axis~="self" then
- collected=apply_axis[axis](collected)
- end
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- return pi.finalizer(collected)
- end
- if not collected or #collected==0 then
- local pf=i<nofparsed and parsed[nofparsed].finalizer
- if pf then
- return pf(collected)
- end
- return nil
- end
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ p.finalized=p.finalized+1
+ return collected
end
- return collected
+ return nil
+ end
end
- local apply=normal_apply
- if trackers then
- trackers.register("xml.path,xml.parse,xml.profile",function()
- if trace_lprofile then
- apply=profiled_apply
- elseif trace_lpath then
- apply=traced_apply
- else
- apply=normal_apply
- end
- end)
+ if collected then
+ p.matched=p.matched+1
end
- function xml.applylpath(list,pattern)
- if not list then
- lastmatch=nil
- return
- end
- local parsed=cache[pattern]
- if parsed then
- lpathcalls=lpathcalls+1
- lpathcached=lpathcached+1
- elseif type(pattern)=="table" then
- lpathcalls=lpathcalls+1
- parsed=pattern
- else
- parsed=lpath(pattern) or pattern
- end
- if not parsed then
- lastmatch=nil
- return
- end
- local nofparsed=#parsed
- if nofparsed==0 then
- lastmatch=nil
- return
- end
- local collected=apply({ list },parsed,nofparsed,list.mi)
- lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ local function traced_apply(list,parsed,nofparsed,order)
+ if trace_lparse then
+ lshow(parsed)
+ end
+ report_lpath("collecting: %s",parsed.pattern)
+ report_lpath("root tags : %s",tagstostring(list))
+ report_lpath("order : %s",order or "unset")
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
return collected
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+ return collected
+ end
+ return nil
+ end
end
- function xml.lastmatch()
- return lastmatch
- end
- local stack={}
- function xml.pushmatch()
- insert(stack,lastmatch)
- end
- function xml.popmatch()
- lastmatch=remove(stack)
+ return collected
+ end
+ local function normal_apply(list,parsed,nofparsed,order)
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ local axis=pi.axis
+ if axis~="self" then
+ collected=apply_axis[axis](collected)
+ end
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ return pi.finalizer(collected)
+ end
+ if not collected or #collected==0 then
+ local pf=i<nofparsed and parsed[nofparsed].finalizer
+ if pf then
+ return pf(collected)
+ end
+ return nil
+ end
end
+ return collected
+ end
+ local apply=normal_apply
+ if trackers then
+ trackers.register("xml.path,xml.parse,xml.profile",function()
+ if trace_lprofile then
+ apply=profiled_apply
+ elseif trace_lpath then
+ apply=traced_apply
+ else
+ apply=normal_apply
+ end
+ end)
+ end
+ function xml.applylpath(list,pattern)
+ if not list then
+ lastmatch=nil
+ return
+ end
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcalls=lpathcalls+1
+ lpathcached=lpathcached+1
+ elseif type(pattern)=="table" then
+ lpathcalls=lpathcalls+1
+ parsed=pattern
+ else
+ parsed=lpath(pattern) or pattern
+ end
+ if not parsed then
+ lastmatch=nil
+ return
+ end
+ local nofparsed=#parsed
+ if nofparsed==0 then
+ lastmatch=nil
+ return
+ end
+ local collected=apply({ list },parsed,nofparsed,list.mi)
+ lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ function xml.lastmatch()
+ return lastmatch
+ end
+ local stack={}
+ function xml.pushmatch()
+ insert(stack,lastmatch)
+ end
+ function xml.popmatch()
+ lastmatch=remove(stack)
+ end
end
local applylpath=xml.applylpath
function xml.filter(root,pattern)
- return applylpath(root,pattern)
+ return applylpath(root,pattern)
end
expressions.child=function(e,pattern)
- return applylpath(e,pattern)
+ return applylpath(e,pattern)
end
expressions.count=function(e,pattern)
- local collected=applylpath(e,pattern)
- return pattern and (collected and #collected) or 0
+ local collected=applylpath(e,pattern)
+ return pattern and (collected and #collected) or 0
end
expressions.oneof=function(s,...)
- for i=1,select("#",...) do
- if s==select(i,...) then
- return true
- end
+ for i=1,select("#",...) do
+ if s==select(i,...) then
+ return true
end
- return false
+ end
+ return false
end
expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
+ xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
+ return false
end
expressions.undefined=function(s)
- return s==nil
+ return s==nil
end
expressions.quit=function(s)
- if s or s==nil then
- quit_expression=true
- end
- return true
+ if s or s==nil then
+ quit_expression=true
+ end
+ return true
end
expressions.print=function(...)
- print(...)
- return true
+ print(...)
+ return true
end
expressions.find=find
expressions.upper=upper
@@ -14491,233 +18053,238 @@ expressions.lower=lower
expressions.number=tonumber
expressions.boolean=toboolean
function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
- if find(str,pattern) then
- return true
- end
- elseif t=="table" then
- for i=1,#str do
- local d=str[i]
- if type(d)=="string" and find(d,pattern) then
- return true
- end
- end
+ local t=type(str)
+ if t=="string" then
+ if find(str,pattern) then
+ return true
end
- return false
+ elseif t=="table" then
+ for i=1,#str do
+ local d=str[i]
+ if type(d)=="string" and find(d,pattern) then
+ return true
+ end
+ end
+ end
+ return false
end
function xml.expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
+ return type(str)=="string" and gsub(str,"^#","") or ""
end
local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local r=e.__p__
- handle(r,r.dt,e.ni)
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local r=e.__p__
+ handle(r,r.dt,e.ni)
end
+ end
end
local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- if handle then
- for c=1,#collected do
- handle(collected[c])
- end
- else
- return collected
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ if handle then
+ for c=1,#collected do
+ handle(collected[c])
+ end
+ else
+ return collected
end
+ end
end
-xml.traverse=traverse
+xml.traverse=traverse
xml.selection=selection
local function dofunction(collected,fnc,...)
- if collected then
- local f=functions[fnc]
- if f then
- for c=1,#collected do
- f(collected[c],...)
- end
- else
- report_lpath("unknown function %a",fnc)
- end
+ if collected then
+ local f=functions[fnc]
+ if f then
+ for c=1,#collected do
+ f(collected[c],...)
+ end
+ else
+ report_lpath("unknown function %a",fnc)
end
+ end
end
finalizers.xml["function"]=dofunction
finalizers.tex["function"]=dofunction
expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
+ local rdt=e.__p__.dt
+ return rdt and rdt[n] or ""
end
expressions.name=function(e,n)
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=type(e)=="table" and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=type(e)=="table" and e
+ elseif n<0 then
+ 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
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
end
+ end
end
- if found then
- local ns,tg=found.rn or found.ns or "",found.tg
- if ns~="" then
- return ns..":"..tg
+ else
+ 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
+ if n==1 then
+ found=di
+ break
else
- return tg
+ n=n-1
end
+ end
+ end
+ end
+ if found then
+ local ns=found.rn or found.ns or ""
+ local tg=found.tg
+ if ns~="" then
+ return ns..":"..tg
else
- return ""
+ return tg
end
+ else
+ return ""
+ end
end
expressions.tag=function(e,n)
- if not e then
- return ""
+ if not e then
+ return ""
+ else
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=(type(e)=="table") and e
+ elseif n<0 then
+ 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
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
+ end
+ end
+ end
else
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=(type(e)=="table") and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
+ 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
+ if n==1 then
+ found=di
+ break
+ else
+ n=n-1
+ end
end
- return (found and found.tg) or ""
+ end
end
+ return (found and found.tg) or ""
+ end
end
local dummy=function() end
function xml.elements(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
+ end
end
function xml.collected(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ return collected[c]
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- return collected[c]
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- return collected[c]
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ return collected[c]
+ end
end
+ end
end
function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
- report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
+ pattern=pattern or "."
+ for e in xml.collected(collection,pattern or ".") do
+ report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+ end
end
local function split(e)
- local dt=e.dt
- if dt then
- for i=1,#dt do
- local dti=dt[i]
- if type(dti)=="string" then
- dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti=gsub(dti,"[\n\r]+","\n\n")
- dt[i]=dti
- else
- split(dti)
- end
- end
+ local dt=e.dt
+ if dt then
+ for i=1,#dt do
+ local dti=dt[i]
+ if type(dti)=="string" then
+ dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+ dti=gsub(dti,"[\n\r]+","\n\n")
+ dt[i]=dti
+ else
+ split(dti)
+ end
end
- return e
+ end
+ return e
end
function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
+ for i=1,#c do
+ split(c[i])
+ end
+ return c
end
@@ -14727,14 +18294,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
--- original size: 3574, stripped down to: 1863
+-- original size: 3574, stripped down to: 1808
if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local xml,lpeg,string=xml,lpeg,string
local type=type
@@ -14745,26 +18312,26 @@ local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs
lpegpatterns.xml=lpegpatterns.xml or {}
local xmlpatterns=lpegpatterns.xml
local function xmlgsub(t,old,new)
- local dt=t.dt
- if dt then
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="string" then
- dt[k]=gsub(v,old,new)
- else
- xmlgsub(v,old,new)
- end
- end
+ local dt=t.dt
+ if dt then
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="string" then
+ dt[k]=gsub(v,old,new)
+ else
+ xmlgsub(v,old,new)
+ end
end
+ end
end
function xml.stripleadingspaces(dk,d,k)
- if d and k then
- local dkm=d[k-1]
- if dkm and type(dkm)=="string" then
- local s=match(dkm,"\n(%s+)")
- xmlgsub(dk,"\n"..rep(" ",#s),"\n")
- end
+ if d and k then
+ local dkm=d[k-1]
+ if dkm and type(dkm)=="string" then
+ local s=match(dkm,"\n(%s+)")
+ xmlgsub(dk,"\n"..rep(" ",#s),"\n")
end
+ end
end
local normal=(1-S("<&>"))^0
local special=P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"
@@ -14776,17 +18343,17 @@ local cleansed=Cs(((P("<")*(1-P(">"))^0*P(">"))/""+1)^0)
xmlpatterns.escaped=escaped
xmlpatterns.unescaped=unescaped
xmlpatterns.cleansed=cleansed
-function xml.escaped (str) return lpegmatch(escaped,str) end
+function xml.escaped (str) return lpegmatch(escaped,str) end
function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str) end
+function xml.cleansed (str) return lpegmatch(cleansed,str) end
function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
- local n=#e.dt
- if not check or n==0 or (n==1 and e.dt[1]=="") then
- e.dt={ str }
- end
+ local e=xml.first(root,pattern)
+ if e then
+ local n=#e.dt
+ if not check or n==0 or (n==1 and e.dt[1]=="") then
+ e.dt={ str }
end
+ end
end
@@ -14796,17 +18363,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
--- original size: 30650, stripped down to: 21793
+-- original size: 30771, stripped down to: 19680
if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
+local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
+local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
local report_xml=logs.reporter("xml")
local xml=xml
local xmlcopy,xmlname=xml.copy,xml.name
@@ -14819,308 +18386,313 @@ local utfbyte=utf.byte
local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
local striplinepatterns=utilities.strings.striplinepatterns
local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
+ report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
end
local function withelements(e,handle,depth)
- if e and handle then
- local edt=e.dt
- if edt then
- depth=depth or 0
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- handle(e,depth)
- withelements(e,handle,depth+1)
- end
- end
+ if e and handle then
+ local edt=e.dt
+ if edt then
+ depth=depth or 0
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ handle(e,depth)
+ withelements(e,handle,depth+1)
end
+ end
end
+ end
end
xml.withelements=withelements
function xml.withelement(e,n,handle)
- if e and n~=0 and handle then
- local edt=e.dt
- if edt then
- if n>0 then
- for i=1,#edt do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==1 then
- handle(ei)
- return
- else
- n=n-1
- end
- end
- end
- elseif n<0 then
- for i=#edt,1,-1 do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==-1 then
- handle(ei)
- return
- else
- n=n+1
- end
- end
- end
+ if e and n~=0 and handle then
+ local edt=e.dt
+ if edt then
+ if n>0 then
+ for i=1,#edt do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==1 then
+ handle(ei)
+ return
+ else
+ n=n-1
end
+ end
end
- end
-end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- if handle then
- if reverse then
- for c=#collected,1,-1 do
- handle(collected[c])
- end
+ elseif n<0 then
+ for i=#edt,1,-1 do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==-1 then
+ handle(ei)
+ return
else
- for c=1,#collected do
- handle(collected[c])
- end
+ n=n+1
end
+ end
end
- return collected
+ end
end
+ end
end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
+function xml.each(root,pattern,handle,reverse)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ if handle then
+ if reverse then
+ for c=#collected,1,-1 do
+ handle(collected[c])
+ end
+ else
for c=1,#collected do
- handle(collected[c].at)
+ handle(collected[c])
end
+ end
end
return collected
+ end
+end
+function xml.processattributes(root,pattern,handle)
+ local collected=xmlapplylpath(root,pattern)
+ if collected and handle then
+ for c=1,#collected do
+ handle(collected[c].at)
+ end
+ end
+ return collected
end
function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
+ return xmlapplylpath(root,pattern)
end
function xml.collecttexts(root,pattern,flatten)
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
- local xmltostring=xml.tostring
- for c=1,#collected do
- collected[c]=xmltostring(collected[c].dt)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected and flatten then
+ local xmltostring=xml.tostring
+ for c=1,#collected do
+ collected[c]=xmltostring(collected[c].dt)
end
- return collected or {}
+ end
+ return collected or {}
end
function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- local t,n={},0
- for c=1,#collected do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace then
- t[n]=tg
- elseif ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ local t={}
+ local n=0
+ for c=1,#collected do
+ local e=collected[c]
+ local ns=e.ns
+ local tg=e.tg
+ n=n+1
+ if nonamespace then
+ t[n]=tg
+ elseif ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
+ end
end
+ return t
+ end
end
local no_root={ no_root=true }
local function redo_ni(d)
- for k=1,#d do
- local dk=d[k]
- if type(dk)=="table" then
- dk.ni=k
- end
+ for k=1,#d do
+ local dk=d[k]
+ if type(dk)=="table" then
+ dk.ni=k
end
+ end
end
xml.reindex=redo_ni
local function xmltoelement(whatever,root)
- if not whatever then
- return nil
- end
- local element
- if type(whatever)=="string" then
- element=xmlinheritedconvert(whatever,root)
- else
- element=whatever
- end
- if element.error then
- return whatever
- end
- if element then
- end
- return element
+ if not whatever then
+ return nil
+ end
+ local element
+ if type(whatever)=="string" then
+ element=xmlinheritedconvert(whatever,root)
+ else
+ element=whatever
+ end
+ if element.error then
+ return whatever
+ end
+ if element then
+ end
+ return element
end
xml.toelement=xmltoelement
local function copiedelement(element,newparent)
- if type(element)=="string" then
- return element
- else
- element=xmlcopy(element).dt
- if newparent and type(element)=="table" then
- element.__p__=newparent
- end
- return element
+ if type(element)=="string" then
+ return element
+ else
+ element=xmlcopy(element).dt
+ if newparent and type(element)=="table" then
+ element.__p__=newparent
end
+ return element
+ end
end
function xml.delete(root,pattern)
- if not pattern or pattern=="" then
- local p=root.__p__
+ if not pattern or pattern=="" then
+ local p=root.__p__
+ if p then
+ if trace_manipulations then
+ report('deleting',"--",c,root)
+ end
+ local d=p.dt
+ remove(d,root.ni)
+ redo_ni(d)
+ end
+ else
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
if p then
- if trace_manipulations then
- report('deleting',"--",c,root)
- end
- local d=p.dt
- remove(d,root.ni)
- redo_ni(d)
- end
- else
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('deleting',pattern,c,e)
- end
- local d=p.dt
- local ni=e.ni
- if ni<=#d then
- if false then
- p.dt[ni]=""
- else
- remove(d,ni)
- redo_ni(d)
- end
- else
- end
- end
+ if trace_manipulations then
+ report('deleting',pattern,c,e)
+ end
+ local d=p.dt
+ local ni=e.ni
+ if ni<=#d then
+ if false then
+ p.dt[ni]=""
+ else
+ remove(d,ni)
+ redo_ni(d)
end
+ else
+ end
end
+ end
end
+ end
end
function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('replacing',pattern,c,e)
- end
- local d=p.dt
- local n=e.ni
- local t=copiedelement(element,p)
- if type(t)=="table" then
- d[n]=t[1]
- for i=2,#t do
- n=n+1
- insert(d,n,t[i])
- end
- else
- d[n]=t
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
+ if p then
+ if trace_manipulations then
+ report('replacing',pattern,c,e)
+ end
+ local d=p.dt
+ local n=e.ni
+ local t=copiedelement(element,p)
+ if type(t)=="table" then
+ d[n]=t[1]
+ for i=2,#t do
+ n=n+1
+ insert(d,n,t[i])
+ end
+ else
+ d[n]=t
end
+ redo_ni(d)
+ end
end
+ end
end
local function wrap(e,wrapper)
- local t={
- rn=e.rn,
- tg=e.tg,
- ns=e.ns,
- at=e.at,
- dt=e.dt,
- __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
+ local t={
+ rn=e.rn,
+ tg=e.tg,
+ ns=e.ns,
+ at=e.at,
+ dt=e.dt,
+ __p__=e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn=wrapper.rn or e.rn or ""
+ e.tg=wrapper.tg or e.tg or ""
+ e.ns=wrapper.ns or e.ns or ""
+ e.at=fastcopy(wrapper.at)
+ e.dt={ t }
end
function xml.wrap(root,pattern,whatever)
- if whatever then
- local wrapper=xmltoelement(whatever,root)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if trace_manipulations then
- report('wrapping',pattern,c,e)
- end
- wrap(e,wrapper)
- end
+ if whatever then
+ local wrapper=xmltoelement(whatever,root)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
end
- else
- wrap(root,xmltoelement(pattern))
+ wrap(e,wrapper)
+ end
end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
end
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 edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
- if edt then
- local be,af
- local cp=copiedelement(element,e)
- if prepend then
- be,af=cp,edt
- else
- be,af=edt,cp
- end
- local bn=#be
- for i=1,#af do
- bn=bn+1
- be[bn]=af[i]
- end
- if rri then
- r.dt[rri].dt=be
- else
- d[k].dt=be
- end
- redo_ni(d)
- end
+ 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=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
+ local cp=copiedelement(element,e)
+ if prepend then
+ be,af=cp,edt
+ else
+ be,af=edt,cp
+ end
+ local bn=#be
+ for i=1,#af do
+ bn=bn+1
+ be[bn]=af[i]
+ end
+ if rri then
+ r.dt[rri].dt=be
+ else
+ d[k].dt=be
+ end
+ redo_ni(d)
end
- if not collected then
- elseif collected.tg then
- inject_e(collected)
- else
- for c=1,#collected do
- inject_e(collected[c])
- end
+ end
+ if not collected then
+ elseif collected.tg then
+ inject_e(collected)
+ else
+ for c=1,#collected do
+ inject_e(collected[c])
end
+ end
end
local function insert_element(root,pattern,whatever,before)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
- local r=e.__p__
- local d,k=r.dt,e.ni
- if not before then
- k=k+1
- end
- insert(d,k,copiedelement(element,r))
- redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
- insert_e(collected)
- else
- for c=1,#collected do
- insert_e(collected[c])
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function insert_e(e)
+ local r=e.__p__
+ local d=r.dt
+ local k=e.ni
+ if not before then
+ k=k+1
+ end
+ insert(d,k,copiedelement(element,r))
+ redo_ni(d)
+ end
+ if not collected then
+ elseif collected.tg then
+ insert_e(collected)
+ else
+ for c=1,#collected do
+ insert_e(collected[c])
end
+ end
end
xml.insert_element=insert_element
xml.insertafter=insert_element
@@ -15128,124 +18700,124 @@ xml.insertbefore=function(r,p,e) insert_element(r,p,e,true) end
xml.injectafter=inject_element
xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
- if not level then
- level=1
- end
- for c=1,#collected do
- local ek=collected[c]
- local name=nil
- local ekdt=ek.dt
- if ekdt then
- local ekat=ek.at
- local ekrt=ek.__p__
- if ekrt then
- local epdt=ekrt.dt
- if not attribute or attribute=="" then
- name=(type(ekdt)=="table" and ekdt[1]) or ekdt
- end
- if not name then
- for a in gmatch(attribute or "href","([^|]+)") do
- name=ekat[a]
- if name then
- break
- end
- end
- end
- local data=nil
- if name and name~="" then
- local d,n=loaddata(name)
- data=d or ""
- name=n or name
- if trace_inclusions then
- report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
- end
- end
- if not data or data=="" then
- epdt[ek.ni]=""
- elseif ekat["parse"]=="text" then
- epdt[ek.ni]=xml.escaped(data)
- else
+ pattern=pattern or 'include'
+ loaddata=loaddata or io.loaddata
+ local collected=xmlapplylpath(xmldata,pattern)
+ if collected then
+ if not level then
+ level=1
+ end
+ for c=1,#collected do
+ local ek=collected[c]
+ local name=nil
+ local ekdt=ek.dt
+ if ekdt then
+ local ekat=ek.at
+ local ekrt=ek.__p__
+ if ekrt then
+ local epdt=ekrt.dt
+ if not attribute or attribute=="" then
+ name=(type(ekdt)=="table" and ekdt[1]) or ekdt
+ end
+ if not name then
+ for a in gmatch(attribute or "href","([^|]+)") do
+ name=ekat[a]
+ if name then
+ break
+ end
+ end
+ end
+ local data=nil
+ if name and name~="" then
+ local d,n=loaddata(name)
+ data=d or ""
+ name=n or name
+ if trace_inclusions then
+ report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
+ end
+ end
+ if not data or data=="" then
+ epdt[ek.ni]=""
+ elseif ekat["parse"]=="text" then
+ epdt[ek.ni]=xml.escaped(data)
+ else
local settings=xmldata.settings
local savedresource=settings.currentresource
settings.currentresource=name
- local xi=xmlinheritedconvert(data,xmldata)
- if not xi then
- epdt[ek.ni]=""
- else
- if recursive then
- include(xi,pattern,attribute,recursive,loaddata,level+1)
- end
- local child=xml.body(xi)
- child.__p__=ekrt
- child.__f__=name
+ local xi=xmlinheritedconvert(data,xmldata)
+ if not xi then
+ epdt[ek.ni]=""
+ else
+ if recursive then
+ include(xi,pattern,attribute,recursive,loaddata,level+1)
+ end
+ local child=xml.body(xi)
+ child.__p__=ekrt
+ child.__f__=name
child.cf=name
- epdt[ek.ni]=child
- local settings=xmldata.settings
- local inclusions=settings and settings.inclusions
- if inclusions then
- inclusions[#inclusions+1]=name
- elseif settings then
- settings.inclusions={ name }
- else
- settings={ inclusions={ name } }
- xmldata.settings=settings
- end
- if child.er then
- local badinclusions=settings.badinclusions
- if badinclusions then
- badinclusions[#badinclusions+1]=name
- else
- settings.badinclusions={ name }
- end
- end
- end
-settings.currentresource=savedresource
- end
+ epdt[ek.ni]=child
+ local settings=xmldata.settings
+ local inclusions=settings and settings.inclusions
+ if inclusions then
+ inclusions[#inclusions+1]=name
+ elseif settings then
+ settings.inclusions={ name }
+ else
+ settings={ inclusions={ name } }
+ xmldata.settings=settings
+ end
+ if child.er then
+ local badinclusions=settings.badinclusions
+ if badinclusions then
+ badinclusions[#badinclusions+1]=name
+ else
+ settings.badinclusions={ name }
end
+ end
end
+settings.currentresource=savedresource
+ end
end
+ end
end
+ end
end
xml.include=include
function xml.inclusion(e,default)
- while e do
- local f=e.__f__
- if f then
- return f
- else
- e=e.__p__
- end
+ while e do
+ local f=e.__f__
+ if f then
+ return f
+ else
+ e=e.__p__
end
- return default
+ end
+ return default
end
local function getinclusions(key,e,sorted)
- while e do
- local settings=e.settings
- if settings then
- local inclusions=settings[key]
- if inclusions then
- inclusions=table.unique(inclusions)
- if sorted then
- table.sort(inclusions)
- end
- return inclusions
- else
- e=e.__p__
- end
- else
- e=e.__p__
- end
+ while e do
+ local settings=e.settings
+ if settings then
+ local inclusions=settings[key]
+ if inclusions then
+ inclusions=table.unique(inclusions)
+ if sorted then
+ table.sort(inclusions)
+ end
+ return inclusions
+ else
+ e=e.__p__
+ end
+ else
+ e=e.__p__
end
+ end
end
function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
+ return getinclusions("inclusions",e,sorted)
end
function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
+ return getinclusions("badinclusions",e,sorted)
end
local b_collapser=lpegpatterns.b_collapser
local m_collapser=lpegpatterns.m_collapser
@@ -15254,194 +18826,194 @@ local b_stripper=lpegpatterns.b_stripper
local m_stripper=lpegpatterns.m_stripper
local e_stripper=lpegpatterns.e_stripper
local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
- local n=#edt
- if n==0 then
- return e
- elseif anywhere then
- local t={}
- local m=0
- for e=1,n do
- local str=edt[e]
- if type(str)~="string" then
- m=m+1
- t[m]=str
- elseif str~="" then
- if nolines then
- str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
- else
- str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
- end
- if str~="" then
- m=m+1
- t[m]=str
- end
- end
- end
- e.dt=t
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==0 then
+ return e
+ elseif anywhere then
+ local t={}
+ local m=0
+ for e=1,n do
+ local str=edt[e]
+ if type(str)~="string" then
+ m=m+1
+ t[m]=str
+ elseif str~="" then
+ if nolines then
+ str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
+ else
+ str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
+ end
+ if str~="" then
+ m=m+1
+ t[m]=str
+ end
+ end
+ end
+ e.dt=t
+ else
+ local str=edt[1]
+ if type(str)=="string" then
+ if str~="" then
+ str=lpegmatch(nolines and b_collapser or b_stripper,str)
+ end
+ if str=="" then
+ remove(edt,1)
+ n=n-1
else
- local str=edt[1]
- if type(str)=="string" then
- if str~="" then
- str=lpegmatch(nolines and b_collapser or b_stripper,str)
- end
- if str=="" then
- remove(edt,1)
- n=n-1
- else
- edt[1]=str
- end
- end
- if n>0 then
- str=edt[n]
- if type(str)=="string" then
- if str=="" then
- remove(edt)
- else
- str=lpegmatch(nolines and e_collapser or e_stripper,str)
- if str=="" then
- remove(edt)
- else
- edt[n]=str
- end
- end
- end
+ edt[1]=str
+ end
+ end
+ if n>0 then
+ str=edt[n]
+ if type(str)=="string" then
+ if str=="" then
+ remove(edt)
+ else
+ str=lpegmatch(nolines and e_collapser or e_stripper,str)
+ if str=="" then
+ remove(edt)
+ else
+ edt[n]=str
end
+ end
end
+ end
end
- return e
+ end
+ return e
end
xml.stripelement=stripelement
function xml.strip(root,pattern,nolines,anywhere)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for i=1,#collected do
- stripelement(collected[i],nolines,anywhere)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for i=1,#collected do
+ stripelement(collected[i],nolines,anywhere)
end
+ end
end
local function renamespace(root,oldspace,newspace)
- local ndt=#root.dt
- for i=1,ndt or 0 do
- local e=root[i]
- if type(e)=="table" then
- if e.ns==oldspace then
- e.ns=newspace
- if e.rn then
- e.rn=newspace
- end
- end
- local edt=e.dt
- if edt then
- renamespace(edt,oldspace,newspace)
- end
+ local ndt=#root.dt
+ for i=1,ndt or 0 do
+ local e=root[i]
+ if type(e)=="table" then
+ if e.ns==oldspace then
+ e.ns=newspace
+ if e.rn then
+ e.rn=newspace
end
+ end
+ local edt=e.dt
+ if edt then
+ renamespace(edt,oldspace,newspace)
+ end
end
+ end
end
xml.renamespace=renamespace
function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].tg=newtg
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].tg=newtg
end
+ end
end
function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].ns=newns
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].ns=newns
end
+ end
end
function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if (not e.rn or e.rn=="") and e.ns=="" then
- e.rn=newns
- end
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if (not e.rn or e.rn=="") and e.ns=="" then
+ e.rn=newns
+ end
end
+ end
end
function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- e.tg,e.ns,e.rn=newtg,newns,newrn
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ e.tg,e.ns,e.rn=newtg,newns,newrn
end
+ end
end
function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
- local first=dt[1]
- if first.tg=="@cd@" then
- e.dt=first.dt
- end
- else
+ local dt=e.dt
+ if #dt==1 then
+ local first=dt[1]
+ if first.tg=="@cd@" then
+ e.dt=first.dt
end
+ else
+ end
end
function xml.texttocdata(e)
- local dt=e.dt
- local s=xml.tostring(dt)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(dt)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
function xml.elementtocdata(e)
- local dt=e.dt
- local s=xml.tostring(e)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(e)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" }
local entities=characters and characters.entities or nil
local builtinentities=xml.builtinentities
function xml.addentitiesdoctype(root,option)
- if not entities then
- require("char-ent")
- entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
- local list={}
- local hexify=option=="hexadecimal"
- for k,v in table.sortedhash(root.statistics.entities.names) do
- if not builtinentities[k] then
- local e=entities[k]
- if not e then
- e=format("[%s]",k)
- elseif hexify then
- e=format("&#%05X;",utfbyte(k))
- end
- list[#list+1]=format(" <!ENTITY %s %q >",k,e)
- end
- end
- local dt=root.dt
- local n=dt[1].tg=="@pi@" and 2 or 1
- if #list>0 then
- insert(dt,n,{ "\n" })
- insert(dt,n,{
- tg="@dt@",
- dt={ format("Something [\n%s\n] ",concat(list)) },
- ns="",
- special=true,
- })
- insert(dt,n,{ "\n\n" })
- else
- end
+ if not entities then
+ require("char-ent")
+ entities=characters.entities
+ end
+ if entities and root and root.tg=="@rt@" and root.statistics then
+ local list={}
+ local hexify=option=="hexadecimal"
+ for k,v in table.sortedhash(root.statistics.entities.names) do
+ if not builtinentities[k] then
+ local e=entities[k]
+ if not e then
+ e=format("[%s]",k)
+ elseif hexify then
+ e=format("&#%05X;",utfbyte(k))
+ end
+ list[#list+1]=format(" <!ENTITY %s %q >",k,e)
+ end
end
+ local dt=root.dt
+ local n=dt[1].tg=="@pi@" and 2 or 1
+ if #list>0 then
+ insert(dt,n,{ "\n" })
+ insert(dt,n,{
+ tg="@dt@",
+ dt={ format("Something [\n%s\n] ",concat(list)) },
+ ns="",
+ special=true,
+ })
+ insert(dt,n,{ "\n\n" })
+ else
+ end
+ end
end
xml.all=xml.each
xml.insert=xml.insertafter
@@ -15451,239 +19023,241 @@ xml.before=xml.insertbefore
xml.process=xml.each
xml.obsolete=xml.obsolete or {}
local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace obsolete.replace_element=xml.replace
-xml.each_element=xml.each obsolete.each_element=xml.each
-xml.process_elements=xml.process obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
+xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
+xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
+xml.delete_element=xml.delete obsolete.delete_element=xml.delete
+xml.replace_element=xml.replace obsolete.replace_element=xml.replace
+xml.each_element=xml.each obsolete.each_element=xml.each
+xml.process_elements=xml.process obsolete.process_elements=xml.process
+xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
+xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
+xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
+xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
+xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
+xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
+xml.inject_element=xml.inject obsolete.inject_element=xml.inject
+xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
+xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
+xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
function xml.cdata(e)
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
end
- return ""
+ end
+ return ""
end
function xml.finalizers.xml.cdata(collected)
- if collected then
- local e=collected[1]
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
+ if collected then
+ local e=collected[1]
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
+ end
end
- return ""
+ end
+ return ""
end
function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.setcomment(e,str,n)
- e.dt={ {
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.setcdata(e,str)
- e.dt={ {
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local d=e.dt
- if d==x then
- report_xml("warning: xml.separate changes root")
- x=d
- end
- local t,n={ "\n" },1
- local i,nd=1,#d
- while i<=nd do
- while i<=nd do
- local di=d[i]
- if type(di)=="string" then
- if di=="\n" or find(di,"^%s+$") then
- i=i+1
- else
- d[i]=strip(di)
- break
- end
- else
- break
- end
- end
- if i>nd then
- break
- end
- t[n+1]="\n"
- t[n+2]=d[i]
- t[n+3]="\n"
- n=n+3
- i=i+1
+ local collected=xmlapplylpath(x,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local d=e.dt
+ if d==x then
+ report_xml("warning: xml.separate changes root")
+ x=d
+ end
+ local t={ "\n" }
+ local n=1
+ local i=1
+ local nd=#d
+ while i<=nd do
+ while i<=nd do
+ local di=d[i]
+ if type(di)=="string" then
+ if di=="\n" or find(di,"^%s+$") then
+ i=i+1
+ else
+ d[i]=strip(di)
+ break
end
- t[n+1]="\n"
- setmetatable(t,getmetatable(d))
- e.dt=t
+ else
+ break
+ end
+ end
+ if i>nd then
+ break
end
+ t[n+1]="\n"
+ t[n+2]=d[i]
+ t[n+3]="\n"
+ n=n+3
+ i=i+1
+ end
+ t[n+1]="\n"
+ setmetatable(t,getmetatable(d))
+ e.dt=t
end
- return x
+ end
+ return x
end
local helpers=xml.helpers or {}
xml.helpers=helpers
local function normal(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)=="string" and str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)=="string" and str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
local function recurse(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)~="string" then
- recurse(str,action)
- elseif str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)~="string" then
+ recurse(str,action)
+ elseif str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
function helpers.recursetext(collected,action,recursive)
- if recursive then
- for i=1,#collected do
- recurse(collected[i],action)
- end
- else
- for i=1,#collected do
- normal(collected[i],action)
- end
+ if recursive then
+ for i=1,#collected do
+ recurse(collected[i],action)
end
+ else
+ for i=1,#collected do
+ normal(collected[i],action)
+ end
+ end
end
local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
+ ["@rt@"]="root",
+ ["@pi@"]="instruction",
+ ["@cm@"]="comment",
+ ["@dt@"]="declaration",
+ ["@cd@"]="cdata",
}
local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
- [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
- _namespace=ns~="" and ns or nil,
- _tag=not x.special and tg or nil,
- _type=specials[tg] or "_element",
- }
- if at then
- for k,v in next,at do
- node[k]=v
- end
- end
- local n=0
- for i=1,#dt do
- local di=dt[i]
- if type(di)=="table" then
- if flat and di.special then
- else
- di=convert(di,strip,flat)
- if di then
- n=n+1
- node[n]=di
- end
- end
- elseif strip then
- di=lpegmatch(strip,di)
- if di~="" then
- n=n+1
- node[n]=di
- end
- else
- n=n+1
- node[n]=di
+ local ns=x.ns
+ local tg=x.tg
+ local at=x.at
+ local dt=x.dt
+ local node=flat and {
+ [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
+ } or {
+ _namespace=ns~="" and ns or nil,
+ _tag=not x.special and tg or nil,
+ _type=specials[tg] or "_element",
+ }
+ if at then
+ for k,v in next,at do
+ node[k]=v
+ end
+ end
+ local n=0
+ for i=1,#dt do
+ local di=dt[i]
+ if type(di)=="table" then
+ if flat and di.special then
+ else
+ di=convert(di,strip,flat)
+ if di then
+ n=n+1
+ node[n]=di
end
+ end
+ elseif strip then
+ di=lpegmatch(strip,di)
+ if di~="" then
+ n=n+1
+ node[n]=di
+ end
+ else
+ n=n+1
+ node[n]=di
end
- if next(node) then
- return node
- end
+ end
+ if next(node) then
+ return node
+ end
end
function xml.totable(x,strip,flat)
- if type(x)=="table" then
- if strip then
- strip=striplinepatterns[strip]
- end
- return convert(x,strip,flat)
+ if type(x)=="table" then
+ if strip then
+ strip=striplinepatterns[strip]
end
+ return convert(x,strip,flat)
+ end
end
function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
- return
- end
- if type(name)=="table" then
- attributes=name
- name=namespace
- namespace=""
- elseif type(name)~="string" then
- attributes={}
- name=namespace
- namespace=""
- end
- if type(attributes)~="table" then
- attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
+ if type(e)~="table" or not e.tg then
+ return
+ end
+ if type(name)=="table" then
+ attributes=name
+ name=namespace
+ namespace=""
+ elseif type(name)~="string" then
+ attributes={}
+ name=namespace
+ namespace=""
+ end
+ if type(attributes)~="table" then
+ attributes={}
+ end
+ e.ns=namespace
+ e.rn=namespace
+ e.tg=name
+ e.at=attributes
end
@@ -15693,14 +19267,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 11096, stripped down to: 8243
+-- original size: 11096, stripped down to: 7702
if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber,next=tonumber,next
local concat=table.concat
@@ -15712,241 +19286,241 @@ local xmltostring=xml.tostring
local xmlserialize=xml.serialize
local xmlcollected=xml.collected
local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg
+local reparsedentity=xml.reparsedentitylpeg
local unescapedentity=xml.unescapedentitylpeg
local parsedentity=reparsedentity
local function first(collected)
- return collected and collected[1]
+ return collected and collected[1]
end
local function last(collected)
- return collected and collected[#collected]
+ return collected and collected[#collected]
end
local function all(collected)
- return collected
+ return collected
end
local reverse=table.reversed
local function attribute(collected,name)
- if collected and #collected>0 then
- local at=collected[1].at
- return at and at[name]
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ return at and at[name]
+ end
end
local function att(id,name)
- local at=id.at
- return at and at[name]
+ local at=id.at
+ return at and at[name]
end
local function count(collected)
- return collected and #collected or 0
+ return collected and #collected or 0
end
local function position(collected,n)
- if not collected then
- return 0
- end
- local nc=#collected
- if nc==0 then
- return 0
- end
- n=tonumber(n) or 0
- if n<0 then
- return collected[nc+n+1]
- elseif n>0 then
- return collected[n]
- else
- return collected[1].mi or 0
- end
+ if not collected then
+ return 0
+ end
+ local nc=#collected
+ if nc==0 then
+ return 0
+ end
+ n=tonumber(n) or 0
+ if n<0 then
+ return collected[nc+n+1]
+ elseif n>0 then
+ return collected[n]
+ else
+ return collected[1].mi or 0
+ end
end
local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0
+ return collected and #collected>0 and collected[1].mi or 0
end
local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0
+ return collected and #collected>0 and collected[1].ni or 0
end
local function attributes(collected,arguments)
- if collected and #collected>0 then
- local at=collected[1].at
- if arguments then
- return at[arguments]
- elseif next(at) then
- return at
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ if arguments then
+ return at[arguments]
+ elseif next(at) then
+ return at
end
+ end
end
local function chainattribute(collected,arguments)
- if collected and #collected>0 then
- local e=collected[1]
- while e do
- local at=e.at
- if at then
- local a=at[arguments]
- if a then
- return a
- end
- else
- break
- end
- e=e.__p__
+ if collected and #collected>0 then
+ local e=collected[1]
+ while e do
+ local at=e.at
+ if at then
+ local a=at[arguments]
+ if a then
+ return a
end
+ else
+ break
+ end
+ e=e.__p__
end
- return ""
+ end
+ return ""
end
local function raw(collected)
- if collected and #collected>0 then
- local e=collected[1] or collected
- return e and xmltostring(e) or ""
- else
- return ""
- end
+ if collected and #collected>0 then
+ local e=collected[1] or collected
+ return e and xmltostring(e) or ""
+ else
+ return ""
+ end
end
local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
- result={}
- return result
- end,
- finalize=function()
- return concat(result)
- end,
- handle=function(...)
- result[#result+1]=concat {... }
- end,
- escape=false,
+ name="string",
+ initialize=function()
+ result={}
+ return result
+ end,
+ finalize=function()
+ return concat(result)
+ end,
+ handle=function(...)
+ result[#result+1]=concat {... }
+ end,
+ escape=false,
}
local function xmltotext(root)
- local dt=root.dt
- if not dt then
- return ""
- end
- local nt=#dt
- if nt==0 then
- return ""
- elseif nt==1 and type(dt[1])=="string" then
- return dt[1]
- else
- return xmlserialize(root,xmltexthandler) or ""
- end
+ local dt=root.dt
+ if not dt then
+ return ""
+ end
+ local nt=#dt
+ if nt==0 then
+ return ""
+ elseif nt==1 and type(dt[1])=="string" then
+ return dt[1]
+ else
+ return xmlserialize(root,xmltexthandler) or ""
+ end
end
function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
+ return root and xmlserialize(root,xmltexthandler) or ""
end
local function text(collected)
- if collected then
- local e=collected[1] or collected
- return e and xmltotext(e) or ""
- else
- return ""
- end
+ if collected then
+ local e=collected[1] or collected
+ return e and xmltotext(e) or ""
+ else
+ return ""
+ end
end
local function texts(collected)
- if not collected then
- return {}
- end
- local nc=#collected
- if nc==0 then
- return {}
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- if e and e.dt then
- n=n+1
- t[n]=e.dt
- end
- end
- return t
+ if not collected then
+ return {}
+ end
+ local nc=#collected
+ if nc==0 then
+ return {}
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ if e and e.dt then
+ n=n+1
+ t[n]=e.dt
+ end
+ end
+ return t
end
local function tag(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- return c and c.tg
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ return c and c.tg
end
local function name(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
- return c.tg
- else
- return c.ns..":"..c.tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ if not c then
+ elseif c.ns=="" then
+ return c.tg
+ else
+ return c.ns..":"..c.tg
+ end
end
local function tags(collected,nonamespace)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace or ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace or ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
end
- return t
+ end
+ return t
end
local function empty(collected,spacesonly)
- if not collected then
- return true
- end
- local nc=#collected
- if nc==0 then
- return true
- end
- for c=1,nc do
- local e=collected[c]
- if e then
- local edt=e.dt
- if edt then
- local n=#edt
- if n==1 then
- local edk=edt[1]
- local typ=type(edk)
- if typ=="table" then
- return false
- elseif edk~="" then
- return false
- elseif spacesonly and not find(edk,"%S") then
- return false
- end
- elseif n>1 then
- return false
- end
- end
+ if not collected then
+ return true
+ end
+ local nc=#collected
+ if nc==0 then
+ return true
+ end
+ for c=1,nc do
+ local e=collected[c]
+ if e then
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==1 then
+ local edk=edt[1]
+ local typ=type(edk)
+ if typ=="table" then
+ return false
+ elseif edk~="" then
+ return false
+ elseif spacesonly and not find(edk,"%S") then
+ return false
+ end
+ elseif n>1 then
+ return false
end
+ end
end
- return true
+ end
+ return true
end
finalizers.first=first
finalizers.last=last
@@ -15969,124 +19543,124 @@ finalizers.name=name
finalizers.tags=tags
finalizers.empty=empty
function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
+ return first(xmlfilter(id,pattern))
end
function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
+ return last(xmlfilter(id,pattern))
end
function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
+ return count(xmlfilter(id,pattern))
end
function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
+ return attribute(xmlfilter(id,pattern),a,default)
end
function xml.raw(id,pattern)
- if pattern then
- return raw(xmlfilter(id,pattern))
- else
- return raw(id)
- end
+ if pattern then
+ return raw(xmlfilter(id,pattern))
+ else
+ return raw(id)
+ end
end
function xml.text(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
- return xmltotext(id) or ""
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ return collected and #collected>0 and xmltotext(collected[1]) or ""
+ elseif id then
+ return xmltotext(id) or ""
+ else
+ return ""
+ end
end
function xml.pure(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- if collected and #collected>0 then
- parsedentity=unescapedentity
- local s=collected and #collected>0 and xmltotext(collected[1]) or ""
- parsedentity=reparsedentity
- return s
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ if collected and #collected>0 then
+ parsedentity=unescapedentity
+ local s=collected and #collected>0 and xmltotext(collected[1]) or ""
+ parsedentity=reparsedentity
+ return s
else
- parsedentity=unescapedentity
- local s=xmltotext(id) or ""
- parsedentity=reparsedentity
- return s
+ return ""
end
+ else
+ parsedentity=unescapedentity
+ local s=xmltotext(id) or ""
+ parsedentity=reparsedentity
+ return s
+ end
end
xml.content=text
function xml.position(id,pattern,n)
- return position(xmlfilter(id,pattern),n)
+ return position(xmlfilter(id,pattern),n)
end
function xml.match(id,pattern)
- return match(xmlfilter(id,pattern))
+ return match(xmlfilter(id,pattern))
end
function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
+ return empty(xmlfilter(id,pattern),spacesonly)
end
xml.all=xml.filter
xml.index=xml.position
xml.found=xml.filter
local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
- t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
+ local t={}
+ for e in xmlcollected(x[1] or x,"/*") do
+ t[e.tg]=xmltostring(e.dt) or ""
+ end
+ return next(t) and t or nil
end
xml.table=totable
finalizers.table=totable
local function textonly(e,t)
- if e then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- textonly(e,t)
- else
- t[#t+1]=e
- end
- end
+ if e then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ textonly(e,t)
+ else
+ t[#t+1]=e
end
+ end
end
- return t
+ end
+ return t
end
function xml.textonly(e)
- return concat(textonly(e,{}))
+ return concat(textonly(e,{}))
end
function finalizers.lowerall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=lower(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[lower(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=lower(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[lower(k)]=v
end
+ e.at=t
+ end
end
+ end
end
function finalizers.upperall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=upper(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[upper(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=upper(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[upper(k)]=v
end
+ e.at=t
+ end
end
+ end
end
@@ -16096,14 +19670,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
--- original size: 6407, stripped down to: 4965
+-- original size: 6407, stripped down to: 4640
if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.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 trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local formatters=string.formatters
local reporters=logs.reporters
@@ -16112,152 +19686,152 @@ local xmlcollected=xml.collected
local xmltext=xml.text
local xmlfirst=xml.first
local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
- return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
- local categoryname=category.at.name or ""
- if wantedcategories==true or wantedcategories[categoryname] then
- if nofcategories>1 then
- report("%s options:",categoryname)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for flag in xmlcollected(subcategory,"/flag") do
- local name=flag.at.name
- local value=flag.at.value
- local short=xmltext(xmlfirst(flag,"/short"))
- if value then
- report("--%-20s %s",formatters["%s=%s"](name,value),short)
- else
- report("--%-20s %s",name,short)
- end
- end
- report()
- end
- end
- end
- for category in xmlcollected(root,"/application/examples/category") do
- local title=xmltext(xmlfirst(category,"/title"))
- if title and title~="" then
- report()
- report(title)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for example in xmlcollected(subcategory,"/example") do
- local command=xmltext(xmlfirst(example,"/command"))
- local comment=xmltext(xmlfirst(example,"/comment"))
- report(command)
- end
- report()
- end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
- local comment=xmltext(comment)
+ local root=xml.convert(specification.helpinfo or "")
+ if not root then
+ return
+ end
+ local xs=xml.gethandlers("string")
+ xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
+ xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
+ local wantedcategories=select("#",...)==0 and true or table.tohash {... }
+ local nofcategories=xml.count(root,"/application/flags/category")
+ local report=specification.report
+ for category in xmlcollected(root,"/application/flags/category") do
+ local categoryname=category.at.name or ""
+ if wantedcategories==true or wantedcategories[categoryname] then
+ if nofcategories>1 then
+ report("%s options:",categoryname)
report()
- report(comment)
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for flag in xmlcollected(subcategory,"/flag") do
+ local name=flag.at.name
+ local value=flag.at.value
+ local short=xmltext(xmlfirst(flag,"/short"))
+ if value then
+ report("--%-20s %s",formatters["%s=%s"](name,value),short)
+ else
+ report("--%-20s %s",name,short)
+ end
+ end
report()
+ end
+ end
+ end
+ for category in xmlcollected(root,"/application/examples/category") do
+ local title=xmltext(xmlfirst(category,"/title"))
+ if title and title~="" then
+ report()
+ report(title)
+ report()
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for example in xmlcollected(subcategory,"/example") do
+ local command=xmltext(xmlfirst(example,"/command"))
+ local comment=xmltext(xmlfirst(example,"/comment"))
+ report(command)
+ end
+ report()
end
+ end
+ for comment in xmlcollected(root,"/application/comments/comment") do
+ local comment=xmltext(comment)
+ report()
+ report(comment)
+ report()
+ end
end
local reporthelp=reporters.help
local exporthelp=reporters.export
local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
- return false
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="table" then
+ return false
+ end
+ if type(helpinfo)~="string" then
+ helpinfo="Warning: no helpinfo found."
+ t.helpinfo=helpinfo
+ return false
+ end
+ if string.find(helpinfo,".xml$") then
+ local ownscript=environment.ownscript
+ local helpdata=false
+ if ownscript then
+ local helpfile=file.join(file.pathpart(ownscript),helpinfo)
+ helpdata=io.loaddata(helpfile)
+ if helpdata=="" then
+ helpdata=false
+ end
end
- if type(helpinfo)~="string" then
- helpinfo="Warning: no helpinfo found."
- t.helpinfo=helpinfo
- return false
+ if not helpdata then
+ local helpfile=resolvers.findfile(helpinfo,"tex")
+ helpdata=helpfile and io.loaddata(helpfile)
end
- if string.find(helpinfo,".xml$") then
- local ownscript=environment.ownscript
- local helpdata=false
- if ownscript then
- local helpfile=file.join(file.pathpart(ownscript),helpinfo)
- helpdata=io.loaddata(helpfile)
- if helpdata=="" then
- helpdata=false
- end
- end
- if not helpdata then
- local helpfile=resolvers.findfile(helpinfo,"tex")
- helpdata=helpfile and io.loaddata(helpfile)
- end
- if helpdata and helpdata~="" then
- helpinfo=helpdata
- else
- helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
- end
+ if helpdata and helpdata~="" then
+ helpinfo=helpdata
+ else
+ helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
+ end
+ t.helpinfo=helpinfo
+ return string.find(t.helpinfo,"^<%?xml") and true or false
end
function reporters.help(t,...)
- if xmlfound(t) then
- showhelp(t,...)
- else
- reporthelp(t,...)
- end
+ if xmlfound(t) then
+ showhelp(t,...)
+ else
+ reporthelp(t,...)
+ end
end
function reporters.export(t,methods,filename)
- if not xmlfound(t) then
- return exporthelp(t)
- end
- if not methods or methods=="" then
- methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
- filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
- return exporthelp(t)
- end
- if methods=="all" then
- methods=table.keys(exporters)
- elseif type(methods)=="string" then
- methods=utilities.parsers.settings_to_array(methods)
- else
- return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
- filename=false
- elseif file.pathpart(filename)=="" then
- t.report("export file %a will not be saved on the current path (safeguard)",filename)
- return
- end
- for i=1,#methods do
- local method=methods[i]
- local exporter=exporters[method]
- if exporter then
- local result=exporter(t,method)
- if result and result~="" then
- if filename then
- local fullname=file.replacesuffix(filename,method)
- t.report("saving export in %a",fullname)
- dir.mkdirs(file.pathpart(fullname))
- io.savedata(fullname,result)
- else
- reporters.lines(t,result)
- end
- else
- t.report("no output from exporter %a",method)
- end
+ if not xmlfound(t) then
+ return exporthelp(t)
+ end
+ if not methods or methods=="" then
+ methods=environment.arguments["exporthelp"]
+ end
+ if not filename or filename=="" then
+ filename=environment.files[1]
+ end
+ dofile(resolvers.findfile("trac-exp.lua","tex"))
+ local exporters=logs.exporters
+ if not exporters or not methods then
+ return exporthelp(t)
+ end
+ if methods=="all" then
+ methods=table.keys(exporters)
+ elseif type(methods)=="string" then
+ methods=utilities.parsers.settings_to_array(methods)
+ else
+ return exporthelp(t)
+ end
+ if type(filename)~="string" or filename=="" then
+ filename=false
+ elseif file.pathpart(filename)=="" then
+ t.report("export file %a will not be saved on the current path (safeguard)",filename)
+ return
+ end
+ for i=1,#methods do
+ local method=methods[i]
+ local exporter=exporters[method]
+ if exporter then
+ local result=exporter(t,method)
+ if result and result~="" then
+ if filename then
+ local fullname=file.replacesuffix(filename,method)
+ t.report("saving export in %a",fullname)
+ dir.mkdirs(file.pathpart(fullname))
+ io.savedata(fullname,result)
else
- t.report("unknown exporter %a",method)
+ reporters.lines(t,result)
end
+ else
+ t.report("no output from exporter %a",method)
+ end
+ else
+ t.report("unknown exporter %a",method)
end
+ end
end
@@ -16267,149 +19841,149 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11099, stripped down to: 7516
+-- original size: 11099, stripped down to: 7152
if not modules then modules={} end modules ['data-ini']={
- 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,getmetatable,rawset=next,type,getmetatable,rawset
local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
local report_initialization=logs.reporter("resolvers","initialization")
resolvers=resolvers or {}
local resolvers=resolvers
texconfig.kpse_init=false
texconfig.shell_escape='t'
if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
+ local default_texmfcnf=kpse.default_texmfcnf()
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
+ default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
+ environment.default_texmfcnf=default_texmfcnf
end
kpse={ original=kpse }
setmetatable(kpse,{
- __index=function(kp,name)
- report_initialization("fatal error: kpse library is accessed (key: %s)",name)
- os.exit()
- end
+ __index=function(kp,name)
+ report_initialization("fatal error: kpse library is accessed (key: %s)",name)
+ os.exit()
+ end
} )
do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
- ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
- ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
+ local osfontdir=osgetenv("OSFONTDIR")
+ if osfontdir and osfontdir~="" then
+ elseif osname=="windows" then
+ ossetenv("OSFONTDIR","c:/windows/fonts//")
+ elseif osname=="macosx" then
+ ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+ end
end
do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
- homedir=char(127)
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir)
- ossetenv("USERPROFILE",homedir)
- environment.homedir=homedir
+ local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
+ if not homedir or homedir=="" then
+ homedir=char(127)
+ end
+ homedir=file.collapsepath(homedir)
+ ossetenv("HOME",homedir)
+ ossetenv("USERPROFILE",homedir)
+ environment.homedir=homedir
end
do
- local args=environment.originalarguments or arg
- if not environment.ownmain then
- environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
- ownpath=args[-1] or arg[-1]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- if not ownpath or ownpath=="" then
- ownpath=args[-0] or arg[-0]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- end
- local binary=ownbin
- if not ownpath or ownpath=="" then
- ownpath=ownpath and filedirname(binary)
- end
- if not ownpath or ownpath=="" then
- if os.binsuffix~="" then
- binary=file.replacesuffix(binary,os.binsuffix)
- end
- local path=osgetenv("PATH")
- if path then
- for p in gmatch(path,"[^"..io.pathseparator.."]+") do
- local b=filejoin(p,binary)
- if lfs.isfile(b) then
- local olddir=lfs.currentdir()
- if lfs.chdir(p) then
- local pp=lfs.currentdir()
- if trace_locating and p~=pp then
- report_initialization("following symlink %a to %a",p,pp)
- end
- ownpath=pp
- lfs.chdir(olddir)
- else
- if trace_locating then
- report_initialization("unable to check path %a",p)
- end
- ownpath=p
- end
- break
- end
- end
+ local args=environment.originalarguments or arg
+ if not environment.ownmain then
+ environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
+ end
+ local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
+ local ownpath=environment.ownpath or os.selfdir
+ ownbin=file.collapsepath(ownbin)
+ ownpath=file.collapsepath(ownpath)
+ if not ownpath or ownpath=="" or ownpath=="unset" then
+ ownpath=args[-1] or arg[-1]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ if not ownpath or ownpath=="" then
+ ownpath=args[-0] or arg[-0]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ end
+ local binary=ownbin
+ if not ownpath or ownpath=="" then
+ ownpath=ownpath and filedirname(binary)
+ end
+ if not ownpath or ownpath=="" then
+ if os.binsuffix~="" then
+ binary=file.replacesuffix(binary,os.binsuffix)
+ end
+ local path=osgetenv("PATH")
+ if path then
+ for p in gmatch(path,"[^"..io.pathseparator.."]+") do
+ local b=filejoin(p,binary)
+ if lfs.isfile(b) then
+ local olddir=lfs.currentdir()
+ if lfs.chdir(p) then
+ local pp=lfs.currentdir()
+ if trace_locating and p~=pp then
+ report_initialization("following symlink %a to %a",p,pp)
+ end
+ ownpath=pp
+ lfs.chdir(olddir)
+ else
+ if trace_locating then
+ report_initialization("unable to check path %a",p)
+ end
+ ownpath=p
end
+ break
+ end
end
- if not ownpath or ownpath=="" then
- ownpath="."
- report_initialization("forcing fallback to ownpath %a",ownpath)
- elseif trace_locating then
- report_initialization("using ownpath %a",ownpath)
- end
+ end
end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
+ if not ownpath or ownpath=="" then
+ ownpath="."
+ report_initialization("forcing fallback to ownpath %a",ownpath)
+ elseif trace_locating then
+ report_initialization("using ownpath %a",ownpath)
+ end
+ end
+ environment.ownbin=ownbin
+ environment.ownpath=ownpath
end
resolvers.ownpath=environment.ownpath
function resolvers.getownpath()
- return environment.ownpath
+ return environment.ownpath
end
do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
- ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
- ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
- ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
- report_initialization("error: unable to locate ownpath")
- os.exit()
- end
-end
-local texos=environment.texos or osgetenv("TEXOS")
+ local ownpath=environment.ownpath or dir.current()
+ if ownpath then
+ ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
+ ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
+ ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
+ else
+ report_initialization("error: unable to locate ownpath")
+ os.exit()
+ end
+end
+local texos=environment.texos or osgetenv("TEXOS")
local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
if not texos or texos=="" then
- texos=file.basename(texmfos)
+ texos=file.basename(texmfos)
end
ossetenv('TEXMFOS',texmfos)
-ossetenv('TEXOS',texos)
-ossetenv('SELFAUTOSYSTEM',os.platform)
+ossetenv('TEXOS',texos)
+ossetenv('SELFAUTOSYSTEM',os.platform)
environment.texos=texos
environment.texmfos=texmfos
local texroot=environment.texroot or osgetenv("TEXROOT")
if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
+ texroot=osgetenv('SELFAUTOPARENT')
+ ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
local prefixes=utilities.storage.allocate()
@@ -16418,30 +19992,30 @@ local resolved={}
local abstract={}
local dynamic={}
function resolvers.resetresolve(str)
- resolved,abstract={},{}
+ resolved,abstract={},{}
end
function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
- for i=1,#all do
- all[i]=all[i]..":"
- end
+ local all=table.sortedkeys(prefixes)
+ if separator then
+ for i=1,#all do
+ all[i]=all[i]..":"
end
- return all
+ end
+ return all
end
local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
- return action(target)
- else
- return method..":"..target
- end
+ local action=prefixes[method]
+ if action then
+ return action(target)
+ else
+ return method..":"..target
+ end
end
function resolvers.unresolve(str)
- return abstract[str] or str
+ return abstract[str] or str
end
function resolvers.setdynamic(str)
- dynamic[str]=true
+ dynamic[str]=true
end
local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
local prefix=C(R("az")^2)*P(":")
@@ -16450,65 +20024,65 @@ local notarget=(#S(";,")+P(-1))*Cc("")
local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
local p_simple=prefix*P(-1)
local function resolve(str)
- if type(str)=="table" then
- local res={}
- for i=1,#str do
- res[i]=resolve(str[i])
- end
- return res
- end
- local res=resolved[str]
- if res then
- return res
+ if type(str)=="table" then
+ local res={}
+ for i=1,#str do
+ res[i]=resolve(str[i])
end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
- local res=action(res)
- if not dynamic[simple] then
- resolved[simple]=res
- abstract[res]=simple
- end
- return res
+ return res
+ end
+ local res=resolved[str]
+ if res then
+ return res
+ end
+ local simple=lpegmatch(p_simple,str)
+ local action=prefixes[simple]
+ if action then
+ local res=action(res)
+ if not dynamic[simple] then
+ resolved[simple]=res
+ abstract[res]=simple
end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
return res
+ end
+ res=lpegmatch(p_resolve,str)
+ resolved[str]=res
+ abstract[res]=str
+ return res
end
resolvers.resolve=resolve
if type(osuname)=="function" then
- for k,v in next,osuname() do
- if not prefixes[k] then
- prefixes[k]=function() return v end
- end
+ for k,v in next,osuname() do
+ if not prefixes[k] then
+ prefixes[k]=function() return v end
end
+ end
end
if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
- local colon=P(":")
- for k,v in table.sortedpairs(prefixes) do
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
- return lpegmatch(pattern,str)
+ local pattern
+ local function makepattern(t,k,v)
+ if t then
+ rawset(t,k,v)
+ end
+ local colon=P(":")
+ for k,v in table.sortedpairs(prefixes) do
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
end
+ pattern=Cs((p*colon+colon/";"+P(1))^0)
+ end
+ makepattern()
+ table.setmetatablenewindex(prefixes,makepattern)
+ function resolvers.repath(str)
+ return lpegmatch(pattern,str)
+ end
else
- function resolvers.repath(str)
- return str
- end
+ function resolvers.repath(str)
+ return str
+ end
end
@@ -16518,14 +20092,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-exp"] = package.loaded["data-exp"] or true
--- original size: 18105, stripped down to: 11207
+-- original size: 18105, stripped down to: 10389
if not modules then modules={} end modules ['data-exp']={
- 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 format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
local concat,sort=table.concat,table.sort
@@ -16535,21 +20109,21 @@ local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S
local type,next=type,next
local isdir=lfs.isdir
local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
local report_expansions=logs.reporter("resolvers","expansions")
local report_globbing=logs.reporter("resolvers","globbing")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do
- for sa in gmatch(a,"[^,]+") do
- n=n+1;t[n]=sa..sb
- end
+ local t,n={},0
+ for sb in gmatch(b,"[^,]+") do
+ for sa in gmatch(a,"[^,]+") do
+ n=n+1;t[n]=sa..sb
end
- return concat(t,",")
+ end
+ return concat(t,",")
end
local comma=P(",")
local nocomma=(1-comma)^1
@@ -16559,7 +20133,7 @@ local after=Cs((Carg(1)*nocomma+docomma)^0)
local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
local function f_first (a,b) return lpegmatch(after,b,1,a) end
local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both (a,b) return lpegmatch(both,b,1,a) end
+local function f_both (a,b) return lpegmatch(both,b,1,a) end
local left=P("{")
local right=P("}")
local var=P((1-S("{}" ))^0)
@@ -16572,141 +20146,141 @@ local l_rest=Cs((left*var*(left/"")*var*(right/"")*var*right+other )^0 )
local stripper_1=lpeg.stripper ("{}@")
local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
local function splitpathexpr(str,newlist,validate)
- if trace_expansions then
- report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
+ if trace_expansions then
+ report_expansions("expanding variable %a",str)
+ end
+ local t,ok,done=newlist or {},false,false
+ local n=#t
+ str=lpegmatch(replacer_1,str)
+ repeat
+ local old=str
repeat
- local old=str
- repeat
- local old=str
- str=lpegmatch(l_first,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_second,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_both,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_rest,str)
- until old==str
- until old==str
- str=lpegmatch(stripper_1,str)
- if validate then
- for s in gmatch(str,"[^,]+") do
- s=validate(s)
- if s then
- n=n+1
- t[n]=s
- end
- end
- else
- for s in gmatch(str,"[^,]+") do
- n=n+1
- t[n]=s
- end
+ local old=str
+ str=lpegmatch(l_first,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_second,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_both,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_rest,str)
+ until old==str
+ until old==str
+ str=lpegmatch(stripper_1,str)
+ if validate then
+ for s in gmatch(str,"[^,]+") do
+ s=validate(s)
+ if s then
+ n=n+1
+ t[n]=s
+ end
end
- if trace_expansions then
- for k=1,#t do
- report_expansions("% 4i: %s",k,t[k])
- end
+ else
+ for s in gmatch(str,"[^,]+") do
+ n=n+1
+ t[n]=s
end
- return t
+ end
+ if trace_expansions then
+ for k=1,#t do
+ report_expansions("% 4i: %s",k,t[k])
+ end
+ end
+ return t
end
local function validate(s)
- s=collapsepath(s)
- return s~="" and not find(s,"^!*unset/*$") and s
+ s=collapsepath(s)
+ return s~="" and not find(s,"^!*unset/*$") and s
end
resolvers.validatedpath=validate
function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
- splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
+ local newlist={}
+ for k=1,#pathlist do
+ splitpathexpr(pathlist[k],newlist,validate)
+ end
+ return newlist
end
local usedhomedir=nil
-local donegation=(P("!")/"" )^0
+local donegation=(P("!")/"" )^0
local doslashes=(P("\\")/"/"+1)^0
local function expandedhome()
- if not usedhomedir then
- usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
- if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
- if trace_expansions then
- report_expansions("no home dir set, ignoring dependent path using current path")
- end
- usedhomedir="."
- end
+ if not usedhomedir then
+ usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
+ if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
+ if trace_expansions then
+ report_expansions("no home dir set, ignoring dependent path using current path")
+ end
+ usedhomedir="."
end
- return usedhomedir
+ end
+ return usedhomedir
end
local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
local cleanup=Cs(donegation*dohome*doslashes)
resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
+ return str and lpegmatch(cleanup,str) or ""
end
local expandhome=P("~")/"$HOME"
local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1 )^0
+local dostring=(expandhome+1 )^0
local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
+ lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
)
function resolvers.checkedvariable(str)
- return type(str)=="string" and lpegmatch(stripper,str) or str
+ return type(str)=="string" and lpegmatch(stripper,str) or str
end
local cache={}
local splitter=lpeg.tsplitat(";")
local backslashswapper=lpeg.replacer("\\","/")
local function splitconfigurationpath(str)
- if str then
- local found=cache[str]
- if not found then
- if str=="" then
- found={}
- else
- local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
- found={}
- local noffound=0
- for i=1,#split do
- local s=split[i]
- if not find(s,"^{*unset}*") then
- noffound=noffound+1
- found[noffound]=s
- end
- end
- if trace_expansions then
- report_expansions("splitting path specification %a",str)
- for k=1,noffound do
- report_expansions("% 4i: %s",k,found[k])
- end
- end
- cache[str]=found
- end
+ if str then
+ local found=cache[str]
+ if not found then
+ if str=="" then
+ found={}
+ else
+ local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
+ found={}
+ local noffound=0
+ for i=1,#split do
+ local s=split[i]
+ if not find(s,"^{*unset}*") then
+ noffound=noffound+1
+ found[noffound]=s
+ end
end
- return found
+ if trace_expansions then
+ report_expansions("splitting path specification %a",str)
+ for k=1,noffound do
+ report_expansions("% 4i: %s",k,found[k])
+ end
+ end
+ cache[str]=found
+ end
end
+ return found
+ end
end
resolvers.splitconfigurationpath=splitconfigurationpath
function resolvers.splitpath(str)
- if type(str)=='table' then
- return str
- else
- return splitconfigurationpath(str)
- end
+ if type(str)=='table' then
+ return str
+ else
+ return splitconfigurationpath(str)
+ end
end
function resolvers.joinpath(str)
- if type(str)=='table' then
- return joinpath(str)
- else
- return str
- end
+ if type(str)=='table' then
+ return joinpath(str)
+ else
+ return str
+ end
end
local attributes,directory=lfs.attributes,lfs.dir
local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
@@ -16719,201 +20293,201 @@ local fullcache={}
local nofsharedscans=0
local addcasecraptoo=true
local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name in directory(full) do
- if not lpegmatch(pattern,name) then
- local mode=attributes(full..name,"mode")
- if mode=="file" then
- n=n+1
- noffiles=noffiles+1
- filelist[noffiles]=name
- elseif mode=="directory" then
- m=m+1
- nofdirs=nofdirs+1
- if path~="" then
- dirlist[nofdirs]=path.."/"..name
- else
- dirlist[nofdirs]=name
- end
- end
+ local full=path=="" and spec or (spec..path..'/')
+ local dirlist={}
+ local nofdirs=0
+ local pattern=tolerant and lessweird or weird
+ local filelist={}
+ local noffiles=0
+ for name in directory(full) do
+ if not lpegmatch(pattern,name) then
+ local mode=attributes(full..name,"mode")
+ if mode=="file" then
+ n=n+1
+ noffiles=noffiles+1
+ filelist[noffiles]=name
+ elseif mode=="directory" then
+ m=m+1
+ nofdirs=nofdirs+1
+ if path~="" then
+ dirlist[nofdirs]=path.."/"..name
+ else
+ dirlist[nofdirs]=name
end
+ end
end
- if noffiles>0 then
- sort(filelist)
- for i=1,noffiles do
- local name=filelist[i]
- local lower=lower(name)
- local paths=files[lower]
- if paths then
- if onlyone then
- else
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- if addcasecraptoo then
- local paths=files[name]
- if not paths then
- files[name]=path
- elseif type(paths)=="string" then
- files[name]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- end
- if type(paths)=="string" then
- files[lower]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- else
- files[lower]=path
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- end
+ end
+ if noffiles>0 then
+ sort(filelist)
+ for i=1,noffiles do
+ local name=filelist[i]
+ local lower=lower(name)
+ local paths=files[lower]
+ if paths then
+ if onlyone then
+ else
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
+ if addcasecraptoo then
+ local paths=files[name]
+ if not paths then
+ files[name]=path
+ elseif type(paths)=="string" then
+ files[name]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
+ end
+ if type(paths)=="string" then
+ files[lower]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
- end
- if nofdirs>0 then
- sort(dirlist)
- for i=1,nofdirs do
- files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
+ else
+ files[lower]=path
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
end
+ end
+ end
+ end
+ if nofdirs>0 then
+ sort(dirlist)
+ for i=1,nofdirs do
+ files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
+ end
+ scancache[sub(full,1,-2)]=files
+ return files,remap,n,m,r
end
function resolvers.scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
- local content=fullcache[realpath]
- if content then
- if trace_locating then
- report_expansions("using cached scan of path %a, branch %a",path,branch or path)
- end
- nofsharedscans=nofsharedscans+1
- return content
- end
- end
- statistics.starttiming(timer)
+ local realpath=resolveprefix(path)
+ if usecache then
+ local content=fullcache[realpath]
+ if content then
+ if trace_locating then
+ report_expansions("using cached scan of path %a, branch %a",path,branch or path)
+ end
+ nofsharedscans=nofsharedscans+1
+ return content
+ end
+ end
+ statistics.starttiming(timer)
+ if trace_locating then
+ report_expansions("scanning path %a, branch %a",path,branch or path)
+ end
+ local content
+ if isdir(realpath) then
+ local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
+ content={
+ metadata={
+ path=path,
+ files=n,
+ directories=m,
+ remappings=r,
+ },
+ files=files,
+ remap=remap,
+ }
if trace_locating then
- report_expansions("scanning path %a, branch %a",path,branch or path)
+ report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
end
- local content
- if isdir(realpath) then
- local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
- content={
- metadata={
- path=path,
- files=n,
- directories=m,
- remappings=r,
- },
- files=files,
- remap=remap,
- }
- if trace_locating then
- report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
- end
- else
- content={
- metadata={
- path=path,
- files=0,
- directories=0,
- remappings=0,
- },
- files={},
- remap={},
- }
- if trace_locating then
- report_expansions("invalid path %a",realpath)
- end
- end
- if usecache then
- scanned[#scanned+1]=realpath
- fullcache[realpath]=content
+ else
+ content={
+ metadata={
+ path=path,
+ files=0,
+ directories=0,
+ remappings=0,
+ },
+ files={},
+ remap={},
+ }
+ if trace_locating then
+ report_expansions("invalid path %a",realpath)
end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
+ end
+ if usecache then
+ scanned[#scanned+1]=realpath
+ fullcache[realpath]=content
+ end
+ nofscans=nofscans+1
+ statistics.stoptiming(timer)
+ return content
end
function resolvers.simplescanfiles(path,branch,usecache)
- return resolvers.scanfiles(path,branch,usecache,true,true)
+ return resolvers.scanfiles(path,branch,usecache,true,true)
end
function resolvers.scandata()
- table.sort(scanned)
- return {
- n=nofscans,
- shared=nofsharedscans,
- time=statistics.elapsedtime(timer),
- paths=scanned,
- }
+ table.sort(scanned)
+ return {
+ n=nofscans,
+ shared=nofsharedscans,
+ time=statistics.elapsedtime(timer),
+ paths=scanned,
+ }
end
function resolvers.get_from_content(content,path,name)
- if not content then
- return
- end
- local files=content.files
- if not files then
- return
- end
- local remap=content.remap
- if not remap then
- return
- end
- if name then
- local used=lower(name)
- return path,remap[used] or used
- else
- local name=path
- local used=lower(name)
- local path=files[used]
- if path then
- return path,remap[used] or used
- end
- end
+ if not content then
+ return
+ end
+ local files=content.files
+ if not files then
+ return
+ end
+ local remap=content.remap
+ if not remap then
+ return
+ end
+ if name then
+ local used=lower(name)
+ return path,remap[used] or used
+ else
+ local name=path
+ local used=lower(name)
+ local path=files[used]
+ if path then
+ return path,remap[used] or used
+ end
+ end
end
local nothing=function() end
function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
- local pattern=lower(pattern)
- local files=content.files
- local remap=content.remap
- if files and remap then
- local f=sortedkeys(files)
- local n=#f
- local i=0
- local function iterator()
- while i<n do
- i=i+1
- local k=f[i]
- if find(k,pattern) then
- return files[k],remap and remap[k] or k
- end
- end
- end
- return iterator
+ if content and type(pattern)=="string" then
+ local pattern=lower(pattern)
+ local files=content.files
+ local remap=content.remap
+ if files and remap then
+ local f=sortedkeys(files)
+ local n=#f
+ local i=0
+ local function iterator()
+ while i<n do
+ i=i+1
+ local k=f[i]
+ if find(k,pattern) then
+ return files[k],remap and remap[k] or k
+ end
end
+ end
+ return iterator
end
- return nothing
+ end
+ return nothing
end
@@ -16923,14 +20497,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9360, stripped down to: 6903
+-- original size: 9360, stripped down to: 6312
if not modules then modules={} end modules ['data-env']={
- 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 lower,gsub=string.lower,string.gsub
local next=next
@@ -16950,255 +20524,255 @@ resolvers.suffixmap=suffixmap
resolvers.usertypes=usertypes
local luasuffixes=utilities.lua.suffixes
local relations=allocate {
- core={
- ofm={
- names={ "ofm","omega font metric","omega font metrics" },
- variable='OFMFONTS',
- suffixes={ 'ofm','tfm' },
- },
- ovf={
- names={ "ovf","omega virtual font","omega virtual fonts" },
- variable='OVFFONTS',
- suffixes={ 'ovf','vf' },
- },
- tfm={
- names={ "tfm","tex font metric","tex font metrics" },
- variable='TFMFONTS',
- suffixes={ 'tfm' },
- },
- vf={
- names={ "vf","virtual font","virtual fonts" },
- variable='VFFONTS',
- suffixes={ 'vf' },
- },
- otf={
- names={ "otf","opentype","opentype font","opentype fonts"},
- variable='OPENTYPEFONTS',
- suffixes={ 'otf' },
- },
- ttf={
- names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
- variable='TTFONTS',
- suffixes={ 'ttf','ttc','dfont' },
- },
- afm={
- names={ "afm","adobe font metric","adobe font metrics" },
- variable="AFMFONTS",
- suffixes={ "afm" },
- },
- pfb={
- names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
- variable='T1FONTS',
- suffixes={ 'pfb','pfa' },
- },
- fea={
- names={ "fea","font feature","font features","font feature file","font feature files" },
- variable='FONTFEATURES',
- suffixes={ 'fea' },
- },
- cid={
- names={ "cid","cid map","cid maps","cid file","cid files" },
- variable='FONTCIDMAPS',
- suffixes={ 'cid','cidmap' },
- },
- fmt={
- names={ "fmt","format","tex format" },
- variable='TEXFORMATS',
- suffixes={ 'fmt' },
- },
- mem={
- names={ 'mem',"metapost format" },
- variable='MPMEMS',
- suffixes={ 'mem' },
- },
- mp={
- names={ "mp" },
- variable='MPINPUTS',
- suffixes={ 'mp','mpvi','mpiv','mpii' },
- usertype=true,
- },
- tex={
- names={ "tex" },
- variable='TEXINPUTS',
- suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
- usertype=true,
- },
- icc={
- names={ "icc","icc profile","icc profiles" },
- variable='ICCPROFILES',
- suffixes={ 'icc' },
- },
- texmfscripts={
- names={ "texmfscript","texmfscripts","script","scripts" },
- variable='TEXMFSCRIPTS',
- suffixes={ 'lua','rb','pl','py' },
- },
- lua={
- names={ "lua" },
- variable='LUAINPUTS',
- suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
- usertype=true,
- },
- lib={
- names={ "lib" },
- variable='CLUAINPUTS',
- suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
- },
- bib={
- names={ 'bib' },
- variable='BIBINPUTS',
- suffixes={ 'bib' },
- usertype=true,
- },
- bst={
- names={ 'bst' },
- variable='BSTINPUTS',
- suffixes={ 'bst' },
- usertype=true,
- },
- fontconfig={
- names={ 'fontconfig','fontconfig file','fontconfig files' },
- variable='FONTCONFIG_PATH',
- },
- pk={
- names={ "pk" },
- variable='PKFONTS',
- suffixes={ 'pk' },
- },
+ core={
+ ofm={
+ names={ "ofm","omega font metric","omega font metrics" },
+ variable='OFMFONTS',
+ suffixes={ 'ofm','tfm' },
+ },
+ ovf={
+ names={ "ovf","omega virtual font","omega virtual fonts" },
+ variable='OVFFONTS',
+ suffixes={ 'ovf','vf' },
+ },
+ tfm={
+ names={ "tfm","tex font metric","tex font metrics" },
+ variable='TFMFONTS',
+ suffixes={ 'tfm' },
+ },
+ vf={
+ names={ "vf","virtual font","virtual fonts" },
+ variable='VFFONTS',
+ suffixes={ 'vf' },
+ },
+ otf={
+ names={ "otf","opentype","opentype font","opentype fonts"},
+ variable='OPENTYPEFONTS',
+ suffixes={ 'otf' },
+ },
+ ttf={
+ names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
+ variable='TTFONTS',
+ suffixes={ 'ttf','ttc','dfont' },
+ },
+ afm={
+ names={ "afm","adobe font metric","adobe font metrics" },
+ variable="AFMFONTS",
+ suffixes={ "afm" },
+ },
+ pfb={
+ names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
+ variable='T1FONTS',
+ suffixes={ 'pfb','pfa' },
+ },
+ fea={
+ names={ "fea","font feature","font features","font feature file","font feature files" },
+ variable='FONTFEATURES',
+ suffixes={ 'fea' },
+ },
+ cid={
+ names={ "cid","cid map","cid maps","cid file","cid files" },
+ variable='FONTCIDMAPS',
+ suffixes={ 'cid','cidmap' },
+ },
+ fmt={
+ names={ "fmt","format","tex format" },
+ variable='TEXFORMATS',
+ suffixes={ 'fmt' },
+ },
+ mem={
+ names={ 'mem',"metapost format" },
+ variable='MPMEMS',
+ suffixes={ 'mem' },
+ },
+ mp={
+ names={ "mp" },
+ variable='MPINPUTS',
+ suffixes={ 'mp','mpvi','mpiv','mpii' },
+ usertype=true,
+ },
+ tex={
+ names={ "tex" },
+ variable='TEXINPUTS',
+ suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
+ usertype=true,
+ },
+ icc={
+ names={ "icc","icc profile","icc profiles" },
+ variable='ICCPROFILES',
+ suffixes={ 'icc' },
+ },
+ texmfscripts={
+ names={ "texmfscript","texmfscripts","script","scripts" },
+ variable='TEXMFSCRIPTS',
+ suffixes={ 'lua','rb','pl','py' },
+ },
+ lua={
+ names={ "lua" },
+ variable='LUAINPUTS',
+ suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
+ usertype=true,
},
- obsolete={
- enc={
- names={ "enc","enc files","enc file","encoding files","encoding file" },
- variable='ENCFONTS',
- suffixes={ 'enc' },
- },
- map={
- names={ "map","map files","map file" },
- variable='TEXFONTMAPS',
- suffixes={ 'map' },
- },
- lig={
- names={ "lig files","lig file","ligature file","ligature files" },
- variable='LIGFONTS',
- suffixes={ 'lig' },
- },
- opl={
- names={ "opl" },
- variable='OPLFONTS',
- suffixes={ 'opl' },
- },
- ovp={
- names={ "ovp" },
- variable='OVPFONTS',
- suffixes={ 'ovp' },
- },
+ lib={
+ names={ "lib" },
+ variable='CLUAINPUTS',
+ suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
},
- kpse={
- base={
- names={ 'base',"metafont format" },
- variable='MFBASES',
- suffixes={ 'base','bas' },
- },
- cmap={
- names={ 'cmap','cmap files','cmap file' },
- variable='CMAPFONTS',
- suffixes={ 'cmap' },
- },
- cnf={
- names={ 'cnf' },
- suffixes={ 'cnf' },
- },
- web={
- names={ 'web' },
- suffixes={ 'web','ch' }
- },
- cweb={
- names={ 'cweb' },
- suffixes={ 'w','web','ch' },
- },
- gf={
- names={ 'gf' },
- suffixes={ '<resolution>gf' },
- },
- mf={
- names={ 'mf' },
- variable='MFINPUTS',
- suffixes={ 'mf' },
- },
- mft={
- names={ 'mft' },
- suffixes={ 'mft' },
- },
- pk={
- names={ 'pk' },
- suffixes={ '<resolution>pk' },
- },
+ bib={
+ names={ 'bib' },
+ variable='BIBINPUTS',
+ suffixes={ 'bib' },
+ usertype=true,
},
+ bst={
+ names={ 'bst' },
+ variable='BSTINPUTS',
+ suffixes={ 'bst' },
+ usertype=true,
+ },
+ fontconfig={
+ names={ 'fontconfig','fontconfig file','fontconfig files' },
+ variable='FONTCONFIG_PATH',
+ },
+ pk={
+ names={ "pk" },
+ variable='PKFONTS',
+ suffixes={ 'pk' },
+ },
+ },
+ obsolete={
+ enc={
+ names={ "enc","enc files","enc file","encoding files","encoding file" },
+ variable='ENCFONTS',
+ suffixes={ 'enc' },
+ },
+ map={
+ names={ "map","map files","map file" },
+ variable='TEXFONTMAPS',
+ suffixes={ 'map' },
+ },
+ lig={
+ names={ "lig files","lig file","ligature file","ligature files" },
+ variable='LIGFONTS',
+ suffixes={ 'lig' },
+ },
+ opl={
+ names={ "opl" },
+ variable='OPLFONTS',
+ suffixes={ 'opl' },
+ },
+ ovp={
+ names={ "ovp" },
+ variable='OVPFONTS',
+ suffixes={ 'ovp' },
+ },
+ },
+ kpse={
+ base={
+ names={ 'base',"metafont format" },
+ variable='MFBASES',
+ suffixes={ 'base','bas' },
+ },
+ cmap={
+ names={ 'cmap','cmap files','cmap file' },
+ variable='CMAPFONTS',
+ suffixes={ 'cmap' },
+ },
+ cnf={
+ names={ 'cnf' },
+ suffixes={ 'cnf' },
+ },
+ web={
+ names={ 'web' },
+ suffixes={ 'web','ch' }
+ },
+ cweb={
+ names={ 'cweb' },
+ suffixes={ 'w','web','ch' },
+ },
+ gf={
+ names={ 'gf' },
+ suffixes={ '<resolution>gf' },
+ },
+ mf={
+ names={ 'mf' },
+ variable='MFINPUTS',
+ suffixes={ 'mf' },
+ },
+ mft={
+ names={ 'mft' },
+ suffixes={ 'mft' },
+ },
+ pk={
+ names={ 'pk' },
+ suffixes={ '<resolution>pk' },
+ },
+ },
}
resolvers.relations=relations
function resolvers.updaterelations()
- for category,categories in next,relations do
- for name,relation in next,categories do
- local rn=relation.names
- local rv=relation.variable
- if rn and rv then
- local rs=relation.suffixes
- local ru=relation.usertype
- for i=1,#rn do
- local rni=lower(gsub(rn[i]," ",""))
- formats[rni]=rv
- if rs then
- suffixes[rni]=rs
- for i=1,#rs do
- local rsi=rs[i]
- suffixmap[rsi]=rni
- end
- end
- end
- if ru then
- usertypes[name]=true
- end
+ for category,categories in next,relations do
+ for name,relation in next,categories do
+ local rn=relation.names
+ local rv=relation.variable
+ if rn and rv then
+ local rs=relation.suffixes
+ local ru=relation.usertype
+ for i=1,#rn do
+ local rni=lower(gsub(rn[i]," ",""))
+ formats[rni]=rv
+ if rs then
+ suffixes[rni]=rs
+ for i=1,#rs do
+ local rsi=rs[i]
+ suffixmap[rsi]=rni
end
+ end
+ end
+ if ru then
+ usertypes[name]=true
end
+ end
end
+ end
end
resolvers.updaterelations()
local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
+ return k and rawget(t,lower(gsub(k," ",""))) or nil
end
setmetatableindex(formats,simplified)
setmetatableindex(suffixes,simplified)
setmetatableindex(suffixmap,simplified)
function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
+ local s=suffixes[str]
+ return s and s[1] or ""
end
function resolvers.suffixofformat(str)
- return suffixes[str] or {}
+ return suffixes[str] or {}
end
for name,format in next,formats do
- dangerous[name]=true
+ dangerous[name]=true
end
dangerous.tex=nil
function resolvers.formatofvariable(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.formatofsuffix(str)
- return suffixmap[suffixonly(str)] or 'tex'
+ return suffixmap[suffixonly(str)] or 'tex'
end
function resolvers.variableofformat(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
- return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
- return formats[v]
- end
- return ''
+ local v=formats[str]
+ if v then
+ return v
+ end
+ v=suffixmap[suffixonly(str)]
+ if v then
+ return formats[v]
+ end
+ return ''
end
@@ -17208,14 +20782,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16116, stripped down to: 11459
+-- original size: 16116, stripped down to: 10782
if not modules then modules={} end modules ['data-tmp']={
- 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,concat=string.format,string.lower,string.gsub,table.concat
local concat=table.concat
@@ -17223,19 +20797,19 @@ local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
local next,type=next,type
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
local report_resolvers=logs.reporter("resolvers","caching")
local resolvers=resolvers
local cleanpath=resolvers.cleanpath
-local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
-local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
+local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
+local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
local compile=utilities.lua.compile
function utilities.lua.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip end
- return compile(luafile,lucfile,cleanup,strip)
+ if cleanup==nil then cleanup=directive_cleanup end
+ if strip==nil then strip=directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
end
caches=caches or {}
local caches=caches
@@ -17250,324 +20824,324 @@ caches.relocate=false
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local writable,readables,usedreadables=nil,{},{}
local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- cachepath=file.collapsepath(cachepath)
- local valid=isdir(cachepath)
- if valid then
- if is_readable(cachepath) then
- readables[#readables+1]=cachepath
- if not writable and is_writable(cachepath) then
- writable=cachepath
- end
- end
- elseif not writable and caches.force then
- local cacheparent=file.dirname(cachepath)
- if is_writable(cacheparent) and true then
- if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
- mkdirs(cachepath)
- if isdir(cachepath) and is_writable(cachepath) then
- report_caches("path %a created",cachepath)
- writable=cachepath
- readables[#readables+1]=cachepath
- end
- end
- end
- end
+ local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ cachepath=file.collapsepath(cachepath)
+ local valid=isdir(cachepath)
+ if valid then
+ if is_readable(cachepath) then
+ readables[#readables+1]=cachepath
+ if not writable and is_writable(cachepath) then
+ writable=cachepath
end
- end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- cachepath=resolvers.expansion(cachepath)
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- local valid=isdir(cachepath)
- if valid and is_readable(cachepath) then
- if not writable and is_writable(cachepath) then
- readables[#readables+1]=cachepath
- writable=cachepath
- break
- end
- end
+ end
+ elseif not writable and caches.force then
+ local cacheparent=file.dirname(cachepath)
+ if is_writable(cacheparent) and true then
+ if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
+ mkdirs(cachepath)
+ if isdir(cachepath) and is_writable(cachepath) then
+ report_caches("path %a created",cachepath)
+ writable=cachepath
+ readables[#readables+1]=cachepath
+ end
end
+ end
end
+ end
end
- if not writable then
- report_caches("fatal error: there is no valid writable cache path defined")
- os.exit()
- elseif #readables==0 then
- report_caches("fatal error: there is no valid readable cache path defined")
- os.exit()
- end
- writable=dir.expandname(resolvers.cleanpath(writable))
- local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
- if tree then
- caches.tree=tree
- writable=mkdirs(writable,base,more,tree)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more,tree)
- end
- else
- writable=mkdirs(writable,base,more)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more)
+ end
+ local texmfcaches=caches.defaults
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ cachepath=resolvers.expansion(cachepath)
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ local valid=isdir(cachepath)
+ if valid and is_readable(cachepath) then
+ if not writable and is_writable(cachepath) then
+ readables[#readables+1]=cachepath
+ writable=cachepath
+ break
+ end
end
+ end
end
- if trace_cache then
- for i=1,#readables do
- report_caches("using readable path %a (order %s)",readables[i],i)
- end
- report_caches("using writable path %a",writable)
+ end
+ if not writable then
+ report_caches("fatal error: there is no valid writable cache path defined")
+ os.exit()
+ elseif #readables==0 then
+ report_caches("fatal error: there is no valid readable cache path defined")
+ os.exit()
+ end
+ writable=dir.expandname(resolvers.cleanpath(writable))
+ local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
+ if tree then
+ caches.tree=tree
+ writable=mkdirs(writable,base,more,tree)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more,tree)
end
- identify=function()
- return writable,readables
+ else
+ writable=mkdirs(writable,base,more)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more)
end
+ end
+ if trace_cache then
+ for i=1,#readables do
+ report_caches("using readable path %a (order %s)",readables[i],i)
+ end
+ report_caches("using writable path %a",writable)
+ end
+ identify=function()
return writable,readables
+ end
+ return writable,readables
end
function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
- local result={}
- local done={}
- for i=1,#readables do
- local readable=readables[i]
- if readable==writable then
- done[readable]=true
- result[#result+1]=formatters["readable+writable: %a"](readable)
- elseif usedreadables[i] then
- done[readable]=true
- result[#result+1]=formatters["readable: %a"](readable)
- end
- end
- if not done[writable] then
- result[#result+1]=formatters["writable: %a"](writable)
- end
- return concat(result,separator or " | ")
- else
- return writable or "?"
+ local writable,readables=identify()
+ if #readables>1 then
+ local result={}
+ local done={}
+ for i=1,#readables do
+ local readable=readables[i]
+ if readable==writable then
+ done[readable]=true
+ result[#result+1]=formatters["readable+writable: %a"](readable)
+ elseif usedreadables[i] then
+ done[readable]=true
+ result[#result+1]=formatters["readable: %a"](readable)
+ end
end
+ if not done[writable] then
+ result[#result+1]=formatters["writable: %a"](writable)
+ end
+ return concat(result,separator or " | ")
+ else
+ return writable or "?"
+ end
end
function caches.configfiles()
- return concat(resolvers.configurationfiles(),";")
+ return concat(resolvers.configurationfiles(),";")
end
function caches.hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5.hex(tree)
- if trace_cache or trace_locating then
- report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
+ tree=gsub(tree,"[\\/]+$","")
+ tree=lower(tree)
+ local hash=md5.hex(tree)
+ if trace_cache or trace_locating then
+ report_caches("hashing tree %a, hash %a",tree,hash)
+ end
+ return hash
end
function caches.treehash()
- local tree=caches.configfiles()
- if not tree or tree=="" then
- return false
- else
- return caches.hashed(tree)
- end
+ local tree=caches.configfiles()
+ if not tree or tree=="" then
+ return false
+ else
+ return caches.hashed(tree)
+ end
end
local r_cache,w_cache={},{}
local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done={}
- for i=1,#readables do
- done[i]=file.join(readables[i],...)
- end
- else
- done=readables
- end
- r_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=r_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done={}
+ for i=1,#readables do
+ done[i]=file.join(readables[i],...)
+ end
+ else
+ done=readables
end
- return done
+ r_cache[hash]=done
+ end
+ return done
end
local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done=mkdirs(writable,...)
- else
- done=writable
- end
- w_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=w_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done=mkdirs(writable,...)
+ else
+ done=writable
end
- return done
+ w_cache[hash]=done
+ end
+ return done
end
caches.getreadablepaths=getreadablepaths
caches.getwritablepath=getwritablepath
function caches.getfirstreadablefile(filename,...)
- local fullname,path=caches.setfirstwritablefile(filename,...)
+ local fullname,path=caches.setfirstwritablefile(filename,...)
+ if is_readable(fullname) then
+ return fullname,path
+ end
+ local rd=getreadablepaths(...)
+ for i=1,#rd do
+ local path=rd[i]
+ local fullname=file.join(path,filename)
if is_readable(fullname) then
- return fullname,path
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
- local path=rd[i]
- local fullname=file.join(path,filename)
- if is_readable(fullname) then
- usedreadables[i]=true
- return fullname,path
- end
+ usedreadables[i]=true
+ return fullname,path
end
- return fullname,path
+ end
+ return fullname,path
end
function caches.setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=file.join(wr,filename)
- return fullname,wr
+ local wr=getwritablepath(...)
+ local fullname=file.join(wr,filename)
+ return fullname,wr
end
function caches.define(category,subcategory)
- return function()
- return getwritablepath(category,subcategory)
- end
+ return function()
+ return getwritablepath(category,subcategory)
+ end
end
function caches.setluanames(path,name)
- return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
+ return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
end
function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
- readables={ readables }
+ if type(readables)=="string" then
+ readables={ readables }
+ end
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local tmaname,tmcname=caches.setluanames(path,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader and isfile(tmaname) then
+ local tmacrap,tmcname=caches.setluanames(writable,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ utilities.lua.compile(tmaname,tmcname)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader then
+ loader=loadfile(tmaname)
+ end
end
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local tmaname,tmcname=caches.setluanames(path,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader and isfile(tmaname) then
- local tmacrap,tmcname=caches.setluanames(writable,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- utilities.lua.compile(tmaname,tmcname)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader then
- loader=loadfile(tmaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
end
- return false
+ end
+ return false
end
function caches.is_writable(filepath,filename)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- return is_writable(tmaname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ return is_writable(tmaname)
end
local saveoptions={ compact=true }
function caches.savedata(filepath,filename,data,raw)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- data.cache_uuid=os.uuid()
- if caches.direct then
- file.savedata(tmaname,table.serialize(data,true,saveoptions))
- else
- table.tofile(tmaname,data,true,saveoptions)
- end
- utilities.lua.compile(tmaname,tmcname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ data.cache_uuid=os.uuid()
+ if caches.direct then
+ file.savedata(tmaname,table.serialize(data,true,saveoptions))
+ else
+ table.tofile(tmaname,data,true,saveoptions)
+ end
+ utilities.lua.compile(tmaname,tmcname)
end
local content_state={}
function caches.contentstate()
- return content_state or {}
+ return content_state or {}
end
function caches.loadcontent(cachename,dataname,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
- if blob then
- local data=blob()
- if data and data.content then
- if data.type==dataname then
- if data.version==resolvers.cacheversion then
- content_state[#content_state+1]=data.uuid
- if trace_locating then
- report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
- end
- return data.content
- else
- report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
- end
- else
- report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
+ if blob then
+ local data=blob()
+ if data and data.content then
+ if data.type==dataname then
+ if data.version==resolvers.cacheversion then
+ content_state[#content_state+1]=data.uuid
+ if trace_locating then
+ report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
+ end
+ return data.content
+ else
+ report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
end
+ else
+ report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
+ end
elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
end
+ elseif trace_locating then
+ report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ end
end
function caches.collapsecontent(content)
- for k,v in next,content do
- if type(v)=="table" and #v==1 then
- content[k]=v[1]
- end
+ for k,v in next,content do
+ if type(v)=="table" and #v==1 then
+ content[k]=v[1]
end
+ end
end
function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local luaname=addsuffix(filename,luasuffixes.lua)
+ local lucname=addsuffix(filename,luasuffixes.luc)
+ if trace_locating then
+ report_resolvers("preparing %a for %a",dataname,cachename)
+ end
+ local data={
+ type=dataname,
+ root=cachename,
+ version=resolvers.cacheversion,
+ date=os.date("%Y-%m-%d"),
+ time=os.date("%H:%M:%S"),
+ content=content,
+ uuid=os.uuid(),
+ }
+ local ok=io.savedata(luaname,table.serialize(data,true))
+ if ok then
if trace_locating then
- report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
- type=dataname,
- root=cachename,
- version=resolvers.cacheversion,
- date=os.date("%Y-%m-%d"),
- time=os.date("%H:%M:%S"),
- content=content,
- uuid=os.uuid(),
- }
- local ok=io.savedata(luaname,table.serialize(data,true))
- if ok then
- if trace_locating then
- report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
- end
- if utilities.lua.compile(luaname,lucname) then
- if trace_locating then
- report_resolvers("%a compiled to %a",dataname,lucname)
- end
- return true
- else
- if trace_locating then
- report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
- end
- os.remove(lucname)
- end
- elseif trace_locating then
- report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
+ end
+ if utilities.lua.compile(luaname,lucname) then
+ if trace_locating then
+ report_resolvers("%a compiled to %a",dataname,lucname)
+ end
+ return true
+ else
+ if trace_locating then
+ report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
+ end
+ os.remove(lucname)
end
+ elseif trace_locating then
+ report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ end
end
@@ -17577,14 +21151,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-met"] = package.loaded["data-met"] or true
--- original size: 5310, stripped down to: 3980
+-- original size: 5310, stripped down to: 3784
if not modules then modules={} end modules ['data-met']={
- 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 find,format=string.find,string.format
local sequenced=table.sequenced
@@ -17598,86 +21172,86 @@ local allocate=utilities.storage.allocate
local resolvers=resolvers
local registered={}
local function splitmethod(filename)
- if not filename then
- return { scheme="unknown",original=filename }
- end
- if type(filename)=="table" then
- return filename
- end
- filename=file.collapsepath(filename,".")
- if not find(filename,"://",1,true) then
- return { scheme="file",path=filename,original=filename,filename=filename }
- end
- local specification=url.hashed(filename)
- if not specification.scheme or specification.scheme=="" then
- return { scheme="file",path=filename,original=filename,filename=filename }
- else
- return specification
- end
+ if not filename then
+ return { scheme="unknown",original=filename }
+ end
+ if type(filename)=="table" then
+ return filename
+ end
+ filename=file.collapsepath(filename,".")
+ if not find(filename,"://",1,true) then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ end
+ local specification=url.hashed(filename)
+ if not specification.scheme or specification.scheme=="" then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ else
+ return specification
+ end
end
resolvers.splitmethod=splitmethod
local function methodhandler(what,first,...)
- local method=registered[what]
- if method then
- local how,namespace=method.how,method.namespace
- if how=="uri" or how=="url" then
- local specification=splitmethod(first)
- local scheme=specification.scheme
- local resolver=namespace and namespace[scheme]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
- end
- return resolver(specification,...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
- end
- return resolver(specification,...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
- end
- end
- elseif how=="tag" then
- local resolver=namespace and namespace[first]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,first)
- end
- return resolver(...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
- end
- return resolver(...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
- end
- end
+ local method=registered[what]
+ if method then
+ local how,namespace=method.how,method.namespace
+ if how=="uri" or how=="url" then
+ local specification=splitmethod(first)
+ local scheme=specification.scheme
+ local resolver=namespace and namespace[scheme]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+ end
+ return resolver(specification,...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
+ end
+ return resolver(specification,...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
end
- else
- report_methods("resolving, invalid method %a")
+ end
+ elseif how=="tag" then
+ local resolver=namespace and namespace[first]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,first)
+ end
+ return resolver(...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
+ end
+ return resolver(...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
+ end
+ end
end
+ else
+ report_methods("resolving, invalid method %a")
+ end
end
resolvers.methodhandler=methodhandler
function resolvers.registermethod(name,namespace,how)
- registered[name]={ how=how or "tag",namespace=namespace }
- namespace["byscheme"]=function(scheme,filename,...)
- if scheme=="file" then
- return methodhandler(name,filename,...)
- else
- return methodhandler(name,addurlscheme(filename,scheme),...)
- end
+ registered[name]={ how=how or "tag",namespace=namespace }
+ namespace["byscheme"]=function(scheme,filename,...)
+ if scheme=="file" then
+ return methodhandler(name,filename,...)
+ else
+ return methodhandler(name,addurlscheme(filename,scheme),...)
end
+ end
end
-local concatinators=allocate { notfound=file.join }
-local locators=allocate { notfound=function() end }
-local hashers=allocate { notfound=function() end }
-local generators=allocate { notfound=function() end }
+local concatinators=allocate { notfound=file.join }
+local locators=allocate { notfound=function() end }
+local hashers=allocate { notfound=function() end }
+local generators=allocate { notfound=function() end }
resolvers.concatinators=concatinators
resolvers.locators=locators
resolvers.hashers=hashers
@@ -17695,17 +21269,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-res"] = package.loaded["data-res"] or true
--- original size: 68263, stripped down to: 47789
+-- original size: 68195, stripped down to: 43680
if not modules then modules={} end modules ['data-res']={
- 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 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
local P,S,R,C,Cc,Cs,Ct,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Carg
@@ -17727,11 +21301,11 @@ local isfile=lfs.isfile
local isdir=lfs.isdir
local setmetatableindex=table.setmetatableindex
local luasuffixes=utilities.lua.suffixes
-local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
+local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
+local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
local report_resolving=logs.reporter("resolvers","resolving")
local resolvers=resolvers
local expandedpathfromlist=resolvers.expandedpathfromlist
@@ -17752,15 +21326,15 @@ resolvers.luacnfname="texmfcnf.lua"
resolvers.luacnffallback="contextcnf.lua"
resolvers.luacnfstate="unknown"
if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
+ resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
else
- resolvers.luacnfspec=concat ({
- "home:texmf/web2c",
- "selfautoparent:/texmf-local/web2c",
- "selfautoparent:/texmf-context/web2c",
- "selfautoparent:/texmf-dist/web2c",
- "selfautoparent:/texmf/web2c",
- },";")
+ resolvers.luacnfspec=concat ({
+ "home:texmf/web2c",
+ "selfautoparent:/texmf-local/web2c",
+ "selfautoparent:/texmf-context/web2c",
+ "selfautoparent:/texmf-dist/web2c",
+ "selfautoparent:/texmf/web2c",
+ },";")
end
local unset_variable="unset"
local formats=resolvers.formats
@@ -17771,24 +21345,24 @@ local suffixmap=resolvers.suffixmap
resolvers.defaultsuffixes={ "tex" }
local instance=nil
function resolvers.setenv(key,value,raw)
- if instance then
- instance.environment[key]=value
- ossetenv(key,raw and value or resolveprefix(value))
- end
+ if instance then
+ instance.environment[key]=value
+ ossetenv(key,raw and value or resolveprefix(value))
+ end
end
local function getenv(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
- return value
- else
- local e=osgetenv(key)
- return e~=nil and e~="" and checkedvariable(e) or ""
- end
+ local value=rawget(instance.environment,key)
+ if value and value~="" then
+ return value
+ else
+ local e=osgetenv(key)
+ return e~=nil and e~="" and checkedvariable(e) or ""
+ end
end
resolvers.getenv=getenv
resolvers.env=getenv
local function resolvevariable(k)
- return instance.expansions[k]
+ return instance.expansions[k]
end
local dollarstripper=lpeg.stripper("$")
local inhibitstripper=P("!")^0*Cs(P(1)^0)
@@ -17802,1506 +21376,1506 @@ local somevariable=R("az","AZ","09","__","--")^1/resolvevariable
local variable=(P("$")/"")*(somevariable+(P("{")/"")*somevariable*(P("}")/""))
local variableresolver=Cs((variable+P(1))^0)
local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
+ return lpegmatch(variableexpander,var) or var
end
function resolvers.reset()
- if trace_locating then
- report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
- environment=environment,
- variables=variables,
- expansions=expansions,
- order=order,
- files={},
- setups={},
- found={},
- foundintrees={},
- hashes={},
- hashed={},
- pathlists=false,
- specification={},
- lists={},
- data={},
- fakepaths={},
- remember=true,
- diskcache=true,
- renewcache=false,
- renewtree=false,
- loaderror=false,
- savelists=true,
- pattern=nil,
- force_suffixes=true,
- pathstack={},
- }
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v=order[i][k]
- if v~=nil then
- t[k]=v
- return v
- end
- end
- if v==nil then
- v=""
- end
- t[k]=v
- return v
- end)
- setmetatableindex(environment,function(t,k)
- local v=osgetenv(k)
- if v==nil then
- v=variables[k]
- end
- if v~=nil then
- v=checkedvariable(v) or ""
- end
- v=resolvers.repath(v)
- t[k]=v
- return v
- end)
- setmetatableindex(expansions,function(t,k)
- local v=environment[k]
- if type(v)=="string" then
- v=lpegmatch(variableresolver,v)
- v=lpegmatch(variablecleaner,v)
- end
+ if trace_locating then
+ report_resolving("creating instance")
+ end
+ local environment={}
+ local variables={}
+ local expansions={}
+ local order={}
+ instance={
+ environment=environment,
+ variables=variables,
+ expansions=expansions,
+ order=order,
+ files={},
+ setups={},
+ found={},
+ foundintrees={},
+ hashes={},
+ hashed={},
+ pathlists=false,
+ specification={},
+ lists={},
+ data={},
+ fakepaths={},
+ remember=true,
+ diskcache=true,
+ renewcache=false,
+ renewtree=false,
+ loaderror=false,
+ savelists=true,
+ pattern=nil,
+ force_suffixes=true,
+ pathstack={},
+ }
+ setmetatableindex(variables,function(t,k)
+ local v
+ for i=1,#order do
+ v=order[i][k]
+ if v~=nil then
t[k]=v
return v
- end)
+ end
+ end
+ if v==nil then
+ v=""
+ end
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(environment,function(t,k)
+ local v=osgetenv(k)
+ if v==nil then
+ v=variables[k]
+ end
+ if v~=nil then
+ v=checkedvariable(v) or ""
+ end
+ v=resolvers.repath(v)
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(expansions,function(t,k)
+ local v=environment[k]
+ if type(v)=="string" then
+ v=lpegmatch(variableresolver,v)
+ v=lpegmatch(variablecleaner,v)
+ end
+ t[k]=v
+ return v
+ end)
end
function resolvers.initialized()
- return instance~=nil
+ return instance~=nil
end
local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
+ instance.lists={}
+ instance.pathlists=false
+ instance.found={}
end
local function reset_caches()
- instance.lists={}
- instance.pathlists=false
+ instance.lists={}
+ instance.pathlists=false
end
local slash=P("/")
local pathexpressionpattern=Cs (
- Cc("^")*(
- Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+ Cc("^")*(
+ Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$")
+ )^1*Cc("$")
)
local cache={}
local function makepathexpression(str)
- if str=="." then
- return "^%./$"
- else
- local c=cache[str]
- if not c then
- c=lpegmatch(pathexpressionpattern,str)
- cache[str]=c
- end
- return c
+ if str=="." then
+ return "^%./$"
+ else
+ local c=cache[str]
+ if not c then
+ c=lpegmatch(pathexpressionpattern,str)
+ cache[str]=c
end
+ return c
+ end
end
local function reportcriticalvariables(cnfspec)
- if trace_locating then
- for i=1,#resolvers.criticalvars do
- local k=resolvers.criticalvars[i]
- local v=resolvers.getenv(k) or "unknown"
- report_resolving("variable %a set to %a",k,v)
- end
- report_resolving()
- if cnfspec then
- report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
- end
- report_resolving()
+ if trace_locating then
+ for i=1,#resolvers.criticalvars do
+ local k=resolvers.criticalvars[i]
+ local v=resolvers.getenv(k) or "unknown"
+ report_resolving("variable %a set to %a",k,v)
+ end
+ report_resolving()
+ if cnfspec then
+ report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
end
- reportcriticalvariables=function() end
+ report_resolving()
+ end
+ reportcriticalvariables=function() end
end
local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
- local cnfspec=getenv("TEXMFCNF")
- if cnfspec=="" then
- cnfspec=resolvers.luacnfspec
- resolvers.luacnfstate="default"
- else
- resolvers.luacnfstate="environment"
- end
- reportcriticalvariables(cnfspec)
- local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
- local function locatecnf(luacnfname,kind)
- for i=1,#cnfpaths do
- local filepath=cnfpaths[i]
- local filename=collapsepath(filejoin(filepath,luacnfname))
- local realname=resolveprefix(filename)
- if trace_locating then
- local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
- local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
- report_resolving("looking for %s %a on %s path %a from specification %a",
- kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
- end
- if isfile(realname) then
- specification[#specification+1]=filename
- if trace_locating then
- report_resolving("found %s configuration file %a",kind,realname)
- end
- end
- end
- end
- locatecnf(resolvers.luacnfname,"regular")
- if #specification==0 then
- locatecnf(resolvers.luacnffallback,"fallback")
- end
+ local specification=instance.specification
+ if #specification==0 then
+ local cnfspec=getenv("TEXMFCNF")
+ if cnfspec=="" then
+ cnfspec=resolvers.luacnfspec
+ resolvers.luacnfstate="default"
+ else
+ resolvers.luacnfstate="environment"
+ end
+ reportcriticalvariables(cnfspec)
+ local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
+ local function locatecnf(luacnfname,kind)
+ for i=1,#cnfpaths do
+ local filepath=cnfpaths[i]
+ local filename=collapsepath(filejoin(filepath,luacnfname))
+ local realname=resolveprefix(filename)
if trace_locating then
- report_resolving()
+ local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
+ local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
+ report_resolving("looking for %s %a on %s path %a from specification %a",
+ kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+ end
+ if isfile(realname) then
+ specification[#specification+1]=filename
+ if trace_locating then
+ report_resolving("found %s configuration file %a",kind,realname)
+ end
end
- elseif trace_locating then
- report_resolving("configuration files already identified")
+ end
+ end
+ locatecnf(resolvers.luacnfname,"regular")
+ if #specification==0 then
+ locatecnf(resolvers.luacnffallback,"fallback")
+ end
+ if trace_locating then
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("configuration files already identified")
+ end
end
local function load_configuration_files()
- local specification=instance.specification
- if #specification>0 then
- local luacnfname=resolvers.luacnfname
- for i=1,#specification do
- local filename=specification[i]
- local pathname=filedirname(filename)
- local filename=filejoin(pathname,luacnfname)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local setups=instance.setups
- local data=blob()
- local parent=data and data.parent
- if parent then
- local filename=filejoin(pathname,parent)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local parentdata=blob()
- if parentdata then
- report_resolving("loading configuration file %a",filename)
- data=table.merged(parentdata,data)
- end
- end
- end
- data=data and data.content
- if data then
- if trace_locating then
- report_resolving("loading configuration file %a",filename)
- report_resolving()
- end
- local variables=data.variables or {}
- local warning=false
- for k,v in next,data do
- local variant=type(v)
- if variant=="table" then
- initializesetter(filename,k,v)
- elseif variables[k]==nil then
- if trace_locating and not warning then
- report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
- k,resolveprefix(filename))
- warning=true
- end
- variables[k]=v
- end
- end
- setups[pathname]=variables
- if resolvers.luacnfstate=="default" then
- local cnfspec=variables["TEXMFCNF"]
- if cnfspec then
- if trace_locating then
- report_resolving("reloading configuration due to TEXMF redefinition")
- end
- resolvers.setenv("TEXMFCNF",cnfspec)
- instance.specification={}
- identify_configuration_files()
- load_configuration_files()
- resolvers.luacnfstate="configuration"
- break
- end
- end
- else
- if trace_locating then
- report_resolving("skipping configuration file %a (no content)",filename)
- end
- setups[pathname]={}
- instance.loaderror=true
- end
- elseif trace_locating then
- report_resolving("skipping configuration file %a (no valid format)",filename)
+ local specification=instance.specification
+ if #specification>0 then
+ local luacnfname=resolvers.luacnfname
+ for i=1,#specification do
+ local filename=specification[i]
+ local pathname=filedirname(filename)
+ local filename=filejoin(pathname,luacnfname)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local setups=instance.setups
+ local data=blob()
+ local parent=data and data.parent
+ if parent then
+ local filename=filejoin(pathname,parent)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local parentdata=blob()
+ if parentdata then
+ report_resolving("loading configuration file %a",filename)
+ data=table.merged(parentdata,data)
end
- instance.order[#instance.order+1]=instance.setups[pathname]
- if instance.loaderror then
- break
+ end
+ end
+ data=data and data.content
+ if data then
+ if trace_locating then
+ report_resolving("loading configuration file %a",filename)
+ report_resolving()
+ end
+ local variables=data.variables or {}
+ local warning=false
+ for k,v in next,data do
+ local variant=type(v)
+ if variant=="table" then
+ initializesetter(filename,k,v)
+ elseif variables[k]==nil then
+ if trace_locating and not warning then
+ report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
+ k,resolveprefix(filename))
+ warning=true
+ end
+ variables[k]=v
+ end
+ end
+ setups[pathname]=variables
+ if resolvers.luacnfstate=="default" then
+ local cnfspec=variables["TEXMFCNF"]
+ if cnfspec then
+ if trace_locating then
+ report_resolving("reloading configuration due to TEXMF redefinition")
+ end
+ resolvers.setenv("TEXMFCNF",cnfspec)
+ instance.specification={}
+ identify_configuration_files()
+ load_configuration_files()
+ resolvers.luacnfstate="configuration"
+ break
end
+ end
+ else
+ if trace_locating then
+ report_resolving("skipping configuration file %a (no content)",filename)
+ end
+ setups[pathname]={}
+ instance.loaderror=true
end
- elseif trace_locating then
- report_resolving("warning: no lua configuration files found")
+ elseif trace_locating then
+ report_resolving("skipping configuration file %a (no valid format)",filename)
+ end
+ instance.order[#instance.order+1]=instance.setups[pathname]
+ if instance.loaderror then
+ break
+ end
end
+ elseif trace_locating then
+ report_resolving("warning: no lua configuration files found")
+ end
end
function resolvers.configurationfiles()
- return instance.specification or {}
+ return instance.specification or {}
end
local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- resolvers.hashers.byscheme(hash.type,hash.name)
- if instance.loaderror then break end
- end
+ instance.loaderror=false
+ instance.files={}
+ if not instance.renewcache then
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ resolvers.hashers.byscheme(hash.type,hash.name)
+ if instance.loaderror then break end
end
+ end
end
local function locate_file_databases()
- local texmfpaths=resolvers.expandedpathlist("TEXMF")
- if #texmfpaths>0 then
- for i=1,#texmfpaths do
- local path=collapsepath(texmfpaths[i])
- path=gsub(path,"/+$","")
- local stripped=lpegmatch(inhibitstripper,path)
- if stripped~="" then
- local runtime=stripped==path
- path=cleanpath(path)
- local spec=resolvers.splitmethod(stripped)
- if runtime and (spec.noscheme or spec.scheme=="file") then
- stripped="tree:///"..stripped
- elseif spec.scheme=="cache" or spec.scheme=="file" then
- stripped=spec.path
- end
- if trace_locating then
- if runtime then
- report_resolving("locating list of %a (runtime) (%s)",path,stripped)
- else
- report_resolving("locating list of %a (cached)",path)
- end
- end
- methodhandler('locators',stripped)
- end
+ local texmfpaths=resolvers.expandedpathlist("TEXMF")
+ if #texmfpaths>0 then
+ for i=1,#texmfpaths do
+ local path=collapsepath(texmfpaths[i])
+ path=gsub(path,"/+$","")
+ local stripped=lpegmatch(inhibitstripper,path)
+ if stripped~="" then
+ local runtime=stripped==path
+ path=cleanpath(path)
+ local spec=resolvers.splitmethod(stripped)
+ if runtime and (spec.noscheme or spec.scheme=="file") then
+ stripped="tree:///"..stripped
+ elseif spec.scheme=="cache" or spec.scheme=="file" then
+ stripped=spec.path
end
if trace_locating then
- report_resolving()
+ if runtime then
+ report_resolving("locating list of %a (runtime) (%s)",path,stripped)
+ else
+ report_resolving("locating list of %a (cached)",path)
+ end
end
- elseif trace_locating then
- report_resolving("no texmf paths are defined (using TEXMF)")
- end
-end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- methodhandler('generators',hash.name)
+ methodhandler('locators',stripped)
+ end
end
if trace_locating then
- report_resolving()
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("no texmf paths are defined (using TEXMF)")
+ end
+end
+local function generate_file_databases()
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ methodhandler('generators',hash.name)
+ end
+ if trace_locating then
+ report_resolving()
+ end
end
local function save_file_databases()
- for i=1,#instance.hashes do
- local hash=instance.hashes[i]
- local cachename=hash.name
- if hash.cache then
- local content=instance.files[cachename]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",cachename)
- end
- caches.savecontent(cachename,"files",content)
- elseif trace_locating then
- report_resolving("not saving runtime tree %a",cachename)
- end
+ for i=1,#instance.hashes do
+ local hash=instance.hashes[i]
+ local cachename=hash.name
+ if hash.cache then
+ local content=instance.files[cachename]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",cachename)
+ end
+ caches.savecontent(cachename,"files",content)
+ elseif trace_locating then
+ report_resolving("not saving runtime tree %a",cachename)
end
+ end
end
function resolvers.renew(hashname)
- if hashname and hashname~="" then
- local expanded=resolvers.expansion(hashname) or ""
- if expanded~="" then
- if trace_locating then
- report_resolving("identifying tree %a from %a",expanded,hashname)
- end
- hashname=expanded
- else
- if trace_locating then
- report_resolving("identifying tree %a",hashname)
- end
- end
- local realpath=resolveprefix(hashname)
- if isdir(realpath) then
- if trace_locating then
- report_resolving("using path %a",realpath)
- end
- methodhandler('generators',hashname)
- local content=instance.files[hashname]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",hashname)
- end
- caches.savecontent(hashname,"files",content)
- else
- report_resolving("invalid path %a",realpath)
- end
+ if hashname and hashname~="" then
+ local expanded=resolvers.expansion(hashname) or ""
+ if expanded~="" then
+ if trace_locating then
+ report_resolving("identifying tree %a from %a",expanded,hashname)
+ end
+ hashname=expanded
+ else
+ if trace_locating then
+ report_resolving("identifying tree %a",hashname)
+ end
end
+ local realpath=resolveprefix(hashname)
+ if isdir(realpath) then
+ if trace_locating then
+ report_resolving("using path %a",realpath)
+ end
+ methodhandler('generators',hashname)
+ local content=instance.files[hashname]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",hashname)
+ end
+ caches.savecontent(hashname,"files",content)
+ else
+ report_resolving("invalid path %a",realpath)
+ end
+ end
end
local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
- load_file_databases()
- if instance.loaderror then
- generate_file_databases()
- save_file_databases()
- end
- else
- generate_file_databases()
- if instance.renewcache then
- save_file_databases()
- end
+ locate_file_databases()
+ if instance.diskcache and not instance.renewcache then
+ load_file_databases()
+ if instance.loaderror then
+ generate_file_databases()
+ save_file_databases()
+ end
+ else
+ generate_file_databases()
+ if instance.renewcache then
+ save_file_databases()
end
+ end
end
function resolvers.appendhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a appended",name)
- end
- insert(instance.hashes,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a appended",name)
end
+ insert(instance.hashes,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.prependhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a prepended",name)
- end
- insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a prepended",name)
end
+ insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.extendtexmfvariable(specification)
- local t=resolvers.splitpath(getenv("TEXMF"))
- insert(t,1,specification)
- local newspec=concat(t,",")
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"]=newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"]=newspec
- else
- end
- reset_hashes()
+ local t=resolvers.splitpath(getenv("TEXMF"))
+ insert(t,1,specification)
+ local newspec=concat(t,",")
+ if instance.environment["TEXMF"] then
+ instance.environment["TEXMF"]=newspec
+ elseif instance.variables["TEXMF"] then
+ instance.variables["TEXMF"]=newspec
+ else
+ end
+ reset_hashes()
end
function resolvers.splitexpansions()
- local ie=instance.expansions
- for k,v in next,ie do
- local t,tn,h,p={},0,{},splitconfigurationpath(v)
- for kk=1,#p do
- local vv=p[kk]
- if vv~="" and not h[vv] then
- tn=tn+1
- t[tn]=vv
- h[vv]=true
- end
- end
- if #t>1 then
- ie[k]=t
- else
- ie[k]=t[1]
- end
+ local ie=instance.expansions
+ for k,v in next,ie do
+ local t,tn,h,p={},0,{},splitconfigurationpath(v)
+ for kk=1,#p do
+ local vv=p[kk]
+ if vv~="" and not h[vv] then
+ tn=tn+1
+ t[tn]=vv
+ h[vv]=true
+ end
end
+ if #t>1 then
+ ie[k]=t
+ else
+ ie[k]=t[1]
+ end
+ end
end
function resolvers.datastate()
- return caches.contentstate()
+ return caches.contentstate()
end
function resolvers.variable(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.variables[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.variables[name]
+ return result~=nil and result or ""
end
function resolvers.expansion(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.expansions[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.expansions[name]
+ return result~=nil and result or ""
end
function resolvers.unexpandedpathlist(str)
- local pth=resolvers.variable(str)
- local lst=resolvers.splitpath(pth)
- return expandedpathfromlist(lst)
+ local pth=resolvers.variable(str)
+ local lst=resolvers.splitpath(pth)
+ return expandedpathfromlist(lst)
end
function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+ return joinpath(resolvers.unexpandedpathlist(str))
end
function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
- lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
- lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
- report_resolving("pushing path %a",lastpath)
- end
+ local pathstack=instance.pathstack
+ local lastpath=pathstack[#pathstack]
+ local pluspath=filedirname(name)
+ if lastpath then
+ lastpath=collapsepath(filejoin(lastpath,pluspath))
+ else
+ lastpath=collapsepath(pluspath)
+ end
+ insert(pathstack,lastpath)
+ if trace_paths then
+ report_resolving("pushing path %a",lastpath)
+ end
end
function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
- report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
+ local pathstack=instance.pathstack
+ if trace_paths and #pathstack>0 then
+ report_resolving("popping path %a",pathstack[#pathstack])
+ end
+ remove(pathstack)
end
function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
+ local pathstack=instance.pathstack
+ local currentpath=pathstack[#pathstack]
+ return currentpath~="" and currentpath or nil
end
local done={}
function resolvers.resetextrapaths()
- local ep=instance.extra_paths
- if not ep then
- done={}
- instance.extra_paths={}
- elseif #ep>0 then
- done={}
- reset_caches()
- end
+ local ep=instance.extra_paths
+ if not ep then
+ done={}
+ instance.extra_paths={}
+ elseif #ep>0 then
+ done={}
+ reset_caches()
+ end
end
function resolvers.getextrapaths()
- return instance.extra_paths or {}
+ return instance.extra_paths or {}
end
function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
- if not paths or path=="" then
- return
- elseif done[paths] then
- return
- end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local ep=instance.extra_paths or {}
- local oldn=#ep
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
- if nofsubpaths>0 then
- for i=1,nofpaths do
- local p=paths[i]
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=p.."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- else
- for i=1,nofpaths do
- local p=paths[i]
- if not done[p] then
- newn=newn+1
- ep[newn]=cleanpath(p)
- done[p]=true
- end
- end
+ if not subpaths or subpaths=="" then
+ if not paths or path=="" then
+ return
+ elseif done[paths] then
+ return
+ end
+ end
+ local paths=settings_to_array(paths)
+ local subpaths=settings_to_array(subpaths)
+ local ep=instance.extra_paths or {}
+ local oldn=#ep
+ local newn=oldn
+ local nofpaths=#paths
+ local nofsubpaths=#subpaths
+ if nofpaths>0 then
+ if nofsubpaths>0 then
+ for i=1,nofpaths do
+ local p=paths[i]
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=p.."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
end
- elseif nofsubpaths>0 then
- for i=1,oldn do
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=ep[i].."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
+ end
+ else
+ for i=1,nofpaths do
+ local p=paths[i]
+ if not done[p] then
+ newn=newn+1
+ ep[newn]=cleanpath(p)
+ done[p]=true
end
+ end
end
- if newn>0 then
- instance.extra_paths=ep
- end
- if newn~=oldn then
- reset_caches()
+ elseif nofsubpaths>0 then
+ for i=1,oldn do
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=ep[i].."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
+ end
end
+ end
+ if newn>0 then
+ instance.extra_paths=ep
+ end
+ if newn~=oldn then
+ reset_caches()
+ end
end
function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- if instance.extra_stack then
- insert(instance.extra_stack,1,paths)
- else
- instance.extra_stack={ paths }
- end
- reset_caches()
+ local paths=settings_to_array(path)
+ if instance.extra_stack then
+ insert(instance.extra_stack,1,paths)
+ else
+ instance.extra_stack={ paths }
+ end
+ reset_caches()
end
function resolvers.popextrapath()
- if instance.extra_stack then
- reset_caches()
- return remove(instance.extra_stack,1)
- end
+ if instance.extra_stack then
+ reset_caches()
+ return remove(instance.extra_stack,1)
+ end
end
local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
- for k=1,#p do
- local v=p[k]
- if not done[v] then
- done[v]=true
- newn=newn+1
- new[newn]=v
- end
- end
+ local done={}
+ local new={}
+ local newn=0
+ local function add(p)
+ for k=1,#p do
+ local v=p[k]
+ if not done[v] then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ end
end
- for k=1,#list do
- local v=list[k]
- if done[v] then
- elseif find(v,"^[%.%/]$") then
- done[v]=true
- newn=newn+1
- new[newn]=v
- else
- break
- end
+ end
+ for k=1,#list do
+ local v=list[k]
+ if done[v] then
+ elseif find(v,"^[%.%/]$") then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ else
+ break
+ end
+ end
+ if extra_too then
+ local es=instance.extra_stack
+ if es and #es>0 then
+ for k=1,#es do
+ add(es[k])
+ end
end
- if extra_too then
- local es=instance.extra_stack
- if es and #es>0 then
- for k=1,#es do
- add(es[k])
- end
- end
- local ep=instance.extra_paths
- if ep and #ep>0 then
- add(ep)
- end
+ local ep=instance.extra_paths
+ if ep and #ep>0 then
+ add(ep)
end
- add(list)
- return new
+ end
+ add(list)
+ return new
end
function resolvers.cleanpathlist(str)
- local t=resolvers.expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i]=collapsepath(cleanpath(t[i]))
- end
+ local t=resolvers.expandedpathlist(str)
+ if t then
+ for i=1,#t do
+ t[i]=collapsepath(cleanpath(t[i]))
end
- return t
+ end
+ return t
end
function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
+ return joinpath(resolvers.expandedpathlist(str))
end
function resolvers.expandedpathlist(str,extra_too)
- if not str then
- return {}
- elseif instance.savelists then
- str=lpegmatch(dollarstripper,str)
- local lists=instance.lists
- local lst=lists[str]
- if not lst then
- local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
- lst=expandedpathfromlist(l)
- lists[str]=lst
- end
- return lst
- else
- local lst=resolvers.splitpath(resolvers.expansion(str))
- return made_list(instance,expandedpathfromlist(lst),extra_too)
+ if not str then
+ return {}
+ elseif instance.savelists then
+ str=lpegmatch(dollarstripper,str)
+ local lists=instance.lists
+ local lst=lists[str]
+ if not lst then
+ local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+ lst=expandedpathfromlist(l)
+ lists[str]=lst
end
+ return lst
+ else
+ local lst=resolvers.splitpath(resolvers.expansion(str))
+ return made_list(instance,expandedpathfromlist(lst),extra_too)
+ end
end
function resolvers.expandedpathlistfromvariable(str)
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp~="" and tmp or str)
+ str=lpegmatch(dollarstripper,str)
+ local tmp=resolvers.variableofformatorsuffix(str)
+ return resolvers.expandedpathlist(tmp~="" and tmp or str)
end
function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+ return joinpath(resolvers.expandedpathlistfromvariable(str))
end
function resolvers.cleanedpathlist(v)
- local t=resolvers.expandedpathlist(v)
- for i=1,#t do
- t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
- end
- return t
+ local t=resolvers.expandedpathlist(v)
+ for i=1,#t do
+ t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
+ end
+ return t
end
function resolvers.expandbraces(str)
- local pth=expandedpathfromlist(resolvers.splitpath(str))
- return joinpath(pth)
+ local pth=expandedpathfromlist(resolvers.splitpath(str))
+ return joinpath(pth)
end
function resolvers.registerfilehash(name,content,someerror)
- if content then
- instance.files[name]=content
- else
- instance.files[name]={}
- if somerror==true then
- instance.loaderror=someerror
- end
+ if content then
+ instance.files[name]=content
+ else
+ instance.files[name]={}
+ if somerror==true then
+ instance.loaderror=someerror
end
+ end
end
function resolvers.getfilehashes()
- return instance and instance.files or {}
+ return instance and instance.files or {}
end
function resolvers.gethashes()
- return instance and instance.hashes or {}
+ return instance and instance.hashes or {}
end
function resolvers.renewcache()
- if instance then
- instance.renewcache=true
- end
+ if instance then
+ instance.renewcache=true
+ end
end
local function isreadable(name)
- local readable=isfile(name)
- if trace_detail then
- if readable then
- report_resolving("file %a is readable",name)
- else
- report_resolving("file %a is not readable",name)
- end
+ local readable=isfile(name)
+ if trace_detail then
+ if readable then
+ report_resolving("file %a is readable",name)
+ else
+ report_resolving("file %a is not readable",name)
end
- return readable
+ end
+ return readable
end
local function collect_files(names)
- local filelist={}
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
- if not pathname or find(path,pathname) then
- local variant=hash.type
- local search=filejoin(root,path,name)
- local result=methodhandler('concatinators',variant,root,path,name)
- if trace_detail then
- report_resolving("match: variant %a, search %a, result %a",variant,search,result)
- end
- noffiles=noffiles+1
- filelist[noffiles]={ variant,search,result }
- end
+ local filelist={}
+ local noffiles=0
+ local function check(hash,root,pathname,path,basename,name)
+ if not pathname or find(path,pathname) then
+ local variant=hash.type
+ local search=filejoin(root,path,name)
+ local result=methodhandler('concatinators',variant,root,path,name)
+ if trace_detail then
+ report_resolving("match: variant %a, search %a, result %a",variant,search,result)
+ end
+ noffiles=noffiles+1
+ filelist[noffiles]={ variant,search,result }
end
- for k=1,#names do
- local filename=names[k]
+ end
+ for k=1,#names do
+ local filename=names[k]
+ if trace_detail then
+ report_resolving("checking name %a",filename)
+ end
+ local basename=filebasename(filename)
+ local pathname=filedirname(filename)
+ if pathname=="" or find(pathname,"^%.") then
+ pathname=false
+ else
+ pathname=gsub(pathname,"%*",".*")
+ pathname="/"..pathname.."$"
+ end
+ local hashes=instance.hashes
+ for h=1,#hashes do
+ local hash=hashes[h]
+ local hashname=hash.name
+ local content=hashname and instance.files[hashname]
+ if content then
if trace_detail then
- report_resolving("checking name %a",filename)
+ report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
end
- local basename=filebasename(filename)
- local pathname=filedirname(filename)
- if pathname=="" or find(pathname,"^%.") then
- pathname=false
- else
- pathname=gsub(pathname,"%*",".*")
- pathname="/"..pathname.."$"
- end
- local hashes=instance.hashes
- for h=1,#hashes do
- local hash=hashes[h]
- local hashname=hash.name
- local content=hashname and instance.files[hashname]
- if content then
- if trace_detail then
- report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
- end
- local path,name=lookup(content,basename)
- if path then
- local metadata=content.metadata
- local realroot=metadata and metadata.path or hashname
- if type(path)=="string" then
- check(hash,realroot,pathname,path,basename,name)
- else
- for i=1,#path do
- check(hash,realroot,pathname,path[i],basename,name)
- end
- end
- end
- elseif trace_locating then
- report_resolving("no match in %a (%s)",hashname,basename)
+ local path,name=lookup(content,basename)
+ if path then
+ local metadata=content.metadata
+ local realroot=metadata and metadata.path or hashname
+ if type(path)=="string" then
+ check(hash,realroot,pathname,path,basename,name)
+ else
+ for i=1,#path do
+ check(hash,realroot,pathname,path[i],basename,name)
end
+ end
end
+ elseif trace_locating then
+ report_resolving("no match in %a (%s)",hashname,basename)
+ end
end
- return noffiles>0 and filelist or nil
+ end
+ return noffiles>0 and filelist or nil
end
local fit={}
function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
- local collapsed=collapsepath(foundname,true)
- local t={
- filename=filename,
- format=format~="" and format or nil,
- filetype=filetype~="" and filetype or nil,
- usedmethod=usedmethod,
- foundname=foundname,
- fullname=collapsed,
- }
- fit[foundname]=t
- foundintrees[#foundintrees+1]=t
- end
+ local foundintrees=instance.foundintrees
+ if usedmethod=="direct" and filename==foundname and fit[foundname] then
+ else
+ local collapsed=collapsepath(foundname,true)
+ local t={
+ filename=filename,
+ format=format~="" and format or nil,
+ filetype=filetype~="" and filetype or nil,
+ usedmethod=usedmethod,
+ foundname=foundname,
+ fullname=collapsed,
+ }
+ fit[foundname]=t
+ foundintrees[#foundintrees+1]=t
+ end
end
function resolvers.foundintrees()
- return instance.foundintrees or {}
+ return instance.foundintrees or {}
end
function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
+ local f=fit[fullname]
+ return f and f.usedmethod=="database"
end
local function can_be_dir(name)
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
- if isdir(name) then
- fakepaths[name]=1
- else
- fakepaths[name]=2
- end
+ local fakepaths=instance.fakepaths
+ if not fakepaths[name] then
+ if isdir(name) then
+ fakepaths[name]=1
+ else
+ fakepaths[name]=2
end
- return fakepaths[name]==1
+ end
+ return fakepaths[name]==1
end
local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
- if filesuffix=="" or not suffixmap[filesuffix] then
- local defaultsuffixes=resolvers.defaultsuffixes
- local formatofsuffix=resolvers.formatofsuffix
- for i=1,#defaultsuffixes do
- local forcedname=filename..'.'..defaultsuffixes[i]
- wantedfiles[#wantedfiles+1]=forcedname
- filetype=formatofsuffix(forcedname)
- if trace_locating then
- report_resolving("forcing filetype %a",filetype)
- end
- end
- else
- filetype=resolvers.formatofsuffix(filename)
- if trace_locating then
- report_resolving("using suffix based filetype %a",filetype)
- end
+ local filetype=''
+ local filesuffix=suffixonly(filename)
+ local wantedfiles={}
+ wantedfiles[#wantedfiles+1]=filename
+ if askedformat=="" then
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local defaultsuffixes=resolvers.defaultsuffixes
+ local formatofsuffix=resolvers.formatofsuffix
+ for i=1,#defaultsuffixes do
+ local forcedname=filename..'.'..defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1]=forcedname
+ filetype=formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolving("forcing filetype %a",filetype)
end
+ end
else
- if filesuffix=="" or not suffixmap[filesuffix] then
- local format_suffixes=suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
- end
- end
- end
- filetype=askedformat
- if trace_locating then
- report_resolving("using given filetype %a",filetype)
+ filetype=resolvers.formatofsuffix(filename)
+ if trace_locating then
+ report_resolving("using suffix based filetype %a",filetype)
+ end
+ end
+ else
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local format_suffixes=suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
end
+ end
end
- return filetype,wantedfiles
+ filetype=askedformat
+ if trace_locating then
+ report_resolving("using given filetype %a",filetype)
+ end
+ end
+ return filetype,wantedfiles
end
local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
- if trace_detail then
- report_resolving("file %a found directly",filename)
- end
- return "direct",{ filename }
+ if not dangerous[askedformat] and isreadable(filename) then
+ if trace_detail then
+ report_resolving("file %a found directly",filename)
end
+ return "direct",{ filename }
+ end
end
local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
- if trace_locating then
- report_resolving("checking wildcard %a",filename)
- end
- local result=resolvers.findwildcardfiles(filename)
- if result then
- return "wildcard",result
- end
- end
-end
-local function find_qualified(filename,allresults,askedformat,alsostripped)
- if not is_qualified_path(filename) then
- return
- end
+ if find(filename,'*',1,true) then
if trace_locating then
- report_resolving("checking qualified name %a",filename)
+ report_resolving("checking wildcard %a",filename)
end
- if isreadable(filename) then
- if trace_detail then
- report_resolving("qualified file %a found",filename)
- end
- return "qualified",{ filename }
+ local result=resolvers.findwildcardfiles(filename)
+ if result then
+ return "wildcard",result
end
+ end
+end
+local function find_qualified(filename,allresults,askedformat,alsostripped)
+ if not is_qualified_path(filename) then
+ return
+ end
+ if trace_locating then
+ report_resolving("checking qualified name %a",filename)
+ end
+ if isreadable(filename) then
if trace_detail then
- report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then
- local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s=format_suffixes[i]
- forcedname=filename.."."..s
- if isreadable(forcedname) then
- if trace_locating then
- report_resolving("no suffix, forcing format filetype %a",s)
- end
- return "qualified",{ forcedname }
- end
- end
+ report_resolving("qualified file %a found",filename)
+ end
+ return "qualified",{ filename }
+ end
+ if trace_detail then
+ report_resolving("locating qualified file %a",filename)
+ end
+ local forcedname,suffix="",suffixonly(filename)
+ if suffix=="" then
+ local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s=format_suffixes[i]
+ forcedname=filename.."."..s
+ if isreadable(forcedname) then
+ if trace_locating then
+ report_resolving("no suffix, forcing format filetype %a",s)
+ end
+ return "qualified",{ forcedname }
end
+ end
end
- if alsostripped and suffix and suffix~="" then
- local basename=filebasename(filename)
- local pattern=lpegmatch(preparetreepattern,filename)
- local savedformat=askedformat
- local format=savedformat or ""
- if format=="" then
- askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if alsostripped and suffix and suffix~="" then
+ local basename=filebasename(filename)
+ local pattern=lpegmatch(preparetreepattern,filename)
+ local savedformat=askedformat
+ local format=savedformat or ""
+ if format=="" then
+ askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if not format then
+ askedformat="othertextfiles"
+ end
+ if basename~=filename then
+ local resolved=collect_instance_files(basename,askedformat,allresults)
+ if #resolved==0 then
+ local lowered=lower(basename)
+ if filename~=lowered then
+ resolved=collect_instance_files(lowered,askedformat,allresults)
end
- if not format then
- askedformat="othertextfiles"
+ end
+ resolvers.format=savedformat
+ if #resolved>0 then
+ local result={}
+ for r=1,#resolved do
+ local rr=resolved[r]
+ if find(rr,pattern) then
+ result[#result+1]=rr
+ end
end
- if basename~=filename then
- local resolved=collect_instance_files(basename,askedformat,allresults)
- if #resolved==0 then
- local lowered=lower(basename)
- if filename~=lowered then
- resolved=collect_instance_files(lowered,askedformat,allresults)
- end
- end
- resolvers.format=savedformat
- if #resolved>0 then
- local result={}
- for r=1,#resolved do
- local rr=resolved[r]
- if find(rr,pattern) then
- result[#result+1]=rr
- end
- end
- if #result>0 then
- return "qualified",result
- end
- end
+ if #result>0 then
+ return "qualified",result
end
+ end
end
+ end
end
local function check_subpath(fname)
- if isreadable(fname) then
- if trace_detail then
- report_resolving("found %a by deep scanning",fname)
- end
- return fname
+ if isreadable(fname) then
+ if trace_detail then
+ report_resolving("found %a by deep scanning",fname)
end
+ return fname
+ end
end
local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
- local entry={}
- if pathlist and #pathlist>0 then
- for k=1,#pathlist do
- local path=pathlist[k]
- local prescanned=find(path,'^!!')
- local resursive=find(path,'//$')
- local pathname=lpegmatch(inhibitstripper,path)
- local expression=makepathexpression(pathname)
- local barename=gsub(pathname,"/+$","")
- barename=resolveprefix(barename)
- local scheme=url.hasscheme(barename)
- local schemename=gsub(barename,"%.%*$",'')
- entry[k]={
- path=path,
- pathname=pathname,
- prescanned=prescanned,
- recursive=recursive,
- expression=expression,
- barename=barename,
- scheme=scheme,
- schemename=schemename,
- }
- end
- entry.typespec=typespec
- list[filetype]=entry
- else
- list[filetype]=false
- end
- return entry
+ local typespec=resolvers.variableofformat(filetype)
+ local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
+ local entry={}
+ if pathlist and #pathlist>0 then
+ for k=1,#pathlist do
+ local path=pathlist[k]
+ local prescanned=find(path,'^!!')
+ local resursive=find(path,'//$')
+ local pathname=lpegmatch(inhibitstripper,path)
+ local expression=makepathexpression(pathname)
+ local barename=gsub(pathname,"/+$","")
+ barename=resolveprefix(barename)
+ local scheme=url.hasscheme(barename)
+ local schemename=gsub(barename,"%.%*$",'')
+ entry[k]={
+ path=path,
+ pathname=pathname,
+ prescanned=prescanned,
+ recursive=recursive,
+ expression=expression,
+ barename=barename,
+ scheme=scheme,
+ schemename=schemename,
+ }
+ end
+ entry.typespec=typespec
+ list[filetype]=entry
+ else
+ list[filetype]=false
+ end
+ return entry
end
local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
- pathlists=setmetatableindex({},makepathlist)
- instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
- local method="intree"
- local filelist=collect_files(wantedfiles)
- local dirlist={}
- local result={}
- if filelist then
- for i=1,#filelist do
- dirlist[i]=filedirname(filelist[i][3]).."/"
+ local pathlists=instance.pathlists
+ if not pathlists then
+ pathlists=setmetatableindex({},makepathlist)
+ instance.pathlists=pathlists
+ end
+ local pathlist=pathlists[filetype]
+ if pathlist then
+ local method="intree"
+ local filelist=collect_files(wantedfiles)
+ local dirlist={}
+ local result={}
+ if filelist then
+ for i=1,#filelist do
+ dirlist[i]=filedirname(filelist[i][3]).."/"
+ end
+ end
+ if trace_detail then
+ report_resolving("checking filename %a in tree",filename)
+ end
+ for k=1,#pathlist do
+ local entry=pathlist[k]
+ local path=entry.path
+ local pathname=entry.pathname
+ local done=false
+ if filelist then
+ local expression=entry.expression
+ if trace_detail then
+ report_resolving("using pattern %a for path %a",expression,pathname)
+ end
+ for k=1,#filelist do
+ local fl=filelist[k]
+ local f=fl[2]
+ local d=dirlist[k]
+ if find(d,expression) or find(resolveprefix(d),expression) then
+ result[#result+1]=resolveprefix(fl[3])
+ done=true
+ if allresults then
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
+ end
+ else
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
+ end
+ break
end
+ elseif trace_detail then
+ report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ end
end
- if trace_detail then
- report_resolving("checking filename %a in tree",filename)
- end
- for k=1,#pathlist do
- local entry=pathlist[k]
- local path=entry.path
- local pathname=entry.pathname
- local done=false
- if filelist then
- local expression=entry.expression
+ end
+ if done then
+ method="database"
+ else
+ method="filesystem"
+ local scheme=entry.scheme
+ if not scheme or scheme=="file" then
+ local pname=entry.schemename
+ if not find(pname,"*",1,true) then
+ if can_be_dir(pname) then
+ if not done and not entry.prescanned then
if trace_detail then
- report_resolving("using pattern %a for path %a",expression,pathname)
- end
- for k=1,#filelist do
- local fl=filelist[k]
- local f=fl[2]
- local d=dirlist[k]
- if find(d,expression) or find(resolveprefix(d),expression) then
- result[#result+1]=resolveprefix(fl[3])
- done=true
- if allresults then
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
- end
- else
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
- end
- break
- end
- elseif trace_detail then
- report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ report_resolving("quick root scan for %a",pname)
+ end
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local fname=check_subpath(filejoin(pname,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
- end
- end
- if done then
- method="database"
- else
- method="filesystem"
- local scheme=entry.scheme
- if not scheme or scheme=="file" then
- local pname=entry.schemename
- if not find(pname,"*",1,true) then
- if can_be_dir(pname) then
- if not done and not entry.prescanned then
- if trace_detail then
- report_resolving("quick root scan for %a",pname)
- end
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local fname=check_subpath(filejoin(pname,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- if not done and entry.recursive then
- if trace_detail then
- report_resolving("scanning filesystem for %a",pname)
- end
- local files=resolvers.simplescanfiles(pname,false,true)
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local subpath=files[w]
- if not subpath or subpath=="" then
- elseif type(subpath)=="string" then
- local fname=check_subpath(filejoin(pname,subpath,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- else
- for i=1,#subpath do
- local sp=subpath[i]
- if sp=="" then
- else
- local fname=check_subpath(filejoin(pname,sp,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- end
- end
- end
+ end
+ end
+ if not done and entry.recursive then
+ if trace_detail then
+ report_resolving("scanning filesystem for %a",pname)
+ end
+ local files=resolvers.simplescanfiles(pname,false,true)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local subpath=files[w]
+ if not subpath or subpath=="" then
+ elseif type(subpath)=="string" then
+ local fname=check_subpath(filejoin(pname,subpath,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
+ end
else
- end
- else
- for k=1,#wantedfiles do
- local pname=entry.barename
- local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
- if fname then
+ for i=1,#subpath do
+ local sp=subpath[i]
+ if sp=="" then
+ else
+ local fname=check_subpath(filejoin(pname,sp,w))
+ if fname then
result[#result+1]=fname
done=true
if not allresults then
- break
+ break
end
+ end
end
+ end
+ if done and not allresults then
+ break
+ end
end
+ end
end
+ end
end
- if done and not allresults then
+ else
+ end
+ else
+ for k=1,#wantedfiles do
+ local pname=entry.barename
+ local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
break
+ end
end
+ end
end
- if #result>0 then
- return method,result
- end
+ end
+ if done and not allresults then
+ break
+ end
+ end
+ if #result>0 then
+ return method,result
end
+ end
end
local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_detail then
- report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
- local fname=wantedfiles[k]
- if fname and isreadable(fname) then
- filename=fname
- result[#result+1]=filejoin('.',fname)
- if not allresults then
- break
- end
- end
- end
- if #result>0 then
- return "onpath",result
+ if trace_detail then
+ report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
+ end
+ local result={}
+ for k=1,#wantedfiles do
+ local fname=wantedfiles[k]
+ if fname and isreadable(fname) then
+ filename=fname
+ result[#result+1]=filejoin('.',fname)
+ if not allresults then
+ break
+ end
end
+ end
+ if #result>0 then
+ return "onpath",result
+ end
end
local function find_otherwise(filename,filetype,wantedfiles,allresults)
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
- return "otherwise",{ resolveprefix(fl[3]) }
- end
+ local filelist=collect_files(wantedfiles)
+ local fl=filelist and filelist[1]
+ if fl then
+ return "otherwise",{ resolveprefix(fl[3]) }
+ end
end
collect_instance_files=function(filename,askedformat,allresults)
- if not filename or filename=="" then
- return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/")
- if allresults then
- local filetype,wantedfiles=find_analyze(filename,askedformat)
- local results={
- { find_direct (filename,true) },
- { find_wildcard (filename,true) },
- { find_qualified(filename,true,askedformat) },
- { find_intree (filename,filetype,wantedfiles,true) },
- { find_onpath (filename,filetype,wantedfiles,true) },
- { find_otherwise(filename,filetype,wantedfiles,true) },
- }
- local result,status,done={},{},{}
- for k,r in next,results do
- local method,list=r[1],r[2]
- if method and list then
- for i=1,#list do
- local c=collapsepath(list[i])
- if not done[c] then
- result[#result+1]=c
- done[c]=true
- end
- status[#status+1]=formatters["%-10s: %s"](method,c)
- end
- end
- end
- if trace_detail then
- report_resolving("lookup status: %s",table.serialize(status,filename))
+ if not filename or filename=="" then
+ return {}
+ end
+ askedformat=askedformat or ""
+ filename=collapsepath(filename,".")
+ filename=gsub(filename,"^%./",getcurrentdir().."/")
+ if allresults then
+ local filetype,wantedfiles=find_analyze(filename,askedformat)
+ local results={
+ { find_direct (filename,true) },
+ { find_wildcard (filename,true) },
+ { find_qualified(filename,true,askedformat) },
+ { find_intree (filename,filetype,wantedfiles,true) },
+ { find_onpath (filename,filetype,wantedfiles,true) },
+ { find_otherwise(filename,filetype,wantedfiles,true) },
+ }
+ local result,status,done={},{},{}
+ for k,r in next,results do
+ local method,list=r[1],r[2]
+ if method and list then
+ for i=1,#list do
+ local c=collapsepath(list[i])
+ if not done[c] then
+ result[#result+1]=c
+ done[c]=true
+ end
+ status[#status+1]=formatters["%-10s: %s"](method,c)
end
- return result,status
- else
- local method,result,stamp,filetype,wantedfiles
- if instance.remember then
- if askedformat=="" then
- stamp=formatters["%s::%s"](suffixonly(filename),filename)
- else
- stamp=formatters["%s::%s"](askedformat,filename)
- end
- result=stamp and instance.found[stamp]
- if result then
- if trace_locating then
- report_resolving("remembered file %a",filename)
- end
- return result
- end
+ end
+ end
+ if trace_detail then
+ report_resolving("lookup status: %s",table.serialize(status,filename))
+ end
+ return result,status
+ else
+ local method,result,stamp,filetype,wantedfiles
+ if instance.remember then
+ if askedformat=="" then
+ stamp=formatters["%s::%s"](suffixonly(filename),filename)
+ else
+ stamp=formatters["%s::%s"](askedformat,filename)
+ end
+ result=stamp and instance.found[stamp]
+ if result then
+ if trace_locating then
+ report_resolving("remembered file %a",filename)
end
- method,result=find_direct(filename)
+ return result
+ end
+ end
+ method,result=find_direct(filename)
+ if not result then
+ method,result=find_wildcard(filename)
+ if not result then
+ method,result=find_qualified(filename,false,askedformat)
if not result then
- method,result=find_wildcard(filename)
- if not result then
- method,result=find_qualified(filename,false,askedformat)
- if not result then
- filetype,wantedfiles=find_analyze(filename,askedformat)
- method,result=find_intree(filename,filetype,wantedfiles)
- if not result then
- method,result=find_onpath(filename,filetype,wantedfiles)
- if resolve_otherwise and not result then
- method,result=find_otherwise(filename,filetype,wantedfiles)
- end
- end
- end
- end
- end
- if result and #result>0 then
- local foundname=collapsepath(result[1])
- resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
- result={ foundname }
- else
- result={}
- end
- if stamp then
- if trace_locating then
- report_resolving("remembering file %a using hash %a",filename,stamp)
+ filetype,wantedfiles=find_analyze(filename,askedformat)
+ method,result=find_intree(filename,filetype,wantedfiles)
+ if not result then
+ method,result=find_onpath(filename,filetype,wantedfiles)
+ if resolve_otherwise and not result then
+ method,result=find_otherwise(filename,filetype,wantedfiles)
end
- instance.found[stamp]=result
+ end
end
- return result
+ end
+ end
+ if result and #result>0 then
+ local foundname=collapsepath(result[1])
+ resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
+ result={ foundname }
+ else
+ result={}
end
+ if stamp then
+ if trace_locating then
+ report_resolving("remembering file %a using hash %a",filename,stamp)
+ end
+ instance.found[stamp]=result
+ end
+ return result
+ end
end
local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
- return {}
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
- local lowered=lower(filename)
- if filename~=lowered then
- result,status=collect_instance_files(lowered,filetype or "",allresults)
- end
+ if not filename or filename=="" then
+ return {}
+ end
+ local result,status=collect_instance_files(filename,filetype or "",allresults)
+ if not result or #result==0 then
+ local lowered=lower(filename)
+ if filename~=lowered then
+ result,status=collect_instance_files(lowered,filetype or "",allresults)
end
- return result or {},status
+ end
+ return result or {},status
end
function resolvers.findfiles(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,true)
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,true)
+ end
end
function resolvers.findfile(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,false)[1] or ""
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,false)[1] or ""
+ end
end
function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
+ return filedirname(findfiles(filename,filetype,false)[1] or "")
end
local function findgivenfiles(filename,allresults)
- local base=filebasename(filename)
- local result={}
- local hashes=instance.hashes
- local function okay(hash,path,name)
- local found=methodhandler('concatinators',hash.type,hash.name,path,name)
- if found and found~="" then
- result[#result+1]=resolveprefix(found)
- return not allresults
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local content=instance.files[hash.name]
- if content then
- local path,name=lookup(content,base)
- if not path then
- elseif type(path)=="string" then
- if okay(hash,path,name) then
- return result
- end
- else
- for i=1,#path do
- if okay(hash,path[i],name) then
- return result
- end
- end
- end
+ local base=filebasename(filename)
+ local result={}
+ local hashes=instance.hashes
+ local function okay(hash,path,name)
+ local found=methodhandler('concatinators',hash.type,hash.name,path,name)
+ if found and found~="" then
+ result[#result+1]=resolveprefix(found)
+ return not allresults
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local content=instance.files[hash.name]
+ if content then
+ local path,name=lookup(content,base)
+ if not path then
+ elseif type(path)=="string" then
+ if okay(hash,path,name) then
+ return result
+ end
+ else
+ for i=1,#path do
+ if okay(hash,path[i],name) then
+ return result
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
+ return findgivenfiles(filename,true)
end
function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
+ return findgivenfiles(filename,false)[1] or ""
end
local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
+ (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
)
function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
+ return lpegmatch(makewildcard,pattern) or pattern
end
local function findwildcardfiles(filename,allresults,result)
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- local files=instance.files
- if find(name,"*",1,true) then
- local hashes=instance.hashes
- local function okay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
+ local result=result or {}
+ local base=filebasename(filename)
+ local dirn=filedirname(filename)
+ local path=lower(lpegmatch(makewildcard,dirn) or dirn)
+ local name=lower(lpegmatch(makewildcard,base) or base)
+ local files=instance.files
+ if find(name,"*",1,true) then
+ local hashes=instance.hashes
+ local function okay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- for found,base in filtered(files[hashname],name) do
- if type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ for found,base in filtered(files[hashname],name) do
+ if type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
end
- end
- else
- local function okayokay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
+ end
end
+ end
end
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- local found,base=lookup(content,base)
- if not found then
- elseif type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
+ end
+ end
+ else
+ local function okayokay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
+ end
+ end
+ end
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ local found,base=lookup(content,base)
+ if not found then
+ elseif type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
+ end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
end
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
+ return findwildcardfiles(filename,true,result)
end
function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
+ return findwildcardfiles(filename,false)[1] or ""
end
function resolvers.automount()
end
function resolvers.starttiming()
- statistics.starttiming(instance)
+ statistics.starttiming(instance)
end
function resolvers.stoptiming()
- statistics.stoptiming(instance)
+ statistics.stoptiming(instance)
end
function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
- load_databases()
- resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
+ resolvers.starttiming()
+ identify_configuration_files()
+ load_configuration_files()
+ if option~="nofiles" then
+ load_databases()
+ resolvers.automount()
+ end
+ resolvers.stoptiming()
+ local files=instance.files
+ return files and next(files) and true
end
function resolvers.loadtime()
- return statistics.elapsedtime(instance)
+ return statistics.elapsedtime(instance)
end
local function report(str)
- if trace_locating then
- report_resolving(str)
- else
- print(str)
- end
+ if trace_locating then
+ report_resolving(str)
+ else
+ print(str)
+ end
end
function resolvers.dowithfilesandreport(command,files,...)
- if files and #files>0 then
- if trace_locating then
- report('')
- end
- if type(files)=="string" then
- files={ files }
- end
- for f=1,#files do
- local file=files[f]
- local result=command(file,...)
- if type(result)=='string' then
- report(result)
- else
- for i=1,#result do
- report(result[i])
- end
- end
+ if files and #files>0 then
+ if trace_locating then
+ report('')
+ end
+ if type(files)=="string" then
+ files={ files }
+ end
+ for f=1,#files do
+ local file=files[f]
+ local result=command(file,...)
+ if type(result)=='string' then
+ report(result)
+ else
+ for i=1,#result do
+ report(result[i])
end
+ end
end
+ end
end
-function resolvers.showpath(str)
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+function resolvers.showpath(str)
+ return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
end
function resolvers.registerfile(files,name,path)
- if files[name] then
- if type(files[name])=='string' then
- files[name]={ files[name],path }
- else
- files[name]=path
- end
+ if files[name] then
+ if type(files[name])=='string' then
+ files[name]={ files[name],path }
else
- files[name]=path
+ files[name]=path
end
+ else
+ files[name]=path
+ end
end
function resolvers.dowithpath(name,func)
- local pathlist=resolvers.expandedpathlist(name)
- for i=1,#pathlist do
- func("^"..cleanpath(pathlist[i]))
- end
+ local pathlist=resolvers.expandedpathlist(name)
+ for i=1,#pathlist do
+ func("^"..cleanpath(pathlist[i]))
+ end
end
function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
+ func(expandedvariable(name))
end
function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(name)
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
- fmtname=resolvers.findfile(fullname)
- fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
- local barename=removesuffix(fmtname)
- local luaname=addsuffix(barename,luasuffixes.lua)
- local lucname=addsuffix(barename,luasuffixes.luc)
- local luiname=addsuffix(barename,luasuffixes.lui)
- if isfile(luiname) then
- return barename,luiname
- elseif isfile(lucname) then
- return barename,lucname
- elseif isfile(luaname) then
- return barename,luaname
- end
- end
- return nil,nil
+ local engine=environment.ownmain or "luatex"
+ local barename=removesuffix(name)
+ local fullname=addsuffix(barename,"fmt")
+ local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
+ if fmtname=="" then
+ fmtname=resolvers.findfile(fullname)
+ fmtname=cleanpath(fmtname)
+ end
+ if fmtname~="" then
+ local barename=removesuffix(fmtname)
+ local luaname=addsuffix(barename,luasuffixes.lua)
+ local lucname=addsuffix(barename,luasuffixes.luc)
+ local luiname=addsuffix(barename,luasuffixes.lui)
+ if isfile(luiname) then
+ return barename,luiname
+ elseif isfile(lucname) then
+ return barename,lucname
+ elseif isfile(luaname) then
+ return barename,luaname
+ end
+ end
+ return nil,nil
end
function resolvers.booleanvariable(str,default)
- local b=resolvers.expansion(str)
- if b=="" then
- return default
- else
- b=toboolean(b)
- return (b==nil and default) or b
- end
+ local b=resolvers.expansion(str)
+ if b=="" then
+ return default
+ else
+ b=toboolean(b)
+ return (b==nil and default) or b
+ end
end
function resolvers.dowithfilesintree(pattern,handle,before,after)
- local hashes=instance.hashes
- for i=1,#hashes do
- local hash=hashes[i]
- local blobtype=hash.type
- local blobpath=hash.name
- if blobtype and blobpath then
- local total=0
- local checked=0
- local done=0
- if before then
- before(blobtype,blobpath,pattern)
- end
- for path,name in filtered(instance.files[blobpath],pattern) do
- if type(path)=="string" then
- checked=checked+1
- if handle(blobtype,blobpath,path,name) then
- done=done+1
- end
- else
- checked=checked+#path
- for i=1,#path do
- if handle(blobtype,blobpath,path[i],name) then
- done=done+1
- end
- end
- end
- end
- if after then
- after(blobtype,blobpath,pattern,total,checked,done)
+ local hashes=instance.hashes
+ for i=1,#hashes do
+ local hash=hashes[i]
+ local blobtype=hash.type
+ local blobpath=hash.name
+ if blobtype and blobpath then
+ local total=0
+ local checked=0
+ local done=0
+ if before then
+ before(blobtype,blobpath,pattern)
+ end
+ for path,name in filtered(instance.files[blobpath],pattern) do
+ if type(path)=="string" then
+ checked=checked+1
+ if handle(blobtype,blobpath,path,name) then
+ done=done+1
+ end
+ else
+ checked=checked+#path
+ for i=1,#path do
+ if handle(blobtype,blobpath,path[i],name) then
+ done=done+1
end
+ end
end
+ end
+ if after then
+ after(blobtype,blobpath,pattern,checked,done)
+ end
end
+ end
end
local obsolete=resolvers.obsolete or {}
resolvers.obsolete=obsolete
-resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
-resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
+resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
+resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
function resolvers.knownvariables(pattern)
- if instance then
- local environment=instance.environment
- local variables=instance.variables
- local expansions=instance.expansions
- local order=instance.order
- local pattern=upper(pattern or "")
- local result={}
- for i=1,#order do
- for key in next,order[i] do
- if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
- result[key]={
- environment=rawget(environment,key),
- variable=key,
- expansion=expansions[key],
- resolved=resolveprefix(expansions[key]),
- }
- end
- end
+ if instance then
+ local environment=instance.environment
+ local variables=instance.variables
+ local expansions=instance.expansions
+ local order=instance.order
+ local pattern=upper(pattern or "")
+ local result={}
+ for i=1,#order do
+ for key in next,order[i] do
+ if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
+ result[key]={
+ environment=rawget(environment,key),
+ variable=key,
+ expansion=expansions[key],
+ resolved=resolveprefix(expansions[key]),
+ }
end
- return result
- else
- return {}
+ end
end
+ return result
+ else
+ return {}
+ end
end
@@ -19311,14 +22885,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-pre"] = package.loaded["data-pre"] or true
--- original size: 4090, stripped down to: 3059
+-- original size: 4854, stripped down to: 2889
if not modules then modules={} end modules ['data-pre']={
- 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 resolvers=resolvers
local prefixes=resolvers.prefixes
@@ -19331,64 +22905,64 @@ local dirname=file.dirname
local joinpath=file.join
local isfile=lfs.isfile
prefixes.environment=function(str)
- return cleanpath(expansion(str))
+ return cleanpath(expansion(str))
end
local function relative(str,n)
- if not isfile(str) then
- local pstr="./"..str
+ if not isfile(str) then
+ local pstr="./"..str
+ if isfile(pstr) then
+ str=pstr
+ else
+ local p="../"
+ for i=1,n or 2 do
+ local pstr=p..str
if isfile(pstr) then
- str=pstr
+ str=pstr
+ break
else
- local p="../"
- for i=1,n or 2 do
- local pstr=p..str
- if isfile(pstr) then
- str=pstr
- break
- else
- p=p.."../"
- end
- end
+ p=p.."../"
end
+ end
end
- return cleanpath(str)
+ end
+ return cleanpath(str)
end
local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(fullname~="" and fullname or str)
end
prefixes.relative=relative
prefixes.locate=locate
prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
- fullname=locate(str)
- end
- return fullname
+ local fullname=relative(str)
+ if not isfile(fullname) then
+ fullname=locate(str)
+ end
+ return fullname
end
prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(basename((fullname~="" and fullname) or str))
end
prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(dirname((fullname~="" and fullname) or str))
end
prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOLOC')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOPARENT')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTODIR')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('HOME')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.env=prefixes.environment
prefixes.rel=prefixes.relative
@@ -19398,24 +22972,24 @@ prefixes.full=prefixes.locate
prefixes.file=prefixes.filename
prefixes.path=prefixes.pathname
local function toppath()
- local inputstack=resolvers.inputstack
- if not inputstack then
- return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
- return "."
- else
- return pathname
- end
+ local inputstack=resolvers.inputstack
+ if not inputstack then
+ return "."
+ end
+ local pathname=dirname(inputstack[#inputstack] or "")
+ if pathname=="" then
+ return "."
+ else
+ return pathname
+ end
end
local function jobpath()
- local path=resolvers.stackpath()
- if not path or path=="" then
- return "."
- else
- return path
- end
+ local path=resolvers.stackpath()
+ if not path or path=="" then
+ return "."
+ else
+ return path
+ end
end
resolvers.toppath=toppath
resolvers.jobpath=jobpath
@@ -19423,8 +22997,6 @@ prefixes.toppath=function(str) return cleanpath(joinpath(toppath(),str)) end
prefixes.jobpath=function(str) return cleanpath(joinpath(jobpath(),str)) end
resolvers.setdynamic("toppath")
resolvers.setdynamic("jobpath")
-prefixes.jobfile=prefixes.jobpath
-resolvers.setdynamic("jobfile")
end -- of closure
@@ -19433,14 +23005,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-inp"] = package.loaded["data-inp"] or true
--- original size: 910, stripped down to: 823
+-- original size: 910, stripped down to: 818
if not modules then modules={} end modules ['data-inp']={
- 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 allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -19463,14 +23035,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-out"] = package.loaded["data-out"] or true
--- original size: 530, stripped down to: 475
+-- original size: 530, stripped down to: 470
if not modules then modules={} end modules ['data-out']={
- 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 allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -19486,16 +23058,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-fil"] = package.loaded["data-fil"] or true
--- original size: 3863, stripped down to: 3310
+-- original size: 3863, stripped down to: 3170
if not modules then modules={} end modules ['data-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 trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_files=logs.reporter("resolvers","files")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -19503,88 +23075,88 @@ local finders,openers,loaders,savers=resolvers.finders,resolvers.openers,resolve
local locators,hashers,generators,concatinators=resolvers.locators,resolvers.hashers,resolvers.generators,resolvers.concatinators
local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
function locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename)
- if realname and realname~='' and lfs.isdir(realname) then
- if trace_locating then
- report_files("file locator %a found as %a",filename,realname)
- end
- resolvers.appendhash('file',filename,true)
- elseif trace_locating then
- report_files("file locator %a not found",filename)
+ local filename=specification.filename
+ local realname=resolveprefix(filename)
+ if realname and realname~='' and lfs.isdir(realname) then
+ if trace_locating then
+ report_files("file locator %a found as %a",filename,realname)
end
+ resolvers.appendhash('file',filename,true)
+ elseif trace_locating then
+ report_files("file locator %a not found",filename)
+ end
end
function hashers.file(specification)
- local pathname=specification.filename
- local content=caches.loadcontent(pathname,'files')
- resolvers.registerfilehash(pathname,content,content==nil)
+ local pathname=specification.filename
+ local content=caches.loadcontent(pathname,'files')
+ resolvers.registerfilehash(pathname,content,content==nil)
end
function generators.file(specification)
- local pathname=specification.filename
- local content=resolvers.scanfiles(pathname,false,true)
- resolvers.registerfilehash(pathname,content,true)
+ local pathname=specification.filename
+ local content=resolvers.scanfiles(pathname,false,true)
+ resolvers.registerfilehash(pathname,content,true)
end
concatinators.file=file.join
function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=resolvers.findfile(filename,filetype)
- if foundname and foundname~="" then
- if trace_locating then
- report_files("file finder: %a found",filename)
- end
- return foundname
- else
- if trace_locating then
- report_files("file finder: %a not found",filename)
- end
- return finders.notfound()
+ local filename=specification.filename
+ local foundname=resolvers.findfile(filename,filetype)
+ if foundname and foundname~="" then
+ if trace_locating then
+ report_files("file finder: %a found",filename)
+ end
+ return foundname
+ else
+ if trace_locating then
+ report_files("file finder: %a not found",filename)
end
+ return finders.notfound()
+ end
end
function openers.helpers.textopener(tag,filename,f)
- return {
- reader=function() return f:read () end,
- close=function() logs.show_close(filename) return f:close() end,
- }
+ return {
+ reader=function() return f:read () end,
+ close=function() logs.show_close(filename) return f:close() end,
+ }
end
function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"r")
- if f then
- if trace_locating then
- report_files("file opener: %a opened",filename)
- end
- return openers.helpers.textopener("file",filename,f)
- end
- end
- if trace_locating then
- report_files("file opener: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"r")
+ if f then
+ if trace_locating then
+ report_files("file opener: %a opened",filename)
+ end
+ return openers.helpers.textopener("file",filename,f)
end
- return openers.notfound()
+ end
+ if trace_locating then
+ report_files("file opener: %a not found",filename)
+ end
+ return openers.notfound()
end
function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"rb")
- if f then
- logs.show_load(filename)
- if trace_locating then
- report_files("file loader: %a loaded",filename)
- end
- local s=f:read("*a")
- if checkgarbage then
- checkgarbage(#s)
- end
- f:close()
- if s then
- return true,s,#s
- end
- end
- end
- if trace_locating then
- report_files("file loader: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"rb")
+ if f then
+ logs.show_load(filename)
+ if trace_locating then
+ report_files("file loader: %a loaded",filename)
+ end
+ local s=f:read("*a")
+ if checkgarbage then
+ checkgarbage(#s)
+ end
+ f:close()
+ if s then
+ return true,s,#s
+ end
end
- return loaders.notfound()
+ end
+ if trace_locating then
+ report_files("file loader: %a not found",filename)
+ end
+ return loaders.notfound()
end
@@ -19594,116 +23166,116 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-con"] = package.loaded["data-con"] or true
--- original size: 5029, stripped down to: 3607
+-- original size: 5029, stripped down to: 3432
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
- return stored
+ 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
+ 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
+ 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
- return data
+ 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
@@ -19713,97 +23285,101 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-use"] = package.loaded["data-use"] or true
--- original size: 4272, stripped down to: 3289
+-- original size: 4434, stripped down to: 3180
if not modules then modules={} end modules ['data-use']={
- 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 format,lower,gsub,find=string.format,string.lower,string.gsub,string.find
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_mounts=logs.reporter("resolvers","mounts")
local resolvers=resolvers
resolvers.automounted=resolvers.automounted or {}
function resolvers.automount(usecache)
- local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
- if (not mountpaths or #mountpaths==0) and usecache then
- mountpaths=caches.getreadablepaths("mount")
- end
- if mountpaths and #mountpaths>0 then
- resolvers.starttiming()
- for k=1,#mountpaths do
- local root=mountpaths[k]
- local f=io.open(root.."/url.tmi")
- if f then
- for line in f:lines() do
- if line then
- if find(line,"^[%%#%-]") then
- elseif find(line,"^zip://") then
- if trace_locating then
- report_mounts("mounting %a",line)
- end
- table.insert(resolvers.automounted,line)
- resolvers.usezipfile(line)
- end
- end
- end
- f:close()
+ local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
+ if (not mountpaths or #mountpaths==0) and usecache then
+ mountpaths=caches.getreadablepaths("mount")
+ end
+ if mountpaths and #mountpaths>0 then
+ resolvers.starttiming()
+ for k=1,#mountpaths do
+ local root=mountpaths[k]
+ local f=io.open(root.."/url.tmi")
+ if f then
+ for line in f:lines() do
+ if line then
+ if find(line,"^[%%#%-]") then
+ elseif find(line,"^zip://") then
+ if trace_locating then
+ report_mounts("mounting %a",line)
+ end
+ table.insert(resolvers.automounted,line)
+ resolvers.usezipfile(line)
end
+ end
end
- resolvers.stoptiming()
+ f:close()
+ end
end
+ resolvers.stoptiming()
+ end
end
statistics.register("used config file",function() return caches.configfiles() end)
statistics.register("used cache path",function() return caches.usedpaths() end)
function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner)
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
- local luvname=file.replacesuffix(texname,"luv")
- local luvdata={
- enginebanner=enginebanner,
- formatbanner=formatbanner,
- sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
- sourcefile=sourcefile,
- luaversion=LUAVERSION,
- }
- io.savedata(luvname,table.serialize(luvdata,true))
- lua.registerfinalizer(function()
- logs.report("format banner","%s",banner)
- logs.newline()
- end)
- end
+ local enginebanner=status.banner
+ if formatbanner and enginebanner and sourcefile then
+ local luvname=file.replacesuffix(texname,"luv")
+ local luvdata={
+ enginebanner=enginebanner,
+ formatbanner=formatbanner,
+ sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
+ sourcefile=sourcefile,
+ luaversion=LUAVERSION,
+ }
+ io.savedata(luvname,table.serialize(luvdata,true))
+ lua.registerfinalizer(function()
+ 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
end
function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
- local luvname=file.replacesuffix(texname,"luv")
- if lfs.isfile(luvname) then
- local luv=dofile(luvname)
- if luv and luv.sourcefile then
- local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
- local luvbanner=luv.enginebanner or "?"
- if luvbanner~=enginebanner then
- return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
- end
- local luvhash=luv.sourcehash or "?"
- if luvhash~=sourcehash then
- return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
- end
- local luvluaversion=luv.luaversion or 0
- if luvluaversion~=LUAVERSION then
- return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
- end
- else
- return "invalid status file"
- end
- else
- return "missing status file"
- end
+ local enginebanner=status.banner
+ if enginebanner and texname then
+ local luvname=file.replacesuffix(texname,"luv")
+ if lfs.isfile(luvname) then
+ local luv=dofile(luvname)
+ if luv and luv.sourcefile then
+ local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
+ local luvbanner=luv.enginebanner or "?"
+ if luvbanner~=enginebanner then
+ return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+ end
+ local luvhash=luv.sourcehash or "?"
+ if luvhash~=sourcehash then
+ return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
+ end
+ local luvluaversion=luv.luaversion or 0
+ if luvluaversion~=LUAVERSION then
+ return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
+ end
+ else
+ return "invalid status file"
+ end
+ else
+ return "missing status file"
end
- return true
+ end
+ return true
end
@@ -19813,233 +23389,233 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-zip"] = package.loaded["data-zip"] or true
--- original size: 8716, stripped down to: 6795
+-- original size: 8700, stripped down to: 6313
if not modules then modules={} end modules ['data-zip']={
- 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 format,find,match=string.format,string.find,string.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_zip=logs.reporter("resolvers","zip")
local resolvers=resolvers
zip=zip or {}
local zip=zip
-zip.archives=zip.archives or {}
-local archives=zip.archives
-zip.registeredfiles=zip.registeredfiles or {}
-local registeredfiles=zip.registeredfiles
+local archives=zip.archives or {}
+zip.archives=archives
+local registeredfiles=zip.registeredfiles or {}
+zip.registeredfiles=registeredfiles
local function validzip(str)
- if not find(str,"^zip://") then
- return "zip:///"..str
- else
- return str
- end
+ if not find(str,"^zip://") then
+ return "zip:///"..str
+ else
+ return str
+ end
end
function zip.openarchive(name)
- if not name or name=="" then
- return nil
- else
- local arch=archives[name]
- if not arch then
- local full=resolvers.findfile(name) or ""
- arch=full~="" and zip.open(full) or false
- archives[name]=arch
- end
- return arch
+ if not name or name=="" then
+ return nil
+ else
+ local arch=archives[name]
+ if not arch then
+ local full=resolvers.findfile(name) or ""
+ arch=full~="" and zip.open(full) or false
+ archives[name]=arch
end
+ return arch
+ end
end
function zip.closearchive(name)
- if not name or (name=="" and archives[name]) then
- zip.close(archives[name])
- archives[name]=nil
- end
+ if not name or (name=="" and archives[name]) then
+ zip.close(archives[name])
+ archives[name]=nil
+ end
end
function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and zip.openarchive(archive)
- if trace_locating then
- if zipfile then
- report_zip("locator: archive %a found",archive)
- else
- report_zip("locator: archive %a not found",archive)
- end
+ local archive=specification.filename
+ local zipfile=archive and archive~="" and zip.openarchive(archive)
+ if trace_locating then
+ if zipfile then
+ report_zip("locator: archive %a found",archive)
+ else
+ report_zip("locator: archive %a not found",archive)
end
+ end
end
function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
- report_zip("loading file %a",archive)
- end
- resolvers.usezipfile(specification.original)
+ local archive=specification.filename
+ if trace_locating then
+ report_zip("loading file %a",archive)
+ end
+ resolvers.usezipfile(specification.original)
end
function resolvers.concatinators.zip(zipfile,path,name)
- if not path or path=="" then
- return format('%s?name=%s',zipfile,name)
- else
- return format('%s?name=%s/%s',zipfile,path,name)
- end
+ if not path or path=="" then
+ return format('%s?name=%s',zipfile,name)
+ else
+ return format('%s?name=%s/%s',zipfile,path,name)
+ end
end
function resolvers.finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("finder: archive %a found",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- dfile=zfile:close()
- if trace_locating then
- report_zip("finder: file %a found",queryname)
- end
- return specification.original
- elseif trace_locating then
- report_zip("finder: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("finder: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("finder: archive %a found",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ dfile:close()
+ if trace_locating then
+ report_zip("finder: file %a found",queryname)
+ end
+ return specification.original
+ elseif trace_locating then
+ report_zip("finder: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("finder: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("finder: %a not found",original)
- end
- return resolvers.finders.notfound()
+ end
+ if trace_locating then
+ report_zip("finder: %a not found",original)
+ end
+ return resolvers.finders.notfound()
end
function resolvers.openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("opener; archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- if trace_locating then
- report_zip("opener: file %a found",queryname)
- end
- return resolvers.openers.helpers.textopener('zip',original,dfile)
- elseif trace_locating then
- report_zip("opener: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("opener: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("opener; archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ if trace_locating then
+ report_zip("opener: file %a found",queryname)
+ end
+ return resolvers.openers.helpers.textopener('zip',original,dfile)
+ elseif trace_locating then
+ report_zip("opener: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("opener: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("opener: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("opener: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("loader: archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- logs.show_load(original)
- if trace_locating then
- report_zip("loader; file %a loaded",original)
- end
- local s=dfile:read("*all")
- dfile:close()
- return true,s,#s
- elseif trace_locating then
- report_zip("loader: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("loader; unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("loader: archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ logs.show_load(original)
+ if trace_locating then
+ report_zip("loader; file %a loaded",original)
+ end
+ local s=dfile:read("*all")
+ dfile:close()
+ return true,s,#s
+ elseif trace_locating then
+ report_zip("loader: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("loader; unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("loader: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("loader: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.usezipfile(archive)
- local specification=resolvers.splitmethod(archive)
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
- local z=zip.openarchive(archive)
- if z then
- local tree=url.query(specification.query).tree or ""
- if trace_locating then
- report_zip("registering: archive %a",archive)
- end
- resolvers.starttiming()
- resolvers.prependhash('zip',archive)
- resolvers.extendtexmfvariable(archive)
- registeredfiles[archive]=z
- resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
- resolvers.stoptiming()
- elseif trace_locating then
- report_zip("registering: unknown archive %a",archive)
- end
+ local specification=resolvers.splitmethod(archive)
+ local archive=specification.filename
+ if archive and not registeredfiles[archive] then
+ local z=zip.openarchive(archive)
+ if z then
+ local tree=url.query(specification.query).tree or ""
+ if trace_locating then
+ report_zip("registering: archive %a",archive)
+ end
+ resolvers.starttiming()
+ resolvers.prependhash('zip',archive)
+ resolvers.extendtexmfvariable(archive)
+ registeredfiles[archive]=z
+ resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
+ resolvers.stoptiming()
elseif trace_locating then
- report_zip("registering: archive %a not found",archive)
+ report_zip("registering: unknown archive %a",archive)
end
+ elseif trace_locating then
+ report_zip("registering: archive %a not found",archive)
+ end
end
function resolvers.registerzipfile(z,tree)
- local names={}
- local files={}
- local remap={}
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- local register=resolvers.registerfile
- if trace_locating then
- report_zip("registering: using filter %a",filter)
- end
- for i in z:files() do
- local filename=i.filename
- local path,name=match(filename,filter)
- if not path then
- n=n+1
- register(names,filename,"")
- local usedname=lower(filename)
- files[usedname]=""
- if usedname~=filename then
- remap[usedname]=filename
- end
- elseif name and name~="" then
- n=n+1
- register(names,name,path)
- local usedname=lower(name)
- files[usedname]=path
- if usedname~=name then
- remap[usedname]=name
- end
- else
- end
+ local names={}
+ local files={}
+ local remap={}
+ local n=0
+ local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
+ local register=resolvers.registerfile
+ if trace_locating then
+ report_zip("registering: using filter %a",filter)
+ end
+ for i in z:files() do
+ local filename=i.filename
+ local path,name=match(filename,filter)
+ if not path then
+ n=n+1
+ register(names,filename,"")
+ local usedname=lower(filename)
+ files[usedname]=""
+ if usedname~=filename then
+ remap[usedname]=filename
+ end
+ elseif name and name~="" then
+ n=n+1
+ register(names,name,path)
+ local usedname=lower(name)
+ files[usedname]=path
+ if usedname~=name then
+ remap[usedname]=name
+ end
+ else
end
- report_zip("registering: %s files registered",n)
- return {
- files=files,
- remap=remap,
- }
+ end
+ report_zip("registering: %s files registered",n)
+ return {
+ files=files,
+ remap=remap,
+ }
end
@@ -20049,20 +23625,20 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tre"] = package.loaded["data-tre"] or true
--- original size: 8479, stripped down to: 5580
+-- original size: 8478, stripped down to: 5223
if not modules then modules={} end modules ['data-tre']={
- 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 find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file .join
+local basename,dirname,joinname=file.basename,file.dirname,file .join
local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_trees=logs.reporter("resolvers","trees")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -20071,165 +23647,167 @@ local lookup=resolvers.get_from_content
local collectors={}
local found={}
function resolvers.finders.tree(specification)
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
- if spec~="" then
- local path=dirname(spec)
- local name=basename(spec)
- if path=="" then
- path="."
- end
- local names=collectors[path]
- if not names then
- local pattern=find(path,"/%*+$") and path or (path.."/*")
- names=globdir(pattern)
- collectors[path]=names
- end
- local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
- for i=1,#names do
- local fullname=names[i]
- if find(fullname,pattern) then
- found[spec]=fullname
- return fullname
- end
- end
- local pattern=lower(pattern)
- for i=1,#names do
- local fullname=lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
- found[spec]=fullname
- return fullname
- else
- break
- end
- end
- end
+ local spec=specification.filename
+ local okay=found[spec]
+ if okay==nil then
+ if spec~="" then
+ local path=dirname(spec)
+ local name=basename(spec)
+ if path=="" then
+ path="."
+ end
+ local names=collectors[path]
+ if not names then
+ local pattern=find(path,"/%*+$") and path or (path.."/*")
+ names=globdir(pattern)
+ collectors[path]=names
+ end
+ local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
+ for i=1,#names do
+ local fullname=names[i]
+ if find(fullname,pattern) then
+ found[spec]=fullname
+ return fullname
+ end
+ end
+ local pattern=lower(pattern)
+ for i=1,#names do
+ local fullname=lower(names[i])
+ if find(fullname,pattern) then
+ if isfile(fullname) then
+ found[spec]=fullname
+ return fullname
+ else
+ break
+ end
end
- okay=notfound()
- found[spec]=okay
+ end
end
- return okay
+ okay=notfound()
+ found[spec]=okay
+ end
+ return okay
end
function resolvers.locators.tree(specification)
- local name=specification.filename
- local realname=resolveprefix(name)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
- end
- resolvers.appendhash('tree',name,false)
- elseif trace_locating then
- report_trees("locator %a not found",name)
+ local name=specification.filename
+ local realname=resolveprefix(name)
+ if realname and realname~='' and isdir(realname) then
+ if trace_locating then
+ report_trees("locator %a found",realname)
end
+ resolvers.appendhash('tree',name,false)
+ elseif trace_locating then
+ report_trees("locator %a not found",name)
+ end
end
function resolvers.hashers.tree(specification)
- local name=specification.filename
- report_trees("analyzing %a",name)
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+ local name=specification.filename
+ if trace_locating then
+ report_trees("analyzing %a",name)
+ end
+ resolvers.methodhandler("hashers",name)
+ resolvers.generators.file(specification)
end
local collectors={}
local splitter=lpeg.splitat("/**/")
local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=caches.loadcontent(dataname,"files",dataname)
- if not content then
- content=resolvers.scanfiles(rootname,nil,nil,false,true)
- caches.savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
+ local rootname=lpegmatch(stripper,k)
+ local dataname=joinname(rootname,"dirlist")
+ local content=caches.loadcontent(dataname,"files",dataname)
+ if not content then
+ content=resolvers.scanfiles(rootname,nil,nil,false,true)
+ caches.savecontent(dataname,"files",content,dataname)
+ end
+ t[k]=content
+ return content
end)
local function checked(root,p,n)
- if p then
- if type(p)=="table" then
- for i=1,#p do
- local fullname=joinname(root,p[i],n)
- if isfile(fullname) then
- return fullname
- end
- end
- else
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
+ if p then
+ if type(p)=="table" then
+ for i=1,#p do
+ local fullname=joinname(root,p[i],n)
+ if isfile(fullname) then
+ return fullname
end
+ end
+ else
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- return notfound()
+ end
+ return notfound()
end
local function resolve(specification)
- local filename=specification.filename
- if filename~="" then
- local root,rest=lpegmatch(splitter,filename)
- if root and rest then
- local path,name=dirname(rest),basename(rest)
- if name~=rest then
- local content=collectors[root]
- local p,n=lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern=".*/"..path.."$"
- local istable=type(p)=="table"
- if istable then
- for i=1,#p do
- local pi=p[i]
- if pi==path or find(pi,pattern) then
- local fullname=joinname(root,pi,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- elseif p==path or find(p,pattern) then
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- local queries=specification.queries
- if queries and queries.option=="fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
+ local filename=specification.filename
+ if filename~="" then
+ local root,rest=lpegmatch(splitter,filename)
+ if root and rest then
+ local path,name=dirname(rest),basename(rest)
+ if name~=rest then
+ local content=collectors[root]
+ local p,n=lookup(content,name)
+ if not p then
+ return notfound()
+ end
+ local pattern=".*/"..path.."$"
+ local istable=type(p)=="table"
+ if istable then
+ for i=1,#p do
+ local pi=p[i]
+ if pi==path or find(pi,pattern) then
+ local fullname=joinname(root,pi,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
+ end
+ elseif p==path or find(p,pattern) then
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- local path,name=dirname(filename),basename(filename)
- local root=lpegmatch(stripper,path)
- local content=collectors[path]
- local p,n=lookup(content,name)
- if p then
- return checked(root,p,n)
+ local queries=specification.queries
+ if queries and queries.option=="fileonly" then
+ return checked(root,p,n)
+ else
+ return notfound()
end
+ end
end
- return notfound()
+ local path,name=dirname(filename),basename(filename)
+ local root=lpegmatch(stripper,path)
+ local content=collectors[path]
+ local p,n=lookup(content,name)
+ if p then
+ return checked(root,p,n)
+ end
+ end
+ return notfound()
end
-resolvers.finders .dirlist=resolve
-resolvers.locators .dirlist=resolvers.locators .tree
-resolvers.hashers .dirlist=resolvers.hashers .tree
+resolvers.finders .dirlist=resolve
+resolvers.locators .dirlist=resolvers.locators .tree
+resolvers.hashers .dirlist=resolvers.hashers .tree
resolvers.generators.dirlist=resolvers.generators.file
-resolvers.openers .dirlist=resolvers.openers .file
-resolvers.loaders .dirlist=resolvers.loaders .file
+resolvers.openers .dirlist=resolvers.openers .file
+resolvers.loaders .dirlist=resolvers.loaders .file
function resolvers.finders.dirfile(specification)
- local queries=specification.queries
- if queries then
- queries.option="fileonly"
- else
- specification.queries={ option="fileonly" }
- end
- return resolve(specification)
-end
-resolvers.locators .dirfile=resolvers.locators .dirlist
-resolvers.hashers .dirfile=resolvers.hashers .dirlist
+ local queries=specification.queries
+ if queries then
+ queries.option="fileonly"
+ else
+ specification.queries={ option="fileonly" }
+ end
+ return resolve(specification)
+end
+resolvers.locators .dirfile=resolvers.locators .dirlist
+resolvers.hashers .dirfile=resolvers.hashers .dirlist
resolvers.generators.dirfile=resolvers.generators.dirlist
-resolvers.openers .dirfile=resolvers.openers .dirlist
-resolvers.loaders .dirfile=resolvers.loaders .dirlist
+resolvers.openers .dirfile=resolvers.openers .dirlist
+resolvers.loaders .dirfile=resolvers.loaders .dirlist
end -- of closure
@@ -20238,19 +23816,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-sch"] = package.loaded["data-sch"] or true
--- original size: 6753, stripped down to: 5511
+-- original size: 6753, stripped down to: 5268
if not modules then modules={} end modules ['data-sch']={
- 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 load,tonumber=load,tonumber
local gsub,concat,format=string.gsub,table.concat,string.format
local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
+local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
local report_schemes=logs.reporter("resolvers","schemes")
local http=require("socket.http")
local ltn12=require("ltn12")
@@ -20263,27 +23841,27 @@ schemes.cleaners=cleaners
local threshold=24*60*60
directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
function cleaners.none(specification)
- return specification.original
+ return specification.original
end
function cleaners.strip(specification)
- local path,name=file.splitbase(specification.original)
- if path=="" then
- return (gsub(name,"[^%a%d%.]+","-"))
- else
- return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
+ local path,name=file.splitbase(specification.original)
+ if path=="" then
+ return (gsub(name,"[^%a%d%.]+","-"))
+ else
+ return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
+ end
end
function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
+ return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
end
local cleaner=cleaners.strip
directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
+ local hash=cleaner(specification)
+ if trace_schemes then
+ report_schemes("hashing %a to %a",specification.original,hash)
+ end
+ return hash
end
local cached={}
local loaded={}
@@ -20291,139 +23869,139 @@ local reused={}
local thresholds={}
local handlers={}
local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template="--silent --insecure --create-dirs --output %cachename% %original%",
- checkers={
- cachename="cache",
- original="url",
- }
+ name="curl resolver",
+ method="execute",
+ program="curl",
+ template="--silent --insecure --create-dirs --output %cachename% %original%",
+ checkers={
+ cachename="cache",
+ original="url",
+ }
}
local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
- cached[original]=cachename
- local handler=handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
- end
- logs.flush()
- runner {
- original=original,
- cachename=cachename,
- }
- end
- end
- if io.exists(cachename) then
- cached[original]=cachename
- if trace_schemes then
- report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
- end
- else
- cached[original]=""
- if trace_schemes then
- report_schemes("using missing %a, protocol %a",original,scheme)
- end
+ local original=specification.original
+ local scheme=specification.scheme
+ local cleanname=schemes.cleanname(specification)
+ local cachename=caches.setfirstwritablefile(cleanname,"schemes")
+ if not cached[original] then
+ statistics.starttiming(schemes)
+ if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
+ cached[original]=cachename
+ local handler=handlers[scheme]
+ if handler then
+ if trace_schemes then
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
end
- loaded[scheme]=loaded[scheme]+1
- statistics.stoptiming(schemes)
- else
+ logs.flush()
+ handler(specification,cachename)
+ else
if trace_schemes then
- report_schemes("reusing %a, protocol %a",original,scheme)
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
end
- reused[scheme]=reused[scheme]+1
+ logs.flush()
+ runner {
+ original=original,
+ cachename=cachename,
+ }
+ end
+ end
+ if io.exists(cachename) then
+ cached[original]=cachename
+ if trace_schemes then
+ report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
+ end
+ else
+ cached[original]=""
+ if trace_schemes then
+ report_schemes("using missing %a, protocol %a",original,scheme)
+ end
end
- return cached[original]
+ loaded[scheme]=loaded[scheme]+1
+ statistics.stoptiming(schemes)
+ else
+ if trace_schemes then
+ report_schemes("reusing %a, protocol %a",original,scheme)
+ end
+ reused[scheme]=reused[scheme]+1
+ end
+ return cached[original]
end
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",fetch(specification),filetype)
end
local opener=openers.file
local loader=loaders.file
local function install(scheme,handler,newthreshold)
- handlers [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders [scheme]=finder
- openers [scheme]=opener
- loaders [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
+ handlers [scheme]=handler
+ loaded [scheme]=0
+ reused [scheme]=0
+ finders [scheme]=finder
+ openers [scheme]=opener
+ loaders [scheme]=loader
+ thresholds[scheme]=newthreshold or threshold
end
schemes.install=install
local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local f=io.open(tempname,"wb")
- local status,message=http.request {
- url=specification.original,
- sink=ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
+ local tempname=cachename..".tmp"
+ local f=io.open(tempname,"wb")
+ local status,message=http.request {
+ url=specification.original,
+ sink=ltn12.sink.file(f)
+ }
+ if not status then
+ os.remove(tempname)
+ else
+ os.remove(cachename)
+ os.rename(tempname,cachename)
+ end
+ return cachename
end
install('http',http_handler)
install('https')
install('ftp')
statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in table.sortedhash(loaded) do
- if v>0 then
- nl=nl+1
- l[nl]=k..":"..v
- end
- end
- for k,v in table.sortedhash(reused) do
- if v>0 then
- nr=nr+1
- r[nr]=k..":"..v
- end
- end
- local n=nl+nr
- if n>0 then
- l=nl>0 and concat(l) or "none"
- r=nr>0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes),n,threshold,l,r)
- else
- return nil
- end
+ local l,r,nl,nr={},{},0,0
+ for k,v in table.sortedhash(loaded) do
+ if v>0 then
+ nl=nl+1
+ l[nl]=k..":"..v
+ end
+ end
+ for k,v in table.sortedhash(reused) do
+ if v>0 then
+ nr=nr+1
+ r[nr]=k..":"..v
+ end
+ end
+ local n=nl+nr
+ if n>0 then
+ l=nl>0 and concat(l) or "none"
+ r=nr>0 and concat(r) or "none"
+ return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
+ statistics.elapsedtime(schemes),n,threshold,l,r)
+ else
+ return nil
+ end
end)
local httprequest=http.request
local toquery=url.toquery
local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
- url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply
+ local q=data and toquery(data)
+ if q then
+ url=url.."?"..q
+ end
+ local reply=httprequest(url)
+ return reply
end
schemes.fetchstring=fetchstring
function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
- local s=load("return "..reply)
- if s then
- return s()
- end
+ local reply=fetchstring(url,data)
+ if reply then
+ local s=load("return "..reply)
+ if s then
+ return s()
end
+ end
end
@@ -20433,14 +24011,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lua"] = package.loaded["data-lua"] or true
--- original size: 4207, stripped down to: 3137
+-- original size: 4207, stripped down to: 3041
if not modules then modules={} end modules ['data-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 package,lpeg=package,lpeg
local gsub=string.gsub
@@ -20459,20 +24037,20 @@ helpers.report=logs.reporter("resolvers","libraries")
trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
trackers.register("resolvers.locating",function(v) helpers.trace=v end)
helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
+ "already loaded",
+ "preload table",
+ "lua variable format",
+ "lib variable format",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
}
local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
function helpers.cleanpath(path)
- return resolveprefix(lpegmatch(pattern,path))
+ return resolveprefix(lpegmatch(pattern,path))
end
local loadedaslib=helpers.loadedaslib
local registerpath=helpers.registerpath
@@ -20480,56 +24058,56 @@ local lualibfile=helpers.lualibfile
local luaformatpaths
local libformatpaths
local function getluaformatpaths()
- if not luaformatpaths then
- luaformatpaths={}
- for i=1,#luaformats do
- registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
- end
+ if not luaformatpaths then
+ luaformatpaths={}
+ for i=1,#luaformats do
+ registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
end
- return luaformatpaths
+ end
+ return luaformatpaths
end
local function getlibformatpaths()
- if not libformatpaths then
- libformatpaths={}
- for i=1,#libformats do
- registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
- end
+ if not libformatpaths then
+ libformatpaths={}
+ for i=1,#libformats do
+ registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
end
- return libformatpaths
+ end
+ return libformatpaths
end
local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do
- local format=suffixes[i]
- local resolved=resolvers.findfile(name,format) or ""
- if trace then
- report("%s format, identifying %a using format %a",what,name,format)
- end
- if resolved~="" then
- if trace then
- report("%s format, %a found on %a",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ local report=helpers.report
+ for i=1,#suffixes do
+ local format=suffixes[i]
+ local resolved=resolvers.findfile(name,format) or ""
+ if trace then
+ report("%s format, identifying %a using format %a",what,name,format)
+ end
+ if resolved~="" then
+ if trace then
+ report("%s format, %a found on %a",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbyformat=loadedbyformat
methods["lua variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
end
methods["lib variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
end
resolvers.loadlualib=require
@@ -20540,64 +24118,64 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-aux"] = package.loaded["data-aux"] or true
--- original size: 2438, stripped down to: 2003
+-- original size: 2452, stripped down to: 1877
if not modules then modules={} end modules ['data-aux']={
- 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 find=string.find
local type,next=type,next
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local resolvers=resolvers
local report_scripts=logs.reporter("resolvers","scripts")
function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- newname=file.addsuffix(newname,"lua")
- local oldscript=resolvers.cleanpath(oldname)
+ local scriptpath="context/lua"
+ newname=file.addsuffix(newname,"lua")
+ local oldscript=resolvers.cleanpath(oldname)
+ if trace_locating then
+ report_scripts("to be replaced old script %a",oldscript)
+ end
+ local newscripts=resolvers.findfiles(newname) or {}
+ if #newscripts==0 then
if trace_locating then
- report_scripts("to be replaced old script %a",oldscript)
+ report_scripts("unable to locate new script")
end
- local newscripts=resolvers.findfiles(newname) or {}
- if #newscripts==0 then
+ else
+ for i=1,#newscripts do
+ local newscript=resolvers.cleanpath(newscripts[i])
+ if trace_locating then
+ report_scripts("checking new script %a",newscript)
+ end
+ if oldscript==newscript then
if trace_locating then
- report_scripts("unable to locate new script")
+ report_scripts("old and new script are the same")
end
- else
- for i=1,#newscripts do
- local newscript=resolvers.cleanpath(newscripts[i])
- if trace_locating then
- report_scripts("checking new script %a",newscript)
- end
- if oldscript==newscript then
- if trace_locating then
- report_scripts("old and new script are the same")
- end
- elseif not find(newscript,scriptpath,1,true) then
- if trace_locating then
- report_scripts("new script should come from %a",scriptpath)
- end
- elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
- if trace_locating then
- report_scripts("invalid new script name")
- end
- else
- local newdata=io.loaddata(newscript)
- if newdata then
- if trace_locating then
- report_scripts("old script content replaced by new content")
- end
- io.savedata(oldscript,newdata)
- break
- elseif trace_locating then
- report_scripts("unable to load new script")
- end
- end
+ elseif not find(newscript,scriptpath,1,true) then
+ if trace_locating then
+ report_scripts("new script should come from %a",scriptpath)
end
+ elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+ if trace_locating then
+ report_scripts("invalid new script name")
+ end
+ else
+ local newdata=io.loaddata(newscript)
+ if newdata then
+ if trace_locating then
+ report_scripts("old script content replaced by new content: %s",oldscript)
+ end
+ io.savedata(oldscript,newdata)
+ break
+ elseif trace_locating then
+ report_scripts("unable to load new script")
+ end
+ end
end
+ end
end
@@ -20607,53 +24185,53 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
--- original size: 2601, stripped down to: 1627
+-- original size: 2601, stripped down to: 1549
if not modules then modules={} end modules ['data-tmf']={
- 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 resolvers=resolvers
local report_tds=logs.reporter("resolvers","tds")
function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
- local getenv,setenv=resolvers.getenv,resolvers.setenv
- local texos="texmf-"..os.platform
- local oldroot=environment.texroot
- local newroot=file.collapsepath(tree)
- local newtree=file.join(newroot,texos)
- local newpath=file.join(newtree,"bin")
- if not lfs.isdir(newtree) then
- report_tds("no %a under tree %a",texos,tree)
- os.exit()
- end
- if not lfs.isdir(newpath) then
- report_tds("no '%s/bin' under tree %a",texos,tree)
- os.exit()
- end
- local texmfos=newtree
- environment.texroot=newroot
- environment.texos=texos
- environment.texmfos=texmfos
- if resolve then
- resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
- end
- setenv('SELFAUTOPARENT',newroot)
- setenv('SELFAUTODIR',newtree)
- setenv('SELFAUTOLOC',newpath)
- setenv('TEXROOT',newroot)
- setenv('TEXOS',texos)
- setenv('TEXMFOS',texmfos)
- setenv('TEXMFCNF',resolvers.luacnfspec,true)
- setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
- report_tds("changing from root %a to %a",oldroot,newroot)
- report_tds("prepending %a to PATH",newpath)
- report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
- report_tds()
- end
+ if type(tree)=="string" and tree~="" then
+ local getenv,setenv=resolvers.getenv,resolvers.setenv
+ local texos="texmf-"..os.platform
+ local oldroot=environment.texroot
+ local newroot=file.collapsepath(tree)
+ local newtree=file.join(newroot,texos)
+ local newpath=file.join(newtree,"bin")
+ if not lfs.isdir(newtree) then
+ report_tds("no %a under tree %a",texos,tree)
+ os.exit()
+ end
+ if not lfs.isdir(newpath) then
+ report_tds("no '%s/bin' under tree %a",texos,tree)
+ os.exit()
+ end
+ local texmfos=newtree
+ environment.texroot=newroot
+ environment.texos=texos
+ environment.texmfos=texmfos
+ if resolve then
+ resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
+ end
+ setenv('SELFAUTOPARENT',newroot)
+ setenv('SELFAUTODIR',newtree)
+ setenv('SELFAUTOLOC',newpath)
+ setenv('TEXROOT',newroot)
+ setenv('TEXOS',texos)
+ setenv('TEXMFOS',texmfos)
+ setenv('TEXMFCNF',resolvers.luacnfspec,true)
+ setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
+ report_tds("changing from root %a to %a",oldroot,newroot)
+ report_tds("prepending %a to PATH",newpath)
+ report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
+ report_tds()
+ end
end
@@ -20663,14 +24241,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lst"] = package.loaded["data-lst"] or true
--- original size: 1823, stripped down to: 1591
+-- original size: 1823, stripped down to: 1542
if not modules then modules={} end modules ['data-lst']={
- 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=type
local concat,sortedhash=table.concat,table.sortedhash
@@ -20681,37 +24259,37 @@ local resolveprefix=resolvers.resolve
local report_lists=logs.reporter("resolvers","lists")
local report_resolved=logs.reporter("system","resolved")
local function tabstr(str)
- if type(str)=='table' then
- return concat(str," | ")
- else
- return str
- end
+ if type(str)=='table' then
+ return concat(str," | ")
+ else
+ return str
+ end
end
function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
- report_lists(key)
- report_lists(" env: %s",tabstr(value.environment or "unset"))
- report_lists(" var: %s",tabstr(value.variable or "unset"))
- report_lists(" exp: %s",tabstr(value.expansion or "unset"))
- report_lists(" res: %s",tabstr(value.resolved or "unset"))
- end
+ local result=resolvers.knownvariables(pattern)
+ for key,value in sortedhash(result) do
+ report_lists(key)
+ report_lists(" env: %s",tabstr(value.environment or "unset"))
+ report_lists(" var: %s",tabstr(value.variable or "unset"))
+ report_lists(" exp: %s",tabstr(value.expansion or "unset"))
+ report_lists(" res: %s",tabstr(value.resolved or "unset"))
+ end
end
function listers.configurations()
- local configurations=resolvers.configurationfiles()
- for i=1,#configurations do
- report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
- for i=1,#list do
- local li=resolveprefix(list[i])
- if lfs.isdir(li) then
- report_resolved("path - %s",li)
- else
- report_resolved("path + %s",li)
- end
+ local configurations=resolvers.configurationfiles()
+ for i=1,#configurations do
+ report_resolved("file : %s",resolveprefix(configurations[i]))
+ end
+ report_resolved("")
+ local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+ for i=1,#list do
+ local li=resolveprefix(list[i])
+ if lfs.isdir(li) then
+ report_resolved("path - %s",li)
+ else
+ report_resolved("path + %s",li)
end
+ end
end
@@ -20721,14 +24299,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 14943, stripped down to: 8305
+-- original size: 16094, stripped down to: 8443
if not modules then modules={} end modules ['util-lib']={
- 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=type
local next=next
@@ -20748,256 +24326,291 @@ local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
local done=false
local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
- end
- found_library=required
- else
- if trace then
- report("qualified name %a not found",required)
- end
- end
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ local required_full=gsub(required,"%.","/")
+ local required_path=pathpart(required_full)
+ local required_base=nameonly(required_full)
+ if qualifiedpath(required) then
+ if isfile(addsuffix(required,os.libsuffix)) then
+ if trace then
+ report("qualified name %a found",required)
+ end
+ found_library=required
else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine="luatex"
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ if trace then
+ report("qualified name %a not found",required)
+ end
+ end
+ else
+ local required_name=required_base.."."..os.libsuffix
+ local version=type(version)=="string" and version~="" and version or false
+ local engine="luatex"
+ if trace and not done then
+ local list=expandpaths("lib")
+ for i=1,#list do
+ report("tds path %i: %s",i,list[i])
+ end
+ end
+ local function found(locate,asked_library,how,...)
+ if trace then
+ report("checking %s: %a",how,asked_library)
+ end
+ return locate(asked_library,...)
+ end
+ local function check(locate,...)
+ local found=nil
+ if version then
+ local asked_library=joinfile(required_path,version,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
- end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
+ found=locate(asked_library,...)
+ end
+ if not found or found=="" then
+ local asked_library=joinfile(required_path,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
+ found=locate(asked_library,...)
+ end
+ return found and found~="" and found or false
+ end
+ local function attempt(checkpattern)
+ if trace then
+ report("checking tds lib paths strictly")
+ end
+ local found=findfile and check(findfile,"lib")
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
+ end
+ if trace then
+ report("checking tds lib paths with wildcard")
+ end
+ local asked_library=joinfile(required_path,".*",required_name)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
+ end
+ local list=findfiles(asked_library,"lib",true)
+ if list and #list>0 then
+ sort(list)
+ local found=list[#list]
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
- end
- found_library=attempt()
- end
- else
- found_library=attempt()
+ end
+ if trace then
+ report("checking lib paths")
+ end
+ package.extralibpath(environment.ownpath)
+ local paths=package.libpaths()
+ local pattern="/[^/]+%."..os.libsuffix.."$"
+ for i=1,#paths do
+ required_path=gsub(paths[i],pattern,"")
+ local found=check(lfs.isfound)
+ if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
+ return found
end
+ end
+ return false
end
- if not found_library then
+ if engine then
+ if trace then
+ report("attemp 1, engine %a",engine)
+ end
+ found_library=attempt("/"..engine.."/")
+ if not found_library then
if trace then
- report("not found: %a",required)
+ report("attemp 2, no engine",asked_library)
end
- library=false
+ found_library=attempt()
+ end
else
- if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
- end
+ found_library=attempt()
end
+ end
+ if not found_library then
if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
+ report("not found: %a",required)
end
- return library
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local result,message=action(found_library,required_base)
+ if result then
+ library=result
+ else
+ library=false
+ report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
+ end
+ end
+ if trace then
+ if not library then
+ report("unknown library: %a",required)
+ else
+ report("stored library: %a",required)
+ end
+ end
+ return library or nil
end
do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
- else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
- end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ local loadlib=package.loadlib
+ local pushdir=dir.push
+ local popdir=dir.pop
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ pushdir(pathpart(name))
+ local opener="luaopen_"..base
+ if trace_swiglib then
+ report_swiglib("opening: %a with %a",name,opener)
+ end
+ local library,message=loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
+ else
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
end
+ popdir()
return library
+ end)
+ loadedlibs[required]=library or false
end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
- end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
+ else
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
+ if trace_swiglib then
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
+ else
+ fullname="swiglib."..name
+ end
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
- end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
- end
- return library
+ return library
+ end
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
+ end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- 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
- l=library
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ local loaded={}
+ local function locateindeed(name)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l==nil 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
+ loaded[name]=l
+ elseif trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- elseif version=="system" then
- return locateindeed(name)
- else
- return locate(name,version,trace_ffilib,report_ffilib,locateindeed)
+ 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
- function ffi.load(name)
- local library=ffilib(name)
+ return { required }
+ end
+ function ffilib(name,version)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l~=nil then
+ if trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
+ end
+ return l
+ 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
+ return library
end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
+ end
+ else
+ for i=1,#list do
+ local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
+ if type(library)=="userdata" then
+ return library
end
- return savedffiload(name)
+ end
end
+ end
+ function ffi.load(name)
+ 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
+ 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
@@ -21007,13 +24620,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
--- original size: 5703, stripped down to: 2507
+-- original size: 5703, stripped down to: 2321
if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gmatch,match=string.gmatch,string.match
local type=type
@@ -21026,81 +24639,81 @@ local hash=states.hash
states.tag=states.tag or ""
states.filename=states.filename or ""
function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
- "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
+ tag=tag or states.tag
+ filename=file.addsuffix(filename or states.filename,'lus')
+ io.savedata(filename,
+ "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
+ )
end
function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
+ states.filename=filename
+ states.tag=tag or "whatever"
+ states.filename=file.addsuffix(states.filename,'lus')
+ data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
end
local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
- if type(d)=="table" then
- local dkey,hkey=key,key
- local pre,post=match(key,"(.+)%.([^%.]+)$")
- if pre and post then
- for k in gmatch(pre,"[^%.]+") do
- local dk=d[k]
- if not dk then
- dk={}
- d[k]=dk
- elseif type(dk)=="string" then
- break
- end
- d=dk
- end
- dkey,hkey=post,key
- end
- if value==nil then
- value=default
- elseif value==false then
- elseif persistent then
- value=value or d[dkey] or default
- else
- value=value or default
- end
- d[dkey],h[hkey]=value,value
- elseif type(d)=="string" then
- data[tag],hash[tag]=value,value
+ local d,h=data[tag],hash[tag]
+ if d then
+ if type(d)=="table" then
+ local dkey,hkey=key,key
+ local pre,post=match(key,"(.+)%.([^%.]+)$")
+ if pre and post then
+ for k in gmatch(pre,"[^%.]+") do
+ local dk=d[k]
+ if not dk then
+ dk={}
+ d[k]=dk
+ elseif type(dk)=="string" then
+ break
+ end
+ d=dk
end
+ dkey,hkey=post,key
+ end
+ if value==nil then
+ value=default
+ elseif value==false then
+ elseif persistent then
+ value=value or d[dkey] or default
+ else
+ value=value or default
+ end
+ d[dkey],h[hkey]=value,value
+ elseif type(d)=="string" then
+ data[tag],hash[tag]=value,value
end
+ end
end
local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
- return h[key]
- else
- local d=data[tag]
- if d then
- for k in gmatch(key,"[^%.]+") do
- local dk=d[k]
- if dk~=nil then
- d=dk
- else
- return default
- end
- end
- if d==false then
- return false
- else
- return d or default
- end
+ local h=hash[tag]
+ if h and h[key] then
+ return h[key]
+ else
+ local d=data[tag]
+ if d then
+ for k in gmatch(key,"[^%.]+") do
+ local dk=d[k]
+ if dk~=nil then
+ d=dk
+ else
+ return default
end
+ end
+ if d==false then
+ return false
+ else
+ return d or default
+ end
end
+ end
end
states.set_by_tag=set_by_tag
states.get_by_tag=get_by_tag
function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
+ set_by_tag(states.tag,key,value,default,persistent)
end
function states.get(key,default)
- return get_by_tag(states.tag,key,default)
+ return get_by_tag(states.tag,key,default)
end
@@ -21110,14 +24723,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
--- original size: 9268, stripped down to: 7401
+-- original size: 9418, stripped down to: 7087
if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- 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 mtxrun",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format=string.format
local concat=table.concat
@@ -21125,229 +24738,232 @@ local quoted=string.quoted
local luasuffixes=utilities.lua.suffixes
local report_format=logs.reporter("resolvers","formats")
local function primaryflags()
- local arguments=environment.arguments
- local flags={}
- if arguments.silent then
- flags[#flags+1]="--interaction=batchmode"
- end
- if arguments.jit then
- flags[#flags+1]="--jiton"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local flags={}
+ if arguments.silent then
+ flags[#flags+1]="--interaction=batchmode"
+ end
+ return concat(flags," ")
end
local function secondaryflags()
- local arguments=environment.arguments
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
- flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
- flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
- flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
- flags[#flags+1]="--c:errors"
- end
- if arguments.jit then
- flags[#flags+1]="--c:jiton"
- end
- if arguments.ansi then
- flags[#flags+1]="--c:ansi"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local trackers=arguments.trackers
+ local directives=arguments.directives
+ local flags={}
+ if trackers and trackers~="" then
+ flags[#flags+1]="--c:trackers="..quoted(trackers)
+ end
+ if directives and directives~="" then
+ flags[#flags+1]="--c:directives="..quoted(directives)
+ end
+ if arguments.silent then
+ flags[#flags+1]="--c:silent"
+ end
+ if arguments.errors then
+ flags[#flags+1]="--c:errors"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--c:jiton"
+ end
+ 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
local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
local checkers={
- primaryflags="string",
- secondaryflags="string",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
+ primaryflags="string",
+ secondaryflags="string",
+ luafile="readable",
+ texfile="readable",
+ redirect="string",
+ dump="string",
}
local runners={
- luatex=sandbox.registerrunner {
- name="make luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="make luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="make luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="make luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.make_format(name,arguments)
- local engine=environment.ownmain or "luatex"
- local silent=environment.arguments.silent
- local errors=environment.arguments.errors
- local olddir=dir.current()
- local path=caches.getwritablepath("formats",engine) or ""
- if path~="" then
- lfs.chdir(path)
- end
- report_format("using format path %a",dir.current())
- local texsourcename=file.addsuffix(name,"mkiv")
- local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(name,"tex")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- report_format("no tex source file with name %a (mkiv or tex)",name)
- lfs.chdir(olddir)
- return
- else
- report_format("using tex source file %a",fulltexsourcename)
- end
- local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
- local specificationname=file.replacesuffix(fulltexsourcename,"lus")
- local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- if fullspecificationname=="" then
- specificationname=file.join(texsourcepath,"context.lus")
- fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- end
- if fullspecificationname=="" then
- report_format("unknown stub specification %a",specificationname)
- lfs.chdir(olddir)
- return
- end
- local specificationpath=file.dirname(fullspecificationname)
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
- usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
- elseif type(usedlualibs)=="table" then
- report_format("using stub specification %a",fullspecificationname)
- local texbasename=file.basename(name)
- local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
- local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
- report_format("creating initialization file %a",luastubname)
- utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
- if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
- report_format("using compiled initialization file %a",lucstubname)
- usedluastub=lucstubname
- else
- report_format("using uncompiled initialization file %a",luastubname)
- usedluastub=luastubname
- end
- else
- report_format("invalid stub specification %a",fullspecificationname)
- lfs.chdir(olddir)
- return
- end
- local specification={
- primaryflags=primaryflags(),
- secondaryflags=secondaryflags(),
- luafile=quoted(usedluastub),
- texfile=quoted(fulltexsourcename),
- dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
- elseif silent then
- statistics.starttiming()
- specification.redirect="> temp.log"
- local result=runner(specification)
- local runtime=statistics.stoptiming()
- if result~=0 then
- print(format("%s silent make > fatal error when making format %q",engine,name))
- else
- print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
- end
- os.remove("temp.log")
- else
- runner(specification)
- end
- local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
- local mp=dir.glob(pattern)
- if mp then
- for i=1,#mp do
- local name=mp[i]
- report_format("removing related mplib format %a",file.basename(name))
- os.remove(name)
- end
- end
+ local engine=environment.ownmain or "luatex"
+ local silent=environment.arguments.silent
+ local errors=environment.arguments.errors
+ local olddir=dir.current()
+ local path=caches.getwritablepath("formats",engine) or ""
+ if path~="" then
+ lfs.chdir(path)
+ end
+ report_format("using format path %a",dir.current())
+ local texsourcename=file.addsuffix(name,"mkiv")
+ local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ if fulltexsourcename=="" then
+ texsourcename=file.addsuffix(name,"tex")
+ fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ end
+ if fulltexsourcename=="" then
+ report_format("no tex source file with name %a (mkiv or tex)",name)
+ lfs.chdir(olddir)
+ return
+ else
+ report_format("using tex source file %a",fulltexsourcename)
+ end
+ local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
+ local specificationname=file.replacesuffix(fulltexsourcename,"lus")
+ local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ if fullspecificationname=="" then
+ specificationname=file.join(texsourcepath,"context.lus")
+ fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ end
+ if fullspecificationname=="" then
+ report_format("unknown stub specification %a",specificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specificationpath=file.dirname(fullspecificationname)
+ local usedluastub=nil
+ local usedlualibs=dofile(fullspecificationname)
+ if type(usedlualibs)=="string" then
+ usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
+ elseif type(usedlualibs)=="table" then
+ report_format("using stub specification %a",fullspecificationname)
+ local texbasename=file.basename(name)
+ local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
+ local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
+ report_format("creating initialization file %a",luastubname)
+ utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
+ report_format("using compiled initialization file %a",lucstubname)
+ usedluastub=lucstubname
+ else
+ report_format("using uncompiled initialization file %a",luastubname)
+ usedluastub=luastubname
+ end
+ else
+ report_format("invalid stub specification %a",fullspecificationname)
lfs.chdir(olddir)
+ return
+ end
+ local specification={
+ primaryflags=primaryflags(),
+ secondaryflags=secondaryflags(),
+ luafile=quoted(usedluastub),
+ texfile=quoted(fulltexsourcename),
+ dump=os.platform=="unix" and "\\\\dump" or "\\dump",
+ }
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
+ elseif silent then
+ statistics.starttiming()
+ specification.redirect="> temp.log"
+ local result=runner(specification)
+ local runtime=statistics.stoptiming()
+ if result~=0 then
+ print(format("%s silent make > fatal error when making format %q",engine,name))
+ else
+ print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
+ end
+ os.remove("temp.log")
+ else
+ runner(specification)
+ end
+ local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
+ local mp=dir.glob(pattern)
+ if mp then
+ for i=1,#mp do
+ local name=mp[i]
+ report_format("removing related mplib format %a",file.basename(name))
+ os.remove(name)
+ end
+ end
+ lfs.chdir(olddir)
end
local template=[[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
local checkers={
- flags="string",
- more="string",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
+ flags="string",
+ more="string",
+ fmtfile="readable",
+ luafile="readable",
+ texfile="readable",
}
local runners={
- luatex=sandbox.registerrunner {
- name="run luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="run luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="run luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="run luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.run_format(name,data,more)
- if name and name~="" then
- local engine=environment.ownmain or "luatex"
- local barename=file.removesuffix(name)
- local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
- if fmtname=="" then
- fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
- end
- fmtname=resolvers.cleanpath(fmtname)
- if fmtname=="" then
- report_format("no format with name %a",name)
+ if name and name~="" then
+ local engine=environment.ownmain or "luatex"
+ local barename=file.removesuffix(name)
+ local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
+ if fmtname=="" then
+ fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
+ end
+ fmtname=resolvers.cleanpath(fmtname)
+ if fmtname=="" then
+ report_format("no format with name %a",name)
+ else
+ local barename=file.removesuffix(name)
+ local luaname=file.addsuffix(barename,"luc")
+ if not lfs.isfile(luaname) then
+ luaname=file.addsuffix(barename,"lua")
+ end
+ if not lfs.isfile(luaname) then
+ report_format("using format name %a",fmtname)
+ report_format("no luc/lua file with name %a",barename)
+ else
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be run, no runner available for engine %a",name,engine)
else
- local barename=file.removesuffix(name)
- local luaname=file.addsuffix(barename,"luc")
- if not lfs.isfile(luaname) then
- luaname=file.addsuffix(barename,"lua")
- end
- if not lfs.isfile(luaname) then
- report_format("using format name %a",fmtname)
- report_format("no luc/lua file with name %a",barename)
- else
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be run, no runner available for engine %a",name,engine)
- else
- runner {
- flags=primaryflags(),
- fmtfile=quoted(barename),
- luafile=quoted(luaname),
- texfile=quoted(data),
- more=more,
- }
- end
- end
+ runner {
+ flags=primaryflags(),
+ fmtfile=quoted(barename),
+ luafile=quoted(luaname),
+ texfile=quoted(data),
+ more=more,
+ }
end
+ end
end
+ end
end
end -- of closure
--- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
+-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 877962
--- stripped bytes : 317771
+-- original bytes : 994864
+-- stripped bytes : 395007
-- end library merge
@@ -21370,6 +24986,7 @@ local owntree = environment and environment.ownpath or ownpath
local ownlibs = { -- order can be made better
+ 'l-bit32.lua',
'l-lua.lua',
'l-macro.lua',
'l-sandbox.lua',
@@ -21385,6 +25002,7 @@ local ownlibs = { -- order can be made better
'l-file.lua',
'l-gzip.lua',
'l-md5.lua',
+ 'l-sha.lua',
'l-url.lua',
'l-dir.lua',
'l-boolean.lua',
@@ -21399,6 +25017,19 @@ local ownlibs = { -- order can be made better
'util-prs.lua',
'util-fmt.lua',
+ 'util-soc-imp-reset.lua',
+ 'util-soc-imp-socket.lua',
+ 'util-soc-imp-copas.lua',
+ 'util-soc-imp-ltn12.lua',
+ -- 'util-soc-imp-mbox.lua',
+ 'util-soc-imp-mime.lua',
+ 'util-soc-imp-url.lua',
+ 'util-soc-imp-headers.lua',
+ 'util-soc-imp-tp.lua',
+ 'util-soc-imp-http.lua',
+ 'util-soc-imp-ftp.lua',
+ 'util-soc-imp-smtp.lua',
+
'trac-set.lua',
'trac-log.lua',
'trac-inf.lua', -- was before trac-set
@@ -21601,9 +25232,7 @@ local helpinfo = [[
<flag name="locate"><short>locate given filename in database (default) or system (<ref name="first"/> <ref name="all"/> <ref name="detail"/>)</short></flag>
</subcategory>
<subcategory>
- <flag name="autotree"><short>use texmf tree cf. env texmfstart_tree or texmfstarttree</short></flag>
<flag name="tree" value="pathtotree"><short>use given texmf tree (default file: setuptex.tmf)</short></flag>
- <flag name="environment" value="name"><short>use given (tmf) environment file</short></flag>
<flag name="path" value="runpath"><short>go to given path before execution</short></flag>
<flag name="ifchanged" value="filename"><short>only execute when given file has changed (md checksum)</short></flag>
<flag name="iftouched" value="old,new"><short>only execute when given file has changed (time stamp)</short></flag>
@@ -21623,7 +25252,7 @@ local helpinfo = [[
</subcategory>
<subcategory>
<flag name="edit"><short>launch editor with found file</short></flag>
- <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>)</short></flag>
+ <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>,<ref name="list"/>)</short></flag>
</subcategory>
<subcategory>
<flag name="timedrun"><short>run a script and time its run</short></flag>
@@ -22022,9 +25651,9 @@ function resolvers.launch(str)
end
function runners.launch_file(filename)
- trackers.enable("resolvers.locating")
local allresults = environment.arguments["all"]
- local pattern = environment.arguments["pattern"]
+ local pattern = environment.arguments["pattern"]
+ local listonly = environment.arguments["list"]
if not pattern or pattern == "" then
pattern = filename
end
@@ -22039,14 +25668,32 @@ function runners.launch_file(filename)
t = resolvers.findfiles("*/" .. pattern .. "*",nil,allresults)
end
if t and #t > 0 then
- if allresults then
- for _, v in pairs(t) do
- report("launching %s", v)
- resolvers.launch(v)
+ for i=1,#t do
+ local name = t[i]
+ if listonly then
+ report("% 3i: %-30s %s",i,file.basename(name),file.dirname(name))
+ else
+ report("launching: %s",name)
+ resolvers.launch(name)
+ if not allresults then
+ break
+ end
+ end
+ end
+ if listonly then
+ io.write("\n")
+ io.write("\n[select number]\n\n>> ")
+ local answer = tonumber(io.read())
+ if answer then
+ io.write("\n")
+ local name = t[answer]
+ if name then
+ report("launching: %s",name)
+ resolvers.launch(name)
+ else
+ report("invalid number")
+ end
end
- else
- report("launching %s", t[1])
- resolvers.launch(t[1])
end
else
report("no match for %s", pattern)
@@ -22166,12 +25813,9 @@ function runners.execute_ctx_script(filename,...)
dofile(fullname)
local savename = environment.arguments['save']
if savename then
- local save_list = runners.save_list
- if save_list and next(save_list) then
- if type(savename) ~= "string" then savename = file.basename(fullname) end
- savename = file.replacesuffix(savename,"cfg")
- runners.save_script_session(savename,save_list)
- end
+ if type(savename) ~= "string" then savename = file.basename(fullname) end
+ savename = file.replacesuffix(savename,"cfg")
+ runners.save_script_session(savename,save_list)
end
return true
end
@@ -22188,22 +25832,22 @@ function runners.execute_ctx_script(filename,...)
local scriptbase = match(scriptname,".*mtx%-([^%-]-)%.lua")
if scriptbase then
local data = io.loaddata(scriptname)
-local application = match(data,"local application.-=.-(%{.-%})")
-if application then
- application = loadstring("return " .. application)
- if application then
- application = application()
- local banner = application.banner
- if banner then
- local description, version = match(banner,"^(.-) ([%d.]+)$")
- if description then
- valid[#valid+1] = { scriptbase, version, description }
- else
- valid[#valid+1] = { scriptbase, "", banner }
- end
- end
- end
-end
+ local application = match(data,"local application.-=.-(%{.-%})")
+ if application then
+ application = loadstring("return " .. application)
+ if application then
+ application = application()
+ local banner = application.banner
+ if banner then
+ local description, version = match(banner,"^(.-) ([%d.]+)$")
+ if description then
+ valid[#valid+1] = { scriptbase, version, description }
+ else
+ valid[#valid+1] = { scriptbase, "", banner }
+ end
+ end
+ end
+ end
end
end
if #valid > 0 then
@@ -22243,7 +25887,7 @@ function runners.timedrun(filename) -- just for me
end
function runners.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
function runners.associate(filename)
diff --git a/scripts/context/perl/mptopdf.pl b/scripts/context/perl/mptopdf.pl
index 42db9001e..165d4d217 100644
--- a/scripts/context/perl/mptopdf.pl
+++ b/scripts/context/perl/mptopdf.pl
@@ -118,9 +118,14 @@ if (($pattern eq '')||($Help)) {
@files = glob "$pattern" ;
}
+# this patch was send via debian but is not tested by me
+
foreach my $file (@files) {
$_ = $file ;
- if (s/\.(\d+|mps)$// && -e $file) {
+ # if (s/\.(\d+|mps)$// && -e $file) {
+ if (s/\.(\d+|mps|ps)$// && -e $file) {
+ my $suffix = $1 ;
+ my $pdf = basename($_).".pdf" ;
if ($miktex) {
$command = "pdftex -undump=mptopdf" ;
} else {
@@ -136,15 +141,22 @@ foreach my $file (@files) {
print "\n$program : error while processing tex file\n" ;
exit 1 ;
}
- my $pdfsrc = basename($_).".pdf";
- rename ($pdfsrc, "$_-$1.pdf") ;
- if (-e $pdfsrc) {
- CopyFile ($pdfsrc, "$_-$1.pdf") ;
+ # my $pdfsrc = basename($_).".pdf";
+ # rename ($pdfsrc, "$_-$1.pdf") ;
+ # if (-e $pdfsrc) {
+ # CopyFile ($pdfsrc, "$_-$1.pdf") ;
+ if ($suffix =~ m/\.\d+$/) {
+ rename ($pdf, "$_-$suffix.pdf") ;
+ if (-e $pdf) {
+ CopyFile ($pdf, "$_-$suffix.pdf") ;
+ }
+ $pdf = "$_-$suffix.pdf" ;
}
if ($done) {
$report .= " +" ;
}
- $report .= " $_-$1.pdf" ;
+ # $report .= " $_-$1.pdf" ;
+ $report .= " $pdf" ;
++$done ;
}
}
diff --git a/scripts/context/stubs/install/first-setup.sh b/scripts/context/stubs/install/first-setup.sh
index 11af49233..71fe32c16 100644
--- a/scripts/context/stubs/install/first-setup.sh
+++ b/scripts/context/stubs/install/first-setup.sh
@@ -17,9 +17,23 @@ cpu=`uname -m`
case "$system" in
# linux
Linux)
+ if command -v ldd >/dev/null && ldd --version 2>&1 | grep -E '^musl' >/dev/null
+ then
+ libc=musl
+ else
+ libc=glibc
+ fi
case "$cpu" in
- i*86) platform="linux" ;;
- x86_64|ia64) platform="linux-64" ;;
+ i*86)
+ case "$libc" in
+ glibc) platform="linux" ;;
+ musl) platform="linuxmusl" ;;
+ esac ;;
+ x86_64|ia64)
+ case "$libc" in
+ glibc) platform="linux-64" ;;
+ musl) platform="linuxmusl-64" ;;
+ esac ;;
# a little bit of cheating with ppc64 (won't work on Gentoo)
ppc|ppc64) platform="linux-ppc" ;;
@@ -138,8 +152,8 @@ fi
# download or update the distribution
# you may remove the --context=beta switch if you want to use "current"
# you can use --engine=luatex if you want just mkiv
-env PATH="$PWD/bin:$CONTEXTROOT/texmf-$platform/bin:$PATH" \
-./bin/mtxrun --script ./bin/mtx-update.lua --force --update --make --context=beta --platform=$platform --texroot="$CONTEXTROOT" $@
+env PATH="$PWD/bin:$CONTEXTROOT/texmf-$platform/bin:$PATH" MTX_PLATFORM="$platform" \
+./bin/mtxrun --script ./bin/mtx-update.lua --force --update --make --context=beta --platform="$platform" --texroot="$CONTEXTROOT" $@
echo
echo "When you want to use context, you need to initialize the tree by typing:"
diff --git a/scripts/context/stubs/mswin/metatex.exe b/scripts/context/stubs/mswin/metatex.exe
deleted file mode 100644
index 0e7882cf9..000000000
--- a/scripts/context/stubs/mswin/metatex.exe
+++ /dev/null
Binary files differ
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 0f4767d91..569a7f2e1 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -1,16 +1,5 @@
#!/usr/bin/env texlua
--- for k, v in next, _G.string do
--- local tv = type(v)
--- if tv == "table" then
--- for kk, vv in next, v do
--- print(k,kk,vv)
--- end
--- else
--- print(tv,k,v)
--- end
--- end
-
if not modules then modules = { } end modules ['mtxrun'] = {
version = 1.001,
comment = "runner, lua replacement for texmfstart.rb",
@@ -20,25 +9,43 @@ if not modules then modules = { } end modules ['mtxrun'] = {
}
-- one can make a stub:
+
+-- mtxrun :
--
-- #!/bin/sh
-- env LUATEXDIR=/....../texmf/scripts/context/lua luatex --luaonly mtxrun.lua "$@"
+-- mtxrun.cmd :
+--
+-- @luatex --luaonly %~d0%~p0mtxrun.lua %*
+
-- filename : mtxrun.lua
-- comment : companion to context.tex
-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
-- copyright: PRAGMA ADE / ConTeXt Development Team
-- license : see context related readme files
--- This script is based on texmfstart.rb but does not use kpsewhich to
--- locate files. Although kpse is a library it never came to opening up
--- its interface to other programs (esp scripting languages) and so we
--- do it ourselves. The lua variant evolved out of an experimental ruby
--- one. Interesting is that using a scripting language instead of c does
--- not have a speed penalty. Actually the lua variant is more efficient,
--- especially when multiple calls to kpsewhich are involved. The lua
+-- This script is based on texmfstart.rb but does not use kpsewhich to locate files.
+-- Although kpse is a library it never came to opening up its interface to other
+-- programs (esp scripting languages) and so we do it ourselves. The lua variant
+-- evolved out of an experimental ruby one. Interesting is that using a scripting
+-- language instead of c does not have a speed penalty. Actually the lua variant is
+-- more efficient, especially when multiple calls to kpsewhich are involved. The lua
-- library also gives way more control.
+-- When libraries used here are updates you can run
+--
+-- mtxrun --selfmerge
+--
+-- to update the embedded code. After that you might need to run
+--
+-- mtxrun --selfupdate
+--
+-- to copy the new script (from scripts/context/lua) to location where
+-- binaries are expected. If you want to remove the embedded code you can run
+--
+-- mtxxun --selfclean
+
-- to be done / considered
--
-- support for --exec or make it default
@@ -54,16 +61,147 @@ if not modules then modules = { } end modules ['mtxrun'] = {
do -- create closure to overcome 200 locals limit
+package.loaded["l-bit32"] = package.loaded["l-bit32"] or true
+
+-- original size: 3607, stripped down to: 3009
+
+if not modules then modules={} end modules ['l-bit32']={
+ version=1.001,
+ license="the same as regular Lua",
+ source="bitwise.lua, v 1.24 2014/12/26 17:20:53 roberto",
+ comment="drop-in for bit32, adapted a bit by Hans Hagen",
+}
+if bit32 then
+elseif utf8 then
+ load ([[
+local select = select -- instead of: arg = { ... }
+bit32 = {
+ bnot = function (a)
+ return ~a & 0xFFFFFFFF
+ end,
+ band = function (x, y, z, ...)
+ if not z then
+ return ((x or -1) & (y or -1)) & 0xFFFFFFFF
+ else
+ local res = x & y & z
+ for i=1,select("#",...) do
+ res = res & select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ bor = function (x, y, z, ...)
+ if not z then
+ return ((x or 0) | (y or 0)) & 0xFFFFFFFF
+ else
+ local res = x | y | z
+ for i=1,select("#",...) do
+ res = res | select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ bxor = function (x, y, z, ...)
+ if not z then
+ return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF
+ else
+ local res = x ~ y ~ z
+ for i=1,select("#",...) do
+ res = res ~ select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ btest = function (x, y, z, ...)
+ if not z then
+ return (((x or -1) & (y or -1)) & 0xFFFFFFFF) ~= 0
+ else
+ local res = x & y & z
+ for i=1,select("#",...) do
+ res = res & select(i,...)
+ end
+ return (res & 0xFFFFFFFF) ~= 0
+ end
+ end,
+ lshift = function (a, b)
+ return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF
+ end,
+ rshift = function (a, b)
+ return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF
+ end,
+ arshift = function (a, b)
+ a = a & 0xFFFFFFFF
+ if b <= 0 or (a & 0x80000000) == 0 then
+ return (a >> b) & 0xFFFFFFFF
+ else
+ return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
+ end
+ end,
+ lrotate = function (a ,b)
+ b = b & 31
+ a = a & 0xFFFFFFFF
+ a = (a << b) | (a >> (32 - b))
+ return a & 0xFFFFFFFF
+ end,
+ rrotate = function (a, b)
+ b = -b & 31
+ a = a & 0xFFFFFFFF
+ a = (a << b) | (a >> (32 - b))
+ return a & 0xFFFFFFFF
+ end,
+ extract = function (a, f, w)
+ return (a >> f) & ~(-1 << (w or 1))
+ end,
+ replace = function (a, v, f, w)
+ local mask = ~(-1 << (w or 1))
+ return ((a & ~(mask << f)) | ((v & mask) << f)) & 0xFFFFFFFF
+ end,
+}
+ ]] ) ()
+elseif bit then
+ load ([[
+local band, bnot, rshift, lshift = bit.band, bit.bnot, bit.rshift, bit.lshift
+bit32 = {
+ arshift = bit.arshift,
+ band = band,
+ bnot = bnot,
+ bor = bit.bor,
+ bxor = bit.bxor,
+ btest = function(...)
+ return band(...) ~= 0
+ end,
+ extract = function(a,f,w)
+ return band(rshift(a,f),2^(w or 1)-1)
+ end,
+ lrotate = bit.rol,
+ lshift = lshift,
+ replace = function(a,v,f,w)
+ local mask = 2^(w or 1)-1
+ return band(a,bnot(lshift(mask,f)))+lshift(band(v,mask),f)
+ end,
+ rrotate = bit.ror,
+ rshift = rshift,
+}
+ ]] ) ()
+else
+ xpcall(function() local _,t=require("bit32") if t then bit32=t end return end,function() end)
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 6230, stripped down to: 3662
+-- original size: 6281, stripped down to: 2863
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+).*$")
@@ -71,122 +209,111 @@ 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
+ ffi.number=tonumber
end
-if not bit32 then
- bit32=require("l-bit32")
+if LUAVERSION>5.3 then
+ collectgarbage("generational")
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
end -- of closure
@@ -195,25 +322,27 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-macro"] = package.loaded["l-macro"] or true
--- original size: 8260, stripped down to: 5213
+-- original size: 10131, stripped down to: 5991
if not modules then modules={} end modules ['l-macros']={
- 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 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)
@@ -230,172 +359,214 @@ local definitions={}
local resolve
local subparser
local report_lua=function(...)
- if logs and logs.reporter then
- report_lua=logs.reporter("system","lua")
- report_lua(...)
- else
- print(format(...))
- end
-end
-resolve=C(C(name)*arguments^-1)/function(raw,s,a)
- local d=definitions[s]
- if d then
- if a then
- local n=#a
- local p=patterns[s][n]
- if p then
- local d=d[n]
- for i=1,n do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return lpegmatch(p,d,1,a) or d
- else
- return raw
- end
- else
- return d[0] or raw
- end
- elseif a then
- for i=1,#a do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return s.."("..concat(a,",")..")"
- else
- return raw
- end
-end
-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 n=0
+ if logs and logs.reporter then
+ report_lua=logs.reporter("system","lua")
+ report_lua(...)
+ else
+ print(format(...))
+ end
+end
+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
- n=#a
- local pattern=P(false)
+ local n=#a
+ local p=patterns[s][n]
+ if p then
+ local d=d[n]
for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- p[n]=pattern
+ return lpegmatch(p,d,1,a) or d
+ else
+ return raw
+ end
+ else
+ return d[0] or raw
end
- local d=definitions[k]
- if not d then
- d={ [0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
+ elseif a then
+ for i=1,#a do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ return s.."("..concat(a,",")..")"
+ else
+ return raw
+ end
end
-local register=(C(name)*spaces^0*(arguments+Cc(false))*spaces^0*C(body))/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ [0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+subparser=Cs((resolve+P(1))^1)
+local enddefine=P("#enddefine")/""
+local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ 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=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ 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 unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
- n=#a
- local p=patterns[k]
- if p then
- p[n]=false
- end
- end
- local d=definitions[k]
- if d then
- d[n]=false
+ local n=0
+ if a then
+ n=#a
+ local p=patterns[k]
+ if p then
+ p[n]=false
end
- return ""
+ end
+ local d=definitions[k]
+ if d then
+ d[n]=false
+ end
+ return ""
end
local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define" )*spaces^0/"")*register
-local undefine=(P("undefine" )*spaces^0/"")*unregister
+local define=(P("define" )*spaces^0/"")*register
+local undefine=(P("undefine" )*spaces^0/"")*unregister
local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
function macros.reset()
- definitions={}
- patterns={}
+ definitions={}
+ patterns={}
+end
+function macros.showdefinitions()
+ 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
+ return lpegmatch(parser,str) or str
end
function macros.resolving()
- return next(patterns)
-end
-local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
- return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
- return false,format("file '%s' is invalid",name)
- end
+ 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 n=lpegmatch(parser,c)
- if trace then
- if #n~=#c then
- report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
- if detail then
- report_lua()
- report_lua(n)
- report_lua()
- end
- elseif detail then
- report_lua("no macros expanded in '%s'",name)
- end
+ local f=loadfile(name)
+ os.remove(name)
+ return f
+ end
+end
+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
- if #name>30 then
- n="--[["..sub(name,-30).."]] "..n
- else
- n="--[["..name.."]] "..n
+ end
+ return load(data,name)
+end
+local function loaded(name,trace,detail)
+ local f=io.open(name,"rb")
+ if not f then
+ return false,format("file '%s' not found",name)
+ end
+ local c=f:read("*a")
+ if not c then
+ return false,format("file '%s' is invalid",name)
+ end
+ f:close()
+ local n=lpegmatch(parser,c)
+ if trace then
+ if #n~=#c then
+ report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
+ if detail then
+ report_lua()
+ report_lua(n)
+ report_lua()
+ end
+ elseif detail then
+ report_lua("no macros expanded in '%s'",name)
end
- return load(n)
+ end
+ return reload(lfs and lfs.currentdir(),name,n)
end
macros.loaded=loaded
function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.find_file(filename) or filename
- if not fullname or fullname=="" then
- return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
- return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
- code=code()
- else
- report_lua("error when loading '%s'",fullname)
- return false,message
- end
- if code==nil then
- code=false
- end
- package.loaded[fullname]=code
- return code
+ local filename=file.addsuffix(name,"lua")
+ local fullname=resolvers and resolvers.find_file(filename) or filename
+ if not fullname or fullname=="" then
+ return false
+ end
+ local codeblob=package.loaded[fullname]
+ if codeblob then
+ return codeblob
+ end
+ local code,message=loaded(fullname,macros,trace,trace)
+ if type(code)=="function" then
+ code=code()
+ else
+ report_lua("error when loading '%s'",fullname)
+ return false,message
+ end
+ if code==nil then
+ code=false
+ end
+ package.loaded[fullname]=code
+ return code
end
macros.required=required
@@ -406,14 +577,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
--- original size: 9678, stripped down to: 6688
+-- original size: 9747, stripped down to: 6313
if not modules then modules={} end modules ['l-sandbox']={
- 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 global=_G
local next=next
@@ -439,231 +610,234 @@ local trace=false
local logger=false
local blocked={}
local function report(...)
- tprint("sandbox ! "..format(...))
+ tprint("sandbox ! "..format(...))
end
sandbox.report=report
function sandbox.setreporter(r)
- report=r
- sandbox.report=r
+ report=r
+ sandbox.report=r
end
function sandbox.settrace(v)
- trace=v
+ trace=v
end
function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
+ logger=type(l)=="function" and l or false
end
local function register(func,overload,comment)
- if type(func)=="function" then
- if type(overload)=="string" then
- comment=overload
- overload=nil
- end
- local function f(...)
- if sandboxed then
- local overload=overloads[f]
- if overload then
- if logger then
- local result={ overload(func,...) }
- logger {
- comment=comments[f] or tostring(f),
- arguments={... },
- result=result[1] and true or false,
- }
- return unpack(result)
- else
- return overload(func,...)
- end
- else
- end
- else
- return func(...)
- end
- end
- if comment then
- comments[f]=comment
- if trace then
- report("registering function: %s",comment)
- end
+ if type(func)=="function" then
+ if type(overload)=="string" then
+ comment=overload
+ overload=nil
+ end
+ local function f(...)
+ if sandboxed then
+ local overload=overloads[f]
+ if overload then
+ if logger then
+ local result={ overload(func,...) }
+ logger {
+ comment=comments[f] or tostring(f),
+ arguments={... },
+ result=result[1] and true or false,
+ }
+ return unpack(result)
+ else
+ return overload(func,...)
+ end
+ else
end
- overloads[f]=overload or false
- originals[f]=func
- return f
+ else
+ return func(...)
+ end
end
+ if comment then
+ comments[f]=comment
+ if trace then
+ report("registering function: %s",comment)
+ end
+ end
+ overloads[f]=overload or false
+ originals[f]=func
+ return f
+ end
end
local function redefine(func,comment)
- if type(func)=="function" then
- skiploads[func]=comment or comments[func] or "unknown"
- if overloads[func]==false then
- overloads[func]=nil
- end
+ if type(func)=="function" then
+ skiploads[func]=comment or comments[func] or "unknown"
+ if overloads[func]==false then
+ overloads[func]=nil
end
+ end
end
sandbox.register=register
sandbox.redefine=redefine
function sandbox.original(func)
- return originals and originals[func] or func
+ return originals and originals[func] or func
end
function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
- if trace then
- report("overloading unknown function: %s",comment)
- end
- elseif type(overload)~="function" then
- if trace then
- report("overloading function with bad overload: %s",comment)
- end
- elseif overloads[func]==nil then
- if trace then
- report("function is not registered: %s",comment)
- end
- elseif skiploads[func] then
- if trace then
- report("function is not skipped: %s",comment)
- end
- else
- if trace then
- report("overloading function: %s",comment)
- end
- overloads[func]=overload
+ comment=comment or comments[func] or "?"
+ if type(func)~="function" then
+ if trace then
+ report("overloading unknown function: %s",comment)
+ end
+ elseif type(overload)~="function" then
+ if trace then
+ report("overloading function with bad overload: %s",comment)
+ end
+ elseif overloads[func]==nil then
+ if trace then
+ report("function is not registered: %s",comment)
+ end
+ elseif skiploads[func] then
+ if trace then
+ report("function is not skipped: %s",comment)
end
- return func
+ else
+ if trace then
+ report("overloading function: %s",comment)
+ end
+ overloads[func]=overload
+ end
+ return func
end
local function whatever(specification,what,target)
- if type(specification)~="table" then
- report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
- report("%s needs a category and action",what)
- elseif not sandboxed then
- target[#target+1]=specification
- elseif trace then
- report("already enabled, discarding %s",what)
- end
+ if type(specification)~="table" then
+ report("%s needs a specification",what)
+ elseif type(specification.category)~="string" or type(specification.action)~="function" then
+ report("%s needs a category and action",what)
+ elseif not sandboxed then
+ target[#target+1]=specification
+ elseif trace then
+ report("already enabled, discarding %s",what)
+ end
end
function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
+ whatever(specification,"initializer",initializers)
end
function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
+ whatever(specification,"finalizer",finalizers)
end
function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
- return nil
- elseif b then
- if trace then
- report("using blocked: %s",n)
- end
- return b
- else
- if trace then
- report("requiring: %s",name)
- end
- return requiem(name)
+ local n=gsub(name,"^.*[\\/]","")
+ local n=gsub(n,"[%.].*$","")
+ local b=blocked[n]
+ if b==false then
+ return nil
+ elseif b then
+ if trace then
+ report("using blocked: %s",n)
end
-end
-function blockrequire(name,lib)
+ return b
+ else
if trace then
- report("preventing reload of: %s",name)
+ report("requiring: %s",name)
end
- blocked[name]=lib or _G[name] or false
+ return requiem(name)
+ end
+end
+function blockrequire(name,lib)
+ if trace then
+ report("preventing reload of: %s",name)
+ end
+ blocked[name]=lib or _G[name] or false
end
function sandbox.enable()
- if not sandboxed then
- for i=1,#initializers do
- initializers[i].action()
- end
- for i=1,#finalizers do
- finalizers[i].action()
- end
- local nnot=0
- local nyes=0
- local cnot={}
- local cyes={}
- local skip={}
- for k,v in next,overloads do
- local c=comments[k]
- if v then
- if c then
- cyes[#cyes+1]=c
- else
- nyes=nyes+1
- end
- else
- if c then
- cnot[#cnot+1]=c
- else
- nnot=nnot+1
- end
- end
- end
- for k,v in next,skiploads do
- skip[#skip+1]=v
- end
- if #cyes>0 then
- sort(cyes)
- report("overloaded known: %s",concat(cyes," | "))
- end
- if nyes>0 then
- report("overloaded unknown: %s",nyes)
- end
- if #cnot>0 then
- sort(cnot)
- report("not overloaded known: %s",concat(cnot," | "))
- end
- if nnot>0 then
- report("not overloaded unknown: %s",nnot)
+ if not sandboxed then
+ debug={
+ traceback=debug.traceback,
+ }
+ for i=1,#initializers do
+ initializers[i].action()
+ end
+ for i=1,#finalizers do
+ finalizers[i].action()
+ end
+ local nnot=0
+ local nyes=0
+ local cnot={}
+ local cyes={}
+ local skip={}
+ for k,v in next,overloads do
+ local c=comments[k]
+ if v then
+ if c then
+ cyes[#cyes+1]=c
+ else
+ nyes=nyes+1
end
- if #skip>0 then
- sort(skip)
- report("not overloaded redefined: %s",concat(skip," | "))
+ else
+ if c then
+ cnot[#cnot+1]=c
+ else
+ nnot=nnot+1
end
- initializers=nil
- finalizers=nil
- originals=nil
- sandboxed=true
+ end
+ end
+ for k,v in next,skiploads do
+ skip[#skip+1]=v
+ end
+ if #cyes>0 then
+ sort(cyes)
+ report("overloaded known: %s",concat(cyes," | "))
+ end
+ if nyes>0 then
+ report("overloaded unknown: %s",nyes)
end
+ if #cnot>0 then
+ sort(cnot)
+ report("not overloaded known: %s",concat(cnot," | "))
+ end
+ if nnot>0 then
+ report("not overloaded unknown: %s",nnot)
+ end
+ if #skip>0 then
+ sort(skip)
+ report("not overloaded redefined: %s",concat(skip," | "))
+ end
+ initializers=nil
+ finalizers=nil
+ originals=nil
+ sandboxed=true
+ end
end
blockrequire("lfs",lfs)
blockrequire("io",io)
blockrequire("os",os)
blockrequire("ffi",ffi)
local function supported(library)
- local l=_G[library]
- return l
+ local l=_G[library]
+ return l
end
loadfile=register(loadfile,"loadfile")
if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen")
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
+ io.open=register(io.open,"io.open")
+ io.popen=register(io.popen,"io.popen")
+ io.lines=register(io.lines,"io.lines")
+ io.output=register(io.output,"io.output")
+ io.input=register(io.input,"io.input")
end
if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
+ os.execute=register(os.execute,"os.execute")
+ os.spawn=register(os.spawn,"os.spawn")
+ os.exec=register(os.exec,"os.exec")
+ os.rename=register(os.rename,"os.rename")
+ os.remove=register(os.remove,"os.remove")
end
if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
+ lfs.chdir=register(lfs.chdir,"lfs.chdir")
+ lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
+ lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
+ lfs.isfile=register(lfs.isfile,"lfs.isfile")
+ lfs.isdir=register(lfs.isdir,"lfs.isdir")
+ lfs.attributes=register(lfs.attributes,"lfs.attributes")
+ lfs.dir=register(lfs.dir,"lfs.dir")
+ lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
+ lfs.touch=register(lfs.touch,"lfs.touch")
+ lfs.link=register(lfs.link,"lfs.link")
+ lfs.setmode=register(lfs.setmode,"lfs.setmode")
+ lfs.readlink=register(lfs.readlink,"lfs.readlink")
+ lfs.shortname=register(lfs.shortname,"lfs.shortname")
+ lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
end
@@ -673,14 +847,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-package"] = package.loaded["l-package"] or true
--- original size: 11562, stripped down to: 8625
+-- original size: 11605, stripped down to: 8299
if not modules then modules={} end modules ['l-package']={
- 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=type
local gsub,format,find=string.gsub,string.format,string.find
@@ -688,40 +862,40 @@ local insert,remove=table.insert,table.remove
local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
local package=package
local searchers=package.searchers or package.loaders
-local filejoin=file and file.join or function(path,name) return path.."/"..name end
-local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join or function(path,name) return path.."/"..name end
+local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
local function cleanpath(path)
- return path
+ return path
end
local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
local function lualibfile(name)
- return lpegmatch(pattern,name) or name
+ return lpegmatch(pattern,name) or name
end
local offset=luarocks and 1 or 0
local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
- ["preload table"]=searchers[1+offset],
- ["path specification"]=searchers[2+offset],
- ["cpath specification"]=searchers[3+offset],
- ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
- "already loaded",
- "preload table",
- "qualified path",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
- }
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+ ["preload table"]=searchers[1+offset],
+ ["path specification"]=searchers[2+offset],
+ ["cpath specification"]=searchers[3+offset],
+ ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+ "already loaded",
+ "preload table",
+ "qualified path",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
}
package.helpers=helpers
local methods=helpers.methods
@@ -737,253 +911,256 @@ local nofextralib=-1
local nofpathlua=-1
local nofpathlib=-1
local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
- for i=1,nofpaths do
- helpers.report("using %s path %i: %s",what,i,paths[i])
- end
- else
- helpers.report("no %s paths defined",what)
+ local nofpaths=#paths
+ if nofpaths>0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
end
- return nofpaths
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
end
local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
- nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
+ if helpers.trace and #extraluapaths~=nofextralua then
+ nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
end
local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
- nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
+ if helpers.trace and #extralibpaths~=nofextralib then
+ nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
end
local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
- luapaths=file.splitpath(luapath,";")
- oldluapath=luapath
- nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
- nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+ luapaths=file.splitpath(luapath,";")
+ oldluapath=luapath
+ nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+ nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
end
local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
- libpaths=file.splitpath(libpath,";")
- oldlibpath=libpath
- nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
- nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+ libpaths=file.splitpath(libpath,";")
+ oldlibpath=libpath
+ nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+ nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
end
package.luapaths=getluapaths
package.libpaths=getlibpaths
package.extraluapaths=getextraluapaths
package.extralibpaths=getextralibpaths
local hashes={
- lua={},
- lib={},
+ lua={},
+ lib={},
}
local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
- local path=cleanpath(path)
- if not hash[path] then
- target[#target+1]=path
- hash[path]=true
- if trace then
- report("registered %s path %s: %s",tag,#target,path)
- end
- else
- if trace then
- report("duplicate %s path: %s",tag,path)
- end
- end
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+ local path=cleanpath(path)
+ if not hash[path] then
+ target[#target+1]=path
+ hash[path]=true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
end
- for p=1,#pathlist do
- local path=pathlist[p]
- if type(path)=="table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
+ end
+ for p=1,#pathlist do
+ local path=pathlist[p]
+ if type(path)=="table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
end
+ end
end
local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
- helpers.report("pushing %s path in front: %s",tag,path)
- end
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
end
local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
- if path then
- helpers.report("popping %s path from front: %s",tag,path)
- else
- helpers.report("no %s path to pop",tag)
- end
+ local path=remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
end
+ end
end
helpers.registerpath=registerpath
function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
+ registerpath("extra lua","lua",extraluapaths,...)
end
function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
+ pushpath("extra lua","lua",extraluapaths,path)
end
function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
+ poppath("extra lua","lua",extraluapaths)
end
function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
+ registerpath("extra lib","lib",extralibpaths,...)
end
function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
+ pushpath("extra lib","lib",extralibpaths,path)
end
function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
+ poppath("extra lib","lua",extralibpaths)
end
local function loadedaslib(resolved,rawname)
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
end
helpers.loadedaslib=loadedaslib
local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
- local path=paths[p]
- local resolved=filejoin(path,name)
- if trace then
- helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
- end
- if isreadable(resolved) then
- if trace then
- helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ for p=1,#paths do
+ local path=paths[p]
+ local resolved=filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbypath=loadedbypath
local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
- local trace=helpers.trace
- if trace then
- helpers.report("qualified name, identifying '%s'",what,name)
- end
- if isreadable(name) then
- if trace then
- helpers.report("qualified name, '%s' found",what,name)
- end
- return loadfile(name)
- end
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
+ end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
end
+ end
end
helpers.loadedbyname=loadedbyname
methods["already loaded"]=function(name)
- return package.loaded[name]
+ return package.loaded[name]
end
methods["preload table"]=function(name)
- return builtin["preload table"](name)
+ return builtin["preload table"](name)
end
methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
end
methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
end
methods["lib extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
end
methods["path specification"]=function(name)
- getluapaths()
- return builtin["path specification"](name)
+ getluapaths()
+ return builtin["path specification"](name)
end
methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
+ getlibpaths()
+ return builtin["cpath specification"](name)
end
methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+ return builtin["all in one fallback"](name)
end
methods["not loaded"]=function(name)
- if helpers.trace then
- helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
end
local level=0
local used={}
helpers.traceused=false
function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
- local method=sequence[i]
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
- end
- local result,rest=methods[method](name)
- if type(result)=="function" then
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
- end
- if helpers.traceused then
- used[#used+1]={ level=level,name=name }
- end
- level=level-1
- return result,rest
- end
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+ local method=sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
end
- level=level-1
- return nil
+ local result,rest=methods[method](name)
+ if type(result)=="function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1]={ level=level,name=name }
+ end
+ level=level-1
+ return result,rest
+ end
+ end
+ level=level-1
+ return nil
end
function helpers.showused()
- local n=#used
- if n>0 then
- helpers.report("%s libraries loaded:",n)
- helpers.report()
- for i=1,n do
- local u=used[i]
- helpers.report("%i %a",u.level,u.name)
- end
- helpers.report()
- end
+ local n=#used
+ if n>0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u=used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
end
function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading, name '%s', %s",name,"done")
- else
- helpers.report("unloading, name '%s', %s",name,"not loaded")
- end
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
end
- package.loaded[name]=nil
+ end
+ package.loaded[name]=nil
end
table.insert(searchers,1,helpers.loaded)
+if context then
+ package.path=""
+end
end -- of closure
@@ -992,14 +1169,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38582, stripped down to: 20518
+-- original size: 38434, stripped down to: 19310
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
@@ -1010,7 +1187,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
@@ -1033,7 +1210,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('"')
@@ -1042,9 +1219,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")
@@ -1076,7 +1253,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
@@ -1085,15 +1262,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
@@ -1150,7 +1327,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
@@ -1160,76 +1337,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("")
@@ -1239,505 +1424,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
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
+ 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
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ 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
+ 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
- pattern=(1-pattern)^0*pattern
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ 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
+ 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
- return p
+ 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
+ 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
- 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
+ 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
- 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
+ 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
- return (insensitive and make2 or make1)(tree)
+ 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
+ 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
@@ -1756,32 +1899,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
@@ -1791,14 +1949,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-function"] = package.loaded["l-function"] or true
--- original size: 361, stripped down to: 322
+-- original size: 361, stripped down to: 317
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
@@ -1810,14 +1968,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-string"] = package.loaded["l-string"] or true
--- original size: 6461, stripped down to: 3341
+-- original size: 6461, stripped down to: 3255
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
@@ -1825,25 +1983,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
@@ -1851,81 +2009,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
@@ -1935,166 +2093,172 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 40197, stripped down to: 23561
+-- original size: 41298, stripped down to: 21498
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 a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
end
- return tostring(a)<tostring(b)
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
+ end
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt={}
+ local category=0
+ local s=0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- 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)=="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
@@ -2102,907 +2266,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 n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ 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 n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ if not t then
+ t={}
+ end
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp={}
+ local ntmp=0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
+ end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
+ if not tables then
+ tables={}
+ end
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh={}
+ local h=0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- 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
+ 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
- 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 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"))
- else
- handle(format("%s{",depth))
- end
+ 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
- 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
- end
- if last>0 then
- first=1
- 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
- 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
+ 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
- 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
+ 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 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
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
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 {")
+ 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(name.."={")
+ handle(format("%s [%q]=%q,",depth,k,v))
end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
+ 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
- handle("["..name.."]={")
+ do_serialize(v,k,depth,level+1)
end
- elseif tname=="boolean" then
- if name then
- handle("return {")
+ 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("{")
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
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
+ 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
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
+ 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
- handle("}")
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
end
-function table.serialize(root,name,specification)
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
+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
+ 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
+ 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
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ 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)
+ 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
- f:close()
- io.flush()
+ 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
+ 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
- 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
+ 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
+ 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
- return f
+ 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
- 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
+ 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 ""
+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
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- s[i]=tostring(t[i])
+ 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 n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ 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 n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
- else
- return nothing
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
@@ -3012,14 +3213,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11823, stripped down to: 6945
+-- original size: 11823, stripped down to: 6325
if not modules then modules={} end modules ['l-io']={
- 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 io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -3027,334 +3228,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 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
- f:close()
- flush()
+ if data then
+ g:write(data)
+ end
+ 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
+ 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
+ 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
+ [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
@@ -3364,14 +3565,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5645, stripped down to: 2253
+-- original size: 5720, stripped down to: 2176
if not modules then modules={} end modules ['l-number']={
- 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 tostring,tonumber=tostring,tonumber
local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -3381,99 +3582,107 @@ local floor=math.floor
number=number or {}
local number=number
if bit32 then
- local bextract=bit32.extract
- local t={
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m)
- local n=32
- for i=0,31 do
- local v=bextract(b,i)
- local k=32-i
- if v==1 then
- n=k
- t[k]="1"
- else
- t[k]="0"
- end
- end
- if m then
- m=33-m*8
- if m<1 then
- m=1
- end
- return concat(t,"",m)
- elseif n<8 then
- return concat(t)
- elseif n<16 then
- return concat(t,"",9)
- elseif n<24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
+ local bextract=bit32.extract
+ local t={
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ }
+ 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=w-i
+ if v==1 then
+ n=k
+ t[k]="1"
+ else
+ t[k]="0"
+ end
+ end
+ 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,"",1,m)
+ elseif n<8 then
+ return concat(t)
+ elseif n<16 then
+ return concat(t,"",9)
+ elseif n<24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
end
+ end
else
- function number.tobitstring(n,m)
- if n>0 then
- local t={}
- while n>0 do
- insert(t,1,n%2>0 and 1 or 0)
- n=floor(n/2)
- end
- local nn=8-#t%8
- if nn>0 and nn<8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m=m*8-#t
- if m>0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
+ function number.tobitstring(n,m)
+ if n>0 then
+ local t={}
+ while n>0 do
+ insert(t,1,n%2>0 and 1 or 0)
+ n=floor(n/2)
+ end
+ local nn=8-#t%8
+ if nn>0 and nn<8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m=m*8-#t
+ if m>0 then
+ insert(t,1,rep("0",m))
end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
end
+ end
end
function number.valid(str,default)
- return tonumber(str) or default or nil
+ return tonumber(str) or default or nil
end
function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
- return s
- else
- return "0"..s
- end
+ local s=format("%X",n)
+ if #s%2==0 then
+ return s
+ else
+ return "0"..s
+ end
end
function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
- return 100
- elseif d<-100 then
- return -100
- else
- return d
- end
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+ return 100
+ elseif d<-100 then
+ return -100
+ else
+ return d
+ end
end
function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
- return 255
- elseif b<-255 then
- return -255
- else
- return b
- end
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+ return 255
+ elseif b<-255 then
+ return -255
+ else
+ return b
+ end
+end
+function number.idiv(i,d)
+ return floor(i/d)
end
@@ -3483,14 +3692,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-set"] = package.loaded["l-set"] or true
--- original size: 1923, stripped down to: 1133
+-- original size: 1923, stripped down to: 1044
if not modules then modules={} end modules ['l-set']={
- 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"
}
set=set or {}
local nums={}
@@ -3499,54 +3708,54 @@ local concat=table.concat
local next,type=next,type
set.create=table.tohash
function set.tonumber(t)
- if next(t) then
- local s=""
- for k,v in next,t do
- if v then
- s=s.." "..k
- end
- end
- local n=nums[s]
- if not n then
- n=#tabs+1
- tabs[n]=t
- nums[s]=n
- end
- return n
- else
- return 0
+ if next(t) then
+ local s=""
+ for k,v in next,t do
+ if v then
+ s=s.." "..k
+ end
end
+ local n=nums[s]
+ if not n then
+ n=#tabs+1
+ tabs[n]=t
+ nums[s]=n
+ end
+ return n
+ else
+ return 0
+ end
end
function set.totable(n)
- if n==0 then
- return {}
- else
- return tabs[n] or {}
- end
+ if n==0 then
+ return {}
+ else
+ return tabs[n] or {}
+ end
end
function set.tolist(n)
- if n==0 or not tabs[n] then
- return ""
- else
- local t,n={},0
- for k,v in next,tabs[n] do
- if v then
- n=n+1
- t[n]=k
- end
- end
- return concat(t," ")
+ if n==0 or not tabs[n] then
+ return ""
+ else
+ local t,n={},0
+ for k,v in next,tabs[n] do
+ if v then
+ n=n+1
+ t[n]=k
+ end
end
+ return concat(t," ")
+ end
end
function set.contains(n,s)
- if type(n)=="table" then
- return n[s]
- elseif n==0 then
- return false
- else
- local t=tabs[n]
- return t and t[s]
- end
+ if type(n)=="table" then
+ return n[s]
+ elseif n==0 then
+ return false
+ else
+ local t=tabs[n]
+ return t and t[s]
+ end
end
@@ -3556,14 +3765,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 16268, stripped down to: 9246
+-- original size: 19347, stripped down to: 10258
if not modules then modules={} end modules ['l-os']={
- 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 os=os
local date,time=os.date,os.time
@@ -3571,357 +3780,434 @@ local find,format,gsub,upper,gmatch=string.find,string.format,string.gsub,string
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
-math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
-randomseed(math.initialseed)
-if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
- local osgetenv=os.getenv
- local ossetenv=os.setenv
- local osenv=os.env local _=osenv.PATH
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- if type(v)=="table" then
- v=concat(v,";")
- end
- ossetenv(K,v)
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
+do
+ local selfdir=os.selfdir
+ if selfdir=="" then
+ selfdir=nil
+ end
+ if not selfdir then
+ if arg then
+ for i=1,#arg do
+ local a=arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir=gsub(a,"^.-=","")
+ break
end
- else
- local ossetenv=os.setenv
- local osgetenv=os.getenv
- local osenv={}
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
+ 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
+ local attributes=lfs.attributes
+ isfile=function(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+ end
+ else
+ local open=io.open
+ isfile=function(name)
+ local f=open(name)
+ if f then
+ f:close()
+ return true
end
+ end
end
- local function __index(t,k)
- return os.getenv(k)
- end
- local function __newindex(t,k,v)
- os.setenv(k,v)
+ for p in gmatch(path,patt) do
+ if isfile(p.."/"..name) then
+ selfdir=p
+ break
+ end
end
- os.env={}
- setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
+ os.selfdir=selfdir or "."
+ end
+end
+math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
+randomseed(math.initialseed)
+if not os.__getenv__ then
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+ local osgetenv=os.getenv
+ local ossetenv=os.setenv
+ local osenv=os.env local _=osenv.PATH
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ if type(v)=="table" then
+ v=concat(v,";")
+ end
+ ossetenv(K,v)
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ else
+ local ossetenv=os.setenv
+ local osgetenv=os.getenv
+ local osenv={}
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+ os.env={}
+ setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
local execute=os.execute
local iopopen=io.popen
local function resultof(command)
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- else
- return ""
- end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
end
os.resultof=resultof
function os.pipeto(command)
- return iopopen(command,"w")
+ return iopopen(command,"w")
end
if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
- io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+ io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
end
os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
end
local launchers={
- windows="start %s",
- macosx="open %s",
- unix="$BROWSER %s &> /dev/null &",
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
}
function os.launch(str)
- execute(format(launchers[os.name] or launchers.unix,str))
+ execute(format(launchers[os.name] or launchers.unix,str))
end
if not os.times then
- function os.times()
- return {
- utime=os.gettimeofday(),
- stime=0,
- cutime=0,
- cstime=0,
- }
- end
+ function os.times()
+ return {
+ utime=os.gettimeofday(),
+ stime=0,
+ cutime=0,
+ cstime=0,
+ }
+ end
end
local gettimeofday=os.gettimeofday or os.clock
os.gettimeofday=gettimeofday
local startuptime=gettimeofday()
function os.runtime()
- return gettimeofday()-startuptime
+ return gettimeofday()-startuptime
end
local resolvers=os.resolvers or {}
os.resolvers=resolvers
setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil
+ local r=resolvers[k]
+ return r and r(t,k) or nil
end })
local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
if platform~="" then
- os.platform=platform
+ os.platform=platform
elseif os.type=="windows" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("PROCESSOR_ARCHITECTURE") or ""
- if find(architecture,"AMD64",1,true) then
- platform="win64"
- else
- platform="mswin"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform=""
+ if find(architecture,"AMD64",1,true) then
+ platform="win64"
+ else
+ platform="mswin"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="linux" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- if find(architecture,"x86_64",1,true) then
- platform="linux-64"
- elseif find(architecture,"ppc",1,true) then
- platform="linux-ppc"
- else
- platform="linux"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ 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
+ 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=musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="macosx" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("echo $HOSTTYPE") or ""
- if architecture=="" then
- platform="osx-intel"
- elseif find(architecture,"i386",1,true) then
- platform="osx-intel"
- elseif find(architecture,"x86_64",1,true) then
- platform="osx-64"
- else
- platform="osx-ppc"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=resultof("echo $HOSTTYPE") or ""
+ local platform=""
+ if architecture=="" then
+ platform="osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform="osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform="osx-64"
+ else
+ platform="osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="sunos" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("uname -m") or ""
- if find(architecture,"sparc",1,true) then
- platform="solaris-sparc"
- else
- platform="solaris-intel"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"sparc",1,true) then
+ platform="solaris-sparc"
+ else
+ platform="solaris-intel"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="freebsd" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("uname -m") or ""
- if find(architecture,"amd64",1,true) then
- platform="freebsd-amd64"
- else
- platform="freebsd"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"amd64",1,true) then
+ platform="freebsd-amd64"
+ else
+ platform="freebsd"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- if find(architecture,"x86_64",1,true) then
- platform="kfreebsd-amd64"
- else
- platform="kfreebsd-i386"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"x86_64",1,true) then
+ platform="kfreebsd-amd64"
+ else
+ platform="kfreebsd-i386"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
else
- function resolvers.platform(t,k)
- local platform="linux"
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local platform="linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
end
os.newline=name=="windows" and "\013\010" or "\010"
function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
end
local t={ 8,9,"a","b" }
function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
- random(0xFFFF),random(0xFFFF),
- random(0x0FFF),
- t[ceil(random(4))] or 8,random(0x0FFF),
- random(0xFFFF),
- random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
end
local d
function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
- if delta then
- if d>0 then
- return format("+%02i:00",d)
- else
- return format("-%02i:00",-d)
- end
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d>0 then
+ return format("+%02i:00",d)
else
- return 1
+ return format("-%02i:00",-d)
end
+ else
+ return 1
+ end
end
local timeformat=format("%%s%s",os.timezone(true))
local dateformat="!%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
end
local dateformat="%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=date(dateformat,t)
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=date(dateformat,t)
+ end
+ return lastdate
end
function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
+ local t=tonumber(t)
+ if t and t>0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
end
local memory={}
local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
- local suffix=file.suffix(filename)
- local suffixes=suffix=="" and os.binsuffixes or { suffix }
- for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local df=file.join(directory,filename)
- for i=1,#suffixes do
- local dfs=file.addsuffix(df,suffixes[i])
- if io.exists(dfs) then
- fullname=dfs
- break
- end
- end
- end
- if not fullname then
- fullname=false
+ local fullname=memory[filename]
+ if fullname==nil then
+ local suffix=file.suffix(filename)
+ local suffixes=suffix=="" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local df=file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs=file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname=dfs
+ break
end
- memory[filename]=fullname
+ end
end
- return fullname
+ if not fullname then
+ fullname=false
+ end
+ memory[filename]=fullname
+ end
+ return fullname
end
os.which=which
os.where=which
function os.today()
- return date("!*t")
+ return date("!*t")
end
function os.now()
- return date("!%Y-%m-%d %H:%M:%S")
+ return date("!%Y-%m-%d %H:%M:%S")
end
if not os.sleep then
- local socket=socket
- function os.sleep(n)
- if not socket then
- socket=require("socket")
- end
- socket.sleep(n)
+ local socket=socket
+ function os.sleep(n)
+ if not socket then
+ socket=require("socket")
end
+ socket.sleep(n)
+ end
end
local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
+ return (year%4==0) and (year%100~=0 or year%400==0)
end
os.isleapyear=isleapyear
local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
local function nofdays(year,month)
- if not month then
- return isleapyear(year) and 365 or 364
- else
- return month==2 and isleapyear(year) and 29 or days[month]
- end
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month==2 and isleapyear(year) and 29 or days[month]
+ end
end
os.nofdays=nofdays
function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
+ return date("%w",time { year=year,month=month,day=day })+1
end
function os.validdate(year,month,day)
- if month<1 then
- month=1
- elseif month>12 then
- month=12
- end
- if day<1 then
- day=1
- else
- local max=nofdays(year,month)
- if day>max then
- day=max
- end
- end
- return year,month,day
+ if month<1 then
+ month=1
+ elseif month>12 then
+ month=12
+ end
+ if day<1 then
+ day=1
+ else
+ local max=nofdays(year,month)
+ if day>max then
+ day=max
+ end
+ 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
@@ -3931,19 +4217,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-file"] = package.loaded["l-file"] or true
--- original size: 21616, stripped down to: 10359
+-- original size: 21804, stripped down to: 9980
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
@@ -3951,24 +4237,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(".")
@@ -3982,27 +4266,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
@@ -4011,7 +4295,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)
@@ -4027,142 +4311,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)
- else
- return "",str
- end
+ 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 {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ 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
+ 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)
@@ -4172,30 +4456,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)
- 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
- else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
- end
+ 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
+ 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
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
@@ -4205,56 +4489,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
+ n=n-1
end
- 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)
@@ -4262,26 +4546,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("://")
@@ -4290,40 +4574,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
+ 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
- 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
+ if l<0 then
+ return false
end
- return true
+ end
+ return true
+end
+local symlinkattributes=lfs.symlinkattributes
+function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
end
@@ -4333,51 +4621,51 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
--- original size: 1211, stripped down to: 1002
+-- original size: 1211, stripped down to: 951
if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not gzip then
- return
+ return
end
local suffix,suffixes=file.suffix,file.suffixes
function gzip.load(filename)
- local f=io.open(filename,"rb")
- if not f then
- elseif suffix(filename)=="gz" then
- f:close()
- local g=gzip.open(filename,"rb")
- if g then
- local str=g:read("*all")
- g:close()
- return str
- end
- else
- local str=f:read("*all")
- f:close()
- return str
- end
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+ f:close()
+ local g=gzip.open(filename,"rb")
+ if g then
+ local str=g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str=f:read("*all")
+ f:close()
+ return str
+ end
end
function gzip.save(filename,data)
- if suffix(filename)~="gz" then
- filename=filename..".gz"
- end
- local f=io.open(filename,"wb")
- if f then
- local s=zlib.compress(data or "",9,nil,15+16)
- f:write(s)
- f:close()
- return #s
- end
+ if suffix(filename)~="gz" then
+ filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+ local s=zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
end
function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
end
@@ -4387,87 +4675,119 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-md5"] = package.loaded["l-md5"] or true
--- original size: 3309, stripped down to: 2314
+-- original size: 3309, stripped down to: 2218
if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not md5 then
- md5=optionalrequire("md5")
+ md5=optionalrequire("md5")
end
if not md5 then
- md5={
- sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
- sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
+ md5={
+ sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
end
local md5,file=md5,file
local gsub=string.gsub
do
- local patterns=lpeg and lpeg.patterns
- if patterns then
- local bytestoHEX=patterns.bytestoHEX
- local bytestohex=patterns.bytestohex
- local bytestodec=patterns.bytestodec
- local lpegmatch=lpeg.match
- local md5sum=md5.sum
- if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
- if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
- if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
- md5.sumhexa=md5.hex
- md5.sumHEXA=md5.HEX
- end
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+ local bytestoHEX=patterns.bytestoHEX
+ local bytestohex=patterns.bytestohex
+ local bytestodec=patterns.bytestodec
+ local lpegmatch=lpeg.match
+ local md5sum=md5.sum
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+ md5.sumhexa=md5.hex
+ md5.sumHEXA=md5.HEX
+ end
end
function file.needsupdating(oldname,newname,threshold)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime=lfs.attributes(newname,"modification")
- if not newtime then
- return true
- elseif newtime>=oldtime then
- return false
- elseif oldtime-newtime<(threshold or 1) then
- return false
- else
- return true
- end
- else
- return false
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime=lfs.attributes(newname,"modification")
+ if not newtime then
+ return true
+ elseif newtime>=oldtime then
+ return false
+ elseif oldtime-newtime<(threshold or 1) then
+ return false
+ else
+ return true
+ end
+ else
+ return false
+ end
end
file.needs_updating=file.needsupdating
function file.syncmtimes(oldname,newname)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
end
function file.checksum(name)
- if md5 then
- local data=io.loaddata(name)
- if data then
- return md5.HEX(data)
- end
+ if md5 then
+ local data=io.loaddata(name)
+ if data then
+ return md5.HEX(data)
end
- return nil
+ end
+ return nil
end
function file.loadchecksum(name)
- if md5 then
- local data=io.loaddata(name..".md5")
- return data and (gsub(data,"%s",""))
- end
- return nil
+ if md5 then
+ local data=io.loaddata(name..".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
end
function file.savechecksum(name,checksum)
- if not checksum then checksum=file.checksum(name) end
- if checksum then
- io.savedata(name..".md5",checksum)
- return checksum
- end
- return nil
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+ io.savedata(name..".md5",checksum)
+ return checksum
+ end
+ return nil
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["l-sha"] = package.loaded["l-sha"] or true
+
+-- original size: 1085, stripped down to: 969
+
+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
@@ -4477,14 +4797,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 14755, stripped down to: 7236
+-- original size: 14755, stripped down to: 6981
if not modules then modules={} end modules ['l-url']={
- 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 char,format,byte=string.char,string.format,string.byte
local concat=table.concat
@@ -4497,14 +4817,14 @@ local url=url
local unescapes={}
local escapes={}
setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
end })
setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
end })
local colon=P(":")
local qmark=P("?")
@@ -4523,21 +4843,21 @@ local escaped=(plus/" ")+escapedchar
local noslash=P("/")/""
local plustospace=P("+")/" "
local decoder=Cs((
- plustospace+escapedchar+P("\r\n")/"\n"+P(1)
- )^0 )
+ plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+ )^0 )
local encoder=Cs((
- R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
- )^0 )
+ R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+ )^0 )
lpegpatterns.urldecoder=decoder
lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1- qmark-hash))^0)
-local querystr=Cs(((1- hash))^0)
-local fragmentstr=Cs((escaped+(1- endofstring))^0)
+local pathstr=Cs((escaped+(1- qmark-hash))^0)
+local querystr=Cs(((1- hash))^0)
+local fragmentstr=Cs((escaped+(1- endofstring))^0)
local scheme=schemestr*colon+nothing
local authority=slash*slash*authoritystr+nothing
local path=slash*pathstr+nothing
@@ -4555,19 +4875,19 @@ lpegpatterns.urlescaper=escaper
lpegpatterns.urlunescaper=unescaper
lpegpatterns.urlgetcleaner=getcleaner
function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
+ return lpegmatch(getcleaner,str)
end
local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
end
local isscheme=schemestr*colon*slash*slash
local function hasscheme(str)
- if str then
- local scheme=lpegmatch(isscheme,str)
- return scheme~="" and scheme or false
- else
- return false
- end
+ if str then
+ local scheme=lpegmatch(isscheme,str)
+ return scheme~="" and scheme or false
+ else
+ return false
+ end
end
local rootletter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4577,161 +4897,161 @@ local barswapper=replacer("|",":")
local backslashswapper=replacer("\\","/")
local equal=P("=")
local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal )^0)
local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
},rawset)
local userpart=(1-atsign-colon)^1
local serverpart=(1-colon)^1
local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
local function hashed(str)
- if not str or str=="" then
- return {
- scheme="invalid",
- original=str,
- }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
- rawscheme=detailed[1]
- rawquery=detailed[4]
- somescheme=rawscheme~=""
- somequery=rawquery~=""
- end
- if not somescheme and not somequery then
- return {
- scheme="file",
- authority="",
- path=str,
- query="",
- fragment="",
- original=str,
- noscheme=true,
- filename=str,
- }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename
- local username
- local password
- local host
- local port
- if authority~="" then
- username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
- filename=path
- elseif path=="" then
- filename=""
- else
- filename=authority.."/"..path
- end
+ if not str or str=="" then
return {
- scheme=rawscheme,
- authority=authority,
- path=path,
- query=lpegmatch(unescaper,rawquery),
- queries=lpegmatch(splitquery,rawquery),
- fragment=detailed[5],
- original=str,
- noscheme=false,
- filename=filename,
- host=host,
- port=port,
+ scheme="invalid",
+ original=str,
}
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+ rawscheme=detailed[1]
+ rawquery=detailed[4]
+ somescheme=rawscheme~=""
+ somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme="file",
+ authority="",
+ path=str,
+ query="",
+ fragment="",
+ original=str,
+ noscheme=true,
+ filename=str,
+ }
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename
+ local username
+ local password
+ local host
+ local port
+ if authority~="" then
+ username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+ filename=path
+ elseif path=="" then
+ filename=""
+ else
+ filename=authority.."/"..path
+ end
+ return {
+ scheme=rawscheme,
+ authority=authority,
+ path=path,
+ query=lpegmatch(unescaper,rawquery),
+ queries=lpegmatch(splitquery,rawquery),
+ fragment=detailed[5],
+ original=str,
+ noscheme=false,
+ filename=filename,
+ host=host,
+ port=port,
+ }
end
url.split=split
url.hasscheme=hasscheme
url.hashed=hashed
function url.addscheme(str,scheme)
- if hasscheme(str) then
- return str
- elseif not scheme then
- return "file:///"..str
- else
- return scheme..":///"..str
- end
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///"..str
+ else
+ return scheme..":///"..str
+ end
end
function url.construct(hash)
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
- r=r+1;result[r]=lpegmatch(escaper,scheme)
- r=r+1;result[r]="://"
- end
- if authority and authority~="" then
- r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
- r=r+1;result[r]="/"
- r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
- local done=false
- for k,v in sortedhash(queries) do
- r=r+1;result[r]=done and "&" or "?"
- r=r+1;result[r]=lpegmatch(escaper,k)
- r=r+1;result[r]="="
- r=r+1;result[r]=lpegmatch(escaper,v)
- done=true
- end
- end
- if fragment and fragment~="" then
- r=r+1;result[r]="#"
- r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+ r=r+1;result[r]=lpegmatch(escaper,scheme)
+ r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+ r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+ r=r+1;result[r]="/"
+ r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+ local done=false
+ for k,v in sortedhash(queries) do
+ r=r+1;result[r]=done and "&" or "?"
+ r=r+1;result[r]=lpegmatch(escaper,k)
+ r=r+1;result[r]="="
+ r=r+1;result[r]=lpegmatch(escaper,v)
+ done=true
+ end
+ end
+ if fragment and fragment~="" then
+ r=r+1;result[r]="#"
+ r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
end
local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
end
local function escapestring(str)
- return lpegmatch(escaper,str)
+ return lpegmatch(escaper,str)
end
url.escape=escapestring
function url.query(str)
- if type(str)=="string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
+ if type(str)=="string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
end
function url.toquery(data)
- local td=type(data)
- if td=="string" then
- return #str and escape(data) or nil
- elseif td=="table" then
- if next(data) then
- local t={}
- for k,v in next,data do
- t[#t+1]=format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
- end
- else
+ local td=type(data)
+ if td=="string" then
+ return #str and escape(data) or nil
+ elseif td=="table" then
+ if next(data) then
+ local t={}
+ for k,v in next,data do
+ t[#t+1]=format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
end
+ else
+ end
end
local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
function url.barepath(path)
- if not path or path=="" then
- return ""
- else
- return lpegmatch(pattern,path)
- end
+ if not path or path=="" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
end
@@ -4741,14 +5061,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 17703, stripped down to: 11691
+-- original size: 18002, stripped down to: 10681
if not modules then modules={} end modules ['l-dir']={
- 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,select=type,select
local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -4760,471 +5080,478 @@ local dir=dir
local lfs=lfs
local attributes=lfs.attributes
local walkdir=lfs.dir
-local isdir=lfs.isdir
+local isdir=lfs.isdir
local isfile=lfs.isfile
local currentdir=lfs.currentdir
local chdir=lfs.chdir
local mkdir=lfs.mkdir
local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
- if lpegmatch(tricky,name) then
- return attributes(name,"mode")=="directory"
- else
- return attributes(name.."/.","mode")=="directory"
- end
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode")=="directory"
+ else
+ return attributes(name.."/.","mode")=="directory"
end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
else
- isdir=function(name)
- return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ isdir=function(name)
+ return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
end
function dir.current()
- return (gsub(currentdir(),"\\","/"))
+ return (gsub(currentdir(),"\\","/"))
end
local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- action(full)
- end
- elseif recurse and mode=="directory" then
- if not dirs then
- dirs={ full }
- else
- dirs[#dirs+1]=full
- end
- end
- end
- end
- if dirs then
- for i=1,#dirs do
- glob_pattern_function(dirs[i],patt,recurse,action)
- end
+ if isdir(path) then
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ for name in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ action(full)
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
end
+ end
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
end
+ end
end
local function glob_pattern_table(path,patt,recurse,result)
- if not result then
- result={}
- end
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- result[#result+1]=full
- end
- elseif recurse and mode=="directory" then
- if not dirs then
- dirs={ full }
- else
- dirs[#dirs+1]=full
- end
- end
- end
- end
+ if not result then
+ result={}
+ end
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,a in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ noffiles=noffiles+1
+ result[noffiles]=full
+ end
+ elseif recurse and mode=="directory" then
if dirs then
- for i=1,#dirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
end
+ end
end
- return result
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
+ end
+ end
+ return result
end
local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
- patt=false
- end
- if kind=="function" then
- return glob_pattern_function(path,patt,recurse,method)
- elseif kind=="table" then
- return glob_pattern_table(path,patt,recurse,method)
- else
- return glob_pattern_table(path,patt,recurse,{})
- end
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+ patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
end
dir.globpattern=globpattern
local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
- ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
- else
- ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
- end
- if ok and type(scanner)=="function" then
- if not find(path,"/$") then
- path=path..'/'
- end
- for name in scanner,first do
- if name=="." then
- elseif name==".." then
- else
- local full=path..name
- local attr=attributes(full)
- local mode=attr.mode
- if mode=='file' then
- if find(full,patt) then
- result[name]=attr
- end
- elseif recurse and mode=="directory" then
- attr.list=collectpattern(full,patt,recurse)
- result[name]=attr
- end
- end
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+ ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
+ else
+ ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
+ end
+ if ok and type(scanner)=="function" then
+ if not find(path,"/$") then
+ path=path..'/'
+ end
+ for name in scanner,first do
+ if name=="." then
+ elseif name==".." then
+ else
+ local full=path..name
+ local attr=attributes(full)
+ local mode=attr.mode
+ if mode=='file' then
+ if find(full,patt) then
+ result[name]=attr
+ end
+ elseif recurse and mode=="directory" then
+ attr.list=collectpattern(full,patt,recurse)
+ result[name]=attr
end
+ end
end
- return result
+ end
+ return result
end
dir.collectpattern=collectpattern
local separator,pattern
if onwindows then
- local slash=S("/\\")/"/"
- pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
- }
+ local slash=S("/\\")/"/"
+ pattern={
+ [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+ [3]=Cs(P(1)^0)
+ }
else
- pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
- }
+ pattern={
+ [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ [2]=C(((1-S("*?/"))^0*P("/"))^0),
+ [3]=C(P(1)^0)
+ }
end
local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
)^0 )
local function glob(str,t)
- if type(t)=="function" then
- if type(str)=="table" then
- for s=1,#str do
- glob(str[s],t)
- end
- elseif isfile(str) then
- t(str)
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- globpattern(start,result,recurse,t)
- end
- end
+ if type(t)=="function" then
+ if type(str)=="table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str)=="table" then
+ local t=t or {}
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1]=str
+ return t
+ else
+ return { str }
+ end
else
- if type(str)=="table" then
- local t=t or {}
- for s=1,#str do
- glob(str[s],t)
- end
- return t
- elseif isfile(str) then
- if t then
- t[#t+1]=str
- return t
- else
- return { str }
- end
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- return globpattern(start,result,recurse,t)
- else
- return {}
- end
- end
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ return globpattern(start,result,recurse,t)
+ else
+ return {}
+ end
end
+ end
end
dir.glob=glob
local function globfiles(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if recurse then
- globfiles(path.."/"..name,recurse,func,files)
- end
- elseif mode=="file" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if recurse then
+ globfiles(path.."/"..name,recurse,func,files)
+ end
+ elseif mode=="file" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
end
+ end
end
- return files
+ end
+ return files
end
dir.globfiles=globfiles
local function globdirs(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- if recurse then
- globdirs(path.."/"..name,recurse,func,files)
- end
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ if recurse then
+ globdirs(path.."/"..name,recurse,func,files)
+ end
end
+ end
end
- return files
+ end
+ return files
end
dir.globdirs=globdirs
function dir.ls(pattern)
- return concat(glob(pattern),"\n")
+ return concat(glob(pattern),"\n")
end
local make_indeed=true
if onwindows then
- function dir.mkdirs(...)
- local n=select("#",...)
- local str
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s=="" then
+ elseif str=="" then
+ str=s
else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s=="" then
- elseif str=="" then
- str=s
- else
- str=str.."/"..s
- end
- end
+ str=str.."/"..s
end
- local pth=""
- local drive=false
- local first,middle,last=match(str,"^(//)(//*)(.*)$")
- if first then
+ end
+ end
+ local pth=""
+ local drive=false
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ else
+ first,last=match(str,"^(//)/*(.-)$")
+ if first then
+ middle,last=match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth="//"..middle
else
- first,last=match(str,"^(//)/*(.-)$")
- if first then
- middle,last=match(str,"([^/]+)/+(.-)$")
- if middle then
- pth="//"..middle
- else
- pth="//"..last
- last=""
- end
- else
- first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth,drive=first..middle,true
- else
- middle,last=match(str,"^(/*)(.-)$")
- if not middle then
- last=str
- end
- end
- end
+ pth="//"..last
+ last=""
end
- for s in gmatch(last,"[^/]+") do
- if pth=="" then
- pth=s
- elseif drive then
- pth,drive=pth..s,false
- else
- pth=pth.."/"..s
- end
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
+ else
+ first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth,drive=first..middle,true
+ else
+ middle,last=match(str,"^(/*)(.-)$")
+ if not middle then
+ last=str
+ end
end
- return pth,(isdir(pth)==true)
+ end
end
+ for s in gmatch(last,"[^/]+") do
+ if pth=="" then
+ pth=s
+ elseif drive then
+ pth,drive=pth..s,false
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
else
- function dir.mkdirs(...)
- local n=select("#",...)
- local str,pth
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s and s~="" then
- if str~="" then
- str=str.."/"..s
- else
- str=s
- end
- end
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str,pth
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s and s~="" then
+ if str~="" then
+ str=str.."/"..s
+ else
+ str=s
+ end
end
- str=gsub(str,"/+","/")
- if find(str,"^/") then
- pth="/"
- for s in gmatch(str,"[^/]+") do
- local first=(pth=="/")
- if first then
- pth=pth..s
- else
- pth=pth.."/"..s
- end
- if make_indeed and not first and not isdir(pth) then
- mkdir(pth)
- end
- end
+ end
+ end
+ str=gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth="/"
+ for s in gmatch(str,"[^/]+") do
+ local first=(pth=="/")
+ if first then
+ pth=pth..s
else
- pth="."
- for s in gmatch(str,"[^/]+") do
- pth=pth.."/"..s
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
+ pth=pth.."/"..s
end
- return pth,(isdir(pth)==true)
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth="."
+ for s in gmatch(str,"[^/]+") do
+ pth=pth.."/"..s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
end
+ return pth,(isdir(pth)==true)
+ end
end
dir.makedirs=dir.mkdirs
do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
- local xcurrentdir=dir.current
- function dir.expandname(str)
- local first,nothing,last=match(str,"^(//)(//*)(.*)$")
- if first then
- first=xcurrentdir().."/"
- end
- if not first then
- first,last=match(str,"^(//)/*(.*)$")
- end
- if not first then
- first,last=match(str,"^([a-zA-Z]:)(.*)$")
- if first and not find(last,"^/") then
- local d=currentdir()
- if chdir(first) then
- first=xcurrentdir()
- end
- chdir(d)
- end
- end
- if not first then
- first,last=xcurrentdir(),str
- end
- last=gsub(last,"//","/")
- last=gsub(last,"/%./","/")
- last=gsub(last,"^/*","")
- first=gsub(first,"/*$","")
- if last=="" or last=="." then
- return first
- else
- return first.."/"..last
- end
- end
- else
- function dir.expandname(str)
- if not find(str,"^/") then
- str=currentdir().."/"..str
- end
- str=gsub(str,"//","/")
- str=gsub(str,"/%./","/")
- str=gsub(str,"(.)/%.$","%1")
- return str
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+ local xcurrentdir=dir.current
+ function dir.expandname(str)
+ local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ first=xcurrentdir().."/"
+ end
+ if not first then
+ first,last=match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first,last=match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d=currentdir()
+ if chdir(first) then
+ first=xcurrentdir()
+ end
+ chdir(d)
end
+ end
+ if not first then
+ first,last=xcurrentdir(),str
+ end
+ last=gsub(last,"//","/")
+ last=gsub(last,"/%./","/")
+ last=gsub(last,"^/*","")
+ first=gsub(first,"/*$","")
+ if last=="" or last=="." then
+ return first
+ else
+ return first.."/"..last
+ end
end
+ else
+ function dir.expandname(str)
+ if not find(str,"^/") then
+ str=currentdir().."/"..str
+ end
+ str=gsub(str,"//","/")
+ str=gsub(str,"/%./","/")
+ str=gsub(str,"(.)/%.$","%1")
+ return str
+ end
+ end
end
file.expandname=dir.expandname
local stack={}
function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" then
- chdir(newdir)
- return newdir
- else
- return curdir
- end
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" then
+ chdir(newdir)
+ return newdir
+ else
+ return curdir
+ end
end
function dir.pop()
- local d=remove(stack)
- if d then
- chdir(d)
- end
- return d
+ local d=remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
end
local function found(...)
- for i=1,select("#",...) do
- local path=select(i,...)
- local kind=type(path)
- if kind=="string" then
- if isdir(path) then
- return path
- end
- elseif kind=="table" then
- local path=found(unpack(path))
- if path then
- return path
- end
- end
+ for i=1,select("#",...) do
+ local path=select(i,...)
+ local kind=type(path)
+ if kind=="string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind=="table" then
+ local path=found(unpack(path))
+ if path then
+ return path
+ end
end
+ end
end
dir.found=found
@@ -5235,69 +5562,69 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
--- original size: 1850, stripped down to: 1568
+-- original size: 1850, stripped down to: 1498
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
@@ -5307,18 +5634,24 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 40036, stripped down to: 17837
+-- original size: 41047, stripped down to: 17171
if not modules then modules={} end modules ['l-unicode']={
- 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"
}
-utf=utf or (unicode and unicode.utf8) or {}
-utf.characters=utf.characters or string.utfcharacters
-utf.values=utf.values or string.utfvalues
+utf=utf or {}
+unicode=nil
+if not string.utfcharacters then
+ local gmatch=string.gmatch
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
+end
+utf.characters=string.utfcharacters
local type=type
local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch
local concat=table.concat
@@ -5329,345 +5662,340 @@ local tabletopattern=lpeg.utfchartabletopattern
local bytepairs=string.bytepairs
local finder=lpeg.finder
local replacer=lpeg.replacer
-local utfvalues=utf.values
-local utfgmatch=utf.gmatch
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 }
-end
if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+ local char=string.char
+ if bit32 then
+ local rshift=bit32.rshift
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+rshift(n,6),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+rshift(n,12),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+rshift(n,18),
+ 0x80+(rshift(n,12)%0x40),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
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
+ 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
end
+ end
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
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
end
+ end
end
local utfchar,utfbyte=utf.char,utf.byte
function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
+ return data and lpegmatch(p_utftype,data) or "unknown"
end
local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
)
patterns.toentities=toentities
function utf.toentities(str)
- return lpegmatch(toentities,str)
+ 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 )
+ 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
+ return lpegmatch(pattern,s) or s
end
local validatedutf=Cs (
- (
- patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
- )^0
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
)
patterns.validatedutf=validatedutf
function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
+ 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
+ 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
+ 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
- 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
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
end
- local function slide_two(s,p)
- n=n+1
- if n==first then
- b=p
- else
- return true
- end
+ if n>=last then
+ e=p-1
+ else
+ return p
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
+ 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_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(p_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
- 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)
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
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)
+ 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
+ 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)
+ 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
- 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
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
end
- elseif variant=="function" then
- if option=="pattern" then
- return Cs((p_utf8char/mapping+p_utf8char)^0)
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
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
+ return lpegmatch(pattern,str)
end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8character/mapping+p_utf8character)^0)
else
- return function(str)
- return str or ""
+ local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
end
+ end,pattern
end
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
+ else
return function(str)
- return lpegmatch(r,str)
+ return str or ""
end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
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
+ 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
end
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
function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
+ return lpegmatch(utflinesplitter,str or "")
end
function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
end
function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
+ return lpegmatch(utfcharsplitter_raw,str)
end
function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
end
local utf16_to_utf8_be,utf16_to_utf8_le
local utf32_to_utf8_be,utf32_to_utf8_le
@@ -5681,36 +6009,36 @@ local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_n
local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
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
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ 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
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 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
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))
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
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))
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
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)
@@ -5721,88 +6049,88 @@ 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
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ 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
+ 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
- return t
+ end
+ return t
end
utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -5813,189 +6141,225 @@ 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
+ 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
+ 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
+ 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
+ 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
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
+ 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
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
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
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
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
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
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
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
+ (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 " ")
+ return lpegmatch(pattern,str,1,separator or " ")
end
function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
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
-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
+ 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
end
-if not utf.characters then
- function utf.characters(str)
- return gmatch(str,".[\128-\191]*")
+do
+ local p_nany=p_utf8character/""
+ 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
- string.utfcharacters=utf.characters
+ end
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
+if not string.utfvalues then
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(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
- string.utfvalues=utf.values
+ end
end
+utf.values=string.utfvalues
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
+ 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
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 extract=bit32.extract
+ local char=string.char
+ function utf.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
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
+ 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
- return s
+ end
+ return s
+end
+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)
+ 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
+ end
+ if 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 p_utf8byte/f
+ end
+ end
end
@@ -6005,93 +6369,93 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-math"] = package.loaded["l-math"] or true
--- original size: 2555, stripped down to: 1900
+-- original size: 2555, stripped down to: 1831
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)<floor(n)
- end
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
@@ -6101,14 +6465,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 38734, stripped down to: 22142
+-- original size: 43539, stripped down to: 21641
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"
+ 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 {}
@@ -6121,624 +6485,657 @@ 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 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
if not number then number={} end
-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 ptf=1/65536
+local bpf=(7200/7227)/65536
local function points(n)
- n=tonumber(n)
- return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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)
+ return lpegmatch(pattern,str)
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
+ 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
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((
+ 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
+ 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)
+ extra,start=0,position
+ end+anything
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
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 space=spacer^0
-local nospace=space/""
+ 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-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 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,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["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
+ return str and lpegmatch(striplinepatterns[how],str) or str
+end
+function strings.collapse(str)
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return 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)..'"')
+ 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).."'")
+ 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]",
+ "[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
+ 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
+ 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))*(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==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
if sep1==true then
- return lpegmatch(splitter,s,1,".",",")
+ return lpegmatch(splitter,n,1,".",",")
elseif sep1=="." then
- return lpegmatch(splitter,s,1,sep1,sep2 or ",")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
elseif sep1=="," then
- return lpegmatch(splitter,s,1,sep1,sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ 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
- )
+ 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
+ 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 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
- 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))
+ 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
- return tostring(n)
+ 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
+ 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
+ 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 #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
%s
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,
+}
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ 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)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
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
+ 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 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
+ 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 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ 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)
+ 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
+ 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
+ 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
+ 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
+ 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)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ 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
+ 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
+ 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)
+ 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)
+ 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()
+ 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(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))
+ 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")
@@ -6750,160 +7147,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("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
-patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
+patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+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
@@ -6913,14 +7306,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 27741, stripped down to: 17085
+-- original size: 28772, stripped down to: 16111
if not modules then modules={} end modules ['util-tab']={
- 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"
}
utilities=utilities or {}
utilities.tables=utilities.tables or {}
@@ -6935,219 +7328,220 @@ local formatters=string.formatters
local utftoeight=utf.toeight
local splitter=lpeg.tsplitat(".")
function utilities.tables.definetable(target,nofirst,nolast)
- local composed,t=nil,{}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
- local name=snippets[i]
- if composed then
- composed=composed.."."..name
- t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
- else
- composed=name
- if not nofirst then
- t[#t+1]=formatters["%s = %s or { }"](composed,composed)
- end
- end
- end
+ local composed=nil
+ local t={}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+ local name=snippets[i]
if composed then
- if nolast then
- composed=composed.."."..snippets[#snippets]
- end
- return concat(t,"\n"),composed
+ composed=composed.."."..name
+ t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
else
- return "",target
+ composed=name
+ if not nofirst then
+ t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+ end
+ end
+ end
+ if composed then
+ if nolast then
+ composed=composed.."."..snippets[#snippets]
end
+ return concat(t,"\n"),composed
+ else
+ return "",target
+ end
end
function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
- local li=select(i,...)
- local tl=t[li]
- if not tl then
- tl={}
- t[li]=tl
- end
- t=tl
- end
- return t
+ local t=_G
+ for i=1,select("#",...) do
+ local li=select(i,...)
+ local tl=t[li]
+ if not tl then
+ tl={}
+ t[li]=tl
+ end
+ t=tl
+ end
+ return t
end
function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t=t[name]
+ if not t then
+ return
end
- return t
+ end
+ return t
end
function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
- local name=names[i]
- t[name]=t[name] or {}
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name=names[i]
+ t[name]=t[name] or {}
+ t=t[name]
+ if not t then
+ return
end
- t[names[#names]]=v
+ end
+ t[names[#names]]=v
end
function tables.removevalue(t,value)
- if value then
- for i=1,#t do
- if t[i]==value then
- remove(t,i)
- end
- end
+ if value then
+ for i=1,#t do
+ if t[i]==value then
+ remove(t,i)
+ end
end
+ end
end
function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
- for i=1,#t do
- if t[i]==oldvalue then
- t[i]=newvalue
- end
- end
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i]==oldvalue then
+ t[i]=newvalue
+ end
end
+ end
end
function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i,extra)
+ return
end
- insert(t,1,extra)
+ end
+ insert(t,1,extra)
end
function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i+1,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i+1,extra)
+ return
end
- insert(t,#t+1,extra)
+ end
+ insert(t,#t+1,extra)
end
local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
function table.tocsv(t,specification)
- if t and #t>0 then
- local result={}
- local r={}
- specification=specification or {}
- local fields=specification.fields
- if type(fields)~="string" then
- fields=sortedkeys(t[1])
- end
- local separator=specification.separator or ","
- local noffields=#fields
- if specification.preamble==true then
- for f=1,noffields do
- r[f]=lpegmatch(escape,tostring(fields[f]))
- end
- result[1]=concat(r,separator)
- end
- for i=1,#t do
- local ti=t[i]
- for f=1,noffields do
- local field=ti[fields[f]]
- if type(field)=="string" then
- r[f]=lpegmatch(escape,field)
- else
- r[f]=tostring(field)
- end
- end
- result[i+1]=concat(r,separator)
+ if t and #t>0 then
+ local result={}
+ local r={}
+ specification=specification or {}
+ local fields=specification.fields
+ if type(fields)~="string" then
+ fields=sortedkeys(t[1])
+ end
+ local separator=specification.separator or ","
+ local noffields=#fields
+ if specification.preamble==true then
+ for f=1,noffields do
+ r[f]=lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1]=concat(r,separator)
+ end
+ for i=1,#t do
+ local ti=t[i]
+ for f=1,noffields do
+ local field=ti[fields[f]]
+ if type(field)=="string" then
+ r[f]=lpegmatch(escape,field)
+ else
+ r[f]=tostring(field)
end
- return concat(result,"\n")
- else
- return ""
+ end
+ result[i+1]=concat(r,separator)
end
+ return concat(result,"\n")
+ else
+ return ""
+ end
end
local nspaces=utilities.strings.newrepeater(" ")
local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
- local s=nspaces[d]
- local tk=type(k)
- local tv=type(v)
- if tv=="table" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</entry>"](s,k)
- else
- r=r+1 result[r]=formatters["%s<%s>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</%s>"](s,k)
- end
- elseif tv=="string" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
- end
- elseif tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
- end
+ local r=#result
+ for k,v in sortedpairs(t) do
+ local s=nspaces[d]
+ local tk=type(k)
+ local tv=type(v)
+ if tv=="table" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</entry>"](s,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</%s>"](s,k)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
end
+ end
end
function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
- toxml(t,indent,result,spaces)
- else
- toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+ toxml(t,indent,result,spaces)
+ else
+ toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
end
function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
- protect=true
- capsule={}
- end
+ if type(capsule)~="table" then
+ protect=true
+ capsule={}
+ end
+ for key,value in next,core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key]=value
+ end
+ end
+ if protect then
for key,value in next,core do
+ core[key]=nil
+ end
+ setmetatable(core,{
+ __index=capsule,
+ __newindex=function(t,key,value)
if capsule[key] then
- print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
- os.exit()
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
else
- capsule[key]=value
+ rawset(t,key,value)
end
- end
- if protect then
- for key,value in next,core do
- core[key]=nil
- end
- setmetatable(core,{
- __index=capsule,
- __newindex=function(t,key,value)
- if capsule[key] then
- print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
- os.exit()
- else
- rawset(t,key,value)
- end
- end
- } )
- end
+ end
+ } )
+ end
end
local f_hashed_string=formatters["[%q]=%q,"]
local f_hashed_number=formatters["[%q]=%s,"]
@@ -7161,157 +7555,157 @@ local f_ordered_string=formatters["%q,"]
local f_ordered_number=formatters["%s,"]
local f_ordered_boolean=formatters["%l,"]
function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- for i=0,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
- end
- end
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ for i=0,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
- end
- end
- else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
- end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ else
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_hashed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_hashed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_hashed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
- return r
+ end
end
- return concat(fastserialize(t,true))
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
- if not str or str=="" then
- return
- end
- local code=load(str)
- if not code then
- return
- end
- code=code()
- if not code then
- return
- end
- return code
+ if not str or str=="" then
+ return
+ end
+ local code=load(str)
+ if not code then
+ return
+ end
+ code=code()
+ if not code then
+ return
+ end
+ return code
end
function table.load(filename,loader)
- if filename then
- local t=(loader or io.loaddata)(filename)
- if t and t~="" then
- local t=utftoeight(t)
- t=load(t)
- if type(t)=="function" then
- t=t()
- if type(t)=="table" then
- return t
- end
- end
+ if filename then
+ local t=(loader or io.loaddata)(filename)
+ if t and t~="" then
+ local t=utftoeight(t)
+ t=load(t)
+ if type(t)=="function" then
+ t=t()
+ if type(t)=="table" then
+ return t
end
+ end
end
+ end
end
function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...))
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...))
end
local f_key_value=formatters["%s=%q"]
local f_add_table=formatters[" {%t},\n"]
local f_return_table=formatters["return {\n%t}"]
local function slowdrop(t)
- local r={}
- local l={}
- for i=1,#t do
- local ti=t[i]
- local j=0
- for k,v in next,ti do
- j=j+1
- l[j]=f_key_value(k,v)
- end
- r[i]=f_add_table(l)
- end
- return f_return_table(r)
+ local r={}
+ local l={}
+ for i=1,#t do
+ local ti=t[i]
+ local j=0
+ for k,v in next,ti do
+ j=j+1
+ l[j]=f_key_value(k,v)
+ end
+ r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
end
local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
- local ti=t[i]
- m=m+1 r[m]=" {"
- for k,v in next,ti do
- m=m+1 r[m]=f_key_value(k,v)
- end
- m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+ local ti=t[i]
+ m=m+1 r[m]=" {"
+ for k,v in next,ti do
+ m=m+1 r[m]=f_key_value(k,v)
+ end
+ m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
end
function table.drop(t,slow)
- if #t==0 then
- return "return { }"
- elseif slow==true then
- return slowdrop(t)
- else
- return fastdrop(t)
- end
+ if #t==0 then
+ return "return { }"
+ elseif slow==true then
+ return slowdrop(t)
+ else
+ return fastdrop(t)
+ end
end
local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)
- if not t then
- t={}
- else
- local zero=rawget(t,0)
- for i=zero and 0 or 1,#t do
- local ti=t[i]
- if ti then
- local i=tostring(i)
- t[i]=ti
- t[ti]=i
- end
- end
+function table.twowaymapper(t)
+ if not t then
+ t={}
+ else
+ local zero=rawget(t,0)
+ for i=zero and 0 or 1,#t do
+ local ti=t[i]
+ if ti then
+ local i=tostring(i)
+ t[i]=ti
+ t[ti]=i
+ end
end
- setmetatable(t,selfmapper)
- return t
+ end
+ setmetatable(t,selfmapper)
+ return t
end
local f_start_key_idx=formatters["%w{"]
local f_start_key_num=formatters["%w[%s]={"]
@@ -7349,187 +7743,223 @@ local spaces=utilities.strings.newrepeater(" ")
local original_serialize=table.serialize
local is_simple_table=table.is_simple_table
local function serialize(root,name,specification)
- if type(specification)=="table" then
- return original_serialize(root,name,specification)
- end
- local t
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- n=n+1
- if indexed then
- t[n]=f_start_key_idx(depth)
+ if type(specification)=="table" then
+ return original_serialize(root,name,specification)
+ end
+ local t
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ n=n+1
+ if indexed then
+ t[n]=f_start_key_idx(depth)
+ else
+ local tn=type(name)
+ if tn=="number" then
+ t[n]=f_start_key_num(depth,name)
+ elseif tn=="string" then
+ t[n]=f_start_key_str(depth,name)
+ elseif tn=="boolean" then
+ t[n]=f_start_key_boo(depth,name)
+ else
+ t[n]=f_start_key_nop(depth)
+ end
+ end
+ depth=depth+1
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ 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
+ 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 first and tk=="number" and k<=last and k>=first then
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v)==nil then
+ n=n+1 t[n]=f_val_not(depth)
else
- local tn=type(name)
- if tn=="number" then
- t[n]=f_start_key_num(depth,name)
- elseif tn=="string" then
- t[n]=f_start_key_str(depth,name)
- elseif tn=="boolean" then
- t[n]=f_start_key_boo(depth,name)
- else
- t[n]=f_start_key_nop(depth)
- end
- end
- depth=depth+1
- end
- if root and next(root)~=nil then
- local first=nil
- local last=0
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
end
- if last>0 then
- first=1
+ elseif tv=="boolean" then
+ n=n+1 t[n]=f_val_boo(depth,v)
+ elseif unknown then
+ n=n+1 t[n]=f_val_str(depth,tostring(v))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_not(depth,k)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_not(depth,k)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
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 first and tk=="number" and k<=last and k>=first then
- if tv=="number" then
- n=n+1 t[n]=f_val_num(depth,v)
- elseif tv=="string" then
- n=n+1 t[n]=f_val_str(depth,v)
- elseif tv=="table" then
- if next(v)==nil then
- n=n+1 t[n]=f_val_not(depth)
- else
- local st=is_simple_table(v)
- if st then
- n=n+1 t[n]=f_val_seq(depth,st)
- else
- do_serialize(v,k,depth,level+1,true)
- end
- end
- elseif tv=="boolean" then
- n=n+1 t[n]=f_val_boo(depth,v)
- elseif unknown then
- n=n+1 t[n]=f_val_str(depth,tostring(v))
- end
- elseif tv=="number" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_num(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_num(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
- end
- elseif tv=="string" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_not(depth,k)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_not(depth,k)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_not(depth,k)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
- end
- else
- local st=is_simple_table(v)
- if not st then
- do_serialize(v,k,depth,level+1)
- elseif tk=="number" then
- n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
- end
- end
- elseif tv=="boolean" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
- end
- else
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
- end
- end
+ else
+ local st=is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
end
- end
- if level>0 then
- n=n+1 t[n]=f_stop(depth-1)
- end
- end
- local tname=type(name)
- if tname=="string" then
- if name=="return" then
- t={ f_table_return() }
- else
- t={ f_table_name(name) }
- end
- elseif tname=="number" then
- t={ f_table_entry(name) }
- elseif tname=="boolean" then
- if name then
- t={ f_table_return() }
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+ end
else
- t={ f_table_direct() }
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
end
+ end
+ end
+ if level>0 then
+ n=n+1 t[n]=f_stop(depth-1)
+ end
+ end
+ local tname=type(name)
+ if tname=="string" then
+ if name=="return" then
+ t={ f_table_return() }
else
- t={ f_table_name("t") }
+ t={ f_table_name(name) }
end
- if root then
- if 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
- local st=is_simple_table(root)
- if st then
- return t[1]..f_fin_seq(st)
- else
- do_serialize(root,name,1,0)
- end
- end
+ elseif tname=="number" then
+ t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+ if name then
+ t={ f_table_return() }
+ else
+ t={ f_table_direct() }
+ end
+ else
+ t={ f_table_name("t") }
+ end
+ if root then
+ if 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
+ local st=is_simple_table(root)
+ if st then
+ return t[1]..f_fin_seq(st)
+ else
+ do_serialize(root,name,1,0)
+ end
end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
end
table.serialize=serialize
if setinspector then
- setinspector("table",function(v)
- if type(v)=="table" then
- print(serialize(v,"table",{ metacheck=false }))
- return true
- end
- end)
+ setinspector("table",function(v)
+ if type(v)=="table" then
+ print(serialize(v,"table",{ metacheck=false }))
+ return true
+ end
+ end)
+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
@@ -7539,15 +7969,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 7787, stripped down to: 5858
+-- original size: 8607, stripped down to: 6727
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 {}
@@ -7555,251 +7986,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
@@ -7809,338 +8269,412 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 8716, stripped down to: 6754
+-- original size: 11065, stripped down to: 8209
if not modules then modules={} end modules ['util-sac']={
- 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 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)
+ 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()
end
function streams.size(f)
- return f and f[3] or 0
+ return f and f[3] or 0
end
function streams.setposition(f,i)
- if f[4] then
- if i<=0 then
- f[2]=1
- else
- f[2]=i+1
- end
+ if f[4] then
+ if i<=0 then
+ f[2]=1
else
- if i<=1 then
- f[2]=1
- else
- f[2]=i
- end
+ f[2]=i+1
end
-end
-function streams.getposition(f)
- if f[4] then
- return f[2]-1
+ else
+ if i<=1 then
+ f[2]=1
else
- return f[2]
+ f[2]=i
end
+ end
+end
+function streams.getposition(f)
+ if f[4] then
+ return f[2]-1
+ else
+ return f[2]
+ end
end
function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
- return sub(f[1],b,e)
- else
- return byte(f[1],b,e)
- end
+ local b=f[2]
+ local e=b+n-1
+ if chars then
+ return sub(f[1],b,e)
+ else
+ return byte(f[1],b,e)
+ end
end
function streams.skip(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
+ local i=f[2]
+ f[2]=i+1
+ return byte(f[1],i)
end
function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return byte(f[1],i,j-1)
end
function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return { byte(f[1],i,j-1) }
end
function streams.skipbytes(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
+ local i=f[2]
+ f[2]=i+1
+ return sub(f[1],i,i)
end
function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
-end
-function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return sub(f[1],i,j-1)
+end
+function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ local n=byte(f[1],i)
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-streams.readcardinal1=streams.readbyte
+streams.readcardinal1=streams.readbyte
streams.readcardinal=streams.readcardinal1
streams.readinteger=streams.readinteger1
function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readcardinal2LE(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ 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 streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local d,c,b,a=byte(f[1],i,j)
+ 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 streams.readfixed2(f)
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function streams.readfixed4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
- else
- return (0x100*a+b )+(0x100*c+d)/0x10000
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
end
-function streams.readfixed2(f)
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function streams.read2dot14(f)
local i=f[2]
local j=i+1
f[2]=j+1
local a,b=byte(f[1],i,j)
if a>=0x80 then
- return (a-0x100)+b/0x100
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
else
- return (a )+b/0x100
- end
-end
-if extract then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- 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 n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
+ f[2]=f[2]+2*(n or 1)
end
function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
+ f[2]=f[2]+4*(n or 1)
end
if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
- local i=f[2]
- f[2]=i+1
- return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
- local i=f[2]
- f[2]=i+2
- return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
- local i=f[2]
- f[2]=i+3
- return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
- local i=f[2]
- f[2]=i+4
- return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
- local i=f[2]
- f[2]=i+2
- return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
- local i=f[2]
- f[2]=i+3
- return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
- local i=f[2]
- f[2]=i+4
- return readinteger4(f[1],i)
- end
- function streams.read2dot4(f)
- local i=f[2]
- f[2]=i+2
- return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytes(f[1],i,n)
+ local readcardinal1=sio.readcardinal1
+ local readcardinal2=sio.readcardinal2
+ local readcardinal3=sio.readcardinal3
+ local readcardinal4=sio.readcardinal4
+ local readinteger1=sio.readinteger1
+ local readinteger2=sio.readinteger2
+ local readinteger3=sio.readinteger3
+ local readinteger4=sio.readinteger4
+ local readfixed2=sio.readfixed2
+ local readfixed4=sio.readfixed4
+ local read2dot14=sio.read2dot14
+ local readbytes=sio.readbytes
+ local readbytetable=sio.readbytetable
+ function streams.readcardinal1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readcardinal1(f[1],i)
+ end
+ function streams.readcardinal2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readcardinal2(f[1],i)
+ end
+ function streams.readcardinal3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readcardinal3(f[1],i)
+ end
+ function streams.readcardinal4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readcardinal4(f[1],i)
+ end
+ function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readinteger1(f[1],i)
+ end
+ function streams.readinteger2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readinteger2(f[1],i)
+ end
+ function streams.readinteger3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readinteger3(f[1],i)
+ end
+ function streams.readinteger4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readinteger4(f[1],i)
+ end
+ function streams.read2dot4(f)
+ local i=f[2]
+ f[2]=i+2
+ return read2dot4(f[1],i)
+ end
+ function streams.readbytes(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function streams.readbytetable(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytetable(f[1],i,n)
+ return readbytes(f[1],i,n)
+ end
+ function streams.readbytetable(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readbytetable(f[1],i,n)
+ end
+ streams.readbyte=streams.readcardinal1
+ streams.readsignedbyte=streams.readinteger1
+ streams.readcardinal=streams.readcardinal1
+ 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
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
+ 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
@@ -8150,156 +8684,168 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sto"] = package.loaded["util-sto"] or true
--- original size: 6449, stripped down to: 3069
+-- original size: 6661, stripped down to: 3074
if not modules then modules={} end modules ['util-sto']={
- 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 setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
utilities=utilities or {}
utilities.storage=utilities.storage or {}
local storage=utilities.storage
function storage.mark(t)
- if not t then
- print("\nfatal error: storage cannot be marked\n")
- os.exit()
- return
- end
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
+ local m=getmetatable(t)
+ return m and m.__storage__
end
function storage.checked(t)
- if not t then
- report("\nfatal error: storage has not been allocated\n")
- os.exit()
- return
- end
- return t
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
end
function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
- m.__index=nil
- initialize()
- return data[k]
- end
- setmetatable(data,m)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+ m.__index=nil
+ initialize()
+ return data[k]
+ end
+ setmetatable(data,m)
end
local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
+ t[k]=k
+ return k
end }
function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
-end
-local function f_empty () return "" end
-local function f_self (t,k) t[k]=k return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0 return 0 end
-local function f_ignore() end
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
+end
+local function f_empty () return "" end
+local function f_self (t,k) t[k]=k return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0 return 0 end
+local function f_ignore() end
local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
}
function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- else
- setmetatable(t,{ __index=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ else
+ setmetatable(t,{ __index=i })
+ end
+ return t
end
local f_index={
- ["ignore"]=f_ignore,
+ ["ignore"]=f_ignore,
}
function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__newindex=i
- else
- setmetatable(t,{ __newindex=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__newindex=i
+ else
+ setmetatable(t,{ __newindex=i })
+ end
+ return t
end
function table.setmetatablecall(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
- m.__call=f
- else
- setmetatable(t,{ __call=f })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__call=f
+ else
+ setmetatable(t,{ __call=f })
+ end
+ return t
end
function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- m.__newindex=n
- m.__call=c
- else
- setmetatable(t,{
- __index=i,
- __newindex=n,
- __call=c,
- })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ m.__newindex=n
+ m.__call=c
+ else
+ setmetatable(t,{
+ __index=i,
+ __newindex=n,
+ __call=c,
+ })
+ end
+ return t
end
function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m[key]=value
- return t
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m[key]=value
+ return t
end
function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
+ local m=getmetatable(t)
+ 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
@@ -8309,14 +8855,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 22956, stripped down to: 16106
+-- original size: 23460, stripped down to: 15834
if not modules then modules={} end modules ['util-prs']={
- 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 lpeg,table,string=lpeg,table,string
local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -8338,6 +8884,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("}")
@@ -8357,8 +8904,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -8366,311 +8913,329 @@ local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
local spaces=space^0
local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces
+lpegpatterns.nestedbraces=nestedbraces
lpegpatterns.nestedparents=nestedparents
-lpegpatterns.nested=nestedbraces
+lpegpatterns.nested=nestedbraces
lpegpatterns.argument=argument
lpegpatterns.content=content
-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("")))
local hash={}
local function set(key,value)
- hash[key]=value
+ hash[key]=value
end
local pattern_a_s=(pattern_a/set)^1
local pattern_b_s=(pattern_b/set)^1
local pattern_c_s=(pattern_c/set)^1
+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
- return (pattern_c/set)^1
- elseif how=="tolerant" then
- return (pattern_b/set)^1
- else
- return (pattern_a/set)^1
- end
+ if how=="strict" then
+ return (pattern_c/set)^1
+ elseif how=="tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
end
function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_a_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_a_s,str)
+ return hash
+ 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 {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_b_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
- return nil
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- elseif str and str~="" then
- hash=existing or {}
- lpegmatch(pattern_c_s,str)
- return next(hash) and hash
+ if not str or str=="" then
+ return nil
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
end
+ elseif str and str~="" then
+ hash=existing or {}
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
end
local separator=comma*space^0
-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 pattern=spaces*Ct(value*(separator*value)^0)
patterns.settings_to_array=pattern
function parsers.settings_to_array(str,strict)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- elseif strict then
- if find(str,"{",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
- elseif find(str,",",1,true) then
- return lpegmatch(pattern,str)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
else
- return { str }
+ return { str }
end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
end
function parsers.settings_to_numbers(str)
- if not str or str=="" then
- return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
- str=lpegmatch(pattern,str)
- else
- return { tonumber(str) }
- end
- for i=1,#str do
- str[i]=tonumber(str[i])
- end
- return str
-end
-local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
+ if not str or str=="" then
+ return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+ str=lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i]=tonumber(str[i])
+ end
+ return str
+end
+local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache_a={}
local cache_b={}
function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
- symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
- local symbols=S(symbol)
- local separator=space^0*symbols*space^0
- local value=P(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
- pattern=spaces*withvalue*(separator*withvalue)^0
- cache_b[symbol]=pattern
- else
- pattern=spaces*Ct(value*(separator*value)^0)
- cache_a[symbol]=pattern
- end
- end
- return pattern
+ if not symbol then
+ symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols=S(symbol)
+ local separator=space^0*symbols*space^0
+ 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
+ pattern=spaces*withvalue*(separator*withvalue)^0
+ cache_b[symbol]=pattern
+ else
+ pattern=spaces*Ct(value*(separator*value)^0)
+ cache_a[symbol]=pattern
+ end
+ end
+ return pattern
end
local pattern_a=parsers.groupedsplitat(",",false)
local pattern_b=parsers.groupedsplitat(",",true)
function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_a,str)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_a,str)
+ end
end
function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_b,str,1,action)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
end
local function set(t,v)
- t[#t+1]=v
+ t[#t+1]=v
end
local value=P(Carg(1)*value)/set
local pattern=value*(separator*value)^0*Carg(1)
function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
+ return lpegmatch(pattern,str,nil,t)
end
function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
- local t,tn,s={},0,sortedkeys(h)
- omit=omit and tohash(omit)
- for i=1,#s do
- local key=s[i]
- if not omit or not omit[key] then
- local value=h[key]
- if type(value)=="boolean" then
- if yes and no then
- if value then
- tn=tn+1
- t[tn]=key..'='..yes
- elseif not strict then
- tn=tn+1
- t[tn]=key..'='..no
- end
- elseif value or not strict then
- tn=tn+1
- t[tn]=key..'='..tostring(value)
- end
- else
- tn=tn+1
- t[tn]=key..'='..value
- end
- end
+ if h then
+ local t={}
+ local tn=0
+ local s=sortedkeys(h)
+ omit=omit and tohash(omit)
+ for i=1,#s do
+ local key=s[i]
+ if not omit or not omit[key] then
+ local value=h[key]
+ if type(value)=="boolean" then
+ if yes and no then
+ if value then
+ tn=tn+1
+ t[tn]=key..'='..yes
+ elseif not strict then
+ tn=tn+1
+ t[tn]=key..'='..no
+ end
+ elseif value or not strict then
+ tn=tn+1
+ t[tn]=key..'='..tostring(value)
+ end
+ else
+ tn=tn+1
+ t[tn]=key..'='..value
end
- return concat(t,separator or ",")
- else
- return ""
+ end
end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
end
function parsers.array_to_string(a,separator)
- if a then
- return concat(a,separator or ",")
- else
- return ""
- end
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
end
local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
function utilities.parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
+ return str and lpegmatch(pattern,str) or {}
end
hashes.settings_to_set=table.setmetatableindex(function(t,k)
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
end)
getmetatable(hashes.settings_to_set).__mode="kv"
function parsers.simple_hash_to_string(h,separator)
- local t,tn={},0
- for k,v in sortedhash(h) do
- if v then
- tn=tn+1
- t[tn]=k
- end
+ local t={}
+ local tn=0
+ for k,v in sortedhash(h) do
+ if v then
+ tn=tn+1
+ t[tn]=k
end
- return concat(t,separator or ",")
+ end
+ return concat(t,separator or ",")
end
local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
local splitter=setting^1
function utilities.parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
end
local splitter=lpeg.tsplitat(" ")
function utilities.parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
+ return str and lpegmatch(splitter,str) or {}
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
local pattern_a=spaces*Ct(value*(separator*value)^0)
local function repeater(n,str)
- if not n then
- return str
+ if not n then
+ return str
+ else
+ local s=lpegmatch(pattern_a,str)
+ if n==1 then
+ return unpack(s)
else
- local s=lpegmatch(pattern_a,str)
- if n==1 then
- return unpack(s)
- else
- local t,tn={},0
- for i=1,n do
- for j=1,#s do
- tn=tn+1
- t[tn]=s[j]
- end
- end
- return unpack(t)
+ local t={}
+ local tn=0
+ for i=1,n do
+ for j=1,#s do
+ tn=tn+1
+ t[tn]=s[j]
end
+ end
+ return unpack(t)
end
+ end
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
local pattern_b=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_with_repeat(str,expand)
- if expand then
- return lpegmatch(pattern_b,str) or {}
- else
- return lpegmatch(pattern_a,str) or {}
- end
+ if expand then
+ return lpegmatch(pattern_b,str) or {}
+ else
+ return lpegmatch(pattern_a,str) or {}
+ end
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
local pattern=Ct((space+value)^0)
function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
- sc={}
- self[class]=sc
- if parentclass then
- local sp=self[parentclass]
- if not sp then
- sp={}
- self[parentclass]=sp
- end
- setmetatableindex(sc,sp)
- end
+ local sc=self[class]
+ if not sc then
+ sc={}
+ self[class]=sc
+ if parentclass then
+ local sp=self[parentclass]
+ if not sp then
+ sp={}
+ self[parentclass]=sp
+ end
+ setmetatableindex(sc,sp)
end
- parsers.settings_to_hash(settings,sc)
+ end
+ parsers.settings_to_hash(settings,sc)
end
function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
+ return gmatch(str,"[^, ]+")
end
local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
}
lpegpatterns.splitthousands=pattern
function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local optionalwhitespace=whitespace^0
lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -8684,75 +9249,75 @@ local key=C((1-equal)^1)
local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
function parsers.keq_to_hash(str)
- if str and str~="" then
- return lpegmatch(pattern,str)
- else
- return {}
- end
+ if str and str~="" then
+ return lpegmatch(pattern,str)
+ else
+ return {}
+ end
end
local defaultspecification={ separator=",",quote='"' }
function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
- local quotedata=nil
- for chr in gmatch(quotechar,".") do
- local quotechar=P(chr)
- local quoteword=quotechar*C((1-quotechar)^0)*quotechar
- if quotedata then
- quotedata=quotedata+quoteword
- else
- quotedata=quoteword
- end
- end
- whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
- return lpegmatch(parser,data)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+ local quotedata=nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar=P(chr)
+ local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+ if quotedata then
+ quotedata=quotedata+quoteword
+ else
+ quotedata=quoteword
+ end
end
+ whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
end
function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=P(specification.quote)
- local dquotechar=quotechar*quotechar
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=P(specification.quote)
+ local dquotechar=quotechar*quotechar
/specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
- if getheader then
- local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(headeryes,data,position)
- return data,header
- else
- return lpegmatch(headernop,data)
- end
- end
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header,position=lpegmatch(headerline,data)
+ local data=lpegmatch(headeryes,data,position)
+ return data,header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
end
local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
- for i=first,n or first do
- action(i)
- end
- elseif last then
- for i=first,last do
- action(i)
- end
- else
- action(first)
+ if not first then
+ elseif last==true then
+ for i=first,n or first do
+ action(i)
end
+ elseif last then
+ for i=first,last do
+ action(i)
+ end
+ else
+ action(first)
+ end
end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
@@ -8760,89 +9325,89 @@ local endofstring=lpegpatterns.endofstring
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
- if type(n)=="function" then
- lpegmatch(stepper,str,1,false,n or print)
- else
- lpegmatch(stepper,str,1,n,action or print)
- end
+ if type(n)=="function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
end
local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
patterns.unittotex=pattern
function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
end
local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache={}
local spaces=lpegpatterns.space^0
local dummy=function() end
setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
end)
local commalistiterator=cache[","]
function utilities.parsers.iterator(str,separator)
- local n=#str
- if n==0 then
- return dummy
- else
- local pattern=separator and cache[separator] or commalistiterator
- local p=1
- return function()
- if p<=n then
- local s,e=lpegmatch(pattern,str,p)
- if e then
- p=e
- return s
- end
- end
+ local n=#str
+ if n==0 then
+ return dummy
+ else
+ local pattern=separator and cache[separator] or commalistiterator
+ local p=1
+ return function()
+ if p<=n then
+ local s,e=lpegmatch(pattern,str,p)
+ if e then
+ p=e
+ return s
end
+ end
end
+ end
end
local function initialize(t,name)
- local source=t[name]
- if source then
- local result={}
- for k,v in next,t[name] do
- result[k]=v
- end
- return result
- else
- return {}
+ local source=t[name]
+ if source then
+ local result={}
+ for k,v in next,t[name] do
+ result[k]=v
end
+ return result
+ else
+ return {}
+ end
end
local function fetch(t,name)
- return t[name] or {}
+ return t[name] or {}
end
local function process(result,more)
- for k,v in next,more do
- result[k]=v
- end
- return result
+ for k,v in next,more do
+ result[k]=v
+ end
+ return result
end
local name=C((1-S(", "))^1)
local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
local merge=Cf(parser,process)
function utilities.parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
+ return lpegmatch(merge,list,1,hash)
end
function utilities.parsers.runtime(time)
- if not time then
- time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
+ if not time then
+ time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
end
local spacing=whitespace^0
local apply=P("->")
@@ -8850,11 +9415,11 @@ local method=C((1-apply)^1)
local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
function utilities.parsers.splitmethod(str,default)
- if str then
- return lpegmatch(pattern,str,1,default or false)
- else
- return default or false,""
- end
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false,""
+ end
end
@@ -8864,14 +9429,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
--- original size: 2274, stripped down to: 1781
+-- original size: 2541, stripped down to: 1624
if not modules then modules={} end modules ['util-fmt']={
- 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"
}
utilities=utilities or {}
utilities.formatters=utilities.formatters or {}
@@ -8882,61 +9447,2887 @@ local strip=string.strip
local lpegmatch=lpeg.match
local stripper=lpeg.patterns.stripzeros
function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
+ return lpegmatch(stripper,str)
end
function formatters.formatcolumns(result,between)
- if result and #result>0 then
- between=between or " "
- local widths,numbers={},{}
- local first=result[1]
- local n=#first
- for i=1,n do
- widths[i]=0
+ if result and #result>0 then
+ between=between or " "
+ local widths,numbers={},{}
+ local first=result[1]
+ local n=#first
+ for i=1,n do
+ widths[i]=0
+ end
+ for i=1,#result do
+ local r=result[i]
+ for j=1,n do
+ local rj=r[j]
+ local tj=type(rj)
+ if tj=="number" then
+ numbers[j]=true
+ rj=tostring(rj)
+ elseif tj~="string" then
+ rj=tostring(rj)
+ r[j]=rj
+ end
+ local w=#rj
+ if w>widths[j] then
+ widths[j]=w
end
- for i=1,#result do
- local r=result[i]
- 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
- local w=#rj
- if w>widths[j] then
- widths[j]=w
- end
+ end
+ end
+ for i=1,n do
+ local w=widths[i]
+ if numbers[i] then
+ if w>80 then
+ widths[i]="%s"..between
+ else
+ widths[i]="%0"..w.."i"..between
+ end
+ else
+ if w>80 then
+ widths[i]="%s"..between
+ elseif w>0 then
+ widths[i]="%-"..w.."s"..between
+ else
+ widths[i]="%s"
+ end
+ end
+ end
+ local template=strip(concat(widths))
+ for i=1,#result do
+ local str=format(template,unpack(result[i]))
+ result[i]=strip(str)
+ end
+ end
+ return result
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true
+
+-- original size: 374, stripped down to: 282
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
+
+-- original size: 4870, stripped down to: 3527
+
+
+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
+ 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
+ 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
+package.loaded["socket"]=socket
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
+
+-- original size: 25844, stripped down to: 14821
+
+
+local socket=socket or require("socket")
+local ssl=ssl or nil
+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
+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
+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
+ 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
- for i=1,n do
- local w=widths[i]
- if numbers[i] then
- if w>80 then
- widths[i]="%s"..between
- else
- widths[i]="%0"..w.."i"..between
- end
- else
- if w>80 then
- widths[i]="%s"..between
- elseif w>0 then
- widths[i]="%-"..w.."s"..between
- else
- widths[i]="%s"
- end
+ }
+ } )
+ return set
+end
+local _sleeping={
+ times={},
+ cos={},
+ lethargy={},
+ insert=function()
+ end,
+ remove=function()
+ end,
+ push=function(self,sleeptime,co)
+ if not co then
+ return
+ end
+ if sleeptime<0 then
+ 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=
+ 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=
+ 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
- local template=strip(concat(widths))
- for i=1,#result do
- local str=format(template,unpack(result[i]))
- result[i]=strip(str)
+ end
+}
+local _servers=newset()
+local _reading=newset()
+local _writing=newset()
+local _reading_log={}
+local _writing_log={}
+local _is_timeout={
+ timeout=true,
+ wantread=true,
+ wantwrite=true,
+}
+local function isTCP(socket)
+ return not find(tostring(socket),"^udp")
+end
+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
+local function copasreceivefrom(client,size)
+ local s,err,port
+ if not size or size==0 then
+ size=UDP_DATAGRAM_MAX
+ end
+ repeat
+ 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
+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
+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)
+ 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
+local function copassendto(client,data,ip,port)
+ repeat
+ local s,err=client:sendto(data,ip,port)
+ 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
+local function copasconnect(skt,host,port)
+ skt:settimeout(0)
+ local ret,err,tried_more_than_once
+ repeat
+ ret,err=skt:connect (host,port)
+ if ret or (err~="timeout" and err~="Operation already in progress") then
+ 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
+local function copasdohandshake(skt,sslt)
+ 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
+local function copasflush(client)
+end
+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
+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,
+ 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,
+ bind=function(self,...)
+ return self.socket:bind(...)
+ end,
+ 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,
+ 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,
+}
+local _skt_mt_udp_index={
+ 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,
+ setpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ setsockname=function(self,...)
+ return self.socket:setsockname(...)
+ end,
+ 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
+local function wrap(skt,sslt)
+ if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
+ return skt
+ 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
+function copas.handler(handler,sslparams)
+ return function (skt,...)
+ skt=wrap(skt)
+ if sslparams then
+ skt:dohandshake(sslparams)
+ end
+ return handler(skt,...)
+ end
+end
+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
+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
+ if skt and copas.autoclose and isTCP(skt) then
+ skt:close()
+ end
+ _errhandlers[co]=nil
+ end
+end
+local function _accept(input,handler)
+ local client=input:accept()
+ if client then
+ client:settimeout(0)
+ local co=createcoroutine(handler)
+ _doTick (co,client)
+ end
+ return client
+end
+local function _tickRead(skt)
+ _doTick(_reading:pop(skt),skt)
+end
+local function _tickWrite(skt)
+ _doTick(_writing:pop(skt),skt)
+end
+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
+function copas.addthread(handler,...)
+ local thread=createcoroutine(function(_,...) return handler(...) end)
+ _doTick(thread,nil,...)
+ return thread
+end
+local _tasks={}
+local function addtaskRead(task)
+ task.def_tick=_tickRead
+ _tasks[task]=true
+end
+local function addtaskWrite(task)
+ task.def_tick=_tickWrite
+ _tasks[task]=true
+end
+local function tasks()
+ return next,_tasks
+end
+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)
+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)
+local _sleeping_t={
+ tick=function(self,time,...)
+ _doTick(_sleeping:pop(time),...)
+ end
+}
+function copas.sleep(sleeptime)
+ yieldcoroutine((sleeptime or 0),_sleeping)
+end
+function copas.wakeup(co)
+ _sleeping:wakeup(co)
+end
+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
+ for skt,time in next,_reading_log do
+ if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#r_evs+1
+ _reading_log[skt]=nil
+ r_evs[n]=skt
+ r_evs[skt]=n
+ end
+ end
+ 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
+local function copasfinished()
+ return not (next(_reading) or next(_writing) or _sleeping:getnext())
+end
+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
+function copas.loop(timeout)
+ copas.running=true
+ while not copasfinished() do
+ copasstep(timeout)
+ end
+ copas.running=false
+end
+package.loaded["copas"]=copas
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
+
+-- original size: 8709, stripped down to: 5411
+
+
+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,
+}
+function filter.cycle(low,ctx,extra)
+ if low then
+ return function(chunk)
+ return (low(ctx,chunk,extra))
+ end
+ end
+end
+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
- return result
+ end
+end
+local function empty()
+ return nil
+end
+function source.empty()
+ return empty
+end
+local function sourceerror(err)
+ return function()
+ return nil,err
+ end
+end
+source.error=sourceerror
+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
+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
+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
+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
+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
+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
+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
+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
+local function null()
+ return 1
+end
+function sink.null()
+ return null
+end
+local function sinkerror(err)
+ return function()
+ return nil,err
+ end
+end
+sink.error=sinkerror
+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
+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
+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
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
+
+-- original size: 2328, stripped down to: 1874
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
+
+-- original size: 6863, stripped down to: 5269
+
+
+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)
+ 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
+ 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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
+
+-- original size: 5721, stripped down to: 3754
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
+
+-- original size: 3116, stripped down to: 2533
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
+
+-- original size: 12577, stripped down to: 9577
+
+
+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
+local http={
+ TIMEOUT=60,
+ USERAGENT=socket._VERSION,
+}
+socket.http=http
+local PORT=80
+local SCHEMES={
+ http=true,
+}
+local function receiveheaders(sock,headers)
+ if not headers then
+ headers={}
+ end
+ local line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while line~="" do
+ local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
+ if not (name and value) then
+ return nil,"malformed reponse headers"
+ end
+ name=lower(name)
+ line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while find(line,"^%s") do
+ value=value..line
+ line=sock:receive()
+ if err then
+ return nil,err
+ end
+ end
+ local found=headers[name]
+ if found then
+ value=found..", "..value
+ end
+ headers[name]=value
+ end
+ return headers
+end
+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
+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
+ 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"]
+ local mode="default"
+ if encoding and encoding~="identity" then
+ mode="http-chunked"
+ elseif length then
+ mode="by-length"
+ end
+ 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
+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
+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
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
+
+-- original size: 10357, stripped down to: 8548
+
+
+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
+ 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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
+
+-- original size: 7018, stripped down to: 5883
+
+
+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
end -- of closure
@@ -8945,14 +12336,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-set"] = package.loaded["trac-set"] or true
--- original size: 13044, stripped down to: 9231
+-- original size: 13340, stripped down to: 8826
if not modules then modules={} end modules ['trac-set']={
- 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=type,next,tostring,tonumber
local concat,sortedhash=table.concat,table.sortedhash
@@ -8967,305 +12358,318 @@ utilities.setters=setters
local data={}
local trace_initialize=false
function setters.initialize(filename,name,values)
- local setter=data[name]
- if setter then
- frozen=true
- local data=setter.data
- if data then
- for key,newvalue in sortedhash(values) do
- local newvalue=is_boolean(newvalue,newvalue,true)
- local functions=data[key]
- if functions then
- local oldvalue=functions.value
- if functions.frozen then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
- end
- elseif #functions>0 and not oldvalue then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
- end
- for i=1,#functions do
- functions[i](newvalue)
- end
- functions.value=newvalue
- functions.frozen=functions.frozen or frozen
- else
- if trace_initialize then
- setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
- end
- end
- else
- functions={ default=newvalue,frozen=frozen }
- data[key]=functions
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
- end
- end
+ local setter=data[name]
+ if setter then
+ frozen=true
+ local data=setter.data
+ if data then
+ for key,newvalue in sortedhash(values) do
+ local newvalue=is_boolean(newvalue,newvalue,true)
+ local functions=data[key]
+ if functions then
+ local oldvalue=functions.value
+ if functions.frozen then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+ end
+ elseif #functions>0 and not oldvalue then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
+ end
+ for i=1,#functions do
+ functions[i](newvalue)
+ end
+ functions.value=newvalue
+ functions.frozen=functions.frozen or frozen
+ else
+ if trace_initialize then
+ setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
end
- return true
+ end
+ else
+ functions={ default=newvalue,frozen=frozen }
+ data[key]=functions
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
+ end
end
+ end
+ return true
end
+ end
end
local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
- local done=t.done
- if type(what)=="string" then
- what=settings_to_hash(what)
- end
- if type(what)~="table" then
- return
- end
- if not done then
- done={}
- t.done=done
- end
- for w,value in sortedhash(what) do
- if value=="" then
- value=newvalue
- elseif not value then
- value=false
- else
- value=is_boolean(value,value,true)
- end
- w=topattern(w,true,true)
- for name,functions in sortedhash(data) do
- if done[name] then
- elseif find(name,w) then
- done[name]=true
- for i=1,#functions do
- functions[i](value)
- end
- functions.value=value
- end
- end
+ local data=t.data
+ if not data.frozen then
+ local done=t.done
+ if type(what)=="string" then
+ what=settings_to_hash(what)
+ end
+ if type(what)~="table" then
+ return
+ end
+ if not done then
+ done={}
+ t.done=done
+ end
+ for w,value in sortedhash(what) do
+ if value=="" then
+ value=newvalue
+ elseif not value then
+ value=false
+ else
+ value=is_boolean(value,value,true)
+ end
+ w=topattern(w,true,true)
+ for name,functions in sortedhash(data) do
+ if done[name] then
+ elseif find(name,w) then
+ done[name]=true
+ for i=1,#functions do
+ functions[i](value)
+ end
+ functions.value=value
end
+ end
end
+ end
end
local function reset(t)
- local data=t.data
- if not data.frozen then
- for name,functions in sortedthash(data) do
- for i=1,#functions do
- functions[i](false)
- end
- functions.value=false
- end
+ local data=t.data
+ if not data.frozen then
+ for name,functions in sortedthash(data) do
+ for i=1,#functions do
+ functions[i](false)
+ end
+ functions.value=false
end
+ end
end
local function enable(t,what)
- set(t,what,true)
+ set(t,what,true)
end
local function disable(t,what)
- local data=t.data
- if not what or what=="" then
- t.done={}
- reset(t)
- else
- set(t,what,false)
- end
+ local data=t.data
+ if not what or what=="" then
+ t.done={}
+ reset(t)
+ else
+ set(t,what,false)
+ end
end
function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
- functions={}
- data[what]=functions
- if trace_initialize then
- t.report("defining %a",what)
- end
- end
- local default=functions.default
- for i=1,select("#",...) do
- local fnc=select(i,...)
- local typ=type(fnc)
- if typ=="string" then
- if trace_initialize then
- t.report("coupling %a to %a",what,fnc)
- end
- local s=fnc
- fnc=function(value) set(t,s,value) end
- elseif typ~="function" then
- fnc=nil
- end
- if fnc then
- functions[#functions+1]=fnc
- local value=functions.value or default
- if value~=nil then
- fnc(value)
- functions.value=value
- end
- end
+ local data=t.data
+ what=lower(what)
+ local functions=data[what]
+ if not functions then
+ functions={}
+ data[what]=functions
+ if trace_initialize then
+ t.report("defining %a",what)
+ end
+ end
+ local default=functions.default
+ for i=1,select("#",...) do
+ local fnc=select(i,...)
+ local typ=type(fnc)
+ if typ=="string" then
+ if trace_initialize then
+ t.report("coupling %a to %a",what,fnc)
+ end
+ local s=fnc
+ fnc=function(value) set(t,s,value) end
+ elseif typ~="function" then
+ fnc=nil
+ end
+ if fnc then
+ functions[#functions+1]=fnc
+ local value=functions.value or default
+ if value~=nil then
+ fnc(value)
+ functions.value=value
+ end
end
- return false
+ end
+ return false
end
function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
+ local e=t.enable
+ t.enable,t.done=enable,{}
+ enable(t,what)
+ t.enable,t.done=e,{}
end
function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
+ local e=t.disable
+ t.disable,t.done=disable,{}
+ disable(t,what)
+ t.disable,t.done=e,{}
end
function setters.reset(t)
- t.done={}
- reset(t)
+ t.done={}
+ reset(t)
end
function setters.list(t)
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
- local what=list[l]
- if find(what,"^%*") then
- system[#system+1]=what
- else
- user[#user+1]=what
- end
+ local list=table.sortedkeys(t.data)
+ local user,system={},{}
+ for l=1,#list do
+ local what=list[l]
+ if find(what,"^%*") then
+ system[#system+1]=what
+ else
+ user[#user+1]=what
end
- return user,system
+ end
+ return user,system
end
function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
- local name=list[k]
- local functions=t.data[name]
- if functions then
- local value=functions.value
- local default=functions.default
- local modules=#functions
- if default==nil then
- default="unset"
- elseif type(default)=="table" then
- default=concat(default,"|")
- else
- default=tostring(default)
- end
- if value==nil then
- value="unset"
- elseif type(value)=="table" then
- value=concat(value,"|")
- else
- value=tostring(value)
- end
- t.report(name)
- t.report(" modules : %i",modules)
- t.report(" default : %s",default)
- t.report(" value : %s",value)
- t.report()
- end
+ local list=setters.list(t)
+ t.report()
+ for k=1,#list do
+ local name=list[k]
+ local functions=t.data[name]
+ if functions then
+ local value=functions.value
+ local default=functions.default
+ local modules=#functions
+ if default==nil then
+ default="unset"
+ elseif type(default)=="table" then
+ default=concat(default,"|")
+ else
+ default=tostring(default)
+ end
+ if value==nil then
+ value="unset"
+ elseif type(value)=="table" then
+ value=concat(value,"|")
+ else
+ value=tostring(value)
+ end
+ t.report(name)
+ t.report(" modules : %i",modules)
+ t.report(" default : %s",default)
+ t.report(" value : %s",value)
+ t.report()
end
+ end
end
local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
function setters.report(setter,...)
- print(format("%-15s : %s\n",setter.name,format(...)))
+ print(format("%-15s : %s\n",setter.name,format(...)))
end
local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
+ local d=setter.data[name]
+ return d and d.default
end
local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
+ local d=setter.data[name]
+ return d and (d.value or d.default)
end
function setters.new(name)
- local setter
- setter={
- data=allocate(),
- name=name,
- report=function(...) setters.report (setter,...) end,
- enable=function(...) enable (setter,...) end,
- disable=function(...) disable (setter,...) end,
- reset=function(...) reset (setter,...) end,
- register=function(...) register(setter,...) end,
- list=function(...) list (setter,...) end,
- show=function(...) show (setter,...) end,
- default=function(...) return default (setter,...) end,
- value=function(...) return value (setter,...) end,
- }
- data[name]=setter
- return setter
+ local setter
+ setter={
+ data=allocate(),
+ name=name,
+ report=function(...) setters.report (setter,...) end,
+ enable=function(...) enable (setter,...) end,
+ disable=function(...) disable (setter,...) end,
+ reset=function(...) reset (setter,...) end,
+ register=function(...) register(setter,...) end,
+ list=function(...) list (setter,...) end,
+ show=function(...) show (setter,...) end,
+ default=function(...) return default (setter,...) end,
+ value=function(...) return value (setter,...) end,
+ }
+ data[name]=setter
+ return setter
end
trackers=setters.new("trackers")
directives=setters.new("directives")
experiments=setters.new("experiments")
-local t_enable,t_disable=trackers .enable,trackers .disable
+local t_enable,t_disable=trackers .enable,trackers .disable
local d_enable,d_disable=directives .enable,directives .disable
local e_enable,e_disable=experiments.enable,experiments.disable
-local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
-local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
+local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
+local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
function directives.enable(...)
- if trace_directives then
- directives.report("enabling: % t",{...})
- end
- d_enable(...)
+ if trace_directives then
+ directives.report("enabling: % t",{...})
+ end
+ d_enable(...)
end
function directives.disable(...)
- if trace_directives then
- directives.report("disabling: % t",{...})
- end
- d_disable(...)
+ if trace_directives then
+ directives.report("disabling: % t",{...})
+ end
+ d_disable(...)
end
function experiments.enable(...)
- if trace_experiments then
- experiments.report("enabling: % t",{...})
- end
- e_enable(...)
+ if trace_experiments then
+ experiments.report("enabling: % t",{...})
+ end
+ e_enable(...)
end
function experiments.disable(...)
- if trace_experiments then
- experiments.report("disabling: % t",{...})
- end
- e_disable(...)
+ if trace_experiments then
+ experiments.report("disabling: % t",{...})
+ end
+ e_disable(...)
end
directives.register("system.nostatistics",function(v)
- if statistics then
- statistics.enable=not v
- else
- end
+ if statistics then
+ statistics.enable=not v
+ else
+ end
end)
directives.register("system.nolibraries",function(v)
- if libraries then
- libraries=nil
- else
- end
+ if libraries then
+ libraries=nil
+ else
+ end
end)
if environment then
- local engineflags=environment.engineflags
- if engineflags then
- local list=engineflags["c:trackers"] or engineflags["trackers"]
- if type(list)=="string" then
- setters.initialize("commandline flags","trackers",settings_to_hash(list))
- end
- local list=engineflags["c:directives"] or engineflags["directives"]
- if type(list)=="string" then
- setters.initialize("commandline flags","directives",settings_to_hash(list))
- end
+ local engineflags=environment.engineflags
+ if engineflags then
+ local list=engineflags["c:trackers"] or engineflags["trackers"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","trackers",settings_to_hash(list))
end
-end
-if texconfig then
- local function set(k,v)
- v=tonumber(v)
- if v then
- texconfig[k]=v
- end
+ local list=engineflags["c:directives"] or engineflags["directives"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","directives",settings_to_hash(list))
end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v) end)
- directives.register("luatex.savesize",function(v) set("save_size",v) end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+ end
end
+if texconfig then
+ local function set(k,v)
+ v=tonumber(v)
+ if v then
+ texconfig[k]=v
+ end
+ end
+ directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
+ directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
+ directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
+ directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
+ directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
+ directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
+ directives.register("luatex.paramsize",function(v) set("param_size",v) end)
+ directives.register("luatex.savesize",function(v) set("save_size",v) end)
+ directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+end
+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,
+}
end -- of closure
@@ -9274,14 +12678,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-log"] = package.loaded["trac-log"] or true
--- original size: 32922, stripped down to: 23011
+-- original size: 32608, stripped down to: 20925
if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.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 trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,select,print=next,type,select,print
local format,gmatch,find=string.format,string.gmatch,string.find
@@ -9292,7 +12696,7 @@ local datetime=os.date
local openfile=io.open
local runningtex=tex and (tex.jobname or tex.formatname)
local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
+local write=runningtex and texio and texio.write or io.write
local setmetatableindex=table.setmetatableindex
local formatters=string.formatters
local settings_to_hash=utilities.parsers.settings_to_hash
@@ -9308,404 +12712,404 @@ webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
wiki : http://contextgarden.net
]]
formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
+ formatters,"unichr",
+ [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
)
formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
+ formatters,"chruni",
+ [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
)
local function ignore() end
setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
local report,subreport,status,settarget,setformats,settranslations
local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
if runningtex then
- if texio.setescape then
- texio.setescape(0)
- end
- if arg then
- for k,v in next,arg do
- if v=="--ansi" or v=="--c:ansi" then
- variant="ansi"
- break
- end
- end
- end
- local function useluawrites()
- local texio_write_nl=texio.write_nl
- local texio_write=texio.write
- local io_write=io.write
- write_nl=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write_nl("log",...)
- texio_write_nl("term","")
- io_write(...)
- elseif target=="log" then
- texio_write_nl("log",...)
- elseif target=="term" then
- texio_write_nl("term","")
- io_write(...)
- elseif type(target)=="number" then
- texio_write_nl(target,...)
- elseif target~="none" then
- texio_write_nl("log",target,...)
- texio_write_nl("term","")
- io_write(target,...)
- end
- end
- write=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write("log",...)
- io_write(...)
- elseif target=="log" then
- texio_write("log",...)
- elseif target=="term" then
- io_write(...)
- elseif type(target)=="number" then
- texio_write(target,...)
- elseif target~="none" then
- texio_write("log",target,...)
- io_write(target,...)
- end
- end
- texio.write=write
- texio.write_nl=write_nl
- useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="log",
- log="log",
- file="log",
- console="term",
- terminal="term",
- both="term and log",
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="none",
- log="none",
- file="none",
- console="term",
- terminal="term",
- both="term",
- },
- }
- }
- logs.flush=io.flush
- writer=function(...)
- write_nl(target,...)
- end
- newline=function()
- write_nl(target,"\n")
- end
- report=function(a,b,c,...)
- if c~=nil then
- write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,report_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,report_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- direct=function(a,b,c,...)
- if c~=nil then
- return direct_yes(translations[a],formatters[formats[b]](c,...))
- elseif b then
- return direct_yes(translations[a],formats[b])
- elseif a then
- return direct_nop(translations[a])
- else
- return ""
- end
- end
- subreport=function(a,s,b,c,...)
- if c~=nil then
- write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
- elseif a then
- write_nl(target,subreport_nop(translations[a],translations[s]))
- else
- write_nl(target,"\n")
- end
- end
- subdirect=function(a,s,b,c,...)
- if c~=nil then
- return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
- elseif b then
- return subdirect_yes(translations[a],translations[s],formats[b])
- elseif a then
- return subdirect_nop(translations[a],translations[s])
- else
- return ""
- end
+ if texio.setescape then
+ texio.setescape(0)
+ end
+ if arg then
+ for k,v in next,arg do
+ if v=="--ansi" or v=="--c:ansi" then
+ variant="ansi"
+ break
+ end
end
- status=function(a,b,c,...)
- if c~=nil then
- write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,status_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,status_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
+ end
+ local function useluawrites()
+ local texio_write_nl=texio.write_nl
+ local texio_write=texio.write
+ local io_write=io.write
+ write_nl=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write_nl("log",...)
+ texio_write_nl("term","")
+ io_write(...)
+ elseif target=="log" then
+ texio_write_nl("log",...)
+ elseif target=="term" then
+ texio_write_nl("term","")
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write_nl(target,...)
+ elseif target~="none" then
+ texio_write_nl("log",target,...)
+ texio_write_nl("term","")
+ io_write(target,...)
+ end
end
- settarget=function(askedwhereto)
- whereto=askedwhereto or whereto or "both"
- target=targets[whereto]
- if not target then
- whereto="both"
- target=targets[whereto]
- end
- if target=="term" or target=="term and log" then
- logs.flush=io.flush
- else
- logs.flush=ignore
- end
+ write=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write("log",...)
+ io_write(...)
+ elseif target=="log" then
+ texio_write("log",...)
+ elseif target=="term" then
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write(target,...)
+ elseif target~="none" then
+ texio_write("log",target,...)
+ io_write(target,...)
+ end
end
- local stack={}
- pushtarget=function(newtarget)
- insert(stack,target)
- settarget(newtarget)
+ texio.write=write
+ texio.write_nl=write_nl
+ useluawrites=ignore
+ end
+ local whereto="both"
+ local target=nil
+ local targets=nil
+ local formats=table.setmetatableindex("self")
+ local translations=table.setmetatableindex("self")
+ local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
+ local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="log",
+ log="log",
+ file="log",
+ console="term",
+ terminal="term",
+ both="term and log",
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="none",
+ log="none",
+ file="none",
+ console="term",
+ terminal="term",
+ both="term",
+ },
+ }
+ }
+ logs.flush=io.flush
+ writer=function(...)
+ write_nl(target,...)
+ end
+ newline=function()
+ write_nl(target,"\n")
+ end
+ report=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,report_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,report_nop(translations[a]))
+ else
+ write_nl(target,"\n")
end
- poptarget=function()
- if #stack>0 then
- settarget(remove(stack))
- end
+ end
+ direct=function(a,b,c,...)
+ if c~=nil then
+ return direct_yes(translations[a],formatters[formats[b]](c,...))
+ elseif b then
+ return direct_yes(translations[a],formats[b])
+ elseif a then
+ return direct_nop(translations[a])
+ else
+ return ""
end
- setformats=function(f)
- formats=f
+ end
+ subreport=function(a,s,b,c,...)
+ if c~=nil then
+ write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
+ elseif a then
+ write_nl(target,subreport_nop(translations[a],translations[s]))
+ else
+ write_nl(target,"\n")
end
- settranslations=function(t)
- translations=t
+ end
+ subdirect=function(a,s,b,c,...)
+ if c~=nil then
+ return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
+ elseif b then
+ return subdirect_yes(translations[a],translations[s],formats[b])
+ elseif a then
+ return subdirect_nop(translations[a],translations[s])
+ else
+ return ""
end
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(target,...)
- writeline(target,f(...))
- end
+ end
+ status=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,status_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,status_nop(translations[a]))
+ else
+ write_nl(target,"\n")
+ end
+ end
+ settarget=function(askedwhereto)
+ whereto=askedwhereto or whereto or "both"
+ target=targets[whereto]
+ if not target then
+ whereto="both"
+ target=targets[whereto]
+ end
+ if target=="term" or target=="term and log" then
+ logs.flush=io.flush
+ else
+ logs.flush=ignore
+ end
+ end
+ local stack={}
+ pushtarget=function(newtarget)
+ insert(stack,target)
+ settarget(newtarget)
+ end
+ poptarget=function()
+ if #stack>0 then
+ settarget(remove(stack))
+ end
+ end
+ setformats=function(f)
+ formats=f
+ end
+ settranslations=function(t)
+ translations=t
+ end
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(target,...)
+ writeline(target,f(...))
+ end
+ end
+ setformatters=function(specification)
+ local t=nil
+ local f=nil
+ local d=variants.default
+ if not specification then
+ elseif type(specification)=="table" then
+ t=specification.targets
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ t=v.targets
+ f=v.formats
+ variant=specification
+ end
end
- setformatters=function(specification)
- local t=nil
- local f=nil
- local d=variants.default
- if not specification then
- elseif type(specification)=="table" then
- t=specification.targets
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- t=v.targets
- f=v.formats
- variant=specification
- end
- end
- targets=t or d.targets
- target=targets[whereto] or target
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- direct_yes=f.direct_yes
- direct_nop=f.direct_nop
- subdirect_yes=f.subdirect_yes
- subdirect_nop=f.subdirect_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- if variant=="ansi" then
- useluawrites()
- end
- settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
+ targets=t or d.targets
+ target=targets[whereto] or target
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ direct_yes=f.direct_yes
+ direct_nop=f.direct_nop
+ subdirect_yes=f.subdirect_yes
+ subdirect_nop=f.subdirect_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ if variant=="ansi" then
+ useluawrites()
+ end
+ settarget(whereto)
+ end
+ setformatters(variant)
+ setlogfile=ignore
+ settimedlog=ignore
else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- }
- logs.flush=ignore
- writer=function(s)
- write_nl(s)
- end
- newline=function()
- write_nl("\n")
+ local report_yes,subreport_yes,status_yes
+ local report_nop,subreport_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ }
+ logs.flush=ignore
+ writer=function(s)
+ write_nl(s)
+ end
+ newline=function()
+ write_nl("\n")
+ end
+ report=function(a,b,c,...)
+ if c then
+ write_nl(report_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(report_yes(a,b))
+ elseif a then
+ write_nl(report_nop(a))
+ else
+ write_nl("")
end
- report=function(a,b,c,...)
- if c then
- write_nl(report_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(report_yes(a,b))
- elseif a then
- write_nl(report_nop(a))
- else
- write_nl("")
- end
+ end
+ subreport=function(a,sub,b,c,...)
+ if c then
+ write_nl(subreport_yes(a,sub,formatters[b](c,...)))
+ elseif b then
+ write_nl(subreport_yes(a,sub,b))
+ elseif a then
+ write_nl(subreport_nop(a,sub))
+ else
+ write_nl("")
end
- subreport=function(a,sub,b,c,...)
- if c then
- write_nl(subreport_yes(a,sub,formatters[b](c,...)))
- elseif b then
- write_nl(subreport_yes(a,sub,b))
- elseif a then
- write_nl(subreport_nop(a,sub))
- else
- write_nl("")
+ end
+ status=function(a,b,c,...)
+ if c then
+ write_nl(status_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(status_yes(a,b))
+ elseif a then
+ write_nl(status_nop(a))
+ else
+ write_nl("\n")
+ end
+ end
+ direct=ignore
+ subdirect=ignore
+ settarget=ignore
+ pushtarget=ignore
+ poptarget=ignore
+ setformats=ignore
+ settranslations=ignore
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(f(s))
+ end
+ end
+ setformatters=function(specification)
+ local f=nil
+ local d=variants.default
+ if specification then
+ if type(specification)=="table" then
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ f=v.formats
end
+ end
end
- status=function(a,b,c,...)
- if c then
- write_nl(status_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(status_yes(a,b))
- elseif a then
- write_nl(status_nop(a))
- else
- write_nl("\n")
- end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
- local writeline=write_nl
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ end
+ setformatters(variant)
+ setlogfile=function(name,keepopen)
+ if name and name~="" then
+ local localtime=os.localtime
+ local writeline=write_nl
+ if keepopen then
+ local f=io.open(name,"ab")
write_nl=function(s)
- writeline(f(s))
- end
- end
- setformatters=function(specification)
- local f=nil
- local d=variants.default
- if specification then
- if type(specification)=="table" then
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- f=v.formats
- end
- end
- end
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
- if name and name~="" then
- local localtime=os.localtime
- local writeline=write_nl
- if keepopen then
- local f=io.open(name,"ab")
- write_nl=function(s)
- writeline(s)
- f:write(localtime()," | ",s,"\n")
- end
- else
- write_nl=function(s)
- writeline(s)
- local f=io.open(name,"ab")
- f:write(localtime()," | ",s,"\n")
- f:close()
- end
- end
+ writeline(s)
+ f:write(localtime()," | ",s,"\n")
end
- setlogfile=ignore
- end
- settimedlog=function()
- local localtime=os.localtime
- local writeline=write_nl
+ else
write_nl=function(s)
- writeline(localtime().." | "..s)
+ writeline(s)
+ local f=io.open(name,"ab")
+ f:write(localtime()," | ",s,"\n")
+ f:close()
end
- settimedlog=ignore
+ end
end
+ setlogfile=ignore
+ end
+ settimedlog=function()
+ local localtime=os.localtime
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(localtime().." | "..s)
+ end
+ settimedlog=ignore
+ end
end
logs.report=report
logs.subreport=subreport
@@ -9727,198 +13131,186 @@ local data={}
local states=nil
local force=false
function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
- local state=states==true
- if not state and type(states)=="table" then
- for c,_ in next,states do
- if find(category,c) then
- state=true
- break
- end
- end
+ local logger=data[category]
+ if not logger then
+ local state=states==true
+ if not state and type(states)=="table" then
+ for c,_ in next,states do
+ if find(category,c) then
+ state=true
+ break
end
- logger={
- reporters={},
- state=state,
- }
- data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
- if subcategory then
- reporter=function(...)
- if force or not logger.state then
- subreport(category,subcategory,...)
- end
- end
- logger.reporters[subcategory]=reporter
- else
- local tag=category
- reporter=function(...)
- if force or not logger.state then
- report(category,...)
- end
- end
- logger.reporters.default=reporter
+ end
+ end
+ logger={
+ reporters={},
+ state=state,
+ }
+ data[category]=logger
+ end
+ local reporter=logger.reporters[subcategory or "default"]
+ if not reporter then
+ if subcategory then
+ reporter=function(...)
+ if force or not logger.state then
+ subreport(category,subcategory,...)
end
+ end
+ logger.reporters[subcategory]=reporter
+ else
+ local tag=category
+ reporter=function(...)
+ if force or not logger.state then
+ report(category,...)
+ end
+ end
+ logger.reporters.default=reporter
end
- return reporter
+ end
+ return reporter
end
logs.new=logs.reporter
local ctxreport=logs.writer
function logs.setmessenger(m)
- ctxreport=m
+ ctxreport=m
end
function logs.messenger(category,subcategory)
- if subcategory then
- return function(...)
- ctxreport(subdirect(category,subcategory,...))
- end
- else
- return function(...)
- ctxreport(direct(category,...))
- end
+ if subcategory then
+ return function(...)
+ ctxreport(subdirect(category,subcategory,...))
end
+ else
+ return function(...)
+ ctxreport(direct(category,...))
+ end
+ end
end
local function setblocked(category,value)
- if category==true or category=="all" then
- category,value="*",true
- elseif category==false then
- category,value="*",false
- elseif value==nil then
- value=true
- end
- if category=="*" then
- states=value
+ if category==true or category=="all" then
+ category,value="*",true
+ elseif category==false then
+ category,value="*",false
+ elseif value==nil then
+ value=true
+ end
+ if category=="*" then
+ states=value
+ for k,v in next,data do
+ v.state=value
+ end
+ else
+ alllocked=false
+ states=settings_to_hash(category,type(states)=="table" and states or nil)
+ for c in next,states do
+ local v=data[c]
+ if v then
+ v.state=value
+ else
+ c=topattern(c,true,true)
for k,v in next,data do
+ if find(k,c) then
v.state=value
+ end
end
- else
- alllocked=false
- states=settings_to_hash(category,type(states)=="table" and states or nil)
- for c in next,states do
- local v=data[c]
- if v then
- v.state=value
- else
- c=topattern(c,true,true)
- for k,v in next,data do
- if find(k,c) then
- v.state=value
- end
- end
- end
- end
+ end
end
+ end
end
function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
+ setblocked(category,value==nil and true or value)
end
function logs.enable(category)
- setblocked(category,false)
+ setblocked(category,false)
end
function logs.categories()
- return sortedkeys(data)
+ return sortedkeys(data)
end
function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
- n=n+1
- local state=v.state
- local reporters=v.reporters
- local nc=#category
- if nc>c then
- c=nc
- end
- for subcategory,_ in next,reporters do
- local ns=#subcategory
- if ns>c then
- s=ns
- end
- local m=nc+ns
- if m>max then
- max=m
- end
- end
- local subcategories=concat(sortedkeys(reporters),", ")
- if state==true then
- state="disabled"
- elseif state==false then
- state="enabled"
- else
- state="unknown"
- end
- report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ local n,c,s,max=0,0,0,0
+ for category,v in table.sortedpairs(data) do
+ n=n+1
+ local state=v.state
+ local reporters=v.reporters
+ local nc=#category
+ if nc>c then
+ c=nc
+ end
+ for subcategory,_ in next,reporters do
+ local ns=#subcategory
+ if ns>c then
+ s=ns
+ end
+ local m=nc+ns
+ if m>max then
+ max=m
+ end
+ end
+ local subcategories=concat(sortedkeys(reporters),", ")
+ if state==true then
+ state="disabled"
+ elseif state==false then
+ state="enabled"
+ else
+ state="unknown"
end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
+ report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ end
+ report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
end
local delayed_reporters={}
setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
+ local v=logs.reporter(k.name)
+ t[k]=v
+ return v
end)
function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
+ delayed_reporters[setter](...)
end
directives.register("logs.blocked",function(v)
- setblocked(v,true)
+ setblocked(v,true)
end)
directives.register("logs.target",function(v)
- settarget(v)
+ settarget(v)
end)
if tex then
- local report=logs.reporter("pages")
- local texgetcount=tex and tex.getcount
- local real,user,sub
- function logs.start_page_number()
- real=texgetcount("realpageno")
- user=texgetcount("userpageno")
- sub=texgetcount("subpageno")
- end
- local timing=false
- local starttime=nil
- local lasttime=nil
- trackers.register("pages.timing",function(v)
- starttime=os.clock()
- timing=true
- end)
- function logs.stop_page_number()
- if timing then
- local elapsed,average
- local stoptime=os.clock()
- 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)
- else
- report("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average)
- end
- 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
- end
- logs.flush()
+ local report=logs.reporter("pages")
+ local texgetcount=tex and tex.getcount
+ local real,user,sub=0,0,0
+ function logs.start_page_number()
+ real=texgetcount("realpageno")
+ user=texgetcount("userpageno")
+ sub=texgetcount("subpageno")
+ end
+ local timing=false
+ local lasttime=nil
+ trackers.register("pages.timing",function(v)
+ timing=""
+ end)
+ function logs.stop_page_number()
+ if timing then
+ local elapsed=statistics.currenttime(statistics)
+ local average,page
+ if not lasttime or real<2 then
+ average=elapsed
+ page=elapsed
+ else
+ 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
+ report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
+ end
+ logs.flush()
+ end
end
local nesting=0
local verbose=false
@@ -9942,222 +13334,222 @@ logs.help=ignore
local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
local p_newline=lpeg.patterns.newline
local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
+ Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
)^1
local function reportlines(t,str)
- if str then
- lpegmatch(linewise,str,1,t)
- end
+ if str then
+ lpegmatch(linewise,str,1,t)
+ end
end
local function reportbanner(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- t.report()
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ t.report()
+ end
end
local function reportversion(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ end
end
local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
- reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
- for i=1,select("#",...) do
- reportlines(t,t.helpinfo[select(i,...)])
- if i<n then
- t.report()
- end
- end
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="string" then
+ reportlines(t,helpinfo)
+ elseif type(helpinfo)=="table" then
+ for i=1,select("#",...) do
+ reportlines(t,t.helpinfo[select(i,...)])
+ if i<n then
+ t.report()
+ end
end
+ end
end
local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
+ t.report()
+ reportlines(t,t.moreinfo)
end
local function reportexport(t,method)
- report(t.helpinfo)
+ report(t.helpinfo)
end
local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
+ lines=reportlines,
+ banner=reportbanner,
+ version=reportversion,
+ help=reporthelp,
+ info=reportinfo,
+ export=reportexport,
}
local exporters={
}
logs.reporters=reporters
logs.exporters=exporters
function logs.application(t)
- t.name=t.name or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
- reporters.banner(t)
- reporters.help(t,...)
- reporters.info(t)
- end
- t.export=function(...)
- reporters.export(t,...)
- end
- t.identify=function()
- reporters.banner(t)
- end
- t.version=function()
- reporters.version(t)
- end
- return t
+ t.name=t.name or "unknown"
+ t.banner=t.banner
+ t.moreinfo=moreinfo
+ t.report=logs.reporter(t.name)
+ t.help=function(...)
+ reporters.banner(t)
+ reporters.help(t,...)
+ reporters.info(t)
+ end
+ t.export=function(...)
+ reporters.export(t,...)
+ end
+ t.identify=function()
+ reporters.banner(t)
+ end
+ t.version=function()
+ reporters.version(t)
+ end
+ return t
end
local f_syslog=formatters["%s %s => %s => %s => %s\r"]
function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
- local f=openfile(whereto,"a")
- if f then
- f:write(message)
- f:close()
- break
- else
- sleep(0.1)
- end
+ local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
+ for i=1,10 do
+ local f=openfile(whereto,"a")
+ if f then
+ f:write(message)
+ f:close()
+ break
+ else
+ sleep(0.1)
end
+ end
end
local report_system=logs.reporter("system","logs")
function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
- return function(...)
- report_system("function %a is obsolete, use %a",old,new)
- loadstring(old.."="..new.." return "..old)()(...)
- end
- elseif type(o)=="table" then
- local t,m={},{}
- m.__index=function(t,k)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- return o[k]
- end
- m.__newindex=function(t,k,v)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- o[k]=v
- end
- if libraries then
- libraries.obsolete[old]=t
- end
- setmetatable(t,m)
- return t
+ local o=loadstring("return "..new)()
+ if type(o)=="function" then
+ return function(...)
+ report_system("function %a is obsolete, use %a",old,new)
+ loadstring(old.."="..new.." return "..old)()(...)
+ end
+ elseif type(o)=="table" then
+ local t,m={},{}
+ m.__index=function(t,k)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ return o[k]
+ end
+ m.__newindex=function(t,k,v)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ o[k]=v
+ end
+ if libraries then
+ libraries.obsolete[old]=t
end
+ setmetatable(t,m)
+ return t
+ end
end
if utilities then
- utilities.report=report_system
+ utilities.report=report_system
end
if tex and tex.error then
- function logs.texerrormessage(...)
- tex.error(format(...),{})
- end
+ function logs.texerrormessage(...)
+ tex.error(format(...))
+ end
else
- function logs.texerrormessage(...)
- print(format(...))
- end
+ function logs.texerrormessage(...)
+ print(format(...))
+ end
end
io.stdout:setvbuf('no')
io.stderr:setvbuf('no')
if package.helpers.report then
- package.helpers.report=logs.reporter("package loader")
+ package.helpers.report=logs.reporter("package loader")
end
if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
- return loggingerrors
- end
- directives.register("logs.errors",function(v)
- loggingerrors=v
- if type(v)=="string" then
- fatalerrors=settings_to_hash(v)
- else
- fatalerrors={}
- end
- end)
- function logs.registerfinalactions(...)
- insert(finalactions,...)
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
- target=t
- state=force
- force=true
- report=type(r)=="function" and r or logs.reporter(r)
- what=w
- pushtarget(target)
+ local finalactions={}
+ local fatalerrors={}
+ local possiblefatal={}
+ local loggingerrors=false
+ function logs.loggingerrors()
+ return loggingerrors
+ end
+ directives.register("logs.errors",function(v)
+ loggingerrors=v
+ if type(v)=="string" then
+ fatalerrors=settings_to_hash(v)
+ else
+ fatalerrors={}
+ end
+ end)
+ function logs.registerfinalactions(...)
+ insert(finalactions,...)
+ end
+ local what=nil
+ local report=nil
+ local state=nil
+ local target=nil
+ local function startlogging(t,r,w,s)
+ target=t
+ state=force
+ force=true
+ report=type(r)=="function" and r or logs.reporter(r)
+ what=w
+ pushtarget(target)
+ newline()
+ if s then
+ report("start %s: %s",what,s)
+ else
+ report("start %s",what)
+ end
+ if target=="logfile" then
+ newline()
+ end
+ return report
+ end
+ local function stoplogging()
+ if target=="logfile" then
+ newline()
+ end
+ report("stop %s",what)
+ if target=="logfile" then
+ newline()
+ end
+ poptarget()
+ state=oldstate
+ end
+ function logs.startfilelogging(...)
+ return startlogging("logfile",...)
+ end
+ logs.stopfilelogging=stoplogging
+ local done=false
+ function logs.starterrorlogging(r,w,...)
+ if not done then
+ pushtarget("terminal")
+ newline()
+ logs.report("error logging","start possible issues")
+ poptarget()
+ done=true
+ end
+ if fatalerrors[w] then
+ possiblefatal[w]=true
+ end
+ return startlogging("terminal",r,w,...)
+ end
+ logs.stoperrorlogging=stoplogging
+ function logs.finalactions()
+ if #finalactions>0 then
+ for i=1,#finalactions do
+ finalactions[i]()
+ end
+ if done then
+ pushtarget("terminal")
newline()
- if s then
- report("start %s: %s",what,s)
- else
- report("start %s",what)
- end
- if target=="logfile" then
- newline()
- end
- return report
- end
- local function stoplogging()
- if target=="logfile" then
- newline()
- end
- report("stop %s",what)
- if target=="logfile" then
- newline()
- end
+ logs.report("error logging","stop possible issues")
poptarget()
- state=oldstate
- end
- function logs.startfilelogging(...)
- return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
- if not done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","start possible issues")
- poptarget()
- done=true
- end
- if fatalerrors[w] then
- possiblefatal[w]=true
- end
- return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
- if #finalactions>0 then
- for i=1,#finalactions do
- finalactions[i]()
- end
- if done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","stop possible issues")
- poptarget()
- end
- return next(possiblefatal) and sortedkeys(possiblefatal) or false
- end
+ end
+ return next(possiblefatal) and sortedkeys(possiblefatal) or false
end
+ end
end
@@ -10167,14 +13559,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
--- original size: 8097, stripped down to: 5534
+-- original size: 9072, stripped down to: 6055
if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.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 trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber,select=type,tonumber,select
local format,lower,find=string.format,string.lower,string.find
@@ -10189,161 +13581,191 @@ statistics.enable=true
statistics.threshold=0.01
local statusinfo,n,registered,timers={},0,{},{}
setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0 }
- t[k]=v
- return v
+ local v={ timing=0,loadtime=0 }
+ t[k]=v
+ return v
end)
local function hastiming(instance)
- return instance and timers[instance]
+ return instance and timers[instance]
end
local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0 }
+ timers[instance or "notimer"]={ timing=0,loadtime=0 }
end
local ticks=clock
local seconds=function(n) return n or 0 end
-local function starttiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it==0 then
- timer.starttime=ticks()
- if not timer.loadtime then
- timer.loadtime=0
- end
- end
- timer.timing=it+1
+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
+ timer.loadtime=0
+ end
+ end
+ timer.timing=it+1
end
local function stoptiming(instance)
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ local stoptime=ticks()
+ local loadtime=stoptime-starttime
+ timer.stoptime=stoptime
+ timer.loadtime=timer.loadtime+loadtime
+ timer.timing=0
+ timer.starttime=0
+ return loadtime
+ end
+ end
+ return 0
+end
+local function elapsed(instance)
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime) or 0
+ 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
- timer.timing=it-1
else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- local stoptime=ticks()
- local loadtime=stoptime-starttime
- timer.stoptime=stoptime
- timer.loadtime=timer.loadtime+loadtime
- timer.timing=0
- timer.starttime=0
- return loadtime
- end
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ return seconds(timer.loadtime+ticks()-starttime)
+ end
end
return 0
-end
-local function elapsed(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- return timer and seconds(timer.loadtime) or 0
- end
+ end
end
local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
+ return format("%0.3f",elapsed(instance))
end
local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
+ return elapsed(instance)>statistics.threshold
end
local function elapsedseconds(instance,rest)
- if elapsedindeed(instance) then
- return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
end
statistics.hastiming=hastiming
statistics.resettiming=resettiming
statistics.starttiming=starttiming
statistics.stoptiming=stoptiming
+statistics.currenttime=currenttime
statistics.elapsed=elapsed
statistics.elapsedtime=elapsedtime
statistics.elapsedindeed=elapsedindeed
statistics.elapsedseconds=elapsedseconds
function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
- local rt=registered[tag] or (#statusinfo+1)
- statusinfo[rt]={ tag,fnc }
- registered[tag]=rt
- if #tag>n then n=#tag end
- end
+ if statistics.enable and type(fnc)=="function" then
+ local rt=registered[tag] or (#statusinfo+1)
+ statusinfo[rt]={ tag,fnc }
+ registered[tag]=rt
+ if #tag>n then n=#tag end
+ end
end
local report=logs.reporter("mkiv lua stats")
function statistics.show()
- if statistics.enable then
- local register=statistics.register
- register("used platform",function()
- return format("%s, type: %s, binary subtree: %s",
- os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
- end)
- register("used engine",function()
- return format("%s version %s with functionality level %s, banner: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
- end)
- register("control sequences",function()
- return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
- end)
- register("callbacks",statistics.callbacks)
- if TEXENGINE=="luajittex" and JITSUPPORTED then
- local jitstatus=jit.status
- if jitstatus then
- local jitstatus={ jitstatus() }
- if jitstatus[1] then
- register("luajit options",concat(jitstatus," ",2))
- end
- end
- end
- register("lua properties",function()
- local hashchar=tonumber(status.luatex_hashchars)
- local hashtype=status.luatex_hashtype
- local mask=lua.mask or "ascii"
- return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
- jit and "luajit" or "lua",
- LUAVERSION,
- statistics.memused(),
- hashtype or "default",
- hashchar and 2^hashchar or "unknown",
- mask,
- mask=="utf" and "τεχ" or "tex")
- end)
- register("runtime",statistics.runtime)
- logs.newline()
- for i=1,#statusinfo do
- local s=statusinfo[i]
- local r=s[2]()
- if r then
- report("%s: %s",s[1],r)
- end
+ if statistics.enable then
+ local register=statistics.register
+ register("used platform",function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+ end)
+ register("used engine",function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+ end)
+ register("control sequences",function()
+ return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+ end)
+ register("callbacks",statistics.callbacks)
+ if TEXENGINE=="luajittex" and JITSUPPORTED then
+ local jitstatus=jit.status
+ if jitstatus then
+ local jitstatus={ jitstatus() }
+ if jitstatus[1] then
+ register("luajit options",concat(jitstatus," ",2))
end
- statistics.enable=false
+ end
end
+ register("lua properties",function()
+ local hashchar=tonumber(status.luatex_hashchars)
+ local hashtype=status.luatex_hashtype
+ local mask=lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashtype or "default",
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask=="utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline()
+ for i=1,#statusinfo do
+ local s=statusinfo[i]
+ local r=s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
+ end
+ statistics.enable=false
+ end
end
function statistics.memused()
- local round=math.round or math.floor
- return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+ local round=math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
end
starttiming(statistics)
function statistics.formatruntime(runtime)
- return format("%s seconds",runtime)
+ return format("%s seconds",runtime)
end
function statistics.runtime()
- stoptiming(statistics)
- return statistics.formatruntime(elapsedtime(statistics))
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report=logs.reporter("system")
-function statistics.timed(action)
- starttiming("run")
- action()
- stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("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
function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
- local name=select(i,...)
- local stat={}
- local func=base[name]
- setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
- base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
- statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
+ for i=1,select("#",...) do
+ local name=select(i,...)
+ local stat={}
+ local func=base[name]
+ setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+ base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
end
@@ -10353,144 +13775,144 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5841, stripped down to: 3511
+-- original size: 5841, stripped down to: 3352
if not modules then modules={} end modules ['trac-pro']={
- 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 getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
+local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
local namespaces=namespaces
local registered={}
local function report_index(k,name)
- if trace_namespaces then
- report_system("reference to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("reference to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("reference to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("reference to %a in protected namespace %a",k,name)
+ end
end
local function report_newindex(k,name)
- if trace_namespaces then
- report_system("assignment to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("assignment to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("assignment to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("assignment to %a in protected namespace %a",k,name)
+ end
end
local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
- return
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
- m={}
- setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
- if not index[k] then
- index[k]=true
- report_index(k,name)
- end
- return nil
+ local data=name=="global" and _G or _G[name]
+ if not data then
+ return
+ end
+ registered[name]=data
+ local m=getmetatable(data)
+ if not m then
+ m={}
+ setmetatable(data,m)
+ end
+ local index,newindex={},{}
+ m.__saved__index=m.__index
+ m.__no__index=function(t,k)
+ if not index[k] then
+ index[k]=true
+ report_index(k,name)
end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
- if not newindex[k] then
- newindex[k]=true
- report_newindex(k,name)
- end
- rawset(t,k,v)
+ return nil
+ end
+ m.__saved__newindex=m.__newindex
+ m.__no__newindex=function(t,k,v)
+ if not newindex[k] then
+ newindex[k]=true
+ report_newindex(k,name)
end
- m.__protection__depth=0
+ rawset(t,k,v)
+ end
+ m.__protection__depth=0
end
local function private(name)
- local data=registered[name]
+ local data=registered[name]
+ if not data then
+ data=_G[name]
if not data then
- data=_G[name]
- if not data then
- data={}
- _G[name]=data
- end
- register(name)
+ data={}
+ _G[name]=data
end
- return data
+ register(name)
+ end
+ return data
end
local function protect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
- m.__protection__depth=pd+1
- else
- m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
- m.__index,m.__newindex=m.__no__index,m.__no__newindex
- m.__protection__depth=1
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>0 then
+ m.__protection__depth=pd+1
+ else
+ m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
+ m.__index,m.__newindex=m.__no__index,m.__no__newindex
+ m.__protection__depth=1
+ end
end
local function unprotect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
- m.__protection__depth=pd-1
- else
- m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
- m.__protection__depth=0
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>1 then
+ m.__protection__depth=pd-1
+ else
+ m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
+ m.__protection__depth=0
+ end
end
local function protectall()
- for name,_ in next,registered do
- if name~="global" then
- protect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ protect(name)
end
+ end
end
local function unprotectall()
- for name,_ in next,registered do
- if name~="global" then
- unprotect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ unprotect(name)
end
+ end
end
-namespaces.register=register
-namespaces.private=private
+namespaces.register=register
+namespaces.private=private
namespaces.protect=protect
namespaces.unprotect=unprotect
namespaces.protectall=protectall
namespaces.unprotectall=unprotectall
namespaces.private("namespaces") registered={} register("global")
directives.register("system.protect",function(v)
- if v then
- protectall()
- else
- unprotectall()
- end
+ if v then
+ protectall()
+ else
+ unprotectall()
+ end
end)
directives.register("system.checkglobals",function(v)
- if v then
- report_system("enabling global namespace guard")
- protect("global")
- else
- report_system("disabling global namespace guard")
- unprotect("global")
- end
+ if v then
+ report_system("enabling global namespace guard")
+ protect("global")
+ else
+ report_system("disabling global namespace guard")
+ unprotect("global")
+ end
end)
@@ -10500,15 +13922,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lua"] = package.loaded["util-lua"] or true
--- original size: 6621, stripped down to: 4764
+-- original size: 6664, stripped down to: 4589
if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -10519,150 +13941,151 @@ local report_lua=logs.reporter("system","lua")
local report_mem=logs.reporter("system","lua memory")
local tracestripping=false
local tracememory=false
-luautilities.stripcode=true
+luautilities.stripcode=true
luautilities.alwaysstripcode=false
luautilities.nofstrippedchunks=0
luautilities.nofstrippedbytes=0
local strippedchunks={}
luautilities.strippedchunks=strippedchunks
luautilities.suffixes={
- tma="tma",
- tmc=jit and "tmb" or "tmc",
- lua="lua",
- luc=jit and "lub" or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc="tuc",
+ tma="tma",
+ tmc=jit and "tmb" or "tmc",
+ lua="lua",
+ luc=jit and "lub" or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
}
local function register(name)
- if tracestripping then
- report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
end
local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
- code=load(code)
- if code then
- code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
- if code and code~="" then
- register(name)
- io.savedata(lucfile,code)
- return true,0
- end
- else
- report_lua("fatal error %a in file %a",1,luafile)
- end
- else
- report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
-end
-function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
- macros=lua.macros
- end
- local code,message
- if macros then
- code,message=macros.loaded(fullname,true,false)
- else
- code,message=loadfile(fullname)
- end
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+ code=load(code)
if code then
- code()
- else
- report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip)=="function" then
- forcestrip=forcestrip(fullname)
- end
- if forcestrip or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
- elseif luautilities.alwaysstripcode then
+ code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code~="" then
register(name)
- return load(dump(code,true)),0
+ io.savedata(lucfile,code)
+ return true,0
+ end
else
- return code,0
+ report_lua("fatal error %a in file %a",1,luafile)
end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
+end
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ name=name or fullname
+ if macros then
+ macros=lua.macros
+ end
+ local code,message
+ if macros then
+ code,message=macros.loaded(fullname,true,false)
+ else
+ code,message=loadfile(fullname)
+ end
+ if code then
+ 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
+ forcestrip=forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.strippedloadstring(code,name,forcestrip)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.loadstring(code,name)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
end
function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
- report_lua("dumping %a into %a stripped",luafile,lucfile)
- if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
- report_lua("removing %a",luafile)
- os.remove(luafile)
- end
- end
- return done
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
end
function luautilities.loadstripped(...)
- local l=load(...)
- if l then
- return load(dump(l,true))
- end
+ local l=load(...)
+ if l then
+ return load(dump(l,true))
+ end
end
local finalizers={}
setmetatable(finalizers,{
- __gc=function(t)
- for i=1,#t do
- pcall(t[i])
- end
+ __gc=function(t)
+ for i=1,#t do
+ pcall(t[i])
end
+ end
} )
function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
+ finalizers[#finalizers+1]=f
end
function luautilities.checkmemory(previous,threshold,trace)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- local delta=current-previous
- if current-previous>checked then
- 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",
- 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",
- previous/1024,current/1024,delta/1024,threshold)
- end
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ local delta=current-previous
+ if current-previous>checked then
+ collectgarbage("collect")
+ local afterwards=collectgarbage("count")
+ if trace or tracememory then
+ 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 %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
end
- return current
+ end
+ return current
end
@@ -10672,17 +14095,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 8984, stripped down to: 6573
+-- original size: 9955, stripped down to: 6693
if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- 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 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
@@ -10700,228 +14121,266 @@ local names={}
local initialize=false
if not (FFISUPPORTED and ffi) then
elseif os.type=="windows" then
- initialize=function()
- local kernel=ffilib("kernel32","system")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
+ initialize=function()
+ local kernel=ffilib("kernel32","system")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
int QueryPerformanceFrequency(int64_t *lpFrequency);
int QueryPerformanceCounter(int64_t *lpPerformanceCount);
]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
end
- initialize=false
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
end
+ initialize=false
+ end
elseif os.type=="unix" then
- initialize=function()
- local C=ffi.C
- local tonumber=ffi.number or tonumber
- ffi.cdef [[
+ initialize=function()
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ ffi.cdef [[
/* what a mess */
typedef int clk_id_t;
typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
typedef struct timespec { long sec; long nsec; } ctx_timespec;
int clock_gettime(clk_id_t timerid, struct timespec *t);
]]
- local target=ffi.new("ctx_timespec[?]",1)
- local clock=C.CLOCK_PROCESS_CPUTIME_ID
- ticks=function ()
- C.clock_gettime(clock,target)
- return tonumber(target[0].sec*1000000000+target[0].nsec)
- end
- seconds=function(ticks)
- return ticks/1000000000
- end
- initialize=false
+ local target=ffi.new("ctx_timespec[?]",1)
+ local clock=C.CLOCK_PROCESS_CPUTIME_ID
+ ticks=function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
+ end
+ seconds=function(ticks)
+ return ticks/1000000000
end
+ initialize=false
+ end
end
setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
- local v=setmetatableindex(function(t,line)
- local v={ total=0,count=0 }
- t[line]=v
- return v
- end)
- t[source]=v
- return v
+ local v=setmetatableindex(function(t,source)
+ local v=setmetatableindex(function(t,line)
+ local v={ total=0,count=0,nesting=0 }
+ t[line]=v
+ return v
end)
- t[name]=v
+ t[source]=v
return v
+ end)
+ t[name]=v
+ return v
end)
+local getinfo=nil
+local sethook=nil
local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
- local source=f.short_src
- if not source then
- return
- end
- local line=f.linedefined or 0
- local name=f.name
- if not name then
- local what=f.what
- if what=="C" then
- name="<anonymous>"
- else
- name=f.namewhat or what or "<unknown>"
- end
- end
- local data=names[name][source][line]
- if where=="call" then
- data.count=data.count+1
- insert(data,ticks())
- elseif where=="return" then
- local t=remove(data)
- if t then
- data.total=data.total+ticks()-t
- end
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
+ end
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ 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 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
end
function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
- for source,lines in next,sources do
- for line,data in next,lines do
- local count=data.count
- if count>threshold then
- if #name>length then
- length=#name
- end
- local total=data.total
- local real=total
- if real>0 then
- real=total-(count*overhead/dummycalls)
- if real<0 then
- real=0
- end
- realtime=realtime+real
- end
- totaltime=totaltime+total
- if line<0 then
- line=0
- end
- dataset[#dataset+1]={ real,total,count,name,source,line }
- end
- end
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ local count=data.count
+ if count>threshold then
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ realtime=realtime+real
+ end
+ totaltime=totaltime+total
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
end
+ end
end
- sort(dataset,function(a,b)
- if a[1]==b[1] then
- if a[2]==b[2] then
- if a[3]==b[3] then
- if a[4]==b[4] then
- if a[5]==b[5] then
- return a[6]<b[6]
- else
- return a[5]<b[5]
- end
- else
- return a[4]<b[4]
- end
- else
- return b[3]<a[3]
- end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
else
- return b[2]<a[2]
+ return a[5]<b[5]
end
+ else
+ return a[4]<b[4]
+ end
else
- return b[1]<a[1]
+ return b[3]<a[3]
end
- end)
- if length>50 then
- length=50
- end
- local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
- for i=1,#dataset do
- local data=dataset[i]
- local real=data[1]
- local total=data[2]
- local count=data[3]
- local name=data[4]
- local source=data[5]
- local line=data[6]
- calls=calls+count
- functions=functions+1
- name=gsub(name,"%s+"," ")
- if #name>length then
- name=sub(name,1,length)
- end
- printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls : %i",calls))
- printer(format("overhead : %f",seconds(overhead/1000)))
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
+ end
+ local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
+ for i=1,#dataset do
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ calls=calls+count
+ functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
+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
- debugger.showstats(function(str) f:write(str,"\n") end,threshold)
- f:close()
- end
+ local f=io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
end
function debugger.enable()
- if nesting==0 then
- running=true
- if initialize then
- initialize()
- end
- sethook(hook,"cr")
- local function dummy() end
- local t=ticks()
- for i=1,dummycalls do
- dummy()
- end
- overhead=ticks()-t
- end
- if nesting>0 then
- nesting=nesting+1
- end
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- if nesting>0 then
- nesting=nesting-1
- end
- if nesting==0 then
- sethook()
- end
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
+ getdebug()
+ if getinfo then
local level=2
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
+ 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
+ end
end
debugger.showtraceback=showtraceback
@@ -10932,91 +14391,91 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7112, stripped down to: 3988
+-- original size: 7112, stripped down to: 3887
if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ 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.templates=utilities.templates or {}
local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
- if trace_template then
- report_template("unknown key %a",k)
- end
- return ""
+ local v=t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v=tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
else
- v=tostring(v)
- if trace_template then
- report_template("setting key %a to value %a",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t,how,recursive)
- else
- return v
- end
+ return v
end
+ end
end
local sqlescape=lpeg.replacer {
- { "'","''" },
- { "\\","\\\\" },
- { "\r\n","\\n" },
- { "\r","\\n" },
+ { "'","''" },
+ { "\\","\\\\" },
+ { "\r\n","\\n" },
+ { "\r","\\n" },
}
local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
lpegpatterns.sqlescape=sqlescape
lpegpatterns.sqlquoted=sqlquoted
local luaescape=lpegpatterns.luaescape
local escapers={
- lua=function(s)
- return lpegmatch(luaescape,s)
- end,
- sql=function(s)
- return lpegmatch(sqlescape,s)
- end,
+ lua=function(s)
+ return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlescape,s)
+ end,
}
local quotedescapers={
- lua=function(s)
- return format("%q",s)
- end,
- sql=function(s)
- return lpegmatch(sqlquoted,s)
- end,
+ lua=function(s)
+ return format("%q",s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
}
local luaescaper=escapers.lua
local quotedluaescaper=quotedescapers.lua
local function replacekeyunquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and escapers[how] or luaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replacekeyquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and quotedescapers[how] or quotedluaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
end
-local single=P("%")
+local single=P("%")
local double=P("%%")
local lquoted=P("%[")
local rquoted=P("]%")
@@ -11033,41 +14492,41 @@ local noloptional=P("%?")/''
local noroptional=P("?%")/''
local nomoptional=P(":")/''
local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
local any=P(1)
replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
local function replace(str,mapping,how,recurse)
- if mapping and str then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
end
templates.replace=replace
function templates.replacer(str,how,recurse)
- return function(mapping)
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
end
function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
end
function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping=t
- end
- for k,v in next,t do
- t[k]=replace(v,mapping,how,recurse)
- end
- return t
+ if not mapping then
+ mapping=t
+ end
+ for k,v in next,t do
+ t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
end
@@ -11077,14 +14536,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
--- original size: 20393, stripped down to: 13924
+-- original size: 20393, stripped down to: 13121
if not modules then modules={} end modules ['util-sbx']={
- 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 sandbox then require("l-sandbox") end
local next,type=next,type
@@ -11117,144 +14576,144 @@ local report=logs.reporter("sandbox")
trackers.register("sandbox",function(v) trace=v end)
sandbox.setreporter(report)
sandbox.finalizer {
- category="files",
- action=function()
- finalized=true
- end
+ category="files",
+ action=function()
+ finalized=true
+ end
}
local function registerroot(root,what)
- if finalized then
- report("roots are already finalized")
- else
- if type(root)=="table" then
- root,what=root[1],root[2]
- end
- if type(root)=="string" and root~="" then
- root=collapsepath(expandname(root))
- if what=="r" or what=="ro" or what=="readable" then
- what="read"
- elseif what=="w" or what=="wo" or what=="writable" then
- what="write"
- end
- validroots[root]=what=="write" or false
- end
+ if finalized then
+ report("roots are already finalized")
+ else
+ if type(root)=="table" then
+ root,what=root[1],root[2]
+ end
+ if type(root)=="string" and root~="" then
+ root=collapsepath(expandname(root))
+ if what=="r" or what=="ro" or what=="readable" then
+ what="read"
+ elseif what=="w" or what=="wo" or what=="writable" then
+ what="write"
+ end
+ validroots[root]=what=="write" or false
end
+ end
end
sandbox.finalizer {
- category="files",
- action=function()
+ category="files",
+ action=function()
+ if p_validroot then
+ report("roots are already initialized")
+ else
+ sandbox.registerroot(".","write")
+ for name in sortedhash(validroots) do
if p_validroot then
- report("roots are already initialized")
+ p_validroot=P(name)+p_validroot
else
- sandbox.registerroot(".","write")
- for name in sortedhash(validroots) do
- if p_validroot then
- p_validroot=P(name)+p_validroot
- else
- p_validroot=P(name)
- end
- end
- p_validroot=p_validroot/validroots
+ p_validroot=P(name)
end
+ end
+ p_validroot=p_validroot/validroots
end
+ end
}
local function registerbinary(name)
- if finalized then
- report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validbinaries then
- return
- end
- if validbinaries==true then
- validbinaries={ [name]=true }
- else
- validbinaries[name]=true
- end
- elseif name==true then
- validbinaries={}
+ if finalized then
+ report("binaries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validbinaries then
+ return
+ end
+ if validbinaries==true then
+ validbinaries={ [name]=true }
+ else
+ validbinaries[name]=true
end
+ elseif name==true then
+ validbinaries={}
+ end
end
local function registerlibrary(name)
- if finalized then
- report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validlibraries then
- return
- end
- if validlibraries==true then
- validlibraries={ [nameonly(name)]=true }
- else
- validlibraries[nameonly(name)]=true
- end
- elseif name==true then
- validlibraries={}
+ if finalized then
+ report("libraries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validlibraries then
+ return
+ end
+ if validlibraries==true then
+ validlibraries={ [nameonly(name)]=true }
+ else
+ validlibraries[nameonly(name)]=true
end
+ elseif name==true then
+ validlibraries={}
+ end
end
local p_write=S("wa") p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
+local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
local function normalized(name)
- if platform=="windows" then
- name=gsub(name,"/","\\")
- end
- return name
+ if platform=="windows" then
+ name=gsub(name,"/","\\")
+ end
+ return name
end
function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
+ return lpegmatch(p_path,name) and true or false
end
local filenamelogger=false
function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
+ filenamelogger=type(l)=="function" and l or false
end
local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
- local asked=collapsepath(expandname(name))
- local okay=lpegmatch(p_validroot,asked)
- if okay==true then
- if filenamelogger then
- filenamelogger(name,"w",asked,true)
- end
- return name
- elseif okay==false then
- if not what then
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- elseif lpegmatch(p_write,what) then
- if filenamelogger then
- filenamelogger(name,"w",asked,false)
- end
- return
- else
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- end
- elseif filenamelogger then
- filenamelogger(name,"*",name,false)
+ if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
+ local asked=collapsepath(expandname(name))
+ local okay=lpegmatch(p_validroot,asked)
+ if okay==true then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,true)
+ end
+ return name
+ elseif okay==false then
+ if not what then
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
end
- else
return name
+ elseif lpegmatch(p_write,what) then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,false)
+ end
+ return
+ else
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
+ end
+ return name
+ end
+ elseif filenamelogger then
+ filenamelogger(name,"*",name,false)
end
+ else
+ return name
+ end
end
local function readable(name,finalized)
- return validfilename(name,"r")
+ return validfilename(name,"r")
end
local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"r")
+ if valid then
+ return normalized(valid)
+ end
end
local function writeable(name,finalized)
- return validfilename(name,"w")
+ return validfilename(name,"w")
end
local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"w")
+ if valid then
+ return normalized(valid)
+ end
end
validators.readable=readable
validators.writeable=normalizedwriteable
@@ -11262,316 +14721,316 @@ validators.normalizedreadable=normalizedreadable
validators.normalizedwriteable=writeable
validators.filename=readable
table.setmetatableindex(validators,function(t,k)
- if k then
- t[k]=readable
- end
- return readable
+ if k then
+ t[k]=readable
+ end
+ return readable
end)
function validators.string(s,finalized)
- if finalized and suspicious(s) then
- return ""
- else
- return s
- end
+ if finalized and suspicious(s) then
+ return ""
+ else
+ return s
+ end
end
function validators.cache(s)
- if finalized then
- return basename(s)
- else
- return s
- end
+ if finalized then
+ return basename(s)
+ else
+ return s
+ end
end
function validators.url(s)
- if finalized and find("^file:") then
- return ""
- else
- return s
- end
+ if finalized and find("^file:") then
+ return ""
+ else
+ return s
+ end
end
local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
+ else
+ end
end
local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
- local checkedtwo=validfilename(two)
- if checkedtwo then
- return action(one,two,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ local checkedtwo=validfilename(two)
+ if checkedtwo then
+ return action(one,two,...)
else
end
+ else
+ end
end
local function iohandler(action,one,...)
- if type(one)=="string" then
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- end
- elseif one then
- return action(one,...)
- else
- return action()
+ if type(one)=="string" then
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
end
+ elseif one then
+ return action(one,...)
+ else
+ return action()
+ end
end
local osexecute=sandbox.original(os.execute)
local iopopen=sandbox.original(io.popen)
local reported={}
local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
- if variables then
- for variable,value in next,variables do
- local checker=validators[checkers[variable]]
- if checker then
- value=checker(unquoted(value),strict)
- if value then
- variables[variable]=optionalquoted(value)
- else
- report("variable %a with value %a fails the check",variable,value)
- return
- end
- else
- report("variable %a has no checker",variable)
- return
- end
- end
- for variable,default in next,defaults do
- local value=variables[variable]
- if not value or value=="" then
- local checker=validators[checkers[variable]]
- if checker then
- default=checker(unquoted(default),strict)
- if default then
- variables[variable]=optionalquoted(default)
- else
- report("variable %a with default %a fails the check",variable,default)
- return
- end
- end
- end
- end
- end
- local command=program.." "..replace(template,variables)
- if reporter then
- reporter("executing runner %a: %s",name,command)
- elseif trace then
- report("executing runner %a: %s",name,command)
- end
- return command
- elseif not reported[name] then
- report("executing program %a of runner %a is not permitted",program,name)
- reported[name]=true
- end
-end
-local runners={
- resultof=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("resultof: %s",command)
- end
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- end
- end
- end,
- execute=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("execute: %s",command)
- end
- return osexecute(command)
+ if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
+ if variables then
+ for variable,value in next,variables do
+ local checker=validators[checkers[variable]]
+ if checker then
+ value=checker(unquoted(value),strict)
+ if value then
+ variables[variable]=optionalquoted(value)
+ else
+ report("variable %a with value %a fails the check",variable,value)
+ return
+ end
+ else
+ report("variable %a has no checker",variable)
+ return
end
- end,
- pipeto=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("pipeto: %s",command)
+ end
+ for variable,default in next,defaults do
+ local value=variables[variable]
+ if not value or value=="" then
+ local checker=validators[checkers[variable]]
+ if checker then
+ default=checker(unquoted(default),strict)
+ if default then
+ variables[variable]=optionalquoted(default)
+ else
+ report("variable %a with default %a fails the check",variable,default)
+ return
end
- return iopopen(command,"w")
- end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
- local wrapped=validrunners[specification]
- inspect(table.sortedkeys(validrunners))
- if wrapped then
- return wrapped
- else
- report("unknown predefined runner %a",specification)
- return
+ end
end
+ end
end
- if type(specification)~="table" then
- report("specification should be a table (or string)")
- return
- end
- local name=specification.name
- if type(name)~="string" then
- report("invalid name, string expected",name)
- return
- end
- if validrunners[name] then
- report("invalid name, runner %a already defined")
- return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
- program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
- report("invalid runner %a specified for platform %a",name,platform)
- return
+ local command=program.." "..replace(template,variables)
+ if reporter then
+ reporter("executing runner %a: %s",name,command)
+ elseif trace then
+ report("executing runner %a: %s",name,command)
end
- local template=specification.template
- if not template then
- report("missing template for runner %a",name)
- return
+ return command
+ elseif not reported[name] then
+ report("executing program %a of runner %a is not permitted",program,name)
+ reported[name]=true
+ end
+end
+local runners={
+ resultof=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("resultof: %s",command)
+ end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ end
end
- local method=specification.method or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
- local finalized=finalized
- local wrapped=function(variables)
- return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
- end
- validrunners[name]=wrapped
- return wrapped
- else
- validrunners[name]=nil
- report("invalid method for runner %a",name)
+ end,
+ execute=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("execute: %s",command)
+ end
+ return osexecute(command)
+ end
+ end,
+ pipeto=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("pipeto: %s",command)
+ end
+ return iopopen(command,"w")
end
+ end,
+}
+function sandbox.registerrunner(specification)
+ if type(specification)=="string" then
+ local wrapped=validrunners[specification]
+ inspect(table.sortedkeys(validrunners))
+ if wrapped then
+ return wrapped
+ else
+ report("unknown predefined runner %a",specification)
+ return
+ end
+ end
+ if type(specification)~="table" then
+ report("specification should be a table (or string)")
+ return
+ end
+ local name=specification.name
+ if type(name)~="string" then
+ report("invalid name, string expected",name)
+ return
+ end
+ if validrunners[name] then
+ report("invalid name, runner %a already defined")
+ return
+ end
+ local program=specification.program
+ if type(program)=="string" then
+ elseif type(program)=="table" then
+ program=program[platform] or program.default or program.unix
+ end
+ if type(program)~="string" or program=="" then
+ report("invalid runner %a specified for platform %a",name,platform)
+ return
+ end
+ local template=specification.template
+ if not template then
+ report("missing template for runner %a",name)
+ return
+ end
+ local method=specification.method or "execute"
+ local checkers=specification.checkers or {}
+ local defaults=specification.defaults or {}
+ local runner=runners[method]
+ if runner then
+ local finalized=finalized
+ local wrapped=function(variables)
+ return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
+ end
+ validrunners[name]=wrapped
+ return wrapped
+ else
+ validrunners[name]=nil
+ report("invalid method for runner %a",name)
+ end
end
function sandbox.getrunner(name)
- return name and validrunners[name]
+ return name and validrunners[name]
end
local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
+ return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
end
local function binaryrunner(action,command,...)
- if validbinaries==false then
- report("no binaries permitted, ignoring command: %s",command)
- return
- end
- if type(command)~="string" then
- report("command should be a string")
- return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
- report("unable to filter binary from command: %s",command)
- return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
- report("binary not permitted, ignoring command: %s",command)
- return
- elseif suspicious(command) then
- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
- return
- end
- return action(command,...)
+ if validbinaries==false then
+ report("no binaries permitted, ignoring command: %s",command)
+ return
+ end
+ if type(command)~="string" then
+ report("command should be a string")
+ return
+ end
+ local program=lpegmatch(p_split,command)
+ if not program or program=="" then
+ report("unable to filter binary from command: %s",command)
+ return
+ end
+ if validbinaries==true then
+ elseif not validbinaries[program] then
+ report("binary not permitted, ignoring command: %s",command)
+ return
+ elseif suspicious(command) then
+ report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
+ return
+ end
+ return action(command,...)
end
local function dummyrunner(action,command,...)
- if type(command)=="table" then
- command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
+ if type(command)=="table" then
+ command=concat(command," ",command[0] and 0 or 1)
+ end
+ report("ignoring command: %s",command)
end
sandbox.filehandlerone=filehandlerone
sandbox.filehandlertwo=filehandlertwo
sandbox.iohandler=iohandler
function sandbox.disablerunners()
- validbinaries=false
+ validbinaries=false
end
function sandbox.disablelibraries()
- validlibraries=false
+ validlibraries=false
end
if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
- validlibraries=false
- for k,v in next,ffi do
- if k~="gc" then
- ffi[k]=nil
- end
- end
+ function sandbox.disablelibraries()
+ validlibraries=false
+ for k,v in next,ffi do
+ if k~="gc" then
+ ffi[k]=nil
+ end
end
- local fiiload=ffi.load
- if fiiload then
- local reported={}
- function ffi.load(name,...)
- if validlibraries==false then
- elseif validlibraries==true then
- return fiiload(name,...)
- elseif validlibraries[nameonly(name)] then
- return fiiload(name,...)
- else
- end
- if not reported[name] then
- report("using library %a is not permitted",name)
- reported[name]=true
- end
- return nil
- end
+ end
+ local fiiload=ffi.load
+ if fiiload then
+ local reported={}
+ function ffi.load(name,...)
+ if validlibraries==false then
+ elseif validlibraries==true then
+ return fiiload(name,...)
+ elseif validlibraries[nameonly(name)] then
+ return fiiload(name,...)
+ else
+ end
+ if not reported[name] then
+ report("using library %a is not permitted",name)
+ reported[name]=true
+ end
+ return nil
end
+ end
end
local overload=sandbox.overload
local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile")
+ overload(loadfile,filehandlerone,"loadfile")
if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
+ overload(io.open,filehandlerone,"io.open")
+ overload(io.popen,binaryrunner,"io.popen")
+ overload(io.input,iohandler,"io.input")
+ overload(io.output,iohandler,"io.output")
+ overload(io.lines,filehandlerone,"io.lines")
end
if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
+ overload(os.execute,binaryrunner,"os.execute")
+ overload(os.spawn,dummyrunner,"os.spawn")
+ overload(os.exec,dummyrunner,"os.exec")
+ overload(os.resultof,binaryrunner,"os.resultof")
+ overload(os.pipeto,binaryrunner,"os.pipeto")
+ overload(os.rename,filehandlertwo,"os.rename")
+ overload(os.remove,filehandlerone,"os.remove")
end
if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
+ overload(lfs.chdir,filehandlerone,"lfs.chdir")
+ overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
+ overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
+ overload(lfs.isfile,filehandlerone,"lfs.isfile")
+ overload(lfs.isdir,filehandlerone,"lfs.isdir")
+ overload(lfs.attributes,filehandlerone,"lfs.attributes")
+ overload(lfs.dir,filehandlerone,"lfs.dir")
+ overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
+ overload(lfs.touch,filehandlerone,"lfs.touch")
+ overload(lfs.link,filehandlertwo,"lfs.link")
+ overload(lfs.setmode,filehandlerone,"lfs.setmode")
+ overload(lfs.readlink,filehandlerone,"lfs.readlink")
+ overload(lfs.shortname,filehandlerone,"lfs.shortname")
+ overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
end
if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
+ zip.open=register(zip.open,filehandlerone,"zip.open")
end
if fontloader then
- fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
- fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
+ fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
+ fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
end
if epdf then
- epdf.open=register(epdf.open,filehandlerone,"epdf.open")
+ epdf.open=register(epdf.open,filehandlerone,"epdf.open")
end
sandbox.registerroot=registerroot
sandbox.registerbinary=registerbinary
@@ -11585,14 +15044,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
--- original size: 7757, stripped down to: 6015
+-- original size: 7819, stripped down to: 5881
if not modules then modules={} end modules ['util-mrg']={
- 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 gsub,format=string.gsub,string.format
local concat=table.concat
@@ -11620,19 +15079,19 @@ local m_report=[[
]]
local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
local function self_fake()
- return m_faked
+ return m_faked
end
local function self_nothing()
- return ""
+ return ""
end
local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
- report("unknown file %a",name)
- else
- report("inserting file %a",name)
- end
- return data or ""
+ local data=io.loaddata(name) or ""
+ if data=="" then
+ report("unknown file %a",name)
+ else
+ report("inserting file %a",name)
+ end
+ return data or ""
end
local space=patterns.space
local eol=patterns.newline
@@ -11661,98 +15120,99 @@ local mandatespacing=(eol+space)^1/""
local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
local lines=emptyline^2/"\n"
local spaces=(space*space)/" "
+local spaces=(space*space*space*space)/" "
local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
+ ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
)^1 )
local strip=Cs((emptyline^2/"\n"+1)^0)
local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
+ return lpegmatch(strip,lpegmatch(compact,data))
end
local function self_compact(data)
- local delta=0
- if merger.strip_comment then
- local before=#data
- data=lpegmatch(compact,data)
- data=lpegmatch(strip,data)
- local after=#data
- delta=before-after
- report("original size %s, compacted to %s, stripped %s",before,after,delta)
- data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
+ local delta=0
+ if merger.strip_comment then
+ local before=#data
+ data=lpegmatch(compact,data)
+ data=lpegmatch(strip,data)
+ local after=#data
+ delta=before-after
+ report("original size %s, compacted to %s, stripped %s",before,after,delta)
+ data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
+ end
+ return lpegmatch(stripreturn,data) or data,delta
end
local function self_save(name,data)
- if data~="" then
- io.savedata(name,data)
- report("saving %s with size %s",name,#data)
- end
+ if data~="" then
+ io.savedata(name,data)
+ report("saving %s with size %s",name,#data)
+ end
end
local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
+ return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
end
local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
+ local result,f,frozen,foundpath={},nil,false,nil
+ result[#result+1]="\n"
+ if type(libs)=='string' then libs={ libs } end
+ if type(list)=='string' then list={ list } end
+ for i=1,#libs do
+ local lib=libs[i]
+ for j=1,#list do
+ local pth=gsub(list[j],"\\","/")
+ report("checking library path %a",pth)
+ local name=pth.."/"..lib
+ if lfs.isfile(name) then
+ foundpath=pth
+ end
+ end
+ if foundpath then break end
+ end
+ if foundpath then
+ report("using library path %a",foundpath)
+ local right,wrong,original,stripped={},{},0,0
for i=1,#libs do
- local lib=libs[i]
- for j=1,#list do
- local pth=gsub(list[j],"\\","/")
- report("checking library path %a",pth)
- local name=pth.."/"..lib
- if lfs.isfile(name) then
- foundpath=pth
- end
- end
- if foundpath then break end
- end
- if foundpath then
- report("using library path %a",foundpath)
- local right,wrong,original,stripped={},{},0,0
- for i=1,#libs do
- local lib=libs[i]
- local fullname=foundpath.."/"..lib
- if lfs.isfile(fullname) then
- report("using library %a",fullname)
- local preloaded=file.nameonly(lib)
- local data=io.loaddata(fullname,true)
- original=original+#data
- local data,delta=self_compact(data)
- right[#right+1]=lib
- result[#result+1]=m_begin_closure
- result[#result+1]=format(m_preloaded,preloaded,preloaded)
- result[#result+1]=data
- result[#result+1]=m_end_closure
- stripped=stripped+delta
- else
- report("skipping library %a",fullname)
- wrong[#wrong+1]=lib
- end
- end
- right=#right>0 and concat(right," ") or "-"
- wrong=#wrong>0 and concat(wrong," ") or "-"
- report("used libraries: %a",right)
- report("skipped libraries: %a",wrong)
- report("original bytes: %a",original)
- report("stripped bytes: %a",stripped)
- result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
- report("no valid library path found")
+ local lib=libs[i]
+ local fullname=foundpath.."/"..lib
+ if lfs.isfile(fullname) then
+ report("using library %a",fullname)
+ local preloaded=file.nameonly(lib)
+ local data=io.loaddata(fullname,true)
+ original=original+#data
+ local data,delta=self_compact(data)
+ right[#right+1]=lib
+ result[#result+1]=m_begin_closure
+ result[#result+1]=format(m_preloaded,preloaded,preloaded)
+ result[#result+1]=data
+ result[#result+1]=m_end_closure
+ stripped=stripped+delta
+ else
+ report("skipping library %a",fullname)
+ wrong[#wrong+1]=lib
+ end
end
- return concat(result,"\n\n")
+ right=#right>0 and concat(right," ") or "-"
+ wrong=#wrong>0 and concat(wrong," ") or "-"
+ report("used libraries: %a",right)
+ report("skipped libraries: %a",wrong)
+ report("original bytes: %a",original)
+ report("stripped bytes: %a",stripped)
+ result[#result+1]=format(m_report,right,wrong,original,stripped)
+ else
+ report("no valid library path found")
+ end
+ return concat(result,"\n\n")
end
function merger.selfcreate(libs,list,target)
- if target then
- self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
+ if target then
+ self_save(target,self_swap(self_fake(),self_libs(libs,list)))
+ end
end
function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
+ self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
end
function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
+ self_save(name,self_swap(self_load(name),self_nothing()))
end
@@ -11762,14 +15222,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9400, stripped down to: 5499
+-- original size: 9738, stripped down to: 5531
if not modules then modules={} end modules ['util-env']={
- 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 allocate,mark=utilities.storage.allocate,utilities.storage.mark
local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
@@ -11781,178 +15241,193 @@ local setlocale=os.setlocale
setlocale(nil,nil)
local report=logs.reporter("system")
function os.setlocale(a,b)
- if a or b then
- if report then
- report()
- report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
- report("now on are on your own and without support. Crashes or unexpected side effects")
- report("can happen but don't bother the luatex and context developer team with it.")
- report()
- report=nil
- end
- setlocale(a,b)
- end
+ if a or b then
+ if report then
+ report()
+ report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+ report("now on are on your own and without support. Crashes or unexpected side effects")
+ report("can happen but don't bother the luatex and context developer team with it.")
+ report()
+ report=nil
+ end
+ setlocale(a,b)
+ end
end
local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
+ ["luatex"]=true,
+ ["luajittex"]=true,
}
local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
+ ["luatex"]="luatex",
+ ["texlua"]="luatex",
+ ["texluac"]="luatex",
+ ["luajittex"]="luajittex",
+ ["texluajit"]="luajittex",
}
local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
+ ["lua"]=true,
+ ["luajit"]=true,
}
environment.validengines=validengines
environment.basicengines=basicengines
if not arg then
- environment.used_as_library=true
+ environment.used_as_library=true
elseif luaengines[file.removesuffix(arg[-1])] then
elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
- arg[-1]=arg[0]
- arg[ 0]=arg[2]
- for k=3,#arg do
- arg[k-2]=arg[k]
- end
- remove(arg)
- remove(arg)
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
+ if arg[1]=="--luaonly" then
+ arg[-1]=arg[0]
+ arg[ 0]=arg[2]
+ for k=3,#arg do
+ arg[k-2]=arg[k]
+ end
+ remove(arg)
+ remove(arg)
+ else
+ end
+ local originalzero=file.basename(arg[0])
+ local specialmapping={ luatools=="base" }
+ if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
arg[0]=specialmapping[originalzero] or originalzero
insert(arg,0,"--script")
insert(arg,0,"mtxrun")
- end
+ end
end
environment.arguments=allocate()
environment.files=allocate()
environment.sortedflags=nil
function environment.initializearguments(arg)
- local arguments,files={},{}
- environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
- for index=1,#arg do
- local argument=arg[index]
- if index>0 then
- local flag,value=match(argument,"^%-+(.-)=(.-)$")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=unquoted(value or "")
- else
- flag=match(argument,"^%-+(.+)")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=true
- else
- files[#files+1]=argument
- end
- end
+ 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
+ local flag,value=match(argument,"^%-+(.-)=(.-)$")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=unquoted(value or "")
+ else
+ flag=match(argument,"^%-+(.+)")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=true
+ else
+ files[#files+1]=argument
end
+ 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
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
+ end
+ environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
end
function environment.setargument(name,value)
- environment.arguments[name]=value
+ environment.arguments[name]=value
end
function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
- return arguments[name]
- elseif partial then
- if not sortedflags then
- sortedflags=allocate(table.sortedkeys(arguments))
- for k=1,#sortedflags do
- sortedflags[k]="^"..sortedflags[k]
- end
- environment.sortedflags=sortedflags
- end
- for k=1,#sortedflags do
- local v=sortedflags[k]
- if find(name,v) then
- return arguments[sub(v,2,#v)]
- end
- end
+ local arguments,sortedflags=environment.arguments,environment.sortedflags
+ if arguments[name] then
+ return arguments[name]
+ elseif partial then
+ if not sortedflags then
+ sortedflags=allocate(table.sortedkeys(arguments))
+ for k=1,#sortedflags do
+ sortedflags[k]="^"..sortedflags[k]
+ end
+ environment.sortedflags=sortedflags
end
- return nil
+ for k=1,#sortedflags do
+ local v=sortedflags[k]
+ if find(name,v) then
+ return arguments[sub(v,2,#v)]
+ end
+ end
+ end
+ return nil
end
environment.argument=environment.getargument
function environment.splitarguments(separator)
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
- local v=originalarguments[k]
- if not done and v==separator then
- done=true
- elseif done then
- after[#after+1]=v
- else
- before[#before+1]=v
- end
+ local done,before,after=false,{},{}
+ local originalarguments=environment.originalarguments
+ for k=1,#originalarguments do
+ local v=originalarguments[k]
+ if not done and v==separator then
+ done=true
+ elseif done then
+ after[#after+1]=v
+ else
+ before[#before+1]=v
end
- return before,after
+ end
+ return before,after
end
function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
- return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
- local result={}
- for i=1,#arg do
- result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
- end
- return concat(result," ")
- else
- return ""
+ local resolveprefix=resolvers.resolve
+ arg=arg or environment.originalarguments
+ if noquote and #arg==1 then
+ return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
+ elseif #arg>0 then
+ local result={}
+ for i=1,#arg do
+ result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
end
+ return concat(result," ")
+ else
+ return ""
+ end
end
function environment.relativepath(path,root)
- if not path then
- path=""
+ if not path then
+ path=""
+ end
+ if not file.is_rootbased_path(path) then
+ if not root then
+ root=file.pathpart(environment.ownscript or environment.ownname or ".")
end
- if not file.is_rootbased_path(path) then
- if not root then
- root=file.pathpart(environment.ownscript or environment.ownname or ".")
- end
- if root=="" then
- root="."
- end
- path=root.."/"..path
+ if root=="" then
+ root="."
end
- return file.collapsepath(path,true)
+ path=root.."/"..path
+ end
+ return file.collapsepath(path,true)
end
if arg then
- local newarg,instring={},false
- for index=1,#arg do
- local argument=arg[index]
- if find(argument,"^\"") then
- newarg[#newarg+1]=gsub(argument,"^\"","")
- if not find(argument,"\"$") then
- instring=true
- end
- elseif find(argument,"\"$") then
- newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
- instring=false
- elseif instring then
- newarg[#newarg]=newarg[#newarg].." "..argument
- else
- newarg[#newarg+1]=argument
- end
- end
- for i=1,-5,-1 do
- newarg[i]=arg[i]
+ local newarg,instring={},false
+ for index=1,#arg do
+ local argument=arg[index]
+ if 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
+ 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
+ newarg[#newarg+1]=argument
end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={}
+ end
+ for i=1,-5,-1 do
+ newarg[i]=arg[i]
+ end
+ environment.initializearguments(newarg)
+ environment.originalarguments=mark(newarg)
+ environment.rawarguments=mark(arg)
+ arg={}
end
@@ -11962,17 +15437,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-env"] = package.loaded["luat-env"] or true
--- original size: 5820, stripped down to: 4155
+-- original size: 6134, stripped down to: 4118
if not modules then modules={} end modules ['luat-env']={
- 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 rawset,rawget,loadfile,assert=rawset,rawget,loadfile,assert
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+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)
local report_lua=logs.reporter("resolvers","lua")
local luautilities=utilities.lua
local luasuffixes=luautilities.suffixes
@@ -11980,133 +15456,146 @@ local texgettoks=tex and tex.gettoks
environment=environment or {}
local environment=environment
local mt={
- __index=function(_,k)
- if k=="version" then
- local version=texgettoks and texgettoks("contextversiontoks")
- if version and version~="" then
- rawset(environment,"version",version)
- return version
- else
- return "unknown"
- end
- elseif k=="kind" then
- local kind=texgettoks and texgettoks("contextkindtoks")
- if kind and kind~="" then
- rawset(environment,"kind",kind)
- return kind
- else
- return "unknown"
- end
- elseif k=="jobname" or k=="formatname" then
- local name=tex and tex[k]
- if name or name=="" then
- rawset(environment,k,name)
- return name
- else
- return "unknown"
- end
- elseif k=="outputfilename" then
- local name=environment.jobname
- rawset(environment,k,name)
- return name
- end
+ __index=function(_,k)
+ if k=="version" then
+ local version=texgettoks and texgettoks("contextversiontoks")
+ if version and version~="" then
+ rawset(environment,"version",version)
+ return version
+ else
+ return "unknown"
+ end
+ elseif k=="kind" then
+ local kind=texgettoks and texgettoks("contextkindtoks")
+ if kind and kind~="" then
+ rawset(environment,"kind",kind)
+ return kind
+ else
+ return "unknown"
+ end
+ elseif k=="jobname" or k=="formatname" then
+ local name=tex and tex[k]
+ if name or name=="" then
+ rawset(environment,k,name)
+ return name
+ else
+ return "unknown"
+ end
+ elseif k=="outputfilename" then
+ local name=environment.jobname
+ rawset(environment,k,name)
+ return name
end
+ end
}
setmetatable(environment,mt)
function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
+ return resolvers.findfile(filename,'tex')
end
function environment.luafile(filename)
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
- return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
- return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
-end
-local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
+ local resolved=resolvers.findfile(filename,'tex') or ""
+ if resolved~="" then
+ return resolved
+ end
+ resolved=resolvers.findfile(filename,'texmfscripts') or ""
+ if resolved~="" then
+ return resolved
+ end
+ return resolvers.findfile(filename,'luatexlibs') or ""
+end
+local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
local function strippable(filename)
- if stripindeed then
- local modu=modules[file.nameonly(filename)]
- return modu and modu.dataonly
- else
- return false
- end
+ if stripindeed then
+ local modu=modules[file.nameonly(filename)]
+ return modu and modu.dataonly
+ else
+ return false
+ end
end
function environment.luafilechunk(filename,silent,macros)
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
- local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
- if not silent then
- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- end
- return data
- else
- if not silent then
- report_lua("unknown file %a",filename)
- end
- return nil
+ filename=file.replacesuffix(filename,"lua")
+ local fullname=environment.luafile(filename)
+ if fullname and fullname~="" then
+ local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
+ if not silent then
+ report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+ end
+ return data
+ else
+ if not silent then
+ report_lua("unknown file %a",filename)
end
+ return nil
+ end
end
function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
- luaname=file.addsuffix(basename,luasuffixes.lua)
- lucname=file.addsuffix(basename,luasuffixes.luc)
- else
- luaname=basename
- lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
+ local lucname,luaname,chunk
+ local basename=file.removesuffix(filename)
+ if basename==filename then
+ luaname=file.addsuffix(basename,luasuffixes.lua)
+ lucname=file.addsuffix(basename,luasuffixes.luc)
+ else
+ luaname=filename
+ lucname=nil
+ end
+ local fullname=(lucname and environment.luafile(lucname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
+ end
+ chunk=loadfile(fullname)
+ end
+ if chunk then
+ chunk()
+ if version then
+ local v=version
+ if modules and modules[filename] then
+ v=modules[filename].version
+ elseif versions and versions[filename] then
+ v=versions[filename]
+ end
+ if v==version then
+ return true
+ else
if trace_locating then
- report_lua("loading %a",fullname)
+ report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
end
- chunk=loadfile(fullname)
+ environment.loadluafile(filename)
+ end
+ else
+ return true
end
- if chunk then
- assert(chunk)()
- if version then
- local v=version
- if modules and modules[filename] then
- v=modules[filename].version
- elseif versions and versions[filename] then
- v=versions[filename]
- end
- if v==version then
- return true
- else
- if trace_locating then
- report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
- end
- environment.loadluafile(filename)
- end
- else
- return true
- end
+ end
+ fullname=(luaname and environment.luafile(luaname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- if not chunk then
- if trace_locating then
- report_lua("unknown file %a",filename)
- end
- else
- assert(chunk)()
- return true
- end
+ chunk=loadfile(fullname)
+ if not chunk then
+ if trace_locating then
+ report_lua("unknown file %a",filename)
+ end
+ else
+ chunk()
+ return true
end
- return false
+ 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)
+ end,
+ __len=function(t)
+ return #environment.files
+ end,
+} )
end -- of closure
@@ -12115,16 +15604,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
--- original size: 60383, stripped down to: 38562
+-- original size: 60383, stripped down to: 35698
if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
+local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
xml=xml or {}
@@ -12142,17 +15631,17 @@ xml.xmlns=xml.xmlns or {}
local check=P(false)
local parse=check
function xml.registerns(namespace,pattern)
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
+ check=check+C(P(lower(pattern)))/namespace
+ parse=P { P(check)+1*V(1) }
end
function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
- xml.xmlns[namespace]=ns
- end
+ local ns=lpegmatch(parse,lower(url))
+ if ns and namespace~=ns then
+ xml.xmlns[namespace]=ns
+ end
end
function xml.resolvens(url)
- return lpegmatch(parse,lower(url)) or ""
+ return lpegmatch(parse,lower(url)) or ""
end
end
local nsremap,resolvens=xml.xmlns,xml.resolvens
@@ -12170,661 +15659,661 @@ local handle_dec_entity
local handle_any_entity_dtd
local handle_any_entity_text
local function preparexmlstate(settings)
- if settings then
- linenumbers=settings.linenumbers
- stack={}
- level=0
- top={}
- at={}
- mt={}
- dt={}
- nt=0
- xmlns={}
- errorstr=nil
- strip=settings.strip_cm_and_dt
- utfize=settings.utfize_entities
- resolve=settings.resolve_entities
- resolve_predefined=settings.resolve_predefined_entities
- unify_predefined=settings.unify_predefined_entities
- cleanup=settings.text_cleanup
- entities=settings.entities or {}
- currentfilename=settings.currentresource
- currentline=1
- parameters={}
- reported_at_errors={}
- dcache={}
- hcache={}
- acache={}
- if utfize==nil then
- settings.utfize_entities=true
- utfize=true
- end
- if resolve_predefined==nil then
- settings.resolve_predefined_entities=true
- resolve_predefined=true
- end
- else
- linenumbers=false
- stack=nil
- level=nil
- top=nil
- at=nil
- mt=nil
- dt=nil
- nt=nil
- xmlns=nil
- errorstr=nil
- strip=nil
- utfize=nil
- resolve=nil
- resolve_predefined=nil
- unify_predefined=nil
- cleanup=nil
- entities=nil
- parameters=nil
- reported_at_errors=nil
- dcache=nil
- hcache=nil
- acache=nil
- currentfilename=nil
- currentline=1
- end
+ if settings then
+ linenumbers=settings.linenumbers
+ stack={}
+ level=0
+ top={}
+ at={}
+ mt={}
+ dt={}
+ nt=0
+ xmlns={}
+ errorstr=nil
+ strip=settings.strip_cm_and_dt
+ utfize=settings.utfize_entities
+ resolve=settings.resolve_entities
+ resolve_predefined=settings.resolve_predefined_entities
+ unify_predefined=settings.unify_predefined_entities
+ cleanup=settings.text_cleanup
+ entities=settings.entities or {}
+ currentfilename=settings.currentresource
+ currentline=1
+ parameters={}
+ reported_at_errors={}
+ dcache={}
+ hcache={}
+ acache={}
+ if utfize==nil then
+ settings.utfize_entities=true
+ utfize=true
+ end
+ if resolve_predefined==nil then
+ settings.resolve_predefined_entities=true
+ resolve_predefined=true
+ end
+ else
+ linenumbers=false
+ stack=nil
+ level=nil
+ top=nil
+ at=nil
+ mt=nil
+ dt=nil
+ nt=nil
+ xmlns=nil
+ errorstr=nil
+ strip=nil
+ utfize=nil
+ resolve=nil
+ resolve_predefined=nil
+ unify_predefined=nil
+ cleanup=nil
+ entities=nil
+ parameters=nil
+ reported_at_errors=nil
+ dcache=nil
+ hcache=nil
+ acache=nil
+ currentfilename=nil
+ currentline=1
+ end
end
local function initialize_mt(root)
- mt={ __index=root }
+ mt={ __index=root }
end
function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
+ getmetatable(root).__index[k]=v
end
function xml.checkerror(top,toclose)
- return ""
+ return ""
end
local checkns=xml.checkns
local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
- value=cleanup(value)
- end
- if tag=="xmlns" then
- xmlns[#xmlns+1]=resolvens(value)
- at[tag]=value
- elseif namespace=="" then
- at[tag]=value
- elseif namespace=="xmlns" then
- checkns(tag,value)
- at["xmlns:"..tag]=value
- else
- at[namespace..":"..tag]=value
- end
+ if cleanup and value~="" then
+ value=cleanup(value)
+ end
+ if tag=="xmlns" then
+ xmlns[#xmlns+1]=resolvens(value)
+ at[tag]=value
+ elseif namespace=="" then
+ at[tag]=value
+ elseif namespace=="xmlns" then
+ checkns(tag,value)
+ at["xmlns:"..tag]=value
+ else
+ at[namespace..":"..tag]=value
+ end
end
local function add_empty(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- cf=currentfilename,
- cl=currentline,
- __p__=top,
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
- remove(xmlns)
- end
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ top=stack[level]
+ dt=top.dt
+ nt=#dt+1
+ local t=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=top,
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ __p__=top,
+ }
+ dt[nt]=t
+ setmetatable(t,mt)
+ if at.xmlns then
+ remove(xmlns)
+ end
+ at={}
end
local function add_begin(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- cf=currentfilename,
- cl=currentline,
- __p__=stack[level],
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ dt={}
+ top=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=stack[level],
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ __p__=stack[level],
+ }
+ setmetatable(top,mt)
+ nt=0
+ level=level+1
+ stack[level]=top
+ at={}
end
local function add_end(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
- errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- elseif toclose.tg~=tag then
- errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt
- if toclose.at.xmlns then
- remove(xmlns)
- end
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local toclose=stack[level]
+ level=level-1
+ top=stack[level]
+ if level<1 then
+ errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ elseif toclose.tg~=tag then
+ errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ end
+ dt=top.dt
+ nt=#dt+1
+ dt[nt]=toclose
+ toclose.ni=nt
+ if toclose.at.xmlns then
+ remove(xmlns)
+ end
end
local function add_text(text)
- if text=="" then
- return
- end
- if cleanup then
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..cleanup(text)
- else
- nt=nt+1
- dt[nt]=cleanup(text)
- end
- else
- nt=1
- dt[1]=cleanup(text)
- end
+ if text=="" then
+ return
+ end
+ if cleanup then
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..cleanup(text)
+ else
+ nt=nt+1
+ dt[nt]=cleanup(text)
+ end
else
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..text
- else
- nt=nt+1
- dt[nt]=text
- end
- else
- nt=1
- dt[1]=text
- end
+ nt=1
+ dt[1]=cleanup(text)
end
-end
-local function add_special(what,spacing,text)
- if spacing~="" then
+ else
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..text
+ else
nt=nt+1
- dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
+ dt[nt]=text
+ end
else
- nt=nt+1
- dt[nt]=linenumbers and {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- cf=currentfilename,
- cl=currentline,
- } or {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- }
+ nt=1
+ dt[1]=text
end
+ end
+end
+local function add_special(what,spacing,text)
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ if strip and (what=="@cm@" or what=="@dt@") then
+ else
+ nt=nt+1
+ dt[nt]=linenumbers and {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ cf=currentfilename,
+ cl=currentline,
+ } or {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ }
+ end
end
local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
+ errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
end
local function attribute_value_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute value %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute value %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
local function attribute_specification_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute specification %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute specification %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
do
- local badentity="&"
- xml.placeholders={
- unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
- unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
- unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return formatters["h:%s"](s),true
+ local badentity="&"
+ xml.placeholders={
+ unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
+ unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
+ unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
+ }
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local p_rest=(1-P(";"))^0
+ local p_many=P(1)^0
+ local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
+ xml.parsedentitylpeg=parsedentity
+ local predefined_unified={
+ [38]="&amp;",
+ [42]="&quot;",
+ [47]="&apos;",
+ [74]="&lt;",
+ [76]="&gt;",
+ }
+ local predefined_simplified={
+ [38]="&",amp="&",
+ [42]='"',quot='"',
+ [47]="'",apos="'",
+ [74]="<",lt="<",
+ [76]=">",gt=">",
+ }
+ local nofprivates=0xF0000
+ local privates_u={
+ [ [[&]] ]="&amp;",
+ [ [["]] ]="&quot;",
+ [ [[']] ]="&apos;",
+ [ [[<]] ]="&lt;",
+ [ [[>]] ]="&gt;",
+ }
+ local privates_p={
+ }
+ local privates_s={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[&]] ]="&U+26;",
+ [ [[']] ]="&U+27;",
+ [ [[<]] ]="&U+3C;",
+ [ [[>]] ]="&U+3E;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_x={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[']] ]="&U+27;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_n={
+ }
+ local escaped=utf.remapper(privates_u,"dynamic")
+ local unprivatized=utf.remapper(privates_p,"dynamic")
+ local unspecialized=utf.remapper(privates_s,"dynamic")
+ local despecialized=utf.remapper(privates_x,"dynamic")
+ xml.unprivatized=unprivatized
+ xml.unspecialized=unspecialized
+ xml.despecialized=despecialized
+ xml.escaped=escaped
+ local function unescaped(s)
+ local p=privates_n[s]
+ if not p then
+ nofprivates=nofprivates+1
+ p=utfchar(nofprivates)
+ privates_n[s]=p
+ s="&"..s..";"
+ privates_u[p]=s
+ privates_p[p]=s
+ privates_s[p]=s
+ end
+ return p
+ end
+ xml.privatetoken=unescaped
+ xml.privatecodes=privates_n
+ xml.specialcodes=privates_s
+ function xml.addspecialcode(key,value)
+ privates_s[key]=value or "&"..s..";"
+ end
+ handle_hex_entity=function(str)
+ local h=hcache[str]
+ if not h then
+ local n=tonumber(str,16)
+ h=unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ elseif utfize then
+ h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring hex entity &#x%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#x%s;",str)
end
+ h="&#x"..str..";"
+ end
+ hcache[str]=h
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return utfchar(n)
- else
- return formatters["d:%s"](s),true
- end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
- [38]="&amp;",
- [42]="&quot;",
- [47]="&apos;",
- [74]="&lt;",
- [76]="&gt;",
- }
- local predefined_simplified={
- [38]="&",amp="&",
- [42]='"',quot='"',
- [47]="'",apos="'",
- [74]="<",lt="<",
- [76]=">",gt=">",
- }
- local nofprivates=0xF0000
- local privates_u={
- [ [[&]] ]="&amp;",
- [ [["]] ]="&quot;",
- [ [[']] ]="&apos;",
- [ [[<]] ]="&lt;",
- [ [[>]] ]="&gt;",
- }
- local privates_p={
- }
- local privates_s={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[&]] ]="&U+26;",
- [ [[']] ]="&U+27;",
- [ [[<]] ]="&U+3C;",
- [ [[>]] ]="&U+3E;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_x={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[']] ]="&U+27;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_n={
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
- local p=privates_n[s]
- if not p then
- nofprivates=nofprivates+1
- p=utfchar(nofprivates)
- privates_n[s]=p
- s="&"..s..";"
- privates_u[p]=s
- privates_p[p]=s
- privates_s[p]=s
- end
- return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
- privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
- local h=hcache[str]
- if not h then
- local n=tonumber(str,16)
- h=unify_predefined and predefined_unified[n]
- if h then
- if trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- elseif utfize then
- h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring hex entity &#x%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- else
- if trace_entities then
- report_xml("found entity &#x%s;",str)
- end
- h="&#x"..str..";"
- end
- hcache[str]=h
- end
- return h
- end
- handle_dec_entity=function(str)
- local d=dcache[str]
- if not d then
- local n=tonumber(str)
- d=unify_predefined and predefined_unified[n]
- if d then
- if trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- elseif utfize then
- d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring dec entity &#%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- else
- if trace_entities then
- report_xml("found entity &#%s;",str)
- end
- d="&#"..str..";"
- end
- dcache[str]=d
+ return h
+ end
+ handle_dec_entity=function(str)
+ local d=dcache[str]
+ if not d then
+ local n=tonumber(str)
+ d=unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ elseif utfize then
+ d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring dec entity &#%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#%s;",str)
end
- return d
+ d="&#"..str..";"
+ end
+ dcache[str]=d
end
- handle_any_entity_dtd=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
+ return d
+ end
+ handle_any_entity_dtd=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
+ a=entities[str]
end
- end
- handle_any_entity_text=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(grammar_parsed_text_two,a) or a
- if type(a)=="number" then
- return ""
- else
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- end
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
end
- return a
+ a=a(str) or ""
+ end
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
end
- return a
- end
- end
- local p_rest=(1-P(";"))^1
- local spec={
- [0x23]="\\Ux{23}",
- [0x24]="\\Ux{24}",
- [0x25]="\\Ux{25}",
- [0x5C]="\\Ux{5C}",
- [0x7B]="\\Ux{7B}",
- [0x7C]="\\Ux{7C}",
- [0x7D]="\\Ux{7D}",
- [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
+ end
+ return a
+ end
+ end
+ handle_any_entity_text=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- return formatters["d:%s"](s),true
+ a=entities[str]
end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- local hash=table.setmetatableindex(function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
+ end
+ a=a(str) or ""
+ end
+ a=lpegmatch(grammar_parsed_text_two,a) or a
+ if type(a)=="number" then
+ return ""
+ else
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
+ end
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- return formatters["u:%s"](s),true
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
+ end
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
+ end
+ return a
+ end
+ end
+ local p_rest=(1-P(";"))^1
+ local spec={
+ [0x23]="\\Ux{23}",
+ [0x24]="\\Ux{24}",
+ [0x25]="\\Ux{25}",
+ [0x5C]="\\Ux{5C}",
+ [0x7B]="\\Ux{7B}",
+ [0x7C]="\\Ux{7C}",
+ [0x7D]="\\Ux{7D}",
+ [0x7E]="\\Ux{7E}",
+ }
+ local hash=table.setmetatableindex(spec,function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- xml.reparsedentitylpeg=reparsedentity
- xml.unescapedentitylpeg=unescapedentity
+ end
+ local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ local hash=table.setmetatableindex(function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
+ end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ xml.reparsedentitylpeg=reparsedentity
+ xml.unescapedentitylpeg=unescapedentity
end
local escaped=xml.escaped
local unescaped=xml.unescaped
local placeholders=xml.placeholders
local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
+ report_xml("error in entity, %a found without ending %a",str,";")
+ return str
end
local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
+ report_xml("error in parsing, unexpected %a found ",chr)
+ add_text(chr)
+ return chr
end
local function handlenewline()
- currentline=currentline+1
+ currentline=currentline+1
end
local spacetab=S(' \t')
local space=S(' \r\n\t')
@@ -12849,141 +16338,141 @@ local space_nl=spacetab+newline
local spacing_nl=Cs((space_nl)^0)
local anything_nl=newline+P(1)
local function weirdentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","weird",k,v)
+ end
+ parameters[k]=v
end
local function normalentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","normal",k,v)
+ end
+ entities[k]=v
end
local function systementity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","system",k,v)
+ end
+ entities[k]=v
end
local function publicentity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","public",k,v)
+ end
+ entities[k]=v
end
local function entityfile(pattern,k,v,n)
- if n then
- local okay,data
- if resolvers then
- okay,data=resolvers.loadbinfile(n)
- else
- data=io.loaddata(n)
- okay=data and data~=""
- end
- if okay then
- if trace_entities then
- report_xml("loading public entities %a as %a from %a",k,v,n)
- end
- lpegmatch(pattern,data)
- return
- end
+ if n then
+ local okay,data
+ if resolvers then
+ okay,data=resolvers.loadbinfile(n)
+ else
+ data=io.loaddata(n)
+ okay=data and data~=""
end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
+ if okay then
+ if trace_entities then
+ report_xml("loading public entities %a as %a from %a",k,v,n)
+ end
+ lpegmatch(pattern,data)
+ return
+ end
+ end
+ report_xml("ignoring public entities %a as %a from %a",k,v,n)
end
local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_dtd)
- local parsedentity_text=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_text)
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
- local endofattributes=slash*close+close
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
- entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
- lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
- lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1
- local somedoctype=C((somespace*(
+ local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
+ local hexentitycontent=R("AF","af","09")^1
+ local decentitycontent=R("09")^1
+ local parsedentity=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_dtd)
+ local parsedentity_text=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_text)
+ local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local text_unparsed=Cs((anything-open)^1)
+ local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
+ local somespace=(spacenewline)^1
+ local optionalspace=(spacenewline)^0
+ local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
+ local endofattributes=slash*close+close
+ local whatever=space*name*optionalspace*equal
+ local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
+ local attributevalue=value+wrongvalue
+ local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
+ local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
+ local parsedtext=text_parsed
+ local unparsedtext=text_unparsed/add_text
+ local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
+ local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
+ local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
+ local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
+ local begincomment=open*P("!--")
+ local endcomment=P("--")*close
+ local begininstruction=open*P("?")
+ local endinstruction=P("?")*close
+ local begincdata=open*P("![CDATA[")
+ local endcdata=P("]]")*close
+ local someinstruction=C((anything-endinstruction)^0)
+ local somecomment=C((anything-endcomment )^0)
+ local somecdata=C((anything-endcdata )^0)
+ local begindoctype=open*P("!DOCTYPE")
+ local enddoctype=close
+ local beginset=P("[")
+ local endset=P("]")
+ local wrdtypename=C((anything-somespace-P(";"))^1)
+ local doctypename=C((anything-somespace-close)^0)
+ local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
+ local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
+ local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
+ local normalentitytype=(doctypename*somespace*value)/normalentity
+ local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
+ local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
+ local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
+ local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
+ entityfile(entitydoctype,...)
+ end
+ local function weirdresolve(s)
+ lpegmatch(entitydoctype,parameters[s])
+ end
+ local function normalresolve(s)
+ lpegmatch(entitydoctype,entities[s])
+ end
+ local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
+ entitydoctype=entitydoctype+entityresolve
+ local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
+ local definitiondoctype=doctypename*somespace*doctypeset
+ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
+ local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
+ local simpledoctype=(anything-close)^1
+ local somedoctype=C((somespace*(
publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
- followup=V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
+ local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
+ local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
+ local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
+ local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
+ local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
+ local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
+ local trailer=space^0*(text_unparsed/set_message)^0
+ local grammar_parsed_text_one=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
+ }
+ local grammar_parsed_text_two=P { "followup",
+ followup=V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
+ }
+ local grammar_unparsed_text=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
+ }
+ return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
end
grammar_parsed_text_one_nop,
grammar_parsed_text_two_nop,
@@ -12992,576 +16481,576 @@ grammar_parsed_text_one_yes,
grammar_parsed_text_two_yes,
grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
local function _xmlconvert_(data,settings,detail)
- settings=settings or {}
- preparexmlstate(settings)
- if settings.linenumbers then
- grammar_parsed_text_one=grammar_parsed_text_one_yes
- grammar_parsed_text_two=grammar_parsed_text_two_yes
- grammar_unparsed_text=grammar_unparsed_text_yes
- else
- grammar_parsed_text_one=grammar_parsed_text_one_nop
- grammar_parsed_text_two=grammar_parsed_text_two_nop
- grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
- data=preprocessor(data,settings) or data
+ settings=settings or {}
+ preparexmlstate(settings)
+ if settings.linenumbers then
+ grammar_parsed_text_one=grammar_parsed_text_one_yes
+ grammar_parsed_text_two=grammar_parsed_text_two_yes
+ grammar_unparsed_text=grammar_unparsed_text_yes
+ else
+ grammar_parsed_text_one=grammar_parsed_text_one_nop
+ grammar_parsed_text_two=grammar_parsed_text_two_nop
+ grammar_unparsed_text=grammar_unparsed_text_nop
+ end
+ local preprocessor=settings.preprocessor
+ if data and data~="" and type(preprocessor)=="function" then
+ data=preprocessor(data,settings) or data
+ end
+ if settings.parent_root then
+ mt=getmetatable(settings.parent_root)
+ else
+ initialize_mt(top)
+ end
+ level=level+1
+ stack[level]=top
+ top.dt={}
+ dt=top.dt
+ nt=0
+ if not data or data=="" then
+ errorstr="empty xml file"
+ elseif data==true then
+ errorstr=detail or "problematic xml file"
+ elseif utfize or resolve then
+ local m=lpegmatch(grammar_parsed_text_one,data)
+ if m then
+ m=lpegmatch(grammar_parsed_text_two,data,m)
end
- if settings.parent_root then
- mt=getmetatable(settings.parent_root)
- else
- initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
- errorstr="empty xml file"
- elseif data==true then
- errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
- local m=lpegmatch(grammar_parsed_text_one,data)
- if m then
- m=lpegmatch(grammar_parsed_text_two,data,m)
- end
- if m then
- else
- errorstr="invalid xml file - parsed text"
- end
- elseif type(data)=="string" then
- if lpegmatch(grammar_unparsed_text,data) then
- errorstr=""
- else
- errorstr="invalid xml file - unparsed text"
- end
+ if m then
else
- errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
- result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
- setmetatable(result,mt)
- setmetatable(result.dt[1],mt)
- setmetatable(stack,mt)
- local errorhandler=settings.error_handler
- if errorhandler==false then
+ errorstr="invalid xml file - parsed text"
+ end
+ elseif type(data)=="string" then
+ if lpegmatch(grammar_unparsed_text,data) then
+ errorstr=""
+ else
+ errorstr="invalid xml file - unparsed text"
+ end
+ else
+ errorstr="invalid xml file - no text at all"
+ end
+ local result
+ if errorstr and errorstr~="" then
+ result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
+ setmetatable(result,mt)
+ setmetatable(result.dt[1],mt)
+ setmetatable(stack,mt)
+ local errorhandler=settings.error_handler
+ if errorhandler==false then
+ else
+ errorhandler=errorhandler or xml.errorhandler
+ if errorhandler then
+ local currentresource=settings.currentresource
+ if currentresource and currentresource~="" then
+ xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
else
- errorhandler=errorhandler or xml.errorhandler
- if errorhandler then
- local currentresource=settings.currentresource
- if currentresource and currentresource~="" then
- xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
- else
- xml.errorhandler(formatters["load error: %s"](errorstr))
- end
- end
- end
- else
- result=stack[1]
- end
- if not settings.no_root then
- result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
- setmetatable(result,mt)
- local rdt=result.dt
- for k=1,#rdt do
- local v=rdt[k]
- if type(v)=="table" and not v.special then
- result.ri=k
- v.__p__=result
- break
- end
+ xml.errorhandler(formatters["load error: %s"](errorstr))
end
+ end
end
- if errorstr and errorstr~="" then
- result.error=true
- else
- errorstr=nil
- end
- result.statistics={
- errormessage=errorstr,
- entities={
- decimals=dcache,
- hexadecimals=hcache,
- names=acache,
- intermediates=parameters,
- }
+ else
+ result=stack[1]
+ end
+ if not settings.no_root then
+ result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
+ setmetatable(result,mt)
+ local rdt=result.dt
+ for k=1,#rdt do
+ local v=rdt[k]
+ if type(v)=="table" and not v.special then
+ result.ri=k
+ v.__p__=result
+ break
+ end
+ end
+ end
+ if errorstr and errorstr~="" then
+ result.error=true
+ else
+ errorstr=nil
+ end
+ result.statistics={
+ errormessage=errorstr,
+ entities={
+ decimals=dcache,
+ hexadecimals=hcache,
+ names=acache,
+ intermediates=parameters,
}
- preparexmlstate()
- return result
+ }
+ preparexmlstate()
+ return result
end
local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
- return result
- elseif type(result)=="string" then
- return _xmlconvert_(true,settings,result)
- else
- return _xmlconvert_(true,settings)
- end
+ local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
+ if ok then
+ return result
+ elseif type(result)=="string" then
+ return _xmlconvert_(true,settings,result)
+ else
+ return _xmlconvert_(true,settings)
+ end
end
xml.convert=xmlconvert
function xml.inheritedconvert(data,xmldata)
- local settings=xmldata.settings
- if settings then
- settings.parent_root=xmldata
- end
- local xc=xmlconvert(data,settings)
- return xc
+ local settings=xmldata.settings
+ if settings then
+ settings.parent_root=xmldata
+ end
+ local xc=xmlconvert(data,settings)
+ return xc
end
function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
+ return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
end
function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
+ local ns,tg=match(tag,"^(.-):?([^:]+)$")
+ local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
+ setmetatable(t,mt)
+ return t
end
function xml.is_valid(root)
- return root and not root.error
+ return root and not root.error
end
xml.errorhandler=report_xml
function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
- local f=io.open(filename,'r')
- if f then
- data=f:read("*all")
- f:close()
- end
- elseif filename then
- data=filename:read("*all")
- end
- if settings then
- settings.currentresource=filename
- local result=xmlconvert(data,settings)
- settings.currentresource=nil
- return result
- else
- return xmlconvert(data,{ currentresource=filename })
- end
+ local data=""
+ if type(filename)=="string" then
+ local f=io.open(filename,'r')
+ if f then
+ data=f:read("*all")
+ f:close()
+ end
+ elseif filename then
+ data=filename:read("*all")
+ end
+ if settings then
+ settings.currentresource=filename
+ local result=xmlconvert(data,settings)
+ settings.currentresource=nil
+ return result
+ else
+ return xmlconvert(data,{ currentresource=filename })
+ end
end
local no_root={ no_root=true }
function xml.toxml(data)
- if type(data)=="string" then
- local root={ xmlconvert(data,no_root) }
- return (#root>1 and root) or root[1]
- else
- return data
- end
+ if type(data)=="string" then
+ local root={ xmlconvert(data,no_root) }
+ return (#root>1 and root) or root[1]
+ else
+ return data
+ end
end
local function copy(old,p)
- if old then
- local new={}
- for k,v in next,old do
- local t=type(v)=="table"
- if k=="at" then
- local t={}
- for k,v in next,v do
- t[k]=v
- end
- new[k]=t
- elseif k=="dt" then
- v.__p__=nil
- v=copy(v,new)
- new[k]=v
- v.__p__=p
- else
- new[k]=v
- end
- end
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ local t=type(v)=="table"
+ if k=="at" then
+ local t={}
+ for k,v in next,v do
+ t[k]=v
+ end
+ new[k]=t
+ elseif k=="dt" then
+ v.__p__=nil
+ v=copy(v,new)
+ new[k]=v
+ v.__p__=p
+ else
+ new[k]=v
+ end
end
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ return new
+ else
+ return {}
+ end
end
xml.copy=copy
function xml.checkbom(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
- return
- end
- end
- insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
- insert(dt,2,"\n" )
+ if root.ri then
+ local dt=root.dt
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
+ return
+ end
end
+ insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
+ insert(dt,2,"\n" )
+ end
end
local f_attribute=formatters['%s=%q']
local function verbose_element(e,handlers,escape)
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
- local n=0
- for k in next,eat do
- n=n+1
- ats[n]=k
- end
- if n==1 then
- local k=ats[1]
- ats=f_attribute(k,escaped(eat[k]))
- else
- sort(ats)
- for i=1,n do
- local k=ats[i]
- ats[i]=f_attribute(k,escaped(eat[k]))
- end
- ats=concat(ats," ")
- end
- end
- if ern and trace_entities and ern~=ens then
- ens=ern
+ local handle=handlers.handle
+ local serialize=handlers.serialize
+ local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
+ local ats=eat and next(eat) and {}
+ if ats then
+ local n=0
+ for k in next,eat do
+ n=n+1
+ ats[n]=k
end
- local n=edt and #edt
- if ens~="" then
- if n and n>0 then
- if ats then
- handle("<",ens,":",etg," ",ats,">")
- else
- handle("<",ens,":",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",ens,":",etg,">")
+ if n==1 then
+ local k=ats[1]
+ ats=f_attribute(k,escaped(eat[k]))
+ else
+ sort(ats)
+ for i=1,n do
+ local k=ats[i]
+ ats[i]=f_attribute(k,escaped(eat[k]))
+ end
+ ats=concat(ats," ")
+ end
+ end
+ if ern and trace_entities and ern~=ens then
+ ens=ern
+ end
+ local n=edt and #edt
+ if ens~="" then
+ if n and n>0 then
+ if ats then
+ handle("<",ens,":",etg," ",ats,">")
+ else
+ handle("<",ens,":",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",ens,":",etg," ",ats,"/>")
- else
- handle("<",ens,":",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",ens,":",etg,">")
else
- if n and n>0 then
- if ats then
- handle("<",etg," ",ats,">")
- else
- handle("<",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",etg,">")
+ if ats then
+ handle("<",ens,":",etg," ",ats,"/>")
+ else
+ handle("<",ens,":",etg,"/>")
+ end
+ end
+ else
+ if n and n>0 then
+ if ats then
+ handle("<",etg," ",ats,">")
+ else
+ handle("<",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",etg," ",ats,"/>")
- else
- handle("<",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",etg,">")
+ else
+ if ats then
+ handle("<",etg," ",ats,"/>")
+ else
+ handle("<",etg,"/>")
+ end
end
+ end
end
local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
+ handlers.handle("<?",e.dt[1],"?>")
end
local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
+ handlers.handle("<!--",e.dt[1],"-->")
end
local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
+ handlers.handle("<![CDATA[",e.dt[1],"]]>")
end
local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">")
+ handlers.handle("<!DOCTYPE",e.dt[1],">")
end
local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
+ handlers.serialize(e.dt,handlers)
end
local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
+ handlers.handle(escaped(e))
end
local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
- local ei=e[i]
- if type(ei)=="string" then
- functions["@tx@"](ei,handlers)
- else
- serialize(ei,handlers)
- end
+ local serialize=handlers.serialize
+ local functions=handlers.functions
+ for i=1,#e do
+ local ei=e[i]
+ if type(ei)=="string" then
+ functions["@tx@"](ei,handlers)
+ else
+ serialize(ei,handlers)
end
+ end
end
local function serialize(e,handlers,...)
- if e then
- local initialize=handlers.initialize
- local finalize=handlers.finalize
- local functions=handlers.functions
- if initialize then
- local state=initialize(...)
- if not state==true then
- return state
- end
- end
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- if finalize then
- return finalize()
- end
+ if e then
+ local initialize=handlers.initialize
+ local finalize=handlers.finalize
+ local functions=handlers.functions
+ if initialize then
+ local state=initialize(...)
+ if not state==true then
+ return state
+ end
end
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
+ end
+ if finalize then
+ return finalize()
+ end
+ end
end
local function xserialize(e,handlers)
- if e then
- local functions=handlers.functions
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
+ if e then
+ local functions=handlers.functions
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ end
end
local handlers={}
local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
- if settings then
- for k,v in next,settings do
- if type(v)=="table" then
- local tk=t[k] if not tk then tk={} t[k]=tk end
- for kk,vv in next,v do
- tk[kk]=vv
- end
- else
- t[k]=v
- end
- end
- if settings.name then
- handlers[settings.name]=t
- end
+ local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
+ if settings then
+ for k,v in next,settings do
+ if type(v)=="table" then
+ local tk=t[k] if not tk then tk={} t[k]=tk end
+ for kk,vv in next,v do
+ tk[kk]=vv
+ end
+ else
+ t[k]=v
+ end
end
- utilities.storage.mark(t)
- return t
+ if settings.name then
+ handlers[settings.name]=t
+ end
+ end
+ utilities.storage.mark(t)
+ return t
end
local nofunction=function() end
function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
+ handler.functions[name]=fnc or nofunction
end
function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
+ return handler.functions[name]
end
function xml.gethandlers(name)
- return handlers[name]
+ return handlers[name]
end
newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
- ["@dc@"]=verbose_document,
- ["@dt@"]=verbose_doctype,
- ["@rt@"]=verbose_root,
- ["@el@"]=verbose_element,
- ["@pi@"]=verbose_pi,
- ["@cm@"]=verbose_comment,
- ["@cd@"]=verbose_cdata,
- ["@tx@"]=verbose_text,
- }
+ name="verbose",
+ initialize=false,
+ finalize=false,
+ serialize=xserialize,
+ handle=print,
+ functions={
+ ["@dc@"]=verbose_document,
+ ["@dt@"]=verbose_doctype,
+ ["@rt@"]=verbose_root,
+ ["@el@"]=verbose_element,
+ ["@pi@"]=verbose_pi,
+ ["@cm@"]=verbose_comment,
+ ["@cd@"]=verbose_cdata,
+ ["@tx@"]=verbose_text,
+ }
}
local result
local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
- result=io.open(name,"wb")
- return result
- end,
- finalize=function()
- result:close()
- return true
- end,
- handle=function(...)
- result:write(...)
- end,
+ name="file",
+ initialize=function(name)
+ result=io.open(name,"wb")
+ return result
+ end,
+ finalize=function()
+ result:close()
+ return true
+ end,
+ handle=function(...)
+ result:write(...)
+ end,
}
function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
+ serialize(root,xmlfilehandler,name)
end
local result,r,threshold={},0,512
local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
- r=0
- return result
- end,
- finalize=function()
- local done=concat(result,"",1,r)
- r=0
- if r>threshold then
- result={}
- end
- return done
- end,
- handle=function(...)
- for i=1,select("#",...) do
- r=r+1
- result[r]=select(i,...)
- end
- end,
+ name="string",
+ initialize=function()
+ r=0
+ return result
+ end,
+ finalize=function()
+ local done=concat(result,"",1,r)
+ r=0
+ if r>threshold then
+ result={}
+ end
+ return done
+ end,
+ handle=function(...)
+ for i=1,select("#",...) do
+ r=r+1
+ result[r]=select(i,...)
+ end
+ end,
}
local function xmltostring(root)
- if not root then
- return ""
- elseif type(root)=="string" then
- return root
- else
- return serialize(root,xmlstringhandler) or ""
- end
+ if not root then
+ return ""
+ elseif type(root)=="string" then
+ return root
+ else
+ return serialize(root,xmlstringhandler) or ""
+ end
end
local function __tostring(root)
- return (root and xmltostring(root)) or ""
+ return (root and xmltostring(root)) or ""
end
initialize_mt=function(root)
- mt={ __tostring=__tostring,__index=root }
+ mt={ __tostring=__tostring,__index=root }
end
xml.defaulthandlers=handlers
xml.newhandlers=newhandlers
xml.serialize=serialize
xml.tostring=xmltostring
local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- xmlstring(edt[i],handle)
- end
- end
- else
- handle(e)
+ if not handle or (e.special and e.tg~="@rt@") then
+ elseif e.tg then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ xmlstring(edt[i],handle)
+ end
end
+ else
+ handle(e)
+ end
end
xml.string=xmlstring
function xml.settings(e)
- while e do
- local s=e.settings
- if s then
- return s
- else
- e=e.__p__
- end
+ while e do
+ local s=e.settings
+ if s then
+ return s
+ else
+ e=e.__p__
end
- return nil
+ end
+ return nil
end
function xml.root(e)
- local r=e
- while e do
- e=e.__p__
- if e then
- r=e
- end
+ local r=e
+ while e do
+ e=e.__p__
+ if e then
+ r=e
end
- return r
+ end
+ return r
end
function xml.parent(root)
- return root.__p__
+ return root.__p__
end
function xml.body(root)
- return root.ri and root.dt[root.ri] or root
+ return root.ri and root.dt[root.ri] or root
end
function xml.name(root)
- if not root then
- return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
- return tg
- else
- return ns..":"..tg
- end
+ if not root then
+ return ""
+ end
+ local ns=root.ns
+ local tg=root.tg
+ if ns=="" then
+ return tg
+ else
+ return ns..":"..tg
+ end
end
function xml.erase(dt,k)
- if dt then
- if k then
- dt[k]=""
- else for k=1,#dt do
- dt[1]={ "" }
- end end
- end
+ if dt then
+ if k then
+ dt[k]=""
+ else for k=1,#dt do
+ dt[1]={ "" }
+ end end
+ end
end
function xml.assign(dt,k,root)
- if dt and k then
- dt[k]=type(root)=="table" and xml.body(root) or root
- return dt[k]
- else
- return xml.body(root)
- end
+ if dt and k then
+ dt[k]=type(root)=="table" and xml.body(root) or root
+ return dt[k]
+ else
+ return xml.body(root)
+ end
end
function xml.tocdata(e,wrapper)
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
- whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
+ local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
+ if wrapper then
+ whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
+ end
+ local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
+ setmetatable(t,getmetatable(e))
+ e.dt={ t }
end
function xml.makestandalone(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" then
- local txt=v.dt[1]
- if find(txt,"xml.*version=") then
- v.dt[1]=txt.." standalone='yes'"
- break
- end
- end
+ if root.ri then
+ local dt=root.dt
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="table" and v.special and v.tg=="@pi@" then
+ local txt=v.dt[1]
+ if find(txt,"xml.*version=") then
+ v.dt[1]=txt.." standalone='yes'"
+ break
end
+ end
end
- return root
+ end
+ return root
end
function xml.kind(e)
- local dt=e and e.dt
- if dt then
- local n=#dt
- if n==1 then
- local d=dt[1]
- if d.special then
- local tg=d.tg
- if tg=="@cd@" then
- return "cdata"
- elseif tg=="@cm" then
- return "comment"
- elseif tg=="@pi@" then
- return "instruction"
- elseif tg=="@dt@" then
- return "declaration"
- end
- elseif type(d)=="string" then
- return "text"
- end
- return "element"
- elseif n>0 then
- return "mixed"
- end
+ local dt=e and e.dt
+ if dt then
+ local n=#dt
+ if n==1 then
+ local d=dt[1]
+ if d.special then
+ local tg=d.tg
+ if tg=="@cd@" then
+ return "cdata"
+ elseif tg=="@cm" then
+ return "comment"
+ elseif tg=="@pi@" then
+ return "instruction"
+ elseif tg=="@dt@" then
+ return "declaration"
+ end
+ elseif type(d)=="string" then
+ return "text"
+ end
+ return "element"
+ elseif n>0 then
+ return "mixed"
end
- return "empty"
+ end
+ return "empty"
end
@@ -13571,14 +17060,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
--- original size: 53301, stripped down to: 32477
+-- original size: 55145, stripped down to: 30992
if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local concat,remove,insert=table.concat,table.remove,table.insert
local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
@@ -13591,21 +17080,21 @@ local trace_lparse=false
local trace_lprofile=false
local report_lpath=logs.reporter("xml","lpath")
if trackers then
- trackers.register("xml.path",function(v)
- trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
- trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
- trace_lpath=v
- trace_lparse=v
- trace_lprofile=v
- end)
+ trackers.register("xml.path",function(v)
+ trace_lpath=v
+ end)
+ trackers.register("xml.parse",function(v)
+ trace_lparse=v
+ end)
+ trackers.register("xml.profile",function(v)
+ trace_lpath=v
+ trace_lparse=v
+ trace_lprofile=v
+ end)
end
local xml=xml
-local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
-local lpathcached=0 function xml.lpathcached() return lpathcached end
+local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
+local lpathcached=0 function xml.lpathcached() return lpathcached end
xml.functions=xml.functions or {}
local functions=xml.functions
xml.expressions=xml.expressions or {}
@@ -13619,216 +17108,271 @@ local xmlpatterns=lpegpatterns.xml
finalizers.xml=finalizers.xml or {}
finalizers.tex=finalizers.tex or {}
local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
- t[name]=fn
- else
- report_lpath("unknown sub finalizer %a",name)
- fn=function() end
- end
- return fn
+ local fn=finalizers[name]
+ if fn then
+ t[name]=fn
+ else
+ report_lpath("unknown sub finalizer %a",name)
+ fn=function() end
+ end
+ return fn
end
setmetatableindex(finalizers.xml,fallback)
setmetatableindex(finalizers.tex,fallback)
xml.defaultprotocol="xml"
local apply_axis={}
apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
- local ll=list[l]
- local rt=ll
- while ll do
- ll=ll.__p__
- if ll then
- rt=ll
- end
- end
- collected[l]=rt
+ local collected={}
+ for l=1,#list do
+ local ll=list[l]
+ local rt=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
+ rt=ll
+ end
end
- return collected
+ collected[l]=rt
+ end
+ return collected
end
apply_axis['self']=function(list)
- return list
+ return list
end
apply_axis['child']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local dt=ll.dt
- if dt then
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- end
- end
- ll.en=en
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ local dt=ll.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ end
end
+ ll.en=en
+ end
end
- return collected
+ end
+ return collected
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]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- c=collect(dk,collected,c)
- end
+ local dt=list.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ c=collect(dk,collected,c)
end
- list.en=en
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant']=function(list)
- local collected,c={},0
- for l=1,#list do
- c=collect(list[l],collected,c)
- end
- return collected
+ local collected={}
+ local c=0
+ for l=1,#list do
+ c=collect(list[l],collected,c)
+ end
+ return collected
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]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- c=collect(dk,collected,c)
- end
+ local dt=list.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ c=collect(dk,collected,c)
end
- list.en=en
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- if ll.special~=true then
- c=c+1
- collected[c]=ll
- end
- c=collect(ll,collected,c)
- end
- return collected
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ if ll.special~=true then
+ c=c+1
+ collected[c]=ll
+ end
+ c=collect(ll,collected,c)
+ end
+ return collected
end
apply_axis['ancestor']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ while ll do
+ ll=ll.__p__
+ if ll then
+ c=c+1
+ collected[c]=ll
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['ancestor-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ c=c+1
+ collected[c]=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
c=c+1
collected[c]=ll
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['parent']=function(list)
- local collected,c={},0
- for l=1,#list do
- local pl=list[l].__p__
- if pl then
- c=c+1
- collected[c]=pl
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local pl=list[l].__p__
+ if pl then
+ c=c+1
+ collected[c]=pl
end
- return collected
+ end
+ return collected
end
apply_axis['attribute']=function(list)
- return {}
+ return {}
end
apply_axis['namespace']=function(list)
- return {}
+ return {}
end
apply_axis['following']=function(list)
- return {}
+ return {}
end
apply_axis['preceding']=function(list)
- return {}
+ return {}
end
apply_axis['following-sibling']=function(list)
- 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
- end
- end
+ 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,#d do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['preceding-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=1,ll.ni-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=1,ll.ni-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['reverse-sibling']=function(list)
- 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
- end
- end
+ 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
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
apply_axis['auto-descendant']=apply_axis['descendant']
@@ -13836,130 +17380,147 @@ apply_axis['auto-child']=apply_axis['child']
apply_axis['auto-self']=apply_axis['self']
apply_axis['initial-child']=apply_axis['child']
local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then
- local nns,ntg=nodes[2],nodes[3]
- if not nns and not ntg then
+ local maxn=#nodes
+ if maxn==3 then
+ local nns=nodes[2]
+ local ntg=nodes[3]
+ if not nns and not ntg then
+ if directive then
+ return list
+ else
+ return {}
+ end
+ else
+ local collected={}
+ local c=0
+ local m=0
+ local p=nil
+ if not nns then
+ for l=1,#list do
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
if directive then
- return list
- else
- return {}
+ if ntg==ltg then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif ntg~=ltg then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- else
- local collected,c,m,p={},0,0,nil
- if not nns then
- for l=1,#list do
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif ntg~=ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- elseif not ntg then
- for l=1,#list do
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif lns~=nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- else
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
+ end
+ end
+ elseif not ntg then
+ for l=1,#list do
+ 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=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif lns~=nns then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- return collected
+ end
end
- else
- local collected,c,m,p={},0,0,nil
+ else
for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=false
- for n=1,maxn,3 do
- local nns,ntg=nodes[n+1],nodes[n+2]
- ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
- if ok then
- break
- end
- end
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=ltg==ntg and lns==nns
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
+ end
end
- return collected
+ end
+ return collected
end
-end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected,c={},0
- quit_expression=false
+ else
+ local collected={}
+ local c=0
+ local m=0
+ local p=nil
for l=1,#list do
- local ll=list[l]
- if expression(list,ll,l,order) then
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=false
+ for n=1,maxn,3 do
+ 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
+ end
+ end
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
c=c+1
collected[c]=ll
+ ll.mi=m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- if quit_expression then
- break
- end
+ end
end
return collected
+ end
end
-local function apply_selector(list,specification)
- if xml.applyselector then
- apply_selector=xml.applyselector
- return apply_selector(list,specification)
- else
- return list
+local quit_expression=false
+local function apply_expression(list,expression,order)
+ local collected={}
+ local c=0
+ quit_expression=false
+ for l=1,#list do
+ local ll=list[l]
+ if expression(list,ll,l,order) then
+ c=c+1
+ collected[c]=ll
+ end
+ if quit_expression then
+ break
end
+ end
+ return collected
+end
+local function apply_selector(list,specification)
+ if xml.applyselector then
+ apply_selector=xml.applyselector
+ return apply_selector(list,specification)
+ else
+ return list
+ end
end
local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
local spaces=S(" \n\r\t\f")^0
@@ -13970,24 +17531,24 @@ local lp_doequal=P("=")/"=="
local lp_or=P("|")/" or "
local lp_and=P("&")/" and "
local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
+ text="(ll.dt[1] or '')",
+ content="ll.dt",
+ name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
+ tag="ll.tg",
+ position="l",
+ firstindex="1",
+ firstelement="1",
+ first="1",
+ lastindex="(#ll.__p__.dt or 1)",
+ lastelement="(ll.__p__.en or 1)",
+ last="#list",
+ rootposition="order",
+ order="order",
+ element="(ll.ei or 1)",
+ index="(ll.ni or 1)",
+ match="(ll.mi or 1)",
+ namespace="ll.ns",
+ ns="ll.ns",
}
local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
@@ -13997,11 +17558,11 @@ local lp_fastpos=lp_fastpos_n+lp_fastpos_p
local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t)
- if expressions[t] then
- return "expr."..t.."("
- else
- return "expr.error("
- end
+ if expressions[t] then
+ return "expr."..t.."("
+ else
+ return "expr.error("
+ end
end
local lparent=P("(")
local rparent=P(")")
@@ -14014,24 +17575,24 @@ local lp_string=Cc("'")*R("az","AZ","--","__")^1*Cc("'")
local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
local cleaner
local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
- s=s and s~="" and lpegmatch(cleaner,s)
- if s and s~="" then
- return "expr."..t.."(ll,"..s..")"
- else
- return "expr."..t.."(ll)"
- end
+ if expressions[t] then
+ s=s and s~="" and lpegmatch(cleaner,s)
+ if s and s~="" then
+ return "expr."..t.."(ll,"..s..")"
else
- return "expr.error("..t..")"
+ return "expr."..t.."(ll)"
end
+ else
+ return "expr.error("..t..")"
+ end
end
local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
+ lp_child+lp_any
local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
+ lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
)
cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
+ lp_reserved+lp_number+lp_string+1 )^1 )
local template_e=[[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -14047,75 +17608,75 @@ local template_f_y=[[
local template_f_n=[[
return xml.finalizers['%s']['%s']
]]
-local register_last_match={ kind="axis",axis="last-match" }
-local register_self={ kind="axis",axis="self" }
-local register_parent={ kind="axis",axis="parent" }
-local register_descendant={ kind="axis",axis="descendant" }
-local register_child={ kind="axis",axis="child" }
+local register_last_match={ kind="axis",axis="last-match" }
+local register_self={ kind="axis",axis="self" }
+local register_parent={ kind="axis",axis="parent" }
+local register_descendant={ kind="axis",axis="descendant" }
+local register_child={ kind="axis",axis="child" }
local register_descendant_or_self={ kind="axis",axis="descendant-or-self" }
-local register_root={ kind="axis",axis="root" }
-local register_ancestor={ kind="axis",axis="ancestor" }
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
-local register_attribute={ kind="axis",axis="attribute" }
-local register_namespace={ kind="axis",axis="namespace" }
-local register_following={ kind="axis",axis="following" }
+local register_root={ kind="axis",axis="root" }
+local register_ancestor={ kind="axis",axis="ancestor" }
+local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
+local register_attribute={ kind="axis",axis="attribute" }
+local register_namespace={ kind="axis",axis="namespace" }
+local register_following={ kind="axis",axis="following" }
local register_following_sibling={ kind="axis",axis="following-sibling" }
-local register_preceding={ kind="axis",axis="preceding" }
+local register_preceding={ kind="axis",axis="preceding" }
local register_preceding_sibling={ kind="axis",axis="preceding-sibling" }
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
+local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" }
-local register_auto_descendant={ kind="axis",axis="auto-descendant" }
-local register_auto_self={ kind="axis",axis="auto-self" }
-local register_auto_child={ kind="axis",axis="auto-child" }
-local register_initial_child={ kind="axis",axis="initial-child" }
+local register_auto_descendant={ kind="axis",axis="auto-descendant" }
+local register_auto_self={ kind="axis",axis="auto-self" }
+local register_auto_child={ kind="axis",axis="auto-child" }
+local register_initial_child={ kind="axis",axis="initial-child" }
local register_all_nodes={ kind="nodes",nodetest=true,nodes={ true,false,false } }
local skip={}
local function errorrunner_e(str,cnv)
- if not skip[str] then
- report_lpath("error in expression: %s => %s",str,cnv)
- skip[str]=cnv or str
- end
- return false
+ if not skip[str] then
+ report_lpath("error in expression: %s => %s",str,cnv)
+ skip[str]=cnv or str
+ end
+ return false
end
local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
+ report_lpath("error in finalizer: %s(%s)",str,arg or "")
+ return false
end
local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
+ return { kind="nodes",nodetest=nodetest,nodes=nodes }
end
local function register_selector(specification)
- return { kind="selector",specification=specification }
+ return { kind="selector",specification=specification }
end
local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local runner=load(format(template_e,converted))
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
+ local converted=lpegmatch(converter,expression)
+ local runner=load(format(template_e,converted))
+ runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
+ return { kind="expression",expression=expression,converted=converted,evaluator=runner }
end
local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
- runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
- runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
+ local runner
+ if arguments and arguments~="" then
+ runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+ else
+ runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
+ end
+ runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
+ return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
end
local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
+ ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
+ sq="'"*(1-S("'"))^0*"'",
+ dq='"'*(1-S('"'))^0*'"',
}
local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
+ ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
+ nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
+ sq=P("'")*(1-P("'"))^0*P("'"),
+ dq=P('"')*(1-P('"'))^0*P('"'),
}
local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
+ return { kind="error",error=format("unparsed: %s",str) }
end
local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes)
local special_2=P("/")*Cc(register_auto_self)
@@ -14123,367 +17684,368 @@ local special_3=P("")*Cc(register_auto_self)
local no_nextcolon=P(-1)+#(1-P(":"))
local no_nextlparent=P(-1)+#(1-P("("))
local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
- (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
- ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
+ patterns=spaces*V("protocol")*spaces*(
+ (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
+ ),
+ protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
+ step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
+ axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
+ special=special_1+special_2+special_3,
+ initial=(P("/")*spaces*Cc(register_initial_child))^-1,
+ error=(P(1)^1)/register_error,
+ shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
+ shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
+ s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
+ s_descendant=P("**")*Cc(register_descendant),
+ s_child=P("*")*no_nextcolon*Cc(register_child),
+ s_parent=P("..")*Cc(register_parent),
+ s_self=P("." )*Cc(register_self),
+ s_root=P("^^")*Cc(register_root),
+ s_ancestor=P("^")*Cc(register_ancestor),
+ s_lastmatch=P("=")*Cc(register_last_match),
+ descendant=P("descendant::")*Cc(register_descendant),
+ child=P("child::")*Cc(register_child),
+ parent=P("parent::")*Cc(register_parent),
+ self=P("self::")*Cc(register_self),
+ root=P('root::')*Cc(register_root),
+ ancestor=P('ancestor::')*Cc(register_ancestor),
+ descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
+ ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
+ following=P('following::')*Cc(register_following),
+ following_sibling=P('following-sibling::')*Cc(register_following_sibling),
+ preceding=P('preceding::')*Cc(register_preceding),
+ preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
+ reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
+ last_match=P('last-match::')*Cc(register_last_match),
+ selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
+ nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
+ expressions=expression/register_expression,
+ letters=R("az")^1,
+ name=(1-S("/[]()|:*!"))^1,
+ negate=P("!")*Cc(false),
+ nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
+ nodetest=V("negate")+Cc(true),
+ nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
+ wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
+ nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
+ finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
}
xmlpatterns.pathparser=pathparser
local cache={}
local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
- local directive,ns,tg=set[i],set[i+1],set[i+2]
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
- return format("not(%s)",concat(t,"|"))
- else
- return concat(t,"|")
- end
+ local t={}
+ for i=1,#set,3 do
+ local directive,ns,tg=set[i],set[i+1],set[i+2]
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+ t[#t+1]=(directive and tg) or format("not(%s)",tg)
+ end
+ if nodetest==false then
+ return format("not(%s)",concat(t,"|"))
+ else
+ return concat(t,"|")
+ end
end
local function tagstostring(list)
- if #list==0 then
- return "no elements"
- else
- local t={}
- for i=1,#list do
- local li=list[i]
- local ns,tg=li.ns,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)
- end
- return concat(t," ")
+ if #list==0 then
+ return "no elements"
+ else
+ local t={}
+ for i=1,#list do
+ local li=list[i]
+ 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)
end
+ return concat(t," ")
+ end
end
xml.nodesettostring=nodesettostring
local lpath
local function lshow(parsed)
- if type(parsed)=="string" then
- parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
- table.serialize(parsed,false))
+ if type(parsed)=="string" then
+ parsed=lpath(parsed)
+ end
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+ table.serialize(parsed,false))
end
xml.lshow=lshow
local function add_comment(p,str)
- local pc=p.comment
- if not pc then
- p.comment={ str }
- else
- pc[#pc+1]=str
- end
+ local pc=p.comment
+ if not pc then
+ p.comment={ str }
+ else
+ pc[#pc+1]=str
+ end
end
lpath=function (pattern)
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
- return pattern
- else
- local parsed=cache[pattern]
- if parsed then
- lpathcached=lpathcached+1
+ lpathcalls=lpathcalls+1
+ if type(pattern)=="table" then
+ return pattern
+ else
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcached=lpathcached+1
+ else
+ parsed=lpegmatch(pathparser,pattern)
+ if parsed then
+ parsed.pattern=pattern
+ local np=#parsed
+ if np==0 then
+ parsed={ pattern=pattern,register_self,state="parsing error" }
+ report_lpath("parsing error in pattern: %s",pattern)
+ lshow(parsed)
else
- parsed=lpegmatch(pathparser,pattern)
- if parsed then
- parsed.pattern=pattern
- local np=#parsed
- if np==0 then
- parsed={ pattern=pattern,register_self,state="parsing error" }
- report_lpath("parsing error in pattern: %s",pattern)
- lshow(parsed)
- else
- local pi=parsed[1]
- if pi.axis=="auto-child" then
- if false then
- add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
- parsed[1]=register_auto_descendant_or_self
- else
- add_comment(parsed,"auto-child replaced by auto-descendant")
- parsed[1]=register_auto_descendant
- end
- elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
- add_comment(parsed,"initial-child removed")
- remove(parsed,1)
- end
- local np=#parsed
- if np>1 then
- local pnp=parsed[np]
- if pnp.kind=="nodes" and pnp.nodetest==true then
- local nodes=pnp.nodes
- if nodes[1]==true and nodes[2]==false and nodes[3]==false then
- add_comment(parsed,"redundant final wildcard filter removed")
- remove(parsed,np)
- end
- end
- end
- end
+ local pi=parsed[1]
+ if pi.axis=="auto-child" then
+ if false then
+ add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
+ parsed[1]=register_auto_descendant_or_self
else
- parsed={ pattern=pattern }
+ add_comment(parsed,"auto-child replaced by auto-descendant")
+ parsed[1]=register_auto_descendant
end
- cache[pattern]=parsed
- if trace_lparse and not trace_lprofile then
- lshow(parsed)
+ elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
+ add_comment(parsed,"initial-child removed")
+ remove(parsed,1)
+ end
+ local np=#parsed
+ if np>1 then
+ local pnp=parsed[np]
+ if pnp.kind=="nodes" and pnp.nodetest==true then
+ local nodes=pnp.nodes
+ if nodes[1]==true and nodes[2]==false and nodes[3]==false then
+ add_comment(parsed,"redundant final wildcard filter removed")
+ remove(parsed,np)
+ end
end
+ end
end
- return parsed
+ else
+ parsed={ pattern=pattern }
+ end
+ cache[pattern]=parsed
+ if trace_lparse and not trace_lprofile then
+ lshow(parsed)
+ end
end
+ return parsed
+ end
end
xml.lpath=lpath
do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil
- local keepmatch=nil
- if directives then
- directives.register("xml.path.keeplastmatch",function(v)
- keepmatch=v
- lastmatch=nil
- end)
- end
- apply_axis["last-match"]=function()
- return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
- local p=profiled[parsed.pattern]
- if p then
- p.tested=p.tested+1
- else
- p={ tested=1,matched=0,finalized=0 }
- profiled[parsed.pattern]=p
- end
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- p.matched=p.matched+1
- p.finalized=p.finalized+1
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- p.finalized=p.finalized+1
- return collected
- end
- return nil
- end
- end
- if collected then
- p.matched=p.matched+1
- end
- return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
- if trace_lparse then
- lshow(parsed)
- end
- report_lpath("collecting: %s",parsed.pattern)
- report_lpath("root tags : %s",tagstostring(list))
- report_lpath("order : %s",order or "unset")
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
- return collected
- end
- return nil
- end
- end
+ local profiled={}
+ xml.profiled=profiled
+ local lastmatch=nil
+ local keepmatch=nil
+ if directives then
+ directives.register("xml.path.keeplastmatch",function(v)
+ keepmatch=v
+ lastmatch=nil
+ end)
+ end
+ apply_axis["last-match"]=function()
+ return lastmatch or {}
+ end
+ local function profiled_apply(list,parsed,nofparsed,order)
+ local p=profiled[parsed.pattern]
+ if p then
+ p.tested=p.tested+1
+ else
+ p={ tested=1,matched=0,finalized=0 }
+ profiled[parsed.pattern]=p
+ end
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ p.matched=p.matched+1
+ p.finalized=p.finalized+1
return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- local axis=pi.axis
- if axis~="self" then
- collected=apply_axis[axis](collected)
- end
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- return pi.finalizer(collected)
- end
- if not collected or #collected==0 then
- local pf=i<nofparsed and parsed[nofparsed].finalizer
- if pf then
- return pf(collected)
- end
- return nil
- end
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ p.finalized=p.finalized+1
+ return collected
end
- return collected
+ return nil
+ end
end
- local apply=normal_apply
- if trackers then
- trackers.register("xml.path,xml.parse,xml.profile",function()
- if trace_lprofile then
- apply=profiled_apply
- elseif trace_lpath then
- apply=traced_apply
- else
- apply=normal_apply
- end
- end)
+ if collected then
+ p.matched=p.matched+1
end
- function xml.applylpath(list,pattern)
- if not list then
- lastmatch=nil
- return
- end
- local parsed=cache[pattern]
- if parsed then
- lpathcalls=lpathcalls+1
- lpathcached=lpathcached+1
- elseif type(pattern)=="table" then
- lpathcalls=lpathcalls+1
- parsed=pattern
- else
- parsed=lpath(pattern) or pattern
- end
- if not parsed then
- lastmatch=nil
- return
- end
- local nofparsed=#parsed
- if nofparsed==0 then
- lastmatch=nil
- return
- end
- local collected=apply({ list },parsed,nofparsed,list.mi)
- lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ local function traced_apply(list,parsed,nofparsed,order)
+ if trace_lparse then
+ lshow(parsed)
+ end
+ report_lpath("collecting: %s",parsed.pattern)
+ report_lpath("root tags : %s",tagstostring(list))
+ report_lpath("order : %s",order or "unset")
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
return collected
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+ return collected
+ end
+ return nil
+ end
end
- function xml.lastmatch()
- return lastmatch
- end
- local stack={}
- function xml.pushmatch()
- insert(stack,lastmatch)
- end
- function xml.popmatch()
- lastmatch=remove(stack)
+ return collected
+ end
+ local function normal_apply(list,parsed,nofparsed,order)
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ local axis=pi.axis
+ if axis~="self" then
+ collected=apply_axis[axis](collected)
+ end
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ return pi.finalizer(collected)
+ end
+ if not collected or #collected==0 then
+ local pf=i<nofparsed and parsed[nofparsed].finalizer
+ if pf then
+ return pf(collected)
+ end
+ return nil
+ end
end
+ return collected
+ end
+ local apply=normal_apply
+ if trackers then
+ trackers.register("xml.path,xml.parse,xml.profile",function()
+ if trace_lprofile then
+ apply=profiled_apply
+ elseif trace_lpath then
+ apply=traced_apply
+ else
+ apply=normal_apply
+ end
+ end)
+ end
+ function xml.applylpath(list,pattern)
+ if not list then
+ lastmatch=nil
+ return
+ end
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcalls=lpathcalls+1
+ lpathcached=lpathcached+1
+ elseif type(pattern)=="table" then
+ lpathcalls=lpathcalls+1
+ parsed=pattern
+ else
+ parsed=lpath(pattern) or pattern
+ end
+ if not parsed then
+ lastmatch=nil
+ return
+ end
+ local nofparsed=#parsed
+ if nofparsed==0 then
+ lastmatch=nil
+ return
+ end
+ local collected=apply({ list },parsed,nofparsed,list.mi)
+ lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ function xml.lastmatch()
+ return lastmatch
+ end
+ local stack={}
+ function xml.pushmatch()
+ insert(stack,lastmatch)
+ end
+ function xml.popmatch()
+ lastmatch=remove(stack)
+ end
end
local applylpath=xml.applylpath
function xml.filter(root,pattern)
- return applylpath(root,pattern)
+ return applylpath(root,pattern)
end
expressions.child=function(e,pattern)
- return applylpath(e,pattern)
+ return applylpath(e,pattern)
end
expressions.count=function(e,pattern)
- local collected=applylpath(e,pattern)
- return pattern and (collected and #collected) or 0
+ local collected=applylpath(e,pattern)
+ return pattern and (collected and #collected) or 0
end
expressions.oneof=function(s,...)
- for i=1,select("#",...) do
- if s==select(i,...) then
- return true
- end
+ for i=1,select("#",...) do
+ if s==select(i,...) then
+ return true
end
- return false
+ end
+ return false
end
expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
+ xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
+ return false
end
expressions.undefined=function(s)
- return s==nil
+ return s==nil
end
expressions.quit=function(s)
- if s or s==nil then
- quit_expression=true
- end
- return true
+ if s or s==nil then
+ quit_expression=true
+ end
+ return true
end
expressions.print=function(...)
- print(...)
- return true
+ print(...)
+ return true
end
expressions.find=find
expressions.upper=upper
@@ -14491,233 +18053,238 @@ expressions.lower=lower
expressions.number=tonumber
expressions.boolean=toboolean
function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
- if find(str,pattern) then
- return true
- end
- elseif t=="table" then
- for i=1,#str do
- local d=str[i]
- if type(d)=="string" and find(d,pattern) then
- return true
- end
- end
+ local t=type(str)
+ if t=="string" then
+ if find(str,pattern) then
+ return true
end
- return false
+ elseif t=="table" then
+ for i=1,#str do
+ local d=str[i]
+ if type(d)=="string" and find(d,pattern) then
+ return true
+ end
+ end
+ end
+ return false
end
function xml.expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
+ return type(str)=="string" and gsub(str,"^#","") or ""
end
local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local r=e.__p__
- handle(r,r.dt,e.ni)
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local r=e.__p__
+ handle(r,r.dt,e.ni)
end
+ end
end
local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- if handle then
- for c=1,#collected do
- handle(collected[c])
- end
- else
- return collected
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ if handle then
+ for c=1,#collected do
+ handle(collected[c])
+ end
+ else
+ return collected
end
+ end
end
-xml.traverse=traverse
+xml.traverse=traverse
xml.selection=selection
local function dofunction(collected,fnc,...)
- if collected then
- local f=functions[fnc]
- if f then
- for c=1,#collected do
- f(collected[c],...)
- end
- else
- report_lpath("unknown function %a",fnc)
- end
+ if collected then
+ local f=functions[fnc]
+ if f then
+ for c=1,#collected do
+ f(collected[c],...)
+ end
+ else
+ report_lpath("unknown function %a",fnc)
end
+ end
end
finalizers.xml["function"]=dofunction
finalizers.tex["function"]=dofunction
expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
+ local rdt=e.__p__.dt
+ return rdt and rdt[n] or ""
end
expressions.name=function(e,n)
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=type(e)=="table" and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=type(e)=="table" and e
+ elseif n<0 then
+ 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
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
end
+ end
end
- if found then
- local ns,tg=found.rn or found.ns or "",found.tg
- if ns~="" then
- return ns..":"..tg
+ else
+ 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
+ if n==1 then
+ found=di
+ break
else
- return tg
+ n=n-1
end
+ end
+ end
+ end
+ if found then
+ local ns=found.rn or found.ns or ""
+ local tg=found.tg
+ if ns~="" then
+ return ns..":"..tg
else
- return ""
+ return tg
end
+ else
+ return ""
+ end
end
expressions.tag=function(e,n)
- if not e then
- return ""
+ if not e then
+ return ""
+ else
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=(type(e)=="table") and e
+ elseif n<0 then
+ 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
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
+ end
+ end
+ end
else
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=(type(e)=="table") and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
+ 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
+ if n==1 then
+ found=di
+ break
+ else
+ n=n-1
+ end
end
- return (found and found.tg) or ""
+ end
end
+ return (found and found.tg) or ""
+ end
end
local dummy=function() end
function xml.elements(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
+ end
end
function xml.collected(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ return collected[c]
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- return collected[c]
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- return collected[c]
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ return collected[c]
+ end
end
+ end
end
function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
- report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
+ pattern=pattern or "."
+ for e in xml.collected(collection,pattern or ".") do
+ report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+ end
end
local function split(e)
- local dt=e.dt
- if dt then
- for i=1,#dt do
- local dti=dt[i]
- if type(dti)=="string" then
- dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti=gsub(dti,"[\n\r]+","\n\n")
- dt[i]=dti
- else
- split(dti)
- end
- end
+ local dt=e.dt
+ if dt then
+ for i=1,#dt do
+ local dti=dt[i]
+ if type(dti)=="string" then
+ dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+ dti=gsub(dti,"[\n\r]+","\n\n")
+ dt[i]=dti
+ else
+ split(dti)
+ end
end
- return e
+ end
+ return e
end
function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
+ for i=1,#c do
+ split(c[i])
+ end
+ return c
end
@@ -14727,14 +18294,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
--- original size: 3574, stripped down to: 1863
+-- original size: 3574, stripped down to: 1808
if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local xml,lpeg,string=xml,lpeg,string
local type=type
@@ -14745,26 +18312,26 @@ local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs
lpegpatterns.xml=lpegpatterns.xml or {}
local xmlpatterns=lpegpatterns.xml
local function xmlgsub(t,old,new)
- local dt=t.dt
- if dt then
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="string" then
- dt[k]=gsub(v,old,new)
- else
- xmlgsub(v,old,new)
- end
- end
+ local dt=t.dt
+ if dt then
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="string" then
+ dt[k]=gsub(v,old,new)
+ else
+ xmlgsub(v,old,new)
+ end
end
+ end
end
function xml.stripleadingspaces(dk,d,k)
- if d and k then
- local dkm=d[k-1]
- if dkm and type(dkm)=="string" then
- local s=match(dkm,"\n(%s+)")
- xmlgsub(dk,"\n"..rep(" ",#s),"\n")
- end
+ if d and k then
+ local dkm=d[k-1]
+ if dkm and type(dkm)=="string" then
+ local s=match(dkm,"\n(%s+)")
+ xmlgsub(dk,"\n"..rep(" ",#s),"\n")
end
+ end
end
local normal=(1-S("<&>"))^0
local special=P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"
@@ -14776,17 +18343,17 @@ local cleansed=Cs(((P("<")*(1-P(">"))^0*P(">"))/""+1)^0)
xmlpatterns.escaped=escaped
xmlpatterns.unescaped=unescaped
xmlpatterns.cleansed=cleansed
-function xml.escaped (str) return lpegmatch(escaped,str) end
+function xml.escaped (str) return lpegmatch(escaped,str) end
function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str) end
+function xml.cleansed (str) return lpegmatch(cleansed,str) end
function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
- local n=#e.dt
- if not check or n==0 or (n==1 and e.dt[1]=="") then
- e.dt={ str }
- end
+ local e=xml.first(root,pattern)
+ if e then
+ local n=#e.dt
+ if not check or n==0 or (n==1 and e.dt[1]=="") then
+ e.dt={ str }
end
+ end
end
@@ -14796,17 +18363,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
--- original size: 30650, stripped down to: 21793
+-- original size: 30771, stripped down to: 19680
if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
+local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
+local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
local report_xml=logs.reporter("xml")
local xml=xml
local xmlcopy,xmlname=xml.copy,xml.name
@@ -14819,308 +18386,313 @@ local utfbyte=utf.byte
local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
local striplinepatterns=utilities.strings.striplinepatterns
local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
+ report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
end
local function withelements(e,handle,depth)
- if e and handle then
- local edt=e.dt
- if edt then
- depth=depth or 0
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- handle(e,depth)
- withelements(e,handle,depth+1)
- end
- end
+ if e and handle then
+ local edt=e.dt
+ if edt then
+ depth=depth or 0
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ handle(e,depth)
+ withelements(e,handle,depth+1)
end
+ end
end
+ end
end
xml.withelements=withelements
function xml.withelement(e,n,handle)
- if e and n~=0 and handle then
- local edt=e.dt
- if edt then
- if n>0 then
- for i=1,#edt do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==1 then
- handle(ei)
- return
- else
- n=n-1
- end
- end
- end
- elseif n<0 then
- for i=#edt,1,-1 do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==-1 then
- handle(ei)
- return
- else
- n=n+1
- end
- end
- end
+ if e and n~=0 and handle then
+ local edt=e.dt
+ if edt then
+ if n>0 then
+ for i=1,#edt do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==1 then
+ handle(ei)
+ return
+ else
+ n=n-1
end
+ end
end
- end
-end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- if handle then
- if reverse then
- for c=#collected,1,-1 do
- handle(collected[c])
- end
+ elseif n<0 then
+ for i=#edt,1,-1 do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==-1 then
+ handle(ei)
+ return
else
- for c=1,#collected do
- handle(collected[c])
- end
+ n=n+1
end
+ end
end
- return collected
+ end
end
+ end
end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
+function xml.each(root,pattern,handle,reverse)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ if handle then
+ if reverse then
+ for c=#collected,1,-1 do
+ handle(collected[c])
+ end
+ else
for c=1,#collected do
- handle(collected[c].at)
+ handle(collected[c])
end
+ end
end
return collected
+ end
+end
+function xml.processattributes(root,pattern,handle)
+ local collected=xmlapplylpath(root,pattern)
+ if collected and handle then
+ for c=1,#collected do
+ handle(collected[c].at)
+ end
+ end
+ return collected
end
function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
+ return xmlapplylpath(root,pattern)
end
function xml.collecttexts(root,pattern,flatten)
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
- local xmltostring=xml.tostring
- for c=1,#collected do
- collected[c]=xmltostring(collected[c].dt)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected and flatten then
+ local xmltostring=xml.tostring
+ for c=1,#collected do
+ collected[c]=xmltostring(collected[c].dt)
end
- return collected or {}
+ end
+ return collected or {}
end
function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- local t,n={},0
- for c=1,#collected do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace then
- t[n]=tg
- elseif ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ local t={}
+ local n=0
+ for c=1,#collected do
+ local e=collected[c]
+ local ns=e.ns
+ local tg=e.tg
+ n=n+1
+ if nonamespace then
+ t[n]=tg
+ elseif ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
+ end
end
+ return t
+ end
end
local no_root={ no_root=true }
local function redo_ni(d)
- for k=1,#d do
- local dk=d[k]
- if type(dk)=="table" then
- dk.ni=k
- end
+ for k=1,#d do
+ local dk=d[k]
+ if type(dk)=="table" then
+ dk.ni=k
end
+ end
end
xml.reindex=redo_ni
local function xmltoelement(whatever,root)
- if not whatever then
- return nil
- end
- local element
- if type(whatever)=="string" then
- element=xmlinheritedconvert(whatever,root)
- else
- element=whatever
- end
- if element.error then
- return whatever
- end
- if element then
- end
- return element
+ if not whatever then
+ return nil
+ end
+ local element
+ if type(whatever)=="string" then
+ element=xmlinheritedconvert(whatever,root)
+ else
+ element=whatever
+ end
+ if element.error then
+ return whatever
+ end
+ if element then
+ end
+ return element
end
xml.toelement=xmltoelement
local function copiedelement(element,newparent)
- if type(element)=="string" then
- return element
- else
- element=xmlcopy(element).dt
- if newparent and type(element)=="table" then
- element.__p__=newparent
- end
- return element
+ if type(element)=="string" then
+ return element
+ else
+ element=xmlcopy(element).dt
+ if newparent and type(element)=="table" then
+ element.__p__=newparent
end
+ return element
+ end
end
function xml.delete(root,pattern)
- if not pattern or pattern=="" then
- local p=root.__p__
+ if not pattern or pattern=="" then
+ local p=root.__p__
+ if p then
+ if trace_manipulations then
+ report('deleting',"--",c,root)
+ end
+ local d=p.dt
+ remove(d,root.ni)
+ redo_ni(d)
+ end
+ else
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
if p then
- if trace_manipulations then
- report('deleting',"--",c,root)
- end
- local d=p.dt
- remove(d,root.ni)
- redo_ni(d)
- end
- else
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('deleting',pattern,c,e)
- end
- local d=p.dt
- local ni=e.ni
- if ni<=#d then
- if false then
- p.dt[ni]=""
- else
- remove(d,ni)
- redo_ni(d)
- end
- else
- end
- end
+ if trace_manipulations then
+ report('deleting',pattern,c,e)
+ end
+ local d=p.dt
+ local ni=e.ni
+ if ni<=#d then
+ if false then
+ p.dt[ni]=""
+ else
+ remove(d,ni)
+ redo_ni(d)
end
+ else
+ end
end
+ end
end
+ end
end
function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('replacing',pattern,c,e)
- end
- local d=p.dt
- local n=e.ni
- local t=copiedelement(element,p)
- if type(t)=="table" then
- d[n]=t[1]
- for i=2,#t do
- n=n+1
- insert(d,n,t[i])
- end
- else
- d[n]=t
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
+ if p then
+ if trace_manipulations then
+ report('replacing',pattern,c,e)
+ end
+ local d=p.dt
+ local n=e.ni
+ local t=copiedelement(element,p)
+ if type(t)=="table" then
+ d[n]=t[1]
+ for i=2,#t do
+ n=n+1
+ insert(d,n,t[i])
+ end
+ else
+ d[n]=t
end
+ redo_ni(d)
+ end
end
+ end
end
local function wrap(e,wrapper)
- local t={
- rn=e.rn,
- tg=e.tg,
- ns=e.ns,
- at=e.at,
- dt=e.dt,
- __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
+ local t={
+ rn=e.rn,
+ tg=e.tg,
+ ns=e.ns,
+ at=e.at,
+ dt=e.dt,
+ __p__=e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn=wrapper.rn or e.rn or ""
+ e.tg=wrapper.tg or e.tg or ""
+ e.ns=wrapper.ns or e.ns or ""
+ e.at=fastcopy(wrapper.at)
+ e.dt={ t }
end
function xml.wrap(root,pattern,whatever)
- if whatever then
- local wrapper=xmltoelement(whatever,root)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if trace_manipulations then
- report('wrapping',pattern,c,e)
- end
- wrap(e,wrapper)
- end
+ if whatever then
+ local wrapper=xmltoelement(whatever,root)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
end
- else
- wrap(root,xmltoelement(pattern))
+ wrap(e,wrapper)
+ end
end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
end
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 edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
- if edt then
- local be,af
- local cp=copiedelement(element,e)
- if prepend then
- be,af=cp,edt
- else
- be,af=edt,cp
- end
- local bn=#be
- for i=1,#af do
- bn=bn+1
- be[bn]=af[i]
- end
- if rri then
- r.dt[rri].dt=be
- else
- d[k].dt=be
- end
- redo_ni(d)
- end
+ 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=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
+ local cp=copiedelement(element,e)
+ if prepend then
+ be,af=cp,edt
+ else
+ be,af=edt,cp
+ end
+ local bn=#be
+ for i=1,#af do
+ bn=bn+1
+ be[bn]=af[i]
+ end
+ if rri then
+ r.dt[rri].dt=be
+ else
+ d[k].dt=be
+ end
+ redo_ni(d)
end
- if not collected then
- elseif collected.tg then
- inject_e(collected)
- else
- for c=1,#collected do
- inject_e(collected[c])
- end
+ end
+ if not collected then
+ elseif collected.tg then
+ inject_e(collected)
+ else
+ for c=1,#collected do
+ inject_e(collected[c])
end
+ end
end
local function insert_element(root,pattern,whatever,before)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
- local r=e.__p__
- local d,k=r.dt,e.ni
- if not before then
- k=k+1
- end
- insert(d,k,copiedelement(element,r))
- redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
- insert_e(collected)
- else
- for c=1,#collected do
- insert_e(collected[c])
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function insert_e(e)
+ local r=e.__p__
+ local d=r.dt
+ local k=e.ni
+ if not before then
+ k=k+1
+ end
+ insert(d,k,copiedelement(element,r))
+ redo_ni(d)
+ end
+ if not collected then
+ elseif collected.tg then
+ insert_e(collected)
+ else
+ for c=1,#collected do
+ insert_e(collected[c])
end
+ end
end
xml.insert_element=insert_element
xml.insertafter=insert_element
@@ -15128,124 +18700,124 @@ xml.insertbefore=function(r,p,e) insert_element(r,p,e,true) end
xml.injectafter=inject_element
xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
- if not level then
- level=1
- end
- for c=1,#collected do
- local ek=collected[c]
- local name=nil
- local ekdt=ek.dt
- if ekdt then
- local ekat=ek.at
- local ekrt=ek.__p__
- if ekrt then
- local epdt=ekrt.dt
- if not attribute or attribute=="" then
- name=(type(ekdt)=="table" and ekdt[1]) or ekdt
- end
- if not name then
- for a in gmatch(attribute or "href","([^|]+)") do
- name=ekat[a]
- if name then
- break
- end
- end
- end
- local data=nil
- if name and name~="" then
- local d,n=loaddata(name)
- data=d or ""
- name=n or name
- if trace_inclusions then
- report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
- end
- end
- if not data or data=="" then
- epdt[ek.ni]=""
- elseif ekat["parse"]=="text" then
- epdt[ek.ni]=xml.escaped(data)
- else
+ pattern=pattern or 'include'
+ loaddata=loaddata or io.loaddata
+ local collected=xmlapplylpath(xmldata,pattern)
+ if collected then
+ if not level then
+ level=1
+ end
+ for c=1,#collected do
+ local ek=collected[c]
+ local name=nil
+ local ekdt=ek.dt
+ if ekdt then
+ local ekat=ek.at
+ local ekrt=ek.__p__
+ if ekrt then
+ local epdt=ekrt.dt
+ if not attribute or attribute=="" then
+ name=(type(ekdt)=="table" and ekdt[1]) or ekdt
+ end
+ if not name then
+ for a in gmatch(attribute or "href","([^|]+)") do
+ name=ekat[a]
+ if name then
+ break
+ end
+ end
+ end
+ local data=nil
+ if name and name~="" then
+ local d,n=loaddata(name)
+ data=d or ""
+ name=n or name
+ if trace_inclusions then
+ report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
+ end
+ end
+ if not data or data=="" then
+ epdt[ek.ni]=""
+ elseif ekat["parse"]=="text" then
+ epdt[ek.ni]=xml.escaped(data)
+ else
local settings=xmldata.settings
local savedresource=settings.currentresource
settings.currentresource=name
- local xi=xmlinheritedconvert(data,xmldata)
- if not xi then
- epdt[ek.ni]=""
- else
- if recursive then
- include(xi,pattern,attribute,recursive,loaddata,level+1)
- end
- local child=xml.body(xi)
- child.__p__=ekrt
- child.__f__=name
+ local xi=xmlinheritedconvert(data,xmldata)
+ if not xi then
+ epdt[ek.ni]=""
+ else
+ if recursive then
+ include(xi,pattern,attribute,recursive,loaddata,level+1)
+ end
+ local child=xml.body(xi)
+ child.__p__=ekrt
+ child.__f__=name
child.cf=name
- epdt[ek.ni]=child
- local settings=xmldata.settings
- local inclusions=settings and settings.inclusions
- if inclusions then
- inclusions[#inclusions+1]=name
- elseif settings then
- settings.inclusions={ name }
- else
- settings={ inclusions={ name } }
- xmldata.settings=settings
- end
- if child.er then
- local badinclusions=settings.badinclusions
- if badinclusions then
- badinclusions[#badinclusions+1]=name
- else
- settings.badinclusions={ name }
- end
- end
- end
-settings.currentresource=savedresource
- end
+ epdt[ek.ni]=child
+ local settings=xmldata.settings
+ local inclusions=settings and settings.inclusions
+ if inclusions then
+ inclusions[#inclusions+1]=name
+ elseif settings then
+ settings.inclusions={ name }
+ else
+ settings={ inclusions={ name } }
+ xmldata.settings=settings
+ end
+ if child.er then
+ local badinclusions=settings.badinclusions
+ if badinclusions then
+ badinclusions[#badinclusions+1]=name
+ else
+ settings.badinclusions={ name }
end
+ end
end
+settings.currentresource=savedresource
+ end
end
+ end
end
+ end
end
xml.include=include
function xml.inclusion(e,default)
- while e do
- local f=e.__f__
- if f then
- return f
- else
- e=e.__p__
- end
+ while e do
+ local f=e.__f__
+ if f then
+ return f
+ else
+ e=e.__p__
end
- return default
+ end
+ return default
end
local function getinclusions(key,e,sorted)
- while e do
- local settings=e.settings
- if settings then
- local inclusions=settings[key]
- if inclusions then
- inclusions=table.unique(inclusions)
- if sorted then
- table.sort(inclusions)
- end
- return inclusions
- else
- e=e.__p__
- end
- else
- e=e.__p__
- end
+ while e do
+ local settings=e.settings
+ if settings then
+ local inclusions=settings[key]
+ if inclusions then
+ inclusions=table.unique(inclusions)
+ if sorted then
+ table.sort(inclusions)
+ end
+ return inclusions
+ else
+ e=e.__p__
+ end
+ else
+ e=e.__p__
end
+ end
end
function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
+ return getinclusions("inclusions",e,sorted)
end
function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
+ return getinclusions("badinclusions",e,sorted)
end
local b_collapser=lpegpatterns.b_collapser
local m_collapser=lpegpatterns.m_collapser
@@ -15254,194 +18826,194 @@ local b_stripper=lpegpatterns.b_stripper
local m_stripper=lpegpatterns.m_stripper
local e_stripper=lpegpatterns.e_stripper
local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
- local n=#edt
- if n==0 then
- return e
- elseif anywhere then
- local t={}
- local m=0
- for e=1,n do
- local str=edt[e]
- if type(str)~="string" then
- m=m+1
- t[m]=str
- elseif str~="" then
- if nolines then
- str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
- else
- str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
- end
- if str~="" then
- m=m+1
- t[m]=str
- end
- end
- end
- e.dt=t
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==0 then
+ return e
+ elseif anywhere then
+ local t={}
+ local m=0
+ for e=1,n do
+ local str=edt[e]
+ if type(str)~="string" then
+ m=m+1
+ t[m]=str
+ elseif str~="" then
+ if nolines then
+ str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
+ else
+ str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
+ end
+ if str~="" then
+ m=m+1
+ t[m]=str
+ end
+ end
+ end
+ e.dt=t
+ else
+ local str=edt[1]
+ if type(str)=="string" then
+ if str~="" then
+ str=lpegmatch(nolines and b_collapser or b_stripper,str)
+ end
+ if str=="" then
+ remove(edt,1)
+ n=n-1
else
- local str=edt[1]
- if type(str)=="string" then
- if str~="" then
- str=lpegmatch(nolines and b_collapser or b_stripper,str)
- end
- if str=="" then
- remove(edt,1)
- n=n-1
- else
- edt[1]=str
- end
- end
- if n>0 then
- str=edt[n]
- if type(str)=="string" then
- if str=="" then
- remove(edt)
- else
- str=lpegmatch(nolines and e_collapser or e_stripper,str)
- if str=="" then
- remove(edt)
- else
- edt[n]=str
- end
- end
- end
+ edt[1]=str
+ end
+ end
+ if n>0 then
+ str=edt[n]
+ if type(str)=="string" then
+ if str=="" then
+ remove(edt)
+ else
+ str=lpegmatch(nolines and e_collapser or e_stripper,str)
+ if str=="" then
+ remove(edt)
+ else
+ edt[n]=str
end
+ end
end
+ end
end
- return e
+ end
+ return e
end
xml.stripelement=stripelement
function xml.strip(root,pattern,nolines,anywhere)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for i=1,#collected do
- stripelement(collected[i],nolines,anywhere)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for i=1,#collected do
+ stripelement(collected[i],nolines,anywhere)
end
+ end
end
local function renamespace(root,oldspace,newspace)
- local ndt=#root.dt
- for i=1,ndt or 0 do
- local e=root[i]
- if type(e)=="table" then
- if e.ns==oldspace then
- e.ns=newspace
- if e.rn then
- e.rn=newspace
- end
- end
- local edt=e.dt
- if edt then
- renamespace(edt,oldspace,newspace)
- end
+ local ndt=#root.dt
+ for i=1,ndt or 0 do
+ local e=root[i]
+ if type(e)=="table" then
+ if e.ns==oldspace then
+ e.ns=newspace
+ if e.rn then
+ e.rn=newspace
end
+ end
+ local edt=e.dt
+ if edt then
+ renamespace(edt,oldspace,newspace)
+ end
end
+ end
end
xml.renamespace=renamespace
function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].tg=newtg
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].tg=newtg
end
+ end
end
function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].ns=newns
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].ns=newns
end
+ end
end
function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if (not e.rn or e.rn=="") and e.ns=="" then
- e.rn=newns
- end
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if (not e.rn or e.rn=="") and e.ns=="" then
+ e.rn=newns
+ end
end
+ end
end
function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- e.tg,e.ns,e.rn=newtg,newns,newrn
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ e.tg,e.ns,e.rn=newtg,newns,newrn
end
+ end
end
function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
- local first=dt[1]
- if first.tg=="@cd@" then
- e.dt=first.dt
- end
- else
+ local dt=e.dt
+ if #dt==1 then
+ local first=dt[1]
+ if first.tg=="@cd@" then
+ e.dt=first.dt
end
+ else
+ end
end
function xml.texttocdata(e)
- local dt=e.dt
- local s=xml.tostring(dt)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(dt)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
function xml.elementtocdata(e)
- local dt=e.dt
- local s=xml.tostring(e)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(e)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" }
local entities=characters and characters.entities or nil
local builtinentities=xml.builtinentities
function xml.addentitiesdoctype(root,option)
- if not entities then
- require("char-ent")
- entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
- local list={}
- local hexify=option=="hexadecimal"
- for k,v in table.sortedhash(root.statistics.entities.names) do
- if not builtinentities[k] then
- local e=entities[k]
- if not e then
- e=format("[%s]",k)
- elseif hexify then
- e=format("&#%05X;",utfbyte(k))
- end
- list[#list+1]=format(" <!ENTITY %s %q >",k,e)
- end
- end
- local dt=root.dt
- local n=dt[1].tg=="@pi@" and 2 or 1
- if #list>0 then
- insert(dt,n,{ "\n" })
- insert(dt,n,{
- tg="@dt@",
- dt={ format("Something [\n%s\n] ",concat(list)) },
- ns="",
- special=true,
- })
- insert(dt,n,{ "\n\n" })
- else
- end
+ if not entities then
+ require("char-ent")
+ entities=characters.entities
+ end
+ if entities and root and root.tg=="@rt@" and root.statistics then
+ local list={}
+ local hexify=option=="hexadecimal"
+ for k,v in table.sortedhash(root.statistics.entities.names) do
+ if not builtinentities[k] then
+ local e=entities[k]
+ if not e then
+ e=format("[%s]",k)
+ elseif hexify then
+ e=format("&#%05X;",utfbyte(k))
+ end
+ list[#list+1]=format(" <!ENTITY %s %q >",k,e)
+ end
end
+ local dt=root.dt
+ local n=dt[1].tg=="@pi@" and 2 or 1
+ if #list>0 then
+ insert(dt,n,{ "\n" })
+ insert(dt,n,{
+ tg="@dt@",
+ dt={ format("Something [\n%s\n] ",concat(list)) },
+ ns="",
+ special=true,
+ })
+ insert(dt,n,{ "\n\n" })
+ else
+ end
+ end
end
xml.all=xml.each
xml.insert=xml.insertafter
@@ -15451,239 +19023,241 @@ xml.before=xml.insertbefore
xml.process=xml.each
xml.obsolete=xml.obsolete or {}
local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace obsolete.replace_element=xml.replace
-xml.each_element=xml.each obsolete.each_element=xml.each
-xml.process_elements=xml.process obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
+xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
+xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
+xml.delete_element=xml.delete obsolete.delete_element=xml.delete
+xml.replace_element=xml.replace obsolete.replace_element=xml.replace
+xml.each_element=xml.each obsolete.each_element=xml.each
+xml.process_elements=xml.process obsolete.process_elements=xml.process
+xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
+xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
+xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
+xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
+xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
+xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
+xml.inject_element=xml.inject obsolete.inject_element=xml.inject
+xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
+xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
+xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
function xml.cdata(e)
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
end
- return ""
+ end
+ return ""
end
function xml.finalizers.xml.cdata(collected)
- if collected then
- local e=collected[1]
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
+ if collected then
+ local e=collected[1]
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
+ end
end
- return ""
+ end
+ return ""
end
function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.setcomment(e,str,n)
- e.dt={ {
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.setcdata(e,str)
- e.dt={ {
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local d=e.dt
- if d==x then
- report_xml("warning: xml.separate changes root")
- x=d
- end
- local t,n={ "\n" },1
- local i,nd=1,#d
- while i<=nd do
- while i<=nd do
- local di=d[i]
- if type(di)=="string" then
- if di=="\n" or find(di,"^%s+$") then
- i=i+1
- else
- d[i]=strip(di)
- break
- end
- else
- break
- end
- end
- if i>nd then
- break
- end
- t[n+1]="\n"
- t[n+2]=d[i]
- t[n+3]="\n"
- n=n+3
- i=i+1
+ local collected=xmlapplylpath(x,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local d=e.dt
+ if d==x then
+ report_xml("warning: xml.separate changes root")
+ x=d
+ end
+ local t={ "\n" }
+ local n=1
+ local i=1
+ local nd=#d
+ while i<=nd do
+ while i<=nd do
+ local di=d[i]
+ if type(di)=="string" then
+ if di=="\n" or find(di,"^%s+$") then
+ i=i+1
+ else
+ d[i]=strip(di)
+ break
end
- t[n+1]="\n"
- setmetatable(t,getmetatable(d))
- e.dt=t
+ else
+ break
+ end
+ end
+ if i>nd then
+ break
end
+ t[n+1]="\n"
+ t[n+2]=d[i]
+ t[n+3]="\n"
+ n=n+3
+ i=i+1
+ end
+ t[n+1]="\n"
+ setmetatable(t,getmetatable(d))
+ e.dt=t
end
- return x
+ end
+ return x
end
local helpers=xml.helpers or {}
xml.helpers=helpers
local function normal(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)=="string" and str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)=="string" and str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
local function recurse(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)~="string" then
- recurse(str,action)
- elseif str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)~="string" then
+ recurse(str,action)
+ elseif str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
function helpers.recursetext(collected,action,recursive)
- if recursive then
- for i=1,#collected do
- recurse(collected[i],action)
- end
- else
- for i=1,#collected do
- normal(collected[i],action)
- end
+ if recursive then
+ for i=1,#collected do
+ recurse(collected[i],action)
end
+ else
+ for i=1,#collected do
+ normal(collected[i],action)
+ end
+ end
end
local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
+ ["@rt@"]="root",
+ ["@pi@"]="instruction",
+ ["@cm@"]="comment",
+ ["@dt@"]="declaration",
+ ["@cd@"]="cdata",
}
local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
- [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
- _namespace=ns~="" and ns or nil,
- _tag=not x.special and tg or nil,
- _type=specials[tg] or "_element",
- }
- if at then
- for k,v in next,at do
- node[k]=v
- end
- end
- local n=0
- for i=1,#dt do
- local di=dt[i]
- if type(di)=="table" then
- if flat and di.special then
- else
- di=convert(di,strip,flat)
- if di then
- n=n+1
- node[n]=di
- end
- end
- elseif strip then
- di=lpegmatch(strip,di)
- if di~="" then
- n=n+1
- node[n]=di
- end
- else
- n=n+1
- node[n]=di
+ local ns=x.ns
+ local tg=x.tg
+ local at=x.at
+ local dt=x.dt
+ local node=flat and {
+ [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
+ } or {
+ _namespace=ns~="" and ns or nil,
+ _tag=not x.special and tg or nil,
+ _type=specials[tg] or "_element",
+ }
+ if at then
+ for k,v in next,at do
+ node[k]=v
+ end
+ end
+ local n=0
+ for i=1,#dt do
+ local di=dt[i]
+ if type(di)=="table" then
+ if flat and di.special then
+ else
+ di=convert(di,strip,flat)
+ if di then
+ n=n+1
+ node[n]=di
end
+ end
+ elseif strip then
+ di=lpegmatch(strip,di)
+ if di~="" then
+ n=n+1
+ node[n]=di
+ end
+ else
+ n=n+1
+ node[n]=di
end
- if next(node) then
- return node
- end
+ end
+ if next(node) then
+ return node
+ end
end
function xml.totable(x,strip,flat)
- if type(x)=="table" then
- if strip then
- strip=striplinepatterns[strip]
- end
- return convert(x,strip,flat)
+ if type(x)=="table" then
+ if strip then
+ strip=striplinepatterns[strip]
end
+ return convert(x,strip,flat)
+ end
end
function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
- return
- end
- if type(name)=="table" then
- attributes=name
- name=namespace
- namespace=""
- elseif type(name)~="string" then
- attributes={}
- name=namespace
- namespace=""
- end
- if type(attributes)~="table" then
- attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
+ if type(e)~="table" or not e.tg then
+ return
+ end
+ if type(name)=="table" then
+ attributes=name
+ name=namespace
+ namespace=""
+ elseif type(name)~="string" then
+ attributes={}
+ name=namespace
+ namespace=""
+ end
+ if type(attributes)~="table" then
+ attributes={}
+ end
+ e.ns=namespace
+ e.rn=namespace
+ e.tg=name
+ e.at=attributes
end
@@ -15693,14 +19267,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 11096, stripped down to: 8243
+-- original size: 11096, stripped down to: 7702
if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber,next=tonumber,next
local concat=table.concat
@@ -15712,241 +19286,241 @@ local xmltostring=xml.tostring
local xmlserialize=xml.serialize
local xmlcollected=xml.collected
local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg
+local reparsedentity=xml.reparsedentitylpeg
local unescapedentity=xml.unescapedentitylpeg
local parsedentity=reparsedentity
local function first(collected)
- return collected and collected[1]
+ return collected and collected[1]
end
local function last(collected)
- return collected and collected[#collected]
+ return collected and collected[#collected]
end
local function all(collected)
- return collected
+ return collected
end
local reverse=table.reversed
local function attribute(collected,name)
- if collected and #collected>0 then
- local at=collected[1].at
- return at and at[name]
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ return at and at[name]
+ end
end
local function att(id,name)
- local at=id.at
- return at and at[name]
+ local at=id.at
+ return at and at[name]
end
local function count(collected)
- return collected and #collected or 0
+ return collected and #collected or 0
end
local function position(collected,n)
- if not collected then
- return 0
- end
- local nc=#collected
- if nc==0 then
- return 0
- end
- n=tonumber(n) or 0
- if n<0 then
- return collected[nc+n+1]
- elseif n>0 then
- return collected[n]
- else
- return collected[1].mi or 0
- end
+ if not collected then
+ return 0
+ end
+ local nc=#collected
+ if nc==0 then
+ return 0
+ end
+ n=tonumber(n) or 0
+ if n<0 then
+ return collected[nc+n+1]
+ elseif n>0 then
+ return collected[n]
+ else
+ return collected[1].mi or 0
+ end
end
local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0
+ return collected and #collected>0 and collected[1].mi or 0
end
local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0
+ return collected and #collected>0 and collected[1].ni or 0
end
local function attributes(collected,arguments)
- if collected and #collected>0 then
- local at=collected[1].at
- if arguments then
- return at[arguments]
- elseif next(at) then
- return at
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ if arguments then
+ return at[arguments]
+ elseif next(at) then
+ return at
end
+ end
end
local function chainattribute(collected,arguments)
- if collected and #collected>0 then
- local e=collected[1]
- while e do
- local at=e.at
- if at then
- local a=at[arguments]
- if a then
- return a
- end
- else
- break
- end
- e=e.__p__
+ if collected and #collected>0 then
+ local e=collected[1]
+ while e do
+ local at=e.at
+ if at then
+ local a=at[arguments]
+ if a then
+ return a
end
+ else
+ break
+ end
+ e=e.__p__
end
- return ""
+ end
+ return ""
end
local function raw(collected)
- if collected and #collected>0 then
- local e=collected[1] or collected
- return e and xmltostring(e) or ""
- else
- return ""
- end
+ if collected and #collected>0 then
+ local e=collected[1] or collected
+ return e and xmltostring(e) or ""
+ else
+ return ""
+ end
end
local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
- result={}
- return result
- end,
- finalize=function()
- return concat(result)
- end,
- handle=function(...)
- result[#result+1]=concat {... }
- end,
- escape=false,
+ name="string",
+ initialize=function()
+ result={}
+ return result
+ end,
+ finalize=function()
+ return concat(result)
+ end,
+ handle=function(...)
+ result[#result+1]=concat {... }
+ end,
+ escape=false,
}
local function xmltotext(root)
- local dt=root.dt
- if not dt then
- return ""
- end
- local nt=#dt
- if nt==0 then
- return ""
- elseif nt==1 and type(dt[1])=="string" then
- return dt[1]
- else
- return xmlserialize(root,xmltexthandler) or ""
- end
+ local dt=root.dt
+ if not dt then
+ return ""
+ end
+ local nt=#dt
+ if nt==0 then
+ return ""
+ elseif nt==1 and type(dt[1])=="string" then
+ return dt[1]
+ else
+ return xmlserialize(root,xmltexthandler) or ""
+ end
end
function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
+ return root and xmlserialize(root,xmltexthandler) or ""
end
local function text(collected)
- if collected then
- local e=collected[1] or collected
- return e and xmltotext(e) or ""
- else
- return ""
- end
+ if collected then
+ local e=collected[1] or collected
+ return e and xmltotext(e) or ""
+ else
+ return ""
+ end
end
local function texts(collected)
- if not collected then
- return {}
- end
- local nc=#collected
- if nc==0 then
- return {}
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- if e and e.dt then
- n=n+1
- t[n]=e.dt
- end
- end
- return t
+ if not collected then
+ return {}
+ end
+ local nc=#collected
+ if nc==0 then
+ return {}
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ if e and e.dt then
+ n=n+1
+ t[n]=e.dt
+ end
+ end
+ return t
end
local function tag(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- return c and c.tg
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ return c and c.tg
end
local function name(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
- return c.tg
- else
- return c.ns..":"..c.tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ if not c then
+ elseif c.ns=="" then
+ return c.tg
+ else
+ return c.ns..":"..c.tg
+ end
end
local function tags(collected,nonamespace)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace or ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace or ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
end
- return t
+ end
+ return t
end
local function empty(collected,spacesonly)
- if not collected then
- return true
- end
- local nc=#collected
- if nc==0 then
- return true
- end
- for c=1,nc do
- local e=collected[c]
- if e then
- local edt=e.dt
- if edt then
- local n=#edt
- if n==1 then
- local edk=edt[1]
- local typ=type(edk)
- if typ=="table" then
- return false
- elseif edk~="" then
- return false
- elseif spacesonly and not find(edk,"%S") then
- return false
- end
- elseif n>1 then
- return false
- end
- end
+ if not collected then
+ return true
+ end
+ local nc=#collected
+ if nc==0 then
+ return true
+ end
+ for c=1,nc do
+ local e=collected[c]
+ if e then
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==1 then
+ local edk=edt[1]
+ local typ=type(edk)
+ if typ=="table" then
+ return false
+ elseif edk~="" then
+ return false
+ elseif spacesonly and not find(edk,"%S") then
+ return false
+ end
+ elseif n>1 then
+ return false
end
+ end
end
- return true
+ end
+ return true
end
finalizers.first=first
finalizers.last=last
@@ -15969,124 +19543,124 @@ finalizers.name=name
finalizers.tags=tags
finalizers.empty=empty
function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
+ return first(xmlfilter(id,pattern))
end
function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
+ return last(xmlfilter(id,pattern))
end
function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
+ return count(xmlfilter(id,pattern))
end
function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
+ return attribute(xmlfilter(id,pattern),a,default)
end
function xml.raw(id,pattern)
- if pattern then
- return raw(xmlfilter(id,pattern))
- else
- return raw(id)
- end
+ if pattern then
+ return raw(xmlfilter(id,pattern))
+ else
+ return raw(id)
+ end
end
function xml.text(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
- return xmltotext(id) or ""
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ return collected and #collected>0 and xmltotext(collected[1]) or ""
+ elseif id then
+ return xmltotext(id) or ""
+ else
+ return ""
+ end
end
function xml.pure(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- if collected and #collected>0 then
- parsedentity=unescapedentity
- local s=collected and #collected>0 and xmltotext(collected[1]) or ""
- parsedentity=reparsedentity
- return s
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ if collected and #collected>0 then
+ parsedentity=unescapedentity
+ local s=collected and #collected>0 and xmltotext(collected[1]) or ""
+ parsedentity=reparsedentity
+ return s
else
- parsedentity=unescapedentity
- local s=xmltotext(id) or ""
- parsedentity=reparsedentity
- return s
+ return ""
end
+ else
+ parsedentity=unescapedentity
+ local s=xmltotext(id) or ""
+ parsedentity=reparsedentity
+ return s
+ end
end
xml.content=text
function xml.position(id,pattern,n)
- return position(xmlfilter(id,pattern),n)
+ return position(xmlfilter(id,pattern),n)
end
function xml.match(id,pattern)
- return match(xmlfilter(id,pattern))
+ return match(xmlfilter(id,pattern))
end
function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
+ return empty(xmlfilter(id,pattern),spacesonly)
end
xml.all=xml.filter
xml.index=xml.position
xml.found=xml.filter
local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
- t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
+ local t={}
+ for e in xmlcollected(x[1] or x,"/*") do
+ t[e.tg]=xmltostring(e.dt) or ""
+ end
+ return next(t) and t or nil
end
xml.table=totable
finalizers.table=totable
local function textonly(e,t)
- if e then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- textonly(e,t)
- else
- t[#t+1]=e
- end
- end
+ if e then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ textonly(e,t)
+ else
+ t[#t+1]=e
end
+ end
end
- return t
+ end
+ return t
end
function xml.textonly(e)
- return concat(textonly(e,{}))
+ return concat(textonly(e,{}))
end
function finalizers.lowerall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=lower(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[lower(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=lower(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[lower(k)]=v
end
+ e.at=t
+ end
end
+ end
end
function finalizers.upperall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=upper(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[upper(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=upper(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[upper(k)]=v
end
+ e.at=t
+ end
end
+ end
end
@@ -16096,14 +19670,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
--- original size: 6407, stripped down to: 4965
+-- original size: 6407, stripped down to: 4640
if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.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 trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local formatters=string.formatters
local reporters=logs.reporters
@@ -16112,152 +19686,152 @@ local xmlcollected=xml.collected
local xmltext=xml.text
local xmlfirst=xml.first
local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
- return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
- local categoryname=category.at.name or ""
- if wantedcategories==true or wantedcategories[categoryname] then
- if nofcategories>1 then
- report("%s options:",categoryname)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for flag in xmlcollected(subcategory,"/flag") do
- local name=flag.at.name
- local value=flag.at.value
- local short=xmltext(xmlfirst(flag,"/short"))
- if value then
- report("--%-20s %s",formatters["%s=%s"](name,value),short)
- else
- report("--%-20s %s",name,short)
- end
- end
- report()
- end
- end
- end
- for category in xmlcollected(root,"/application/examples/category") do
- local title=xmltext(xmlfirst(category,"/title"))
- if title and title~="" then
- report()
- report(title)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for example in xmlcollected(subcategory,"/example") do
- local command=xmltext(xmlfirst(example,"/command"))
- local comment=xmltext(xmlfirst(example,"/comment"))
- report(command)
- end
- report()
- end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
- local comment=xmltext(comment)
+ local root=xml.convert(specification.helpinfo or "")
+ if not root then
+ return
+ end
+ local xs=xml.gethandlers("string")
+ xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
+ xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
+ local wantedcategories=select("#",...)==0 and true or table.tohash {... }
+ local nofcategories=xml.count(root,"/application/flags/category")
+ local report=specification.report
+ for category in xmlcollected(root,"/application/flags/category") do
+ local categoryname=category.at.name or ""
+ if wantedcategories==true or wantedcategories[categoryname] then
+ if nofcategories>1 then
+ report("%s options:",categoryname)
report()
- report(comment)
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for flag in xmlcollected(subcategory,"/flag") do
+ local name=flag.at.name
+ local value=flag.at.value
+ local short=xmltext(xmlfirst(flag,"/short"))
+ if value then
+ report("--%-20s %s",formatters["%s=%s"](name,value),short)
+ else
+ report("--%-20s %s",name,short)
+ end
+ end
report()
+ end
+ end
+ end
+ for category in xmlcollected(root,"/application/examples/category") do
+ local title=xmltext(xmlfirst(category,"/title"))
+ if title and title~="" then
+ report()
+ report(title)
+ report()
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for example in xmlcollected(subcategory,"/example") do
+ local command=xmltext(xmlfirst(example,"/command"))
+ local comment=xmltext(xmlfirst(example,"/comment"))
+ report(command)
+ end
+ report()
end
+ end
+ for comment in xmlcollected(root,"/application/comments/comment") do
+ local comment=xmltext(comment)
+ report()
+ report(comment)
+ report()
+ end
end
local reporthelp=reporters.help
local exporthelp=reporters.export
local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
- return false
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="table" then
+ return false
+ end
+ if type(helpinfo)~="string" then
+ helpinfo="Warning: no helpinfo found."
+ t.helpinfo=helpinfo
+ return false
+ end
+ if string.find(helpinfo,".xml$") then
+ local ownscript=environment.ownscript
+ local helpdata=false
+ if ownscript then
+ local helpfile=file.join(file.pathpart(ownscript),helpinfo)
+ helpdata=io.loaddata(helpfile)
+ if helpdata=="" then
+ helpdata=false
+ end
end
- if type(helpinfo)~="string" then
- helpinfo="Warning: no helpinfo found."
- t.helpinfo=helpinfo
- return false
+ if not helpdata then
+ local helpfile=resolvers.findfile(helpinfo,"tex")
+ helpdata=helpfile and io.loaddata(helpfile)
end
- if string.find(helpinfo,".xml$") then
- local ownscript=environment.ownscript
- local helpdata=false
- if ownscript then
- local helpfile=file.join(file.pathpart(ownscript),helpinfo)
- helpdata=io.loaddata(helpfile)
- if helpdata=="" then
- helpdata=false
- end
- end
- if not helpdata then
- local helpfile=resolvers.findfile(helpinfo,"tex")
- helpdata=helpfile and io.loaddata(helpfile)
- end
- if helpdata and helpdata~="" then
- helpinfo=helpdata
- else
- helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
- end
+ if helpdata and helpdata~="" then
+ helpinfo=helpdata
+ else
+ helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
+ end
+ t.helpinfo=helpinfo
+ return string.find(t.helpinfo,"^<%?xml") and true or false
end
function reporters.help(t,...)
- if xmlfound(t) then
- showhelp(t,...)
- else
- reporthelp(t,...)
- end
+ if xmlfound(t) then
+ showhelp(t,...)
+ else
+ reporthelp(t,...)
+ end
end
function reporters.export(t,methods,filename)
- if not xmlfound(t) then
- return exporthelp(t)
- end
- if not methods or methods=="" then
- methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
- filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
- return exporthelp(t)
- end
- if methods=="all" then
- methods=table.keys(exporters)
- elseif type(methods)=="string" then
- methods=utilities.parsers.settings_to_array(methods)
- else
- return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
- filename=false
- elseif file.pathpart(filename)=="" then
- t.report("export file %a will not be saved on the current path (safeguard)",filename)
- return
- end
- for i=1,#methods do
- local method=methods[i]
- local exporter=exporters[method]
- if exporter then
- local result=exporter(t,method)
- if result and result~="" then
- if filename then
- local fullname=file.replacesuffix(filename,method)
- t.report("saving export in %a",fullname)
- dir.mkdirs(file.pathpart(fullname))
- io.savedata(fullname,result)
- else
- reporters.lines(t,result)
- end
- else
- t.report("no output from exporter %a",method)
- end
+ if not xmlfound(t) then
+ return exporthelp(t)
+ end
+ if not methods or methods=="" then
+ methods=environment.arguments["exporthelp"]
+ end
+ if not filename or filename=="" then
+ filename=environment.files[1]
+ end
+ dofile(resolvers.findfile("trac-exp.lua","tex"))
+ local exporters=logs.exporters
+ if not exporters or not methods then
+ return exporthelp(t)
+ end
+ if methods=="all" then
+ methods=table.keys(exporters)
+ elseif type(methods)=="string" then
+ methods=utilities.parsers.settings_to_array(methods)
+ else
+ return exporthelp(t)
+ end
+ if type(filename)~="string" or filename=="" then
+ filename=false
+ elseif file.pathpart(filename)=="" then
+ t.report("export file %a will not be saved on the current path (safeguard)",filename)
+ return
+ end
+ for i=1,#methods do
+ local method=methods[i]
+ local exporter=exporters[method]
+ if exporter then
+ local result=exporter(t,method)
+ if result and result~="" then
+ if filename then
+ local fullname=file.replacesuffix(filename,method)
+ t.report("saving export in %a",fullname)
+ dir.mkdirs(file.pathpart(fullname))
+ io.savedata(fullname,result)
else
- t.report("unknown exporter %a",method)
+ reporters.lines(t,result)
end
+ else
+ t.report("no output from exporter %a",method)
+ end
+ else
+ t.report("unknown exporter %a",method)
end
+ end
end
@@ -16267,149 +19841,149 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11099, stripped down to: 7516
+-- original size: 11099, stripped down to: 7152
if not modules then modules={} end modules ['data-ini']={
- 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,getmetatable,rawset=next,type,getmetatable,rawset
local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
local report_initialization=logs.reporter("resolvers","initialization")
resolvers=resolvers or {}
local resolvers=resolvers
texconfig.kpse_init=false
texconfig.shell_escape='t'
if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
+ local default_texmfcnf=kpse.default_texmfcnf()
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
+ default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
+ environment.default_texmfcnf=default_texmfcnf
end
kpse={ original=kpse }
setmetatable(kpse,{
- __index=function(kp,name)
- report_initialization("fatal error: kpse library is accessed (key: %s)",name)
- os.exit()
- end
+ __index=function(kp,name)
+ report_initialization("fatal error: kpse library is accessed (key: %s)",name)
+ os.exit()
+ end
} )
do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
- ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
- ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
+ local osfontdir=osgetenv("OSFONTDIR")
+ if osfontdir and osfontdir~="" then
+ elseif osname=="windows" then
+ ossetenv("OSFONTDIR","c:/windows/fonts//")
+ elseif osname=="macosx" then
+ ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+ end
end
do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
- homedir=char(127)
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir)
- ossetenv("USERPROFILE",homedir)
- environment.homedir=homedir
+ local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
+ if not homedir or homedir=="" then
+ homedir=char(127)
+ end
+ homedir=file.collapsepath(homedir)
+ ossetenv("HOME",homedir)
+ ossetenv("USERPROFILE",homedir)
+ environment.homedir=homedir
end
do
- local args=environment.originalarguments or arg
- if not environment.ownmain then
- environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
- ownpath=args[-1] or arg[-1]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- if not ownpath or ownpath=="" then
- ownpath=args[-0] or arg[-0]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- end
- local binary=ownbin
- if not ownpath or ownpath=="" then
- ownpath=ownpath and filedirname(binary)
- end
- if not ownpath or ownpath=="" then
- if os.binsuffix~="" then
- binary=file.replacesuffix(binary,os.binsuffix)
- end
- local path=osgetenv("PATH")
- if path then
- for p in gmatch(path,"[^"..io.pathseparator.."]+") do
- local b=filejoin(p,binary)
- if lfs.isfile(b) then
- local olddir=lfs.currentdir()
- if lfs.chdir(p) then
- local pp=lfs.currentdir()
- if trace_locating and p~=pp then
- report_initialization("following symlink %a to %a",p,pp)
- end
- ownpath=pp
- lfs.chdir(olddir)
- else
- if trace_locating then
- report_initialization("unable to check path %a",p)
- end
- ownpath=p
- end
- break
- end
- end
+ local args=environment.originalarguments or arg
+ if not environment.ownmain then
+ environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
+ end
+ local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
+ local ownpath=environment.ownpath or os.selfdir
+ ownbin=file.collapsepath(ownbin)
+ ownpath=file.collapsepath(ownpath)
+ if not ownpath or ownpath=="" or ownpath=="unset" then
+ ownpath=args[-1] or arg[-1]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ if not ownpath or ownpath=="" then
+ ownpath=args[-0] or arg[-0]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ end
+ local binary=ownbin
+ if not ownpath or ownpath=="" then
+ ownpath=ownpath and filedirname(binary)
+ end
+ if not ownpath or ownpath=="" then
+ if os.binsuffix~="" then
+ binary=file.replacesuffix(binary,os.binsuffix)
+ end
+ local path=osgetenv("PATH")
+ if path then
+ for p in gmatch(path,"[^"..io.pathseparator.."]+") do
+ local b=filejoin(p,binary)
+ if lfs.isfile(b) then
+ local olddir=lfs.currentdir()
+ if lfs.chdir(p) then
+ local pp=lfs.currentdir()
+ if trace_locating and p~=pp then
+ report_initialization("following symlink %a to %a",p,pp)
+ end
+ ownpath=pp
+ lfs.chdir(olddir)
+ else
+ if trace_locating then
+ report_initialization("unable to check path %a",p)
+ end
+ ownpath=p
end
+ break
+ end
end
- if not ownpath or ownpath=="" then
- ownpath="."
- report_initialization("forcing fallback to ownpath %a",ownpath)
- elseif trace_locating then
- report_initialization("using ownpath %a",ownpath)
- end
+ end
end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
+ if not ownpath or ownpath=="" then
+ ownpath="."
+ report_initialization("forcing fallback to ownpath %a",ownpath)
+ elseif trace_locating then
+ report_initialization("using ownpath %a",ownpath)
+ end
+ end
+ environment.ownbin=ownbin
+ environment.ownpath=ownpath
end
resolvers.ownpath=environment.ownpath
function resolvers.getownpath()
- return environment.ownpath
+ return environment.ownpath
end
do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
- ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
- ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
- ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
- report_initialization("error: unable to locate ownpath")
- os.exit()
- end
-end
-local texos=environment.texos or osgetenv("TEXOS")
+ local ownpath=environment.ownpath or dir.current()
+ if ownpath then
+ ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
+ ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
+ ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
+ else
+ report_initialization("error: unable to locate ownpath")
+ os.exit()
+ end
+end
+local texos=environment.texos or osgetenv("TEXOS")
local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
if not texos or texos=="" then
- texos=file.basename(texmfos)
+ texos=file.basename(texmfos)
end
ossetenv('TEXMFOS',texmfos)
-ossetenv('TEXOS',texos)
-ossetenv('SELFAUTOSYSTEM',os.platform)
+ossetenv('TEXOS',texos)
+ossetenv('SELFAUTOSYSTEM',os.platform)
environment.texos=texos
environment.texmfos=texmfos
local texroot=environment.texroot or osgetenv("TEXROOT")
if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
+ texroot=osgetenv('SELFAUTOPARENT')
+ ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
local prefixes=utilities.storage.allocate()
@@ -16418,30 +19992,30 @@ local resolved={}
local abstract={}
local dynamic={}
function resolvers.resetresolve(str)
- resolved,abstract={},{}
+ resolved,abstract={},{}
end
function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
- for i=1,#all do
- all[i]=all[i]..":"
- end
+ local all=table.sortedkeys(prefixes)
+ if separator then
+ for i=1,#all do
+ all[i]=all[i]..":"
end
- return all
+ end
+ return all
end
local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
- return action(target)
- else
- return method..":"..target
- end
+ local action=prefixes[method]
+ if action then
+ return action(target)
+ else
+ return method..":"..target
+ end
end
function resolvers.unresolve(str)
- return abstract[str] or str
+ return abstract[str] or str
end
function resolvers.setdynamic(str)
- dynamic[str]=true
+ dynamic[str]=true
end
local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
local prefix=C(R("az")^2)*P(":")
@@ -16450,65 +20024,65 @@ local notarget=(#S(";,")+P(-1))*Cc("")
local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
local p_simple=prefix*P(-1)
local function resolve(str)
- if type(str)=="table" then
- local res={}
- for i=1,#str do
- res[i]=resolve(str[i])
- end
- return res
- end
- local res=resolved[str]
- if res then
- return res
+ if type(str)=="table" then
+ local res={}
+ for i=1,#str do
+ res[i]=resolve(str[i])
end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
- local res=action(res)
- if not dynamic[simple] then
- resolved[simple]=res
- abstract[res]=simple
- end
- return res
+ return res
+ end
+ local res=resolved[str]
+ if res then
+ return res
+ end
+ local simple=lpegmatch(p_simple,str)
+ local action=prefixes[simple]
+ if action then
+ local res=action(res)
+ if not dynamic[simple] then
+ resolved[simple]=res
+ abstract[res]=simple
end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
return res
+ end
+ res=lpegmatch(p_resolve,str)
+ resolved[str]=res
+ abstract[res]=str
+ return res
end
resolvers.resolve=resolve
if type(osuname)=="function" then
- for k,v in next,osuname() do
- if not prefixes[k] then
- prefixes[k]=function() return v end
- end
+ for k,v in next,osuname() do
+ if not prefixes[k] then
+ prefixes[k]=function() return v end
end
+ end
end
if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
- local colon=P(":")
- for k,v in table.sortedpairs(prefixes) do
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
- return lpegmatch(pattern,str)
+ local pattern
+ local function makepattern(t,k,v)
+ if t then
+ rawset(t,k,v)
+ end
+ local colon=P(":")
+ for k,v in table.sortedpairs(prefixes) do
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
end
+ pattern=Cs((p*colon+colon/";"+P(1))^0)
+ end
+ makepattern()
+ table.setmetatablenewindex(prefixes,makepattern)
+ function resolvers.repath(str)
+ return lpegmatch(pattern,str)
+ end
else
- function resolvers.repath(str)
- return str
- end
+ function resolvers.repath(str)
+ return str
+ end
end
@@ -16518,14 +20092,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-exp"] = package.loaded["data-exp"] or true
--- original size: 18105, stripped down to: 11207
+-- original size: 18105, stripped down to: 10389
if not modules then modules={} end modules ['data-exp']={
- 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 format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
local concat,sort=table.concat,table.sort
@@ -16535,21 +20109,21 @@ local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S
local type,next=type,next
local isdir=lfs.isdir
local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
local report_expansions=logs.reporter("resolvers","expansions")
local report_globbing=logs.reporter("resolvers","globbing")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do
- for sa in gmatch(a,"[^,]+") do
- n=n+1;t[n]=sa..sb
- end
+ local t,n={},0
+ for sb in gmatch(b,"[^,]+") do
+ for sa in gmatch(a,"[^,]+") do
+ n=n+1;t[n]=sa..sb
end
- return concat(t,",")
+ end
+ return concat(t,",")
end
local comma=P(",")
local nocomma=(1-comma)^1
@@ -16559,7 +20133,7 @@ local after=Cs((Carg(1)*nocomma+docomma)^0)
local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
local function f_first (a,b) return lpegmatch(after,b,1,a) end
local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both (a,b) return lpegmatch(both,b,1,a) end
+local function f_both (a,b) return lpegmatch(both,b,1,a) end
local left=P("{")
local right=P("}")
local var=P((1-S("{}" ))^0)
@@ -16572,141 +20146,141 @@ local l_rest=Cs((left*var*(left/"")*var*(right/"")*var*right+other )^0 )
local stripper_1=lpeg.stripper ("{}@")
local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
local function splitpathexpr(str,newlist,validate)
- if trace_expansions then
- report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
+ if trace_expansions then
+ report_expansions("expanding variable %a",str)
+ end
+ local t,ok,done=newlist or {},false,false
+ local n=#t
+ str=lpegmatch(replacer_1,str)
+ repeat
+ local old=str
repeat
- local old=str
- repeat
- local old=str
- str=lpegmatch(l_first,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_second,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_both,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_rest,str)
- until old==str
- until old==str
- str=lpegmatch(stripper_1,str)
- if validate then
- for s in gmatch(str,"[^,]+") do
- s=validate(s)
- if s then
- n=n+1
- t[n]=s
- end
- end
- else
- for s in gmatch(str,"[^,]+") do
- n=n+1
- t[n]=s
- end
+ local old=str
+ str=lpegmatch(l_first,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_second,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_both,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_rest,str)
+ until old==str
+ until old==str
+ str=lpegmatch(stripper_1,str)
+ if validate then
+ for s in gmatch(str,"[^,]+") do
+ s=validate(s)
+ if s then
+ n=n+1
+ t[n]=s
+ end
end
- if trace_expansions then
- for k=1,#t do
- report_expansions("% 4i: %s",k,t[k])
- end
+ else
+ for s in gmatch(str,"[^,]+") do
+ n=n+1
+ t[n]=s
end
- return t
+ end
+ if trace_expansions then
+ for k=1,#t do
+ report_expansions("% 4i: %s",k,t[k])
+ end
+ end
+ return t
end
local function validate(s)
- s=collapsepath(s)
- return s~="" and not find(s,"^!*unset/*$") and s
+ s=collapsepath(s)
+ return s~="" and not find(s,"^!*unset/*$") and s
end
resolvers.validatedpath=validate
function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
- splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
+ local newlist={}
+ for k=1,#pathlist do
+ splitpathexpr(pathlist[k],newlist,validate)
+ end
+ return newlist
end
local usedhomedir=nil
-local donegation=(P("!")/"" )^0
+local donegation=(P("!")/"" )^0
local doslashes=(P("\\")/"/"+1)^0
local function expandedhome()
- if not usedhomedir then
- usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
- if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
- if trace_expansions then
- report_expansions("no home dir set, ignoring dependent path using current path")
- end
- usedhomedir="."
- end
+ if not usedhomedir then
+ usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
+ if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
+ if trace_expansions then
+ report_expansions("no home dir set, ignoring dependent path using current path")
+ end
+ usedhomedir="."
end
- return usedhomedir
+ end
+ return usedhomedir
end
local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
local cleanup=Cs(donegation*dohome*doslashes)
resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
+ return str and lpegmatch(cleanup,str) or ""
end
local expandhome=P("~")/"$HOME"
local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1 )^0
+local dostring=(expandhome+1 )^0
local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
+ lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
)
function resolvers.checkedvariable(str)
- return type(str)=="string" and lpegmatch(stripper,str) or str
+ return type(str)=="string" and lpegmatch(stripper,str) or str
end
local cache={}
local splitter=lpeg.tsplitat(";")
local backslashswapper=lpeg.replacer("\\","/")
local function splitconfigurationpath(str)
- if str then
- local found=cache[str]
- if not found then
- if str=="" then
- found={}
- else
- local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
- found={}
- local noffound=0
- for i=1,#split do
- local s=split[i]
- if not find(s,"^{*unset}*") then
- noffound=noffound+1
- found[noffound]=s
- end
- end
- if trace_expansions then
- report_expansions("splitting path specification %a",str)
- for k=1,noffound do
- report_expansions("% 4i: %s",k,found[k])
- end
- end
- cache[str]=found
- end
+ if str then
+ local found=cache[str]
+ if not found then
+ if str=="" then
+ found={}
+ else
+ local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
+ found={}
+ local noffound=0
+ for i=1,#split do
+ local s=split[i]
+ if not find(s,"^{*unset}*") then
+ noffound=noffound+1
+ found[noffound]=s
+ end
end
- return found
+ if trace_expansions then
+ report_expansions("splitting path specification %a",str)
+ for k=1,noffound do
+ report_expansions("% 4i: %s",k,found[k])
+ end
+ end
+ cache[str]=found
+ end
end
+ return found
+ end
end
resolvers.splitconfigurationpath=splitconfigurationpath
function resolvers.splitpath(str)
- if type(str)=='table' then
- return str
- else
- return splitconfigurationpath(str)
- end
+ if type(str)=='table' then
+ return str
+ else
+ return splitconfigurationpath(str)
+ end
end
function resolvers.joinpath(str)
- if type(str)=='table' then
- return joinpath(str)
- else
- return str
- end
+ if type(str)=='table' then
+ return joinpath(str)
+ else
+ return str
+ end
end
local attributes,directory=lfs.attributes,lfs.dir
local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
@@ -16719,201 +20293,201 @@ local fullcache={}
local nofsharedscans=0
local addcasecraptoo=true
local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name in directory(full) do
- if not lpegmatch(pattern,name) then
- local mode=attributes(full..name,"mode")
- if mode=="file" then
- n=n+1
- noffiles=noffiles+1
- filelist[noffiles]=name
- elseif mode=="directory" then
- m=m+1
- nofdirs=nofdirs+1
- if path~="" then
- dirlist[nofdirs]=path.."/"..name
- else
- dirlist[nofdirs]=name
- end
- end
+ local full=path=="" and spec or (spec..path..'/')
+ local dirlist={}
+ local nofdirs=0
+ local pattern=tolerant and lessweird or weird
+ local filelist={}
+ local noffiles=0
+ for name in directory(full) do
+ if not lpegmatch(pattern,name) then
+ local mode=attributes(full..name,"mode")
+ if mode=="file" then
+ n=n+1
+ noffiles=noffiles+1
+ filelist[noffiles]=name
+ elseif mode=="directory" then
+ m=m+1
+ nofdirs=nofdirs+1
+ if path~="" then
+ dirlist[nofdirs]=path.."/"..name
+ else
+ dirlist[nofdirs]=name
end
+ end
end
- if noffiles>0 then
- sort(filelist)
- for i=1,noffiles do
- local name=filelist[i]
- local lower=lower(name)
- local paths=files[lower]
- if paths then
- if onlyone then
- else
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- if addcasecraptoo then
- local paths=files[name]
- if not paths then
- files[name]=path
- elseif type(paths)=="string" then
- files[name]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- end
- if type(paths)=="string" then
- files[lower]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- else
- files[lower]=path
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- end
+ end
+ if noffiles>0 then
+ sort(filelist)
+ for i=1,noffiles do
+ local name=filelist[i]
+ local lower=lower(name)
+ local paths=files[lower]
+ if paths then
+ if onlyone then
+ else
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
+ if addcasecraptoo then
+ local paths=files[name]
+ if not paths then
+ files[name]=path
+ elseif type(paths)=="string" then
+ files[name]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
+ end
+ if type(paths)=="string" then
+ files[lower]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
- end
- if nofdirs>0 then
- sort(dirlist)
- for i=1,nofdirs do
- files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
+ else
+ files[lower]=path
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
end
+ end
+ end
+ end
+ if nofdirs>0 then
+ sort(dirlist)
+ for i=1,nofdirs do
+ files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
+ end
+ scancache[sub(full,1,-2)]=files
+ return files,remap,n,m,r
end
function resolvers.scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
- local content=fullcache[realpath]
- if content then
- if trace_locating then
- report_expansions("using cached scan of path %a, branch %a",path,branch or path)
- end
- nofsharedscans=nofsharedscans+1
- return content
- end
- end
- statistics.starttiming(timer)
+ local realpath=resolveprefix(path)
+ if usecache then
+ local content=fullcache[realpath]
+ if content then
+ if trace_locating then
+ report_expansions("using cached scan of path %a, branch %a",path,branch or path)
+ end
+ nofsharedscans=nofsharedscans+1
+ return content
+ end
+ end
+ statistics.starttiming(timer)
+ if trace_locating then
+ report_expansions("scanning path %a, branch %a",path,branch or path)
+ end
+ local content
+ if isdir(realpath) then
+ local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
+ content={
+ metadata={
+ path=path,
+ files=n,
+ directories=m,
+ remappings=r,
+ },
+ files=files,
+ remap=remap,
+ }
if trace_locating then
- report_expansions("scanning path %a, branch %a",path,branch or path)
+ report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
end
- local content
- if isdir(realpath) then
- local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
- content={
- metadata={
- path=path,
- files=n,
- directories=m,
- remappings=r,
- },
- files=files,
- remap=remap,
- }
- if trace_locating then
- report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
- end
- else
- content={
- metadata={
- path=path,
- files=0,
- directories=0,
- remappings=0,
- },
- files={},
- remap={},
- }
- if trace_locating then
- report_expansions("invalid path %a",realpath)
- end
- end
- if usecache then
- scanned[#scanned+1]=realpath
- fullcache[realpath]=content
+ else
+ content={
+ metadata={
+ path=path,
+ files=0,
+ directories=0,
+ remappings=0,
+ },
+ files={},
+ remap={},
+ }
+ if trace_locating then
+ report_expansions("invalid path %a",realpath)
end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
+ end
+ if usecache then
+ scanned[#scanned+1]=realpath
+ fullcache[realpath]=content
+ end
+ nofscans=nofscans+1
+ statistics.stoptiming(timer)
+ return content
end
function resolvers.simplescanfiles(path,branch,usecache)
- return resolvers.scanfiles(path,branch,usecache,true,true)
+ return resolvers.scanfiles(path,branch,usecache,true,true)
end
function resolvers.scandata()
- table.sort(scanned)
- return {
- n=nofscans,
- shared=nofsharedscans,
- time=statistics.elapsedtime(timer),
- paths=scanned,
- }
+ table.sort(scanned)
+ return {
+ n=nofscans,
+ shared=nofsharedscans,
+ time=statistics.elapsedtime(timer),
+ paths=scanned,
+ }
end
function resolvers.get_from_content(content,path,name)
- if not content then
- return
- end
- local files=content.files
- if not files then
- return
- end
- local remap=content.remap
- if not remap then
- return
- end
- if name then
- local used=lower(name)
- return path,remap[used] or used
- else
- local name=path
- local used=lower(name)
- local path=files[used]
- if path then
- return path,remap[used] or used
- end
- end
+ if not content then
+ return
+ end
+ local files=content.files
+ if not files then
+ return
+ end
+ local remap=content.remap
+ if not remap then
+ return
+ end
+ if name then
+ local used=lower(name)
+ return path,remap[used] or used
+ else
+ local name=path
+ local used=lower(name)
+ local path=files[used]
+ if path then
+ return path,remap[used] or used
+ end
+ end
end
local nothing=function() end
function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
- local pattern=lower(pattern)
- local files=content.files
- local remap=content.remap
- if files and remap then
- local f=sortedkeys(files)
- local n=#f
- local i=0
- local function iterator()
- while i<n do
- i=i+1
- local k=f[i]
- if find(k,pattern) then
- return files[k],remap and remap[k] or k
- end
- end
- end
- return iterator
+ if content and type(pattern)=="string" then
+ local pattern=lower(pattern)
+ local files=content.files
+ local remap=content.remap
+ if files and remap then
+ local f=sortedkeys(files)
+ local n=#f
+ local i=0
+ local function iterator()
+ while i<n do
+ i=i+1
+ local k=f[i]
+ if find(k,pattern) then
+ return files[k],remap and remap[k] or k
+ end
end
+ end
+ return iterator
end
- return nothing
+ end
+ return nothing
end
@@ -16923,14 +20497,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9360, stripped down to: 6903
+-- original size: 9360, stripped down to: 6312
if not modules then modules={} end modules ['data-env']={
- 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 lower,gsub=string.lower,string.gsub
local next=next
@@ -16950,255 +20524,255 @@ resolvers.suffixmap=suffixmap
resolvers.usertypes=usertypes
local luasuffixes=utilities.lua.suffixes
local relations=allocate {
- core={
- ofm={
- names={ "ofm","omega font metric","omega font metrics" },
- variable='OFMFONTS',
- suffixes={ 'ofm','tfm' },
- },
- ovf={
- names={ "ovf","omega virtual font","omega virtual fonts" },
- variable='OVFFONTS',
- suffixes={ 'ovf','vf' },
- },
- tfm={
- names={ "tfm","tex font metric","tex font metrics" },
- variable='TFMFONTS',
- suffixes={ 'tfm' },
- },
- vf={
- names={ "vf","virtual font","virtual fonts" },
- variable='VFFONTS',
- suffixes={ 'vf' },
- },
- otf={
- names={ "otf","opentype","opentype font","opentype fonts"},
- variable='OPENTYPEFONTS',
- suffixes={ 'otf' },
- },
- ttf={
- names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
- variable='TTFONTS',
- suffixes={ 'ttf','ttc','dfont' },
- },
- afm={
- names={ "afm","adobe font metric","adobe font metrics" },
- variable="AFMFONTS",
- suffixes={ "afm" },
- },
- pfb={
- names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
- variable='T1FONTS',
- suffixes={ 'pfb','pfa' },
- },
- fea={
- names={ "fea","font feature","font features","font feature file","font feature files" },
- variable='FONTFEATURES',
- suffixes={ 'fea' },
- },
- cid={
- names={ "cid","cid map","cid maps","cid file","cid files" },
- variable='FONTCIDMAPS',
- suffixes={ 'cid','cidmap' },
- },
- fmt={
- names={ "fmt","format","tex format" },
- variable='TEXFORMATS',
- suffixes={ 'fmt' },
- },
- mem={
- names={ 'mem',"metapost format" },
- variable='MPMEMS',
- suffixes={ 'mem' },
- },
- mp={
- names={ "mp" },
- variable='MPINPUTS',
- suffixes={ 'mp','mpvi','mpiv','mpii' },
- usertype=true,
- },
- tex={
- names={ "tex" },
- variable='TEXINPUTS',
- suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
- usertype=true,
- },
- icc={
- names={ "icc","icc profile","icc profiles" },
- variable='ICCPROFILES',
- suffixes={ 'icc' },
- },
- texmfscripts={
- names={ "texmfscript","texmfscripts","script","scripts" },
- variable='TEXMFSCRIPTS',
- suffixes={ 'lua','rb','pl','py' },
- },
- lua={
- names={ "lua" },
- variable='LUAINPUTS',
- suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
- usertype=true,
- },
- lib={
- names={ "lib" },
- variable='CLUAINPUTS',
- suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
- },
- bib={
- names={ 'bib' },
- variable='BIBINPUTS',
- suffixes={ 'bib' },
- usertype=true,
- },
- bst={
- names={ 'bst' },
- variable='BSTINPUTS',
- suffixes={ 'bst' },
- usertype=true,
- },
- fontconfig={
- names={ 'fontconfig','fontconfig file','fontconfig files' },
- variable='FONTCONFIG_PATH',
- },
- pk={
- names={ "pk" },
- variable='PKFONTS',
- suffixes={ 'pk' },
- },
+ core={
+ ofm={
+ names={ "ofm","omega font metric","omega font metrics" },
+ variable='OFMFONTS',
+ suffixes={ 'ofm','tfm' },
+ },
+ ovf={
+ names={ "ovf","omega virtual font","omega virtual fonts" },
+ variable='OVFFONTS',
+ suffixes={ 'ovf','vf' },
+ },
+ tfm={
+ names={ "tfm","tex font metric","tex font metrics" },
+ variable='TFMFONTS',
+ suffixes={ 'tfm' },
+ },
+ vf={
+ names={ "vf","virtual font","virtual fonts" },
+ variable='VFFONTS',
+ suffixes={ 'vf' },
+ },
+ otf={
+ names={ "otf","opentype","opentype font","opentype fonts"},
+ variable='OPENTYPEFONTS',
+ suffixes={ 'otf' },
+ },
+ ttf={
+ names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
+ variable='TTFONTS',
+ suffixes={ 'ttf','ttc','dfont' },
+ },
+ afm={
+ names={ "afm","adobe font metric","adobe font metrics" },
+ variable="AFMFONTS",
+ suffixes={ "afm" },
+ },
+ pfb={
+ names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
+ variable='T1FONTS',
+ suffixes={ 'pfb','pfa' },
+ },
+ fea={
+ names={ "fea","font feature","font features","font feature file","font feature files" },
+ variable='FONTFEATURES',
+ suffixes={ 'fea' },
+ },
+ cid={
+ names={ "cid","cid map","cid maps","cid file","cid files" },
+ variable='FONTCIDMAPS',
+ suffixes={ 'cid','cidmap' },
+ },
+ fmt={
+ names={ "fmt","format","tex format" },
+ variable='TEXFORMATS',
+ suffixes={ 'fmt' },
+ },
+ mem={
+ names={ 'mem',"metapost format" },
+ variable='MPMEMS',
+ suffixes={ 'mem' },
+ },
+ mp={
+ names={ "mp" },
+ variable='MPINPUTS',
+ suffixes={ 'mp','mpvi','mpiv','mpii' },
+ usertype=true,
+ },
+ tex={
+ names={ "tex" },
+ variable='TEXINPUTS',
+ suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
+ usertype=true,
+ },
+ icc={
+ names={ "icc","icc profile","icc profiles" },
+ variable='ICCPROFILES',
+ suffixes={ 'icc' },
+ },
+ texmfscripts={
+ names={ "texmfscript","texmfscripts","script","scripts" },
+ variable='TEXMFSCRIPTS',
+ suffixes={ 'lua','rb','pl','py' },
+ },
+ lua={
+ names={ "lua" },
+ variable='LUAINPUTS',
+ suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
+ usertype=true,
},
- obsolete={
- enc={
- names={ "enc","enc files","enc file","encoding files","encoding file" },
- variable='ENCFONTS',
- suffixes={ 'enc' },
- },
- map={
- names={ "map","map files","map file" },
- variable='TEXFONTMAPS',
- suffixes={ 'map' },
- },
- lig={
- names={ "lig files","lig file","ligature file","ligature files" },
- variable='LIGFONTS',
- suffixes={ 'lig' },
- },
- opl={
- names={ "opl" },
- variable='OPLFONTS',
- suffixes={ 'opl' },
- },
- ovp={
- names={ "ovp" },
- variable='OVPFONTS',
- suffixes={ 'ovp' },
- },
+ lib={
+ names={ "lib" },
+ variable='CLUAINPUTS',
+ suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
},
- kpse={
- base={
- names={ 'base',"metafont format" },
- variable='MFBASES',
- suffixes={ 'base','bas' },
- },
- cmap={
- names={ 'cmap','cmap files','cmap file' },
- variable='CMAPFONTS',
- suffixes={ 'cmap' },
- },
- cnf={
- names={ 'cnf' },
- suffixes={ 'cnf' },
- },
- web={
- names={ 'web' },
- suffixes={ 'web','ch' }
- },
- cweb={
- names={ 'cweb' },
- suffixes={ 'w','web','ch' },
- },
- gf={
- names={ 'gf' },
- suffixes={ '<resolution>gf' },
- },
- mf={
- names={ 'mf' },
- variable='MFINPUTS',
- suffixes={ 'mf' },
- },
- mft={
- names={ 'mft' },
- suffixes={ 'mft' },
- },
- pk={
- names={ 'pk' },
- suffixes={ '<resolution>pk' },
- },
+ bib={
+ names={ 'bib' },
+ variable='BIBINPUTS',
+ suffixes={ 'bib' },
+ usertype=true,
},
+ bst={
+ names={ 'bst' },
+ variable='BSTINPUTS',
+ suffixes={ 'bst' },
+ usertype=true,
+ },
+ fontconfig={
+ names={ 'fontconfig','fontconfig file','fontconfig files' },
+ variable='FONTCONFIG_PATH',
+ },
+ pk={
+ names={ "pk" },
+ variable='PKFONTS',
+ suffixes={ 'pk' },
+ },
+ },
+ obsolete={
+ enc={
+ names={ "enc","enc files","enc file","encoding files","encoding file" },
+ variable='ENCFONTS',
+ suffixes={ 'enc' },
+ },
+ map={
+ names={ "map","map files","map file" },
+ variable='TEXFONTMAPS',
+ suffixes={ 'map' },
+ },
+ lig={
+ names={ "lig files","lig file","ligature file","ligature files" },
+ variable='LIGFONTS',
+ suffixes={ 'lig' },
+ },
+ opl={
+ names={ "opl" },
+ variable='OPLFONTS',
+ suffixes={ 'opl' },
+ },
+ ovp={
+ names={ "ovp" },
+ variable='OVPFONTS',
+ suffixes={ 'ovp' },
+ },
+ },
+ kpse={
+ base={
+ names={ 'base',"metafont format" },
+ variable='MFBASES',
+ suffixes={ 'base','bas' },
+ },
+ cmap={
+ names={ 'cmap','cmap files','cmap file' },
+ variable='CMAPFONTS',
+ suffixes={ 'cmap' },
+ },
+ cnf={
+ names={ 'cnf' },
+ suffixes={ 'cnf' },
+ },
+ web={
+ names={ 'web' },
+ suffixes={ 'web','ch' }
+ },
+ cweb={
+ names={ 'cweb' },
+ suffixes={ 'w','web','ch' },
+ },
+ gf={
+ names={ 'gf' },
+ suffixes={ '<resolution>gf' },
+ },
+ mf={
+ names={ 'mf' },
+ variable='MFINPUTS',
+ suffixes={ 'mf' },
+ },
+ mft={
+ names={ 'mft' },
+ suffixes={ 'mft' },
+ },
+ pk={
+ names={ 'pk' },
+ suffixes={ '<resolution>pk' },
+ },
+ },
}
resolvers.relations=relations
function resolvers.updaterelations()
- for category,categories in next,relations do
- for name,relation in next,categories do
- local rn=relation.names
- local rv=relation.variable
- if rn and rv then
- local rs=relation.suffixes
- local ru=relation.usertype
- for i=1,#rn do
- local rni=lower(gsub(rn[i]," ",""))
- formats[rni]=rv
- if rs then
- suffixes[rni]=rs
- for i=1,#rs do
- local rsi=rs[i]
- suffixmap[rsi]=rni
- end
- end
- end
- if ru then
- usertypes[name]=true
- end
+ for category,categories in next,relations do
+ for name,relation in next,categories do
+ local rn=relation.names
+ local rv=relation.variable
+ if rn and rv then
+ local rs=relation.suffixes
+ local ru=relation.usertype
+ for i=1,#rn do
+ local rni=lower(gsub(rn[i]," ",""))
+ formats[rni]=rv
+ if rs then
+ suffixes[rni]=rs
+ for i=1,#rs do
+ local rsi=rs[i]
+ suffixmap[rsi]=rni
end
+ end
+ end
+ if ru then
+ usertypes[name]=true
end
+ end
end
+ end
end
resolvers.updaterelations()
local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
+ return k and rawget(t,lower(gsub(k," ",""))) or nil
end
setmetatableindex(formats,simplified)
setmetatableindex(suffixes,simplified)
setmetatableindex(suffixmap,simplified)
function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
+ local s=suffixes[str]
+ return s and s[1] or ""
end
function resolvers.suffixofformat(str)
- return suffixes[str] or {}
+ return suffixes[str] or {}
end
for name,format in next,formats do
- dangerous[name]=true
+ dangerous[name]=true
end
dangerous.tex=nil
function resolvers.formatofvariable(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.formatofsuffix(str)
- return suffixmap[suffixonly(str)] or 'tex'
+ return suffixmap[suffixonly(str)] or 'tex'
end
function resolvers.variableofformat(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
- return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
- return formats[v]
- end
- return ''
+ local v=formats[str]
+ if v then
+ return v
+ end
+ v=suffixmap[suffixonly(str)]
+ if v then
+ return formats[v]
+ end
+ return ''
end
@@ -17208,14 +20782,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16116, stripped down to: 11459
+-- original size: 16116, stripped down to: 10782
if not modules then modules={} end modules ['data-tmp']={
- 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,concat=string.format,string.lower,string.gsub,table.concat
local concat=table.concat
@@ -17223,19 +20797,19 @@ local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
local next,type=next,type
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
local report_resolvers=logs.reporter("resolvers","caching")
local resolvers=resolvers
local cleanpath=resolvers.cleanpath
-local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
-local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
+local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
+local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
local compile=utilities.lua.compile
function utilities.lua.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip end
- return compile(luafile,lucfile,cleanup,strip)
+ if cleanup==nil then cleanup=directive_cleanup end
+ if strip==nil then strip=directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
end
caches=caches or {}
local caches=caches
@@ -17250,324 +20824,324 @@ caches.relocate=false
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local writable,readables,usedreadables=nil,{},{}
local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- cachepath=file.collapsepath(cachepath)
- local valid=isdir(cachepath)
- if valid then
- if is_readable(cachepath) then
- readables[#readables+1]=cachepath
- if not writable and is_writable(cachepath) then
- writable=cachepath
- end
- end
- elseif not writable and caches.force then
- local cacheparent=file.dirname(cachepath)
- if is_writable(cacheparent) and true then
- if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
- mkdirs(cachepath)
- if isdir(cachepath) and is_writable(cachepath) then
- report_caches("path %a created",cachepath)
- writable=cachepath
- readables[#readables+1]=cachepath
- end
- end
- end
- end
+ local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ cachepath=file.collapsepath(cachepath)
+ local valid=isdir(cachepath)
+ if valid then
+ if is_readable(cachepath) then
+ readables[#readables+1]=cachepath
+ if not writable and is_writable(cachepath) then
+ writable=cachepath
end
- end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- cachepath=resolvers.expansion(cachepath)
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- local valid=isdir(cachepath)
- if valid and is_readable(cachepath) then
- if not writable and is_writable(cachepath) then
- readables[#readables+1]=cachepath
- writable=cachepath
- break
- end
- end
+ end
+ elseif not writable and caches.force then
+ local cacheparent=file.dirname(cachepath)
+ if is_writable(cacheparent) and true then
+ if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
+ mkdirs(cachepath)
+ if isdir(cachepath) and is_writable(cachepath) then
+ report_caches("path %a created",cachepath)
+ writable=cachepath
+ readables[#readables+1]=cachepath
+ end
end
+ end
end
+ end
end
- if not writable then
- report_caches("fatal error: there is no valid writable cache path defined")
- os.exit()
- elseif #readables==0 then
- report_caches("fatal error: there is no valid readable cache path defined")
- os.exit()
- end
- writable=dir.expandname(resolvers.cleanpath(writable))
- local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
- if tree then
- caches.tree=tree
- writable=mkdirs(writable,base,more,tree)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more,tree)
- end
- else
- writable=mkdirs(writable,base,more)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more)
+ end
+ local texmfcaches=caches.defaults
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ cachepath=resolvers.expansion(cachepath)
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ local valid=isdir(cachepath)
+ if valid and is_readable(cachepath) then
+ if not writable and is_writable(cachepath) then
+ readables[#readables+1]=cachepath
+ writable=cachepath
+ break
+ end
end
+ end
end
- if trace_cache then
- for i=1,#readables do
- report_caches("using readable path %a (order %s)",readables[i],i)
- end
- report_caches("using writable path %a",writable)
+ end
+ if not writable then
+ report_caches("fatal error: there is no valid writable cache path defined")
+ os.exit()
+ elseif #readables==0 then
+ report_caches("fatal error: there is no valid readable cache path defined")
+ os.exit()
+ end
+ writable=dir.expandname(resolvers.cleanpath(writable))
+ local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
+ if tree then
+ caches.tree=tree
+ writable=mkdirs(writable,base,more,tree)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more,tree)
end
- identify=function()
- return writable,readables
+ else
+ writable=mkdirs(writable,base,more)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more)
end
+ end
+ if trace_cache then
+ for i=1,#readables do
+ report_caches("using readable path %a (order %s)",readables[i],i)
+ end
+ report_caches("using writable path %a",writable)
+ end
+ identify=function()
return writable,readables
+ end
+ return writable,readables
end
function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
- local result={}
- local done={}
- for i=1,#readables do
- local readable=readables[i]
- if readable==writable then
- done[readable]=true
- result[#result+1]=formatters["readable+writable: %a"](readable)
- elseif usedreadables[i] then
- done[readable]=true
- result[#result+1]=formatters["readable: %a"](readable)
- end
- end
- if not done[writable] then
- result[#result+1]=formatters["writable: %a"](writable)
- end
- return concat(result,separator or " | ")
- else
- return writable or "?"
+ local writable,readables=identify()
+ if #readables>1 then
+ local result={}
+ local done={}
+ for i=1,#readables do
+ local readable=readables[i]
+ if readable==writable then
+ done[readable]=true
+ result[#result+1]=formatters["readable+writable: %a"](readable)
+ elseif usedreadables[i] then
+ done[readable]=true
+ result[#result+1]=formatters["readable: %a"](readable)
+ end
end
+ if not done[writable] then
+ result[#result+1]=formatters["writable: %a"](writable)
+ end
+ return concat(result,separator or " | ")
+ else
+ return writable or "?"
+ end
end
function caches.configfiles()
- return concat(resolvers.configurationfiles(),";")
+ return concat(resolvers.configurationfiles(),";")
end
function caches.hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5.hex(tree)
- if trace_cache or trace_locating then
- report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
+ tree=gsub(tree,"[\\/]+$","")
+ tree=lower(tree)
+ local hash=md5.hex(tree)
+ if trace_cache or trace_locating then
+ report_caches("hashing tree %a, hash %a",tree,hash)
+ end
+ return hash
end
function caches.treehash()
- local tree=caches.configfiles()
- if not tree or tree=="" then
- return false
- else
- return caches.hashed(tree)
- end
+ local tree=caches.configfiles()
+ if not tree or tree=="" then
+ return false
+ else
+ return caches.hashed(tree)
+ end
end
local r_cache,w_cache={},{}
local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done={}
- for i=1,#readables do
- done[i]=file.join(readables[i],...)
- end
- else
- done=readables
- end
- r_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=r_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done={}
+ for i=1,#readables do
+ done[i]=file.join(readables[i],...)
+ end
+ else
+ done=readables
end
- return done
+ r_cache[hash]=done
+ end
+ return done
end
local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done=mkdirs(writable,...)
- else
- done=writable
- end
- w_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=w_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done=mkdirs(writable,...)
+ else
+ done=writable
end
- return done
+ w_cache[hash]=done
+ end
+ return done
end
caches.getreadablepaths=getreadablepaths
caches.getwritablepath=getwritablepath
function caches.getfirstreadablefile(filename,...)
- local fullname,path=caches.setfirstwritablefile(filename,...)
+ local fullname,path=caches.setfirstwritablefile(filename,...)
+ if is_readable(fullname) then
+ return fullname,path
+ end
+ local rd=getreadablepaths(...)
+ for i=1,#rd do
+ local path=rd[i]
+ local fullname=file.join(path,filename)
if is_readable(fullname) then
- return fullname,path
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
- local path=rd[i]
- local fullname=file.join(path,filename)
- if is_readable(fullname) then
- usedreadables[i]=true
- return fullname,path
- end
+ usedreadables[i]=true
+ return fullname,path
end
- return fullname,path
+ end
+ return fullname,path
end
function caches.setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=file.join(wr,filename)
- return fullname,wr
+ local wr=getwritablepath(...)
+ local fullname=file.join(wr,filename)
+ return fullname,wr
end
function caches.define(category,subcategory)
- return function()
- return getwritablepath(category,subcategory)
- end
+ return function()
+ return getwritablepath(category,subcategory)
+ end
end
function caches.setluanames(path,name)
- return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
+ return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
end
function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
- readables={ readables }
+ if type(readables)=="string" then
+ readables={ readables }
+ end
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local tmaname,tmcname=caches.setluanames(path,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader and isfile(tmaname) then
+ local tmacrap,tmcname=caches.setluanames(writable,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ utilities.lua.compile(tmaname,tmcname)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader then
+ loader=loadfile(tmaname)
+ end
end
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local tmaname,tmcname=caches.setluanames(path,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader and isfile(tmaname) then
- local tmacrap,tmcname=caches.setluanames(writable,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- utilities.lua.compile(tmaname,tmcname)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader then
- loader=loadfile(tmaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
end
- return false
+ end
+ return false
end
function caches.is_writable(filepath,filename)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- return is_writable(tmaname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ return is_writable(tmaname)
end
local saveoptions={ compact=true }
function caches.savedata(filepath,filename,data,raw)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- data.cache_uuid=os.uuid()
- if caches.direct then
- file.savedata(tmaname,table.serialize(data,true,saveoptions))
- else
- table.tofile(tmaname,data,true,saveoptions)
- end
- utilities.lua.compile(tmaname,tmcname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ data.cache_uuid=os.uuid()
+ if caches.direct then
+ file.savedata(tmaname,table.serialize(data,true,saveoptions))
+ else
+ table.tofile(tmaname,data,true,saveoptions)
+ end
+ utilities.lua.compile(tmaname,tmcname)
end
local content_state={}
function caches.contentstate()
- return content_state or {}
+ return content_state or {}
end
function caches.loadcontent(cachename,dataname,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
- if blob then
- local data=blob()
- if data and data.content then
- if data.type==dataname then
- if data.version==resolvers.cacheversion then
- content_state[#content_state+1]=data.uuid
- if trace_locating then
- report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
- end
- return data.content
- else
- report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
- end
- else
- report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
+ if blob then
+ local data=blob()
+ if data and data.content then
+ if data.type==dataname then
+ if data.version==resolvers.cacheversion then
+ content_state[#content_state+1]=data.uuid
+ if trace_locating then
+ report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
+ end
+ return data.content
+ else
+ report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
end
+ else
+ report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
+ end
elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
end
+ elseif trace_locating then
+ report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ end
end
function caches.collapsecontent(content)
- for k,v in next,content do
- if type(v)=="table" and #v==1 then
- content[k]=v[1]
- end
+ for k,v in next,content do
+ if type(v)=="table" and #v==1 then
+ content[k]=v[1]
end
+ end
end
function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local luaname=addsuffix(filename,luasuffixes.lua)
+ local lucname=addsuffix(filename,luasuffixes.luc)
+ if trace_locating then
+ report_resolvers("preparing %a for %a",dataname,cachename)
+ end
+ local data={
+ type=dataname,
+ root=cachename,
+ version=resolvers.cacheversion,
+ date=os.date("%Y-%m-%d"),
+ time=os.date("%H:%M:%S"),
+ content=content,
+ uuid=os.uuid(),
+ }
+ local ok=io.savedata(luaname,table.serialize(data,true))
+ if ok then
if trace_locating then
- report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
- type=dataname,
- root=cachename,
- version=resolvers.cacheversion,
- date=os.date("%Y-%m-%d"),
- time=os.date("%H:%M:%S"),
- content=content,
- uuid=os.uuid(),
- }
- local ok=io.savedata(luaname,table.serialize(data,true))
- if ok then
- if trace_locating then
- report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
- end
- if utilities.lua.compile(luaname,lucname) then
- if trace_locating then
- report_resolvers("%a compiled to %a",dataname,lucname)
- end
- return true
- else
- if trace_locating then
- report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
- end
- os.remove(lucname)
- end
- elseif trace_locating then
- report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
+ end
+ if utilities.lua.compile(luaname,lucname) then
+ if trace_locating then
+ report_resolvers("%a compiled to %a",dataname,lucname)
+ end
+ return true
+ else
+ if trace_locating then
+ report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
+ end
+ os.remove(lucname)
end
+ elseif trace_locating then
+ report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ end
end
@@ -17577,14 +21151,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-met"] = package.loaded["data-met"] or true
--- original size: 5310, stripped down to: 3980
+-- original size: 5310, stripped down to: 3784
if not modules then modules={} end modules ['data-met']={
- 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 find,format=string.find,string.format
local sequenced=table.sequenced
@@ -17598,86 +21172,86 @@ local allocate=utilities.storage.allocate
local resolvers=resolvers
local registered={}
local function splitmethod(filename)
- if not filename then
- return { scheme="unknown",original=filename }
- end
- if type(filename)=="table" then
- return filename
- end
- filename=file.collapsepath(filename,".")
- if not find(filename,"://",1,true) then
- return { scheme="file",path=filename,original=filename,filename=filename }
- end
- local specification=url.hashed(filename)
- if not specification.scheme or specification.scheme=="" then
- return { scheme="file",path=filename,original=filename,filename=filename }
- else
- return specification
- end
+ if not filename then
+ return { scheme="unknown",original=filename }
+ end
+ if type(filename)=="table" then
+ return filename
+ end
+ filename=file.collapsepath(filename,".")
+ if not find(filename,"://",1,true) then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ end
+ local specification=url.hashed(filename)
+ if not specification.scheme or specification.scheme=="" then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ else
+ return specification
+ end
end
resolvers.splitmethod=splitmethod
local function methodhandler(what,first,...)
- local method=registered[what]
- if method then
- local how,namespace=method.how,method.namespace
- if how=="uri" or how=="url" then
- local specification=splitmethod(first)
- local scheme=specification.scheme
- local resolver=namespace and namespace[scheme]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
- end
- return resolver(specification,...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
- end
- return resolver(specification,...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
- end
- end
- elseif how=="tag" then
- local resolver=namespace and namespace[first]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,first)
- end
- return resolver(...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
- end
- return resolver(...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
- end
- end
+ local method=registered[what]
+ if method then
+ local how,namespace=method.how,method.namespace
+ if how=="uri" or how=="url" then
+ local specification=splitmethod(first)
+ local scheme=specification.scheme
+ local resolver=namespace and namespace[scheme]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+ end
+ return resolver(specification,...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
+ end
+ return resolver(specification,...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
end
- else
- report_methods("resolving, invalid method %a")
+ end
+ elseif how=="tag" then
+ local resolver=namespace and namespace[first]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,first)
+ end
+ return resolver(...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
+ end
+ return resolver(...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
+ end
+ end
end
+ else
+ report_methods("resolving, invalid method %a")
+ end
end
resolvers.methodhandler=methodhandler
function resolvers.registermethod(name,namespace,how)
- registered[name]={ how=how or "tag",namespace=namespace }
- namespace["byscheme"]=function(scheme,filename,...)
- if scheme=="file" then
- return methodhandler(name,filename,...)
- else
- return methodhandler(name,addurlscheme(filename,scheme),...)
- end
+ registered[name]={ how=how or "tag",namespace=namespace }
+ namespace["byscheme"]=function(scheme,filename,...)
+ if scheme=="file" then
+ return methodhandler(name,filename,...)
+ else
+ return methodhandler(name,addurlscheme(filename,scheme),...)
end
+ end
end
-local concatinators=allocate { notfound=file.join }
-local locators=allocate { notfound=function() end }
-local hashers=allocate { notfound=function() end }
-local generators=allocate { notfound=function() end }
+local concatinators=allocate { notfound=file.join }
+local locators=allocate { notfound=function() end }
+local hashers=allocate { notfound=function() end }
+local generators=allocate { notfound=function() end }
resolvers.concatinators=concatinators
resolvers.locators=locators
resolvers.hashers=hashers
@@ -17695,17 +21269,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-res"] = package.loaded["data-res"] or true
--- original size: 68263, stripped down to: 47789
+-- original size: 68195, stripped down to: 43680
if not modules then modules={} end modules ['data-res']={
- 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 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
local P,S,R,C,Cc,Cs,Ct,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Carg
@@ -17727,11 +21301,11 @@ local isfile=lfs.isfile
local isdir=lfs.isdir
local setmetatableindex=table.setmetatableindex
local luasuffixes=utilities.lua.suffixes
-local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
+local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
+local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
local report_resolving=logs.reporter("resolvers","resolving")
local resolvers=resolvers
local expandedpathfromlist=resolvers.expandedpathfromlist
@@ -17752,15 +21326,15 @@ resolvers.luacnfname="texmfcnf.lua"
resolvers.luacnffallback="contextcnf.lua"
resolvers.luacnfstate="unknown"
if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
+ resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
else
- resolvers.luacnfspec=concat ({
- "home:texmf/web2c",
- "selfautoparent:/texmf-local/web2c",
- "selfautoparent:/texmf-context/web2c",
- "selfautoparent:/texmf-dist/web2c",
- "selfautoparent:/texmf/web2c",
- },";")
+ resolvers.luacnfspec=concat ({
+ "home:texmf/web2c",
+ "selfautoparent:/texmf-local/web2c",
+ "selfautoparent:/texmf-context/web2c",
+ "selfautoparent:/texmf-dist/web2c",
+ "selfautoparent:/texmf/web2c",
+ },";")
end
local unset_variable="unset"
local formats=resolvers.formats
@@ -17771,24 +21345,24 @@ local suffixmap=resolvers.suffixmap
resolvers.defaultsuffixes={ "tex" }
local instance=nil
function resolvers.setenv(key,value,raw)
- if instance then
- instance.environment[key]=value
- ossetenv(key,raw and value or resolveprefix(value))
- end
+ if instance then
+ instance.environment[key]=value
+ ossetenv(key,raw and value or resolveprefix(value))
+ end
end
local function getenv(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
- return value
- else
- local e=osgetenv(key)
- return e~=nil and e~="" and checkedvariable(e) or ""
- end
+ local value=rawget(instance.environment,key)
+ if value and value~="" then
+ return value
+ else
+ local e=osgetenv(key)
+ return e~=nil and e~="" and checkedvariable(e) or ""
+ end
end
resolvers.getenv=getenv
resolvers.env=getenv
local function resolvevariable(k)
- return instance.expansions[k]
+ return instance.expansions[k]
end
local dollarstripper=lpeg.stripper("$")
local inhibitstripper=P("!")^0*Cs(P(1)^0)
@@ -17802,1506 +21376,1506 @@ local somevariable=R("az","AZ","09","__","--")^1/resolvevariable
local variable=(P("$")/"")*(somevariable+(P("{")/"")*somevariable*(P("}")/""))
local variableresolver=Cs((variable+P(1))^0)
local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
+ return lpegmatch(variableexpander,var) or var
end
function resolvers.reset()
- if trace_locating then
- report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
- environment=environment,
- variables=variables,
- expansions=expansions,
- order=order,
- files={},
- setups={},
- found={},
- foundintrees={},
- hashes={},
- hashed={},
- pathlists=false,
- specification={},
- lists={},
- data={},
- fakepaths={},
- remember=true,
- diskcache=true,
- renewcache=false,
- renewtree=false,
- loaderror=false,
- savelists=true,
- pattern=nil,
- force_suffixes=true,
- pathstack={},
- }
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v=order[i][k]
- if v~=nil then
- t[k]=v
- return v
- end
- end
- if v==nil then
- v=""
- end
- t[k]=v
- return v
- end)
- setmetatableindex(environment,function(t,k)
- local v=osgetenv(k)
- if v==nil then
- v=variables[k]
- end
- if v~=nil then
- v=checkedvariable(v) or ""
- end
- v=resolvers.repath(v)
- t[k]=v
- return v
- end)
- setmetatableindex(expansions,function(t,k)
- local v=environment[k]
- if type(v)=="string" then
- v=lpegmatch(variableresolver,v)
- v=lpegmatch(variablecleaner,v)
- end
+ if trace_locating then
+ report_resolving("creating instance")
+ end
+ local environment={}
+ local variables={}
+ local expansions={}
+ local order={}
+ instance={
+ environment=environment,
+ variables=variables,
+ expansions=expansions,
+ order=order,
+ files={},
+ setups={},
+ found={},
+ foundintrees={},
+ hashes={},
+ hashed={},
+ pathlists=false,
+ specification={},
+ lists={},
+ data={},
+ fakepaths={},
+ remember=true,
+ diskcache=true,
+ renewcache=false,
+ renewtree=false,
+ loaderror=false,
+ savelists=true,
+ pattern=nil,
+ force_suffixes=true,
+ pathstack={},
+ }
+ setmetatableindex(variables,function(t,k)
+ local v
+ for i=1,#order do
+ v=order[i][k]
+ if v~=nil then
t[k]=v
return v
- end)
+ end
+ end
+ if v==nil then
+ v=""
+ end
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(environment,function(t,k)
+ local v=osgetenv(k)
+ if v==nil then
+ v=variables[k]
+ end
+ if v~=nil then
+ v=checkedvariable(v) or ""
+ end
+ v=resolvers.repath(v)
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(expansions,function(t,k)
+ local v=environment[k]
+ if type(v)=="string" then
+ v=lpegmatch(variableresolver,v)
+ v=lpegmatch(variablecleaner,v)
+ end
+ t[k]=v
+ return v
+ end)
end
function resolvers.initialized()
- return instance~=nil
+ return instance~=nil
end
local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
+ instance.lists={}
+ instance.pathlists=false
+ instance.found={}
end
local function reset_caches()
- instance.lists={}
- instance.pathlists=false
+ instance.lists={}
+ instance.pathlists=false
end
local slash=P("/")
local pathexpressionpattern=Cs (
- Cc("^")*(
- Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+ Cc("^")*(
+ Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$")
+ )^1*Cc("$")
)
local cache={}
local function makepathexpression(str)
- if str=="." then
- return "^%./$"
- else
- local c=cache[str]
- if not c then
- c=lpegmatch(pathexpressionpattern,str)
- cache[str]=c
- end
- return c
+ if str=="." then
+ return "^%./$"
+ else
+ local c=cache[str]
+ if not c then
+ c=lpegmatch(pathexpressionpattern,str)
+ cache[str]=c
end
+ return c
+ end
end
local function reportcriticalvariables(cnfspec)
- if trace_locating then
- for i=1,#resolvers.criticalvars do
- local k=resolvers.criticalvars[i]
- local v=resolvers.getenv(k) or "unknown"
- report_resolving("variable %a set to %a",k,v)
- end
- report_resolving()
- if cnfspec then
- report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
- end
- report_resolving()
+ if trace_locating then
+ for i=1,#resolvers.criticalvars do
+ local k=resolvers.criticalvars[i]
+ local v=resolvers.getenv(k) or "unknown"
+ report_resolving("variable %a set to %a",k,v)
+ end
+ report_resolving()
+ if cnfspec then
+ report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
end
- reportcriticalvariables=function() end
+ report_resolving()
+ end
+ reportcriticalvariables=function() end
end
local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
- local cnfspec=getenv("TEXMFCNF")
- if cnfspec=="" then
- cnfspec=resolvers.luacnfspec
- resolvers.luacnfstate="default"
- else
- resolvers.luacnfstate="environment"
- end
- reportcriticalvariables(cnfspec)
- local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
- local function locatecnf(luacnfname,kind)
- for i=1,#cnfpaths do
- local filepath=cnfpaths[i]
- local filename=collapsepath(filejoin(filepath,luacnfname))
- local realname=resolveprefix(filename)
- if trace_locating then
- local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
- local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
- report_resolving("looking for %s %a on %s path %a from specification %a",
- kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
- end
- if isfile(realname) then
- specification[#specification+1]=filename
- if trace_locating then
- report_resolving("found %s configuration file %a",kind,realname)
- end
- end
- end
- end
- locatecnf(resolvers.luacnfname,"regular")
- if #specification==0 then
- locatecnf(resolvers.luacnffallback,"fallback")
- end
+ local specification=instance.specification
+ if #specification==0 then
+ local cnfspec=getenv("TEXMFCNF")
+ if cnfspec=="" then
+ cnfspec=resolvers.luacnfspec
+ resolvers.luacnfstate="default"
+ else
+ resolvers.luacnfstate="environment"
+ end
+ reportcriticalvariables(cnfspec)
+ local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
+ local function locatecnf(luacnfname,kind)
+ for i=1,#cnfpaths do
+ local filepath=cnfpaths[i]
+ local filename=collapsepath(filejoin(filepath,luacnfname))
+ local realname=resolveprefix(filename)
if trace_locating then
- report_resolving()
+ local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
+ local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
+ report_resolving("looking for %s %a on %s path %a from specification %a",
+ kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+ end
+ if isfile(realname) then
+ specification[#specification+1]=filename
+ if trace_locating then
+ report_resolving("found %s configuration file %a",kind,realname)
+ end
end
- elseif trace_locating then
- report_resolving("configuration files already identified")
+ end
+ end
+ locatecnf(resolvers.luacnfname,"regular")
+ if #specification==0 then
+ locatecnf(resolvers.luacnffallback,"fallback")
+ end
+ if trace_locating then
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("configuration files already identified")
+ end
end
local function load_configuration_files()
- local specification=instance.specification
- if #specification>0 then
- local luacnfname=resolvers.luacnfname
- for i=1,#specification do
- local filename=specification[i]
- local pathname=filedirname(filename)
- local filename=filejoin(pathname,luacnfname)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local setups=instance.setups
- local data=blob()
- local parent=data and data.parent
- if parent then
- local filename=filejoin(pathname,parent)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local parentdata=blob()
- if parentdata then
- report_resolving("loading configuration file %a",filename)
- data=table.merged(parentdata,data)
- end
- end
- end
- data=data and data.content
- if data then
- if trace_locating then
- report_resolving("loading configuration file %a",filename)
- report_resolving()
- end
- local variables=data.variables or {}
- local warning=false
- for k,v in next,data do
- local variant=type(v)
- if variant=="table" then
- initializesetter(filename,k,v)
- elseif variables[k]==nil then
- if trace_locating and not warning then
- report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
- k,resolveprefix(filename))
- warning=true
- end
- variables[k]=v
- end
- end
- setups[pathname]=variables
- if resolvers.luacnfstate=="default" then
- local cnfspec=variables["TEXMFCNF"]
- if cnfspec then
- if trace_locating then
- report_resolving("reloading configuration due to TEXMF redefinition")
- end
- resolvers.setenv("TEXMFCNF",cnfspec)
- instance.specification={}
- identify_configuration_files()
- load_configuration_files()
- resolvers.luacnfstate="configuration"
- break
- end
- end
- else
- if trace_locating then
- report_resolving("skipping configuration file %a (no content)",filename)
- end
- setups[pathname]={}
- instance.loaderror=true
- end
- elseif trace_locating then
- report_resolving("skipping configuration file %a (no valid format)",filename)
+ local specification=instance.specification
+ if #specification>0 then
+ local luacnfname=resolvers.luacnfname
+ for i=1,#specification do
+ local filename=specification[i]
+ local pathname=filedirname(filename)
+ local filename=filejoin(pathname,luacnfname)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local setups=instance.setups
+ local data=blob()
+ local parent=data and data.parent
+ if parent then
+ local filename=filejoin(pathname,parent)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local parentdata=blob()
+ if parentdata then
+ report_resolving("loading configuration file %a",filename)
+ data=table.merged(parentdata,data)
end
- instance.order[#instance.order+1]=instance.setups[pathname]
- if instance.loaderror then
- break
+ end
+ end
+ data=data and data.content
+ if data then
+ if trace_locating then
+ report_resolving("loading configuration file %a",filename)
+ report_resolving()
+ end
+ local variables=data.variables or {}
+ local warning=false
+ for k,v in next,data do
+ local variant=type(v)
+ if variant=="table" then
+ initializesetter(filename,k,v)
+ elseif variables[k]==nil then
+ if trace_locating and not warning then
+ report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
+ k,resolveprefix(filename))
+ warning=true
+ end
+ variables[k]=v
+ end
+ end
+ setups[pathname]=variables
+ if resolvers.luacnfstate=="default" then
+ local cnfspec=variables["TEXMFCNF"]
+ if cnfspec then
+ if trace_locating then
+ report_resolving("reloading configuration due to TEXMF redefinition")
+ end
+ resolvers.setenv("TEXMFCNF",cnfspec)
+ instance.specification={}
+ identify_configuration_files()
+ load_configuration_files()
+ resolvers.luacnfstate="configuration"
+ break
end
+ end
+ else
+ if trace_locating then
+ report_resolving("skipping configuration file %a (no content)",filename)
+ end
+ setups[pathname]={}
+ instance.loaderror=true
end
- elseif trace_locating then
- report_resolving("warning: no lua configuration files found")
+ elseif trace_locating then
+ report_resolving("skipping configuration file %a (no valid format)",filename)
+ end
+ instance.order[#instance.order+1]=instance.setups[pathname]
+ if instance.loaderror then
+ break
+ end
end
+ elseif trace_locating then
+ report_resolving("warning: no lua configuration files found")
+ end
end
function resolvers.configurationfiles()
- return instance.specification or {}
+ return instance.specification or {}
end
local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- resolvers.hashers.byscheme(hash.type,hash.name)
- if instance.loaderror then break end
- end
+ instance.loaderror=false
+ instance.files={}
+ if not instance.renewcache then
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ resolvers.hashers.byscheme(hash.type,hash.name)
+ if instance.loaderror then break end
end
+ end
end
local function locate_file_databases()
- local texmfpaths=resolvers.expandedpathlist("TEXMF")
- if #texmfpaths>0 then
- for i=1,#texmfpaths do
- local path=collapsepath(texmfpaths[i])
- path=gsub(path,"/+$","")
- local stripped=lpegmatch(inhibitstripper,path)
- if stripped~="" then
- local runtime=stripped==path
- path=cleanpath(path)
- local spec=resolvers.splitmethod(stripped)
- if runtime and (spec.noscheme or spec.scheme=="file") then
- stripped="tree:///"..stripped
- elseif spec.scheme=="cache" or spec.scheme=="file" then
- stripped=spec.path
- end
- if trace_locating then
- if runtime then
- report_resolving("locating list of %a (runtime) (%s)",path,stripped)
- else
- report_resolving("locating list of %a (cached)",path)
- end
- end
- methodhandler('locators',stripped)
- end
+ local texmfpaths=resolvers.expandedpathlist("TEXMF")
+ if #texmfpaths>0 then
+ for i=1,#texmfpaths do
+ local path=collapsepath(texmfpaths[i])
+ path=gsub(path,"/+$","")
+ local stripped=lpegmatch(inhibitstripper,path)
+ if stripped~="" then
+ local runtime=stripped==path
+ path=cleanpath(path)
+ local spec=resolvers.splitmethod(stripped)
+ if runtime and (spec.noscheme or spec.scheme=="file") then
+ stripped="tree:///"..stripped
+ elseif spec.scheme=="cache" or spec.scheme=="file" then
+ stripped=spec.path
end
if trace_locating then
- report_resolving()
+ if runtime then
+ report_resolving("locating list of %a (runtime) (%s)",path,stripped)
+ else
+ report_resolving("locating list of %a (cached)",path)
+ end
end
- elseif trace_locating then
- report_resolving("no texmf paths are defined (using TEXMF)")
- end
-end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- methodhandler('generators',hash.name)
+ methodhandler('locators',stripped)
+ end
end
if trace_locating then
- report_resolving()
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("no texmf paths are defined (using TEXMF)")
+ end
+end
+local function generate_file_databases()
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ methodhandler('generators',hash.name)
+ end
+ if trace_locating then
+ report_resolving()
+ end
end
local function save_file_databases()
- for i=1,#instance.hashes do
- local hash=instance.hashes[i]
- local cachename=hash.name
- if hash.cache then
- local content=instance.files[cachename]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",cachename)
- end
- caches.savecontent(cachename,"files",content)
- elseif trace_locating then
- report_resolving("not saving runtime tree %a",cachename)
- end
+ for i=1,#instance.hashes do
+ local hash=instance.hashes[i]
+ local cachename=hash.name
+ if hash.cache then
+ local content=instance.files[cachename]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",cachename)
+ end
+ caches.savecontent(cachename,"files",content)
+ elseif trace_locating then
+ report_resolving("not saving runtime tree %a",cachename)
end
+ end
end
function resolvers.renew(hashname)
- if hashname and hashname~="" then
- local expanded=resolvers.expansion(hashname) or ""
- if expanded~="" then
- if trace_locating then
- report_resolving("identifying tree %a from %a",expanded,hashname)
- end
- hashname=expanded
- else
- if trace_locating then
- report_resolving("identifying tree %a",hashname)
- end
- end
- local realpath=resolveprefix(hashname)
- if isdir(realpath) then
- if trace_locating then
- report_resolving("using path %a",realpath)
- end
- methodhandler('generators',hashname)
- local content=instance.files[hashname]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",hashname)
- end
- caches.savecontent(hashname,"files",content)
- else
- report_resolving("invalid path %a",realpath)
- end
+ if hashname and hashname~="" then
+ local expanded=resolvers.expansion(hashname) or ""
+ if expanded~="" then
+ if trace_locating then
+ report_resolving("identifying tree %a from %a",expanded,hashname)
+ end
+ hashname=expanded
+ else
+ if trace_locating then
+ report_resolving("identifying tree %a",hashname)
+ end
end
+ local realpath=resolveprefix(hashname)
+ if isdir(realpath) then
+ if trace_locating then
+ report_resolving("using path %a",realpath)
+ end
+ methodhandler('generators',hashname)
+ local content=instance.files[hashname]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",hashname)
+ end
+ caches.savecontent(hashname,"files",content)
+ else
+ report_resolving("invalid path %a",realpath)
+ end
+ end
end
local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
- load_file_databases()
- if instance.loaderror then
- generate_file_databases()
- save_file_databases()
- end
- else
- generate_file_databases()
- if instance.renewcache then
- save_file_databases()
- end
+ locate_file_databases()
+ if instance.diskcache and not instance.renewcache then
+ load_file_databases()
+ if instance.loaderror then
+ generate_file_databases()
+ save_file_databases()
+ end
+ else
+ generate_file_databases()
+ if instance.renewcache then
+ save_file_databases()
end
+ end
end
function resolvers.appendhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a appended",name)
- end
- insert(instance.hashes,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a appended",name)
end
+ insert(instance.hashes,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.prependhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a prepended",name)
- end
- insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a prepended",name)
end
+ insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.extendtexmfvariable(specification)
- local t=resolvers.splitpath(getenv("TEXMF"))
- insert(t,1,specification)
- local newspec=concat(t,",")
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"]=newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"]=newspec
- else
- end
- reset_hashes()
+ local t=resolvers.splitpath(getenv("TEXMF"))
+ insert(t,1,specification)
+ local newspec=concat(t,",")
+ if instance.environment["TEXMF"] then
+ instance.environment["TEXMF"]=newspec
+ elseif instance.variables["TEXMF"] then
+ instance.variables["TEXMF"]=newspec
+ else
+ end
+ reset_hashes()
end
function resolvers.splitexpansions()
- local ie=instance.expansions
- for k,v in next,ie do
- local t,tn,h,p={},0,{},splitconfigurationpath(v)
- for kk=1,#p do
- local vv=p[kk]
- if vv~="" and not h[vv] then
- tn=tn+1
- t[tn]=vv
- h[vv]=true
- end
- end
- if #t>1 then
- ie[k]=t
- else
- ie[k]=t[1]
- end
+ local ie=instance.expansions
+ for k,v in next,ie do
+ local t,tn,h,p={},0,{},splitconfigurationpath(v)
+ for kk=1,#p do
+ local vv=p[kk]
+ if vv~="" and not h[vv] then
+ tn=tn+1
+ t[tn]=vv
+ h[vv]=true
+ end
end
+ if #t>1 then
+ ie[k]=t
+ else
+ ie[k]=t[1]
+ end
+ end
end
function resolvers.datastate()
- return caches.contentstate()
+ return caches.contentstate()
end
function resolvers.variable(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.variables[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.variables[name]
+ return result~=nil and result or ""
end
function resolvers.expansion(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.expansions[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.expansions[name]
+ return result~=nil and result or ""
end
function resolvers.unexpandedpathlist(str)
- local pth=resolvers.variable(str)
- local lst=resolvers.splitpath(pth)
- return expandedpathfromlist(lst)
+ local pth=resolvers.variable(str)
+ local lst=resolvers.splitpath(pth)
+ return expandedpathfromlist(lst)
end
function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+ return joinpath(resolvers.unexpandedpathlist(str))
end
function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
- lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
- lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
- report_resolving("pushing path %a",lastpath)
- end
+ local pathstack=instance.pathstack
+ local lastpath=pathstack[#pathstack]
+ local pluspath=filedirname(name)
+ if lastpath then
+ lastpath=collapsepath(filejoin(lastpath,pluspath))
+ else
+ lastpath=collapsepath(pluspath)
+ end
+ insert(pathstack,lastpath)
+ if trace_paths then
+ report_resolving("pushing path %a",lastpath)
+ end
end
function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
- report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
+ local pathstack=instance.pathstack
+ if trace_paths and #pathstack>0 then
+ report_resolving("popping path %a",pathstack[#pathstack])
+ end
+ remove(pathstack)
end
function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
+ local pathstack=instance.pathstack
+ local currentpath=pathstack[#pathstack]
+ return currentpath~="" and currentpath or nil
end
local done={}
function resolvers.resetextrapaths()
- local ep=instance.extra_paths
- if not ep then
- done={}
- instance.extra_paths={}
- elseif #ep>0 then
- done={}
- reset_caches()
- end
+ local ep=instance.extra_paths
+ if not ep then
+ done={}
+ instance.extra_paths={}
+ elseif #ep>0 then
+ done={}
+ reset_caches()
+ end
end
function resolvers.getextrapaths()
- return instance.extra_paths or {}
+ return instance.extra_paths or {}
end
function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
- if not paths or path=="" then
- return
- elseif done[paths] then
- return
- end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local ep=instance.extra_paths or {}
- local oldn=#ep
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
- if nofsubpaths>0 then
- for i=1,nofpaths do
- local p=paths[i]
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=p.."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- else
- for i=1,nofpaths do
- local p=paths[i]
- if not done[p] then
- newn=newn+1
- ep[newn]=cleanpath(p)
- done[p]=true
- end
- end
+ if not subpaths or subpaths=="" then
+ if not paths or path=="" then
+ return
+ elseif done[paths] then
+ return
+ end
+ end
+ local paths=settings_to_array(paths)
+ local subpaths=settings_to_array(subpaths)
+ local ep=instance.extra_paths or {}
+ local oldn=#ep
+ local newn=oldn
+ local nofpaths=#paths
+ local nofsubpaths=#subpaths
+ if nofpaths>0 then
+ if nofsubpaths>0 then
+ for i=1,nofpaths do
+ local p=paths[i]
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=p.."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
end
- elseif nofsubpaths>0 then
- for i=1,oldn do
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=ep[i].."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
+ end
+ else
+ for i=1,nofpaths do
+ local p=paths[i]
+ if not done[p] then
+ newn=newn+1
+ ep[newn]=cleanpath(p)
+ done[p]=true
end
+ end
end
- if newn>0 then
- instance.extra_paths=ep
- end
- if newn~=oldn then
- reset_caches()
+ elseif nofsubpaths>0 then
+ for i=1,oldn do
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=ep[i].."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
+ end
end
+ end
+ if newn>0 then
+ instance.extra_paths=ep
+ end
+ if newn~=oldn then
+ reset_caches()
+ end
end
function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- if instance.extra_stack then
- insert(instance.extra_stack,1,paths)
- else
- instance.extra_stack={ paths }
- end
- reset_caches()
+ local paths=settings_to_array(path)
+ if instance.extra_stack then
+ insert(instance.extra_stack,1,paths)
+ else
+ instance.extra_stack={ paths }
+ end
+ reset_caches()
end
function resolvers.popextrapath()
- if instance.extra_stack then
- reset_caches()
- return remove(instance.extra_stack,1)
- end
+ if instance.extra_stack then
+ reset_caches()
+ return remove(instance.extra_stack,1)
+ end
end
local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
- for k=1,#p do
- local v=p[k]
- if not done[v] then
- done[v]=true
- newn=newn+1
- new[newn]=v
- end
- end
+ local done={}
+ local new={}
+ local newn=0
+ local function add(p)
+ for k=1,#p do
+ local v=p[k]
+ if not done[v] then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ end
end
- for k=1,#list do
- local v=list[k]
- if done[v] then
- elseif find(v,"^[%.%/]$") then
- done[v]=true
- newn=newn+1
- new[newn]=v
- else
- break
- end
+ end
+ for k=1,#list do
+ local v=list[k]
+ if done[v] then
+ elseif find(v,"^[%.%/]$") then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ else
+ break
+ end
+ end
+ if extra_too then
+ local es=instance.extra_stack
+ if es and #es>0 then
+ for k=1,#es do
+ add(es[k])
+ end
end
- if extra_too then
- local es=instance.extra_stack
- if es and #es>0 then
- for k=1,#es do
- add(es[k])
- end
- end
- local ep=instance.extra_paths
- if ep and #ep>0 then
- add(ep)
- end
+ local ep=instance.extra_paths
+ if ep and #ep>0 then
+ add(ep)
end
- add(list)
- return new
+ end
+ add(list)
+ return new
end
function resolvers.cleanpathlist(str)
- local t=resolvers.expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i]=collapsepath(cleanpath(t[i]))
- end
+ local t=resolvers.expandedpathlist(str)
+ if t then
+ for i=1,#t do
+ t[i]=collapsepath(cleanpath(t[i]))
end
- return t
+ end
+ return t
end
function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
+ return joinpath(resolvers.expandedpathlist(str))
end
function resolvers.expandedpathlist(str,extra_too)
- if not str then
- return {}
- elseif instance.savelists then
- str=lpegmatch(dollarstripper,str)
- local lists=instance.lists
- local lst=lists[str]
- if not lst then
- local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
- lst=expandedpathfromlist(l)
- lists[str]=lst
- end
- return lst
- else
- local lst=resolvers.splitpath(resolvers.expansion(str))
- return made_list(instance,expandedpathfromlist(lst),extra_too)
+ if not str then
+ return {}
+ elseif instance.savelists then
+ str=lpegmatch(dollarstripper,str)
+ local lists=instance.lists
+ local lst=lists[str]
+ if not lst then
+ local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+ lst=expandedpathfromlist(l)
+ lists[str]=lst
end
+ return lst
+ else
+ local lst=resolvers.splitpath(resolvers.expansion(str))
+ return made_list(instance,expandedpathfromlist(lst),extra_too)
+ end
end
function resolvers.expandedpathlistfromvariable(str)
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp~="" and tmp or str)
+ str=lpegmatch(dollarstripper,str)
+ local tmp=resolvers.variableofformatorsuffix(str)
+ return resolvers.expandedpathlist(tmp~="" and tmp or str)
end
function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+ return joinpath(resolvers.expandedpathlistfromvariable(str))
end
function resolvers.cleanedpathlist(v)
- local t=resolvers.expandedpathlist(v)
- for i=1,#t do
- t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
- end
- return t
+ local t=resolvers.expandedpathlist(v)
+ for i=1,#t do
+ t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
+ end
+ return t
end
function resolvers.expandbraces(str)
- local pth=expandedpathfromlist(resolvers.splitpath(str))
- return joinpath(pth)
+ local pth=expandedpathfromlist(resolvers.splitpath(str))
+ return joinpath(pth)
end
function resolvers.registerfilehash(name,content,someerror)
- if content then
- instance.files[name]=content
- else
- instance.files[name]={}
- if somerror==true then
- instance.loaderror=someerror
- end
+ if content then
+ instance.files[name]=content
+ else
+ instance.files[name]={}
+ if somerror==true then
+ instance.loaderror=someerror
end
+ end
end
function resolvers.getfilehashes()
- return instance and instance.files or {}
+ return instance and instance.files or {}
end
function resolvers.gethashes()
- return instance and instance.hashes or {}
+ return instance and instance.hashes or {}
end
function resolvers.renewcache()
- if instance then
- instance.renewcache=true
- end
+ if instance then
+ instance.renewcache=true
+ end
end
local function isreadable(name)
- local readable=isfile(name)
- if trace_detail then
- if readable then
- report_resolving("file %a is readable",name)
- else
- report_resolving("file %a is not readable",name)
- end
+ local readable=isfile(name)
+ if trace_detail then
+ if readable then
+ report_resolving("file %a is readable",name)
+ else
+ report_resolving("file %a is not readable",name)
end
- return readable
+ end
+ return readable
end
local function collect_files(names)
- local filelist={}
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
- if not pathname or find(path,pathname) then
- local variant=hash.type
- local search=filejoin(root,path,name)
- local result=methodhandler('concatinators',variant,root,path,name)
- if trace_detail then
- report_resolving("match: variant %a, search %a, result %a",variant,search,result)
- end
- noffiles=noffiles+1
- filelist[noffiles]={ variant,search,result }
- end
+ local filelist={}
+ local noffiles=0
+ local function check(hash,root,pathname,path,basename,name)
+ if not pathname or find(path,pathname) then
+ local variant=hash.type
+ local search=filejoin(root,path,name)
+ local result=methodhandler('concatinators',variant,root,path,name)
+ if trace_detail then
+ report_resolving("match: variant %a, search %a, result %a",variant,search,result)
+ end
+ noffiles=noffiles+1
+ filelist[noffiles]={ variant,search,result }
end
- for k=1,#names do
- local filename=names[k]
+ end
+ for k=1,#names do
+ local filename=names[k]
+ if trace_detail then
+ report_resolving("checking name %a",filename)
+ end
+ local basename=filebasename(filename)
+ local pathname=filedirname(filename)
+ if pathname=="" or find(pathname,"^%.") then
+ pathname=false
+ else
+ pathname=gsub(pathname,"%*",".*")
+ pathname="/"..pathname.."$"
+ end
+ local hashes=instance.hashes
+ for h=1,#hashes do
+ local hash=hashes[h]
+ local hashname=hash.name
+ local content=hashname and instance.files[hashname]
+ if content then
if trace_detail then
- report_resolving("checking name %a",filename)
+ report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
end
- local basename=filebasename(filename)
- local pathname=filedirname(filename)
- if pathname=="" or find(pathname,"^%.") then
- pathname=false
- else
- pathname=gsub(pathname,"%*",".*")
- pathname="/"..pathname.."$"
- end
- local hashes=instance.hashes
- for h=1,#hashes do
- local hash=hashes[h]
- local hashname=hash.name
- local content=hashname and instance.files[hashname]
- if content then
- if trace_detail then
- report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
- end
- local path,name=lookup(content,basename)
- if path then
- local metadata=content.metadata
- local realroot=metadata and metadata.path or hashname
- if type(path)=="string" then
- check(hash,realroot,pathname,path,basename,name)
- else
- for i=1,#path do
- check(hash,realroot,pathname,path[i],basename,name)
- end
- end
- end
- elseif trace_locating then
- report_resolving("no match in %a (%s)",hashname,basename)
+ local path,name=lookup(content,basename)
+ if path then
+ local metadata=content.metadata
+ local realroot=metadata and metadata.path or hashname
+ if type(path)=="string" then
+ check(hash,realroot,pathname,path,basename,name)
+ else
+ for i=1,#path do
+ check(hash,realroot,pathname,path[i],basename,name)
end
+ end
end
+ elseif trace_locating then
+ report_resolving("no match in %a (%s)",hashname,basename)
+ end
end
- return noffiles>0 and filelist or nil
+ end
+ return noffiles>0 and filelist or nil
end
local fit={}
function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
- local collapsed=collapsepath(foundname,true)
- local t={
- filename=filename,
- format=format~="" and format or nil,
- filetype=filetype~="" and filetype or nil,
- usedmethod=usedmethod,
- foundname=foundname,
- fullname=collapsed,
- }
- fit[foundname]=t
- foundintrees[#foundintrees+1]=t
- end
+ local foundintrees=instance.foundintrees
+ if usedmethod=="direct" and filename==foundname and fit[foundname] then
+ else
+ local collapsed=collapsepath(foundname,true)
+ local t={
+ filename=filename,
+ format=format~="" and format or nil,
+ filetype=filetype~="" and filetype or nil,
+ usedmethod=usedmethod,
+ foundname=foundname,
+ fullname=collapsed,
+ }
+ fit[foundname]=t
+ foundintrees[#foundintrees+1]=t
+ end
end
function resolvers.foundintrees()
- return instance.foundintrees or {}
+ return instance.foundintrees or {}
end
function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
+ local f=fit[fullname]
+ return f and f.usedmethod=="database"
end
local function can_be_dir(name)
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
- if isdir(name) then
- fakepaths[name]=1
- else
- fakepaths[name]=2
- end
+ local fakepaths=instance.fakepaths
+ if not fakepaths[name] then
+ if isdir(name) then
+ fakepaths[name]=1
+ else
+ fakepaths[name]=2
end
- return fakepaths[name]==1
+ end
+ return fakepaths[name]==1
end
local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
- if filesuffix=="" or not suffixmap[filesuffix] then
- local defaultsuffixes=resolvers.defaultsuffixes
- local formatofsuffix=resolvers.formatofsuffix
- for i=1,#defaultsuffixes do
- local forcedname=filename..'.'..defaultsuffixes[i]
- wantedfiles[#wantedfiles+1]=forcedname
- filetype=formatofsuffix(forcedname)
- if trace_locating then
- report_resolving("forcing filetype %a",filetype)
- end
- end
- else
- filetype=resolvers.formatofsuffix(filename)
- if trace_locating then
- report_resolving("using suffix based filetype %a",filetype)
- end
+ local filetype=''
+ local filesuffix=suffixonly(filename)
+ local wantedfiles={}
+ wantedfiles[#wantedfiles+1]=filename
+ if askedformat=="" then
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local defaultsuffixes=resolvers.defaultsuffixes
+ local formatofsuffix=resolvers.formatofsuffix
+ for i=1,#defaultsuffixes do
+ local forcedname=filename..'.'..defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1]=forcedname
+ filetype=formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolving("forcing filetype %a",filetype)
end
+ end
else
- if filesuffix=="" or not suffixmap[filesuffix] then
- local format_suffixes=suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
- end
- end
- end
- filetype=askedformat
- if trace_locating then
- report_resolving("using given filetype %a",filetype)
+ filetype=resolvers.formatofsuffix(filename)
+ if trace_locating then
+ report_resolving("using suffix based filetype %a",filetype)
+ end
+ end
+ else
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local format_suffixes=suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
end
+ end
end
- return filetype,wantedfiles
+ filetype=askedformat
+ if trace_locating then
+ report_resolving("using given filetype %a",filetype)
+ end
+ end
+ return filetype,wantedfiles
end
local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
- if trace_detail then
- report_resolving("file %a found directly",filename)
- end
- return "direct",{ filename }
+ if not dangerous[askedformat] and isreadable(filename) then
+ if trace_detail then
+ report_resolving("file %a found directly",filename)
end
+ return "direct",{ filename }
+ end
end
local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
- if trace_locating then
- report_resolving("checking wildcard %a",filename)
- end
- local result=resolvers.findwildcardfiles(filename)
- if result then
- return "wildcard",result
- end
- end
-end
-local function find_qualified(filename,allresults,askedformat,alsostripped)
- if not is_qualified_path(filename) then
- return
- end
+ if find(filename,'*',1,true) then
if trace_locating then
- report_resolving("checking qualified name %a",filename)
+ report_resolving("checking wildcard %a",filename)
end
- if isreadable(filename) then
- if trace_detail then
- report_resolving("qualified file %a found",filename)
- end
- return "qualified",{ filename }
+ local result=resolvers.findwildcardfiles(filename)
+ if result then
+ return "wildcard",result
end
+ end
+end
+local function find_qualified(filename,allresults,askedformat,alsostripped)
+ if not is_qualified_path(filename) then
+ return
+ end
+ if trace_locating then
+ report_resolving("checking qualified name %a",filename)
+ end
+ if isreadable(filename) then
if trace_detail then
- report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then
- local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s=format_suffixes[i]
- forcedname=filename.."."..s
- if isreadable(forcedname) then
- if trace_locating then
- report_resolving("no suffix, forcing format filetype %a",s)
- end
- return "qualified",{ forcedname }
- end
- end
+ report_resolving("qualified file %a found",filename)
+ end
+ return "qualified",{ filename }
+ end
+ if trace_detail then
+ report_resolving("locating qualified file %a",filename)
+ end
+ local forcedname,suffix="",suffixonly(filename)
+ if suffix=="" then
+ local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s=format_suffixes[i]
+ forcedname=filename.."."..s
+ if isreadable(forcedname) then
+ if trace_locating then
+ report_resolving("no suffix, forcing format filetype %a",s)
+ end
+ return "qualified",{ forcedname }
end
+ end
end
- if alsostripped and suffix and suffix~="" then
- local basename=filebasename(filename)
- local pattern=lpegmatch(preparetreepattern,filename)
- local savedformat=askedformat
- local format=savedformat or ""
- if format=="" then
- askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if alsostripped and suffix and suffix~="" then
+ local basename=filebasename(filename)
+ local pattern=lpegmatch(preparetreepattern,filename)
+ local savedformat=askedformat
+ local format=savedformat or ""
+ if format=="" then
+ askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if not format then
+ askedformat="othertextfiles"
+ end
+ if basename~=filename then
+ local resolved=collect_instance_files(basename,askedformat,allresults)
+ if #resolved==0 then
+ local lowered=lower(basename)
+ if filename~=lowered then
+ resolved=collect_instance_files(lowered,askedformat,allresults)
end
- if not format then
- askedformat="othertextfiles"
+ end
+ resolvers.format=savedformat
+ if #resolved>0 then
+ local result={}
+ for r=1,#resolved do
+ local rr=resolved[r]
+ if find(rr,pattern) then
+ result[#result+1]=rr
+ end
end
- if basename~=filename then
- local resolved=collect_instance_files(basename,askedformat,allresults)
- if #resolved==0 then
- local lowered=lower(basename)
- if filename~=lowered then
- resolved=collect_instance_files(lowered,askedformat,allresults)
- end
- end
- resolvers.format=savedformat
- if #resolved>0 then
- local result={}
- for r=1,#resolved do
- local rr=resolved[r]
- if find(rr,pattern) then
- result[#result+1]=rr
- end
- end
- if #result>0 then
- return "qualified",result
- end
- end
+ if #result>0 then
+ return "qualified",result
end
+ end
end
+ end
end
local function check_subpath(fname)
- if isreadable(fname) then
- if trace_detail then
- report_resolving("found %a by deep scanning",fname)
- end
- return fname
+ if isreadable(fname) then
+ if trace_detail then
+ report_resolving("found %a by deep scanning",fname)
end
+ return fname
+ end
end
local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
- local entry={}
- if pathlist and #pathlist>0 then
- for k=1,#pathlist do
- local path=pathlist[k]
- local prescanned=find(path,'^!!')
- local resursive=find(path,'//$')
- local pathname=lpegmatch(inhibitstripper,path)
- local expression=makepathexpression(pathname)
- local barename=gsub(pathname,"/+$","")
- barename=resolveprefix(barename)
- local scheme=url.hasscheme(barename)
- local schemename=gsub(barename,"%.%*$",'')
- entry[k]={
- path=path,
- pathname=pathname,
- prescanned=prescanned,
- recursive=recursive,
- expression=expression,
- barename=barename,
- scheme=scheme,
- schemename=schemename,
- }
- end
- entry.typespec=typespec
- list[filetype]=entry
- else
- list[filetype]=false
- end
- return entry
+ local typespec=resolvers.variableofformat(filetype)
+ local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
+ local entry={}
+ if pathlist and #pathlist>0 then
+ for k=1,#pathlist do
+ local path=pathlist[k]
+ local prescanned=find(path,'^!!')
+ local resursive=find(path,'//$')
+ local pathname=lpegmatch(inhibitstripper,path)
+ local expression=makepathexpression(pathname)
+ local barename=gsub(pathname,"/+$","")
+ barename=resolveprefix(barename)
+ local scheme=url.hasscheme(barename)
+ local schemename=gsub(barename,"%.%*$",'')
+ entry[k]={
+ path=path,
+ pathname=pathname,
+ prescanned=prescanned,
+ recursive=recursive,
+ expression=expression,
+ barename=barename,
+ scheme=scheme,
+ schemename=schemename,
+ }
+ end
+ entry.typespec=typespec
+ list[filetype]=entry
+ else
+ list[filetype]=false
+ end
+ return entry
end
local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
- pathlists=setmetatableindex({},makepathlist)
- instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
- local method="intree"
- local filelist=collect_files(wantedfiles)
- local dirlist={}
- local result={}
- if filelist then
- for i=1,#filelist do
- dirlist[i]=filedirname(filelist[i][3]).."/"
+ local pathlists=instance.pathlists
+ if not pathlists then
+ pathlists=setmetatableindex({},makepathlist)
+ instance.pathlists=pathlists
+ end
+ local pathlist=pathlists[filetype]
+ if pathlist then
+ local method="intree"
+ local filelist=collect_files(wantedfiles)
+ local dirlist={}
+ local result={}
+ if filelist then
+ for i=1,#filelist do
+ dirlist[i]=filedirname(filelist[i][3]).."/"
+ end
+ end
+ if trace_detail then
+ report_resolving("checking filename %a in tree",filename)
+ end
+ for k=1,#pathlist do
+ local entry=pathlist[k]
+ local path=entry.path
+ local pathname=entry.pathname
+ local done=false
+ if filelist then
+ local expression=entry.expression
+ if trace_detail then
+ report_resolving("using pattern %a for path %a",expression,pathname)
+ end
+ for k=1,#filelist do
+ local fl=filelist[k]
+ local f=fl[2]
+ local d=dirlist[k]
+ if find(d,expression) or find(resolveprefix(d),expression) then
+ result[#result+1]=resolveprefix(fl[3])
+ done=true
+ if allresults then
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
+ end
+ else
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
+ end
+ break
end
+ elseif trace_detail then
+ report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ end
end
- if trace_detail then
- report_resolving("checking filename %a in tree",filename)
- end
- for k=1,#pathlist do
- local entry=pathlist[k]
- local path=entry.path
- local pathname=entry.pathname
- local done=false
- if filelist then
- local expression=entry.expression
+ end
+ if done then
+ method="database"
+ else
+ method="filesystem"
+ local scheme=entry.scheme
+ if not scheme or scheme=="file" then
+ local pname=entry.schemename
+ if not find(pname,"*",1,true) then
+ if can_be_dir(pname) then
+ if not done and not entry.prescanned then
if trace_detail then
- report_resolving("using pattern %a for path %a",expression,pathname)
- end
- for k=1,#filelist do
- local fl=filelist[k]
- local f=fl[2]
- local d=dirlist[k]
- if find(d,expression) or find(resolveprefix(d),expression) then
- result[#result+1]=resolveprefix(fl[3])
- done=true
- if allresults then
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
- end
- else
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
- end
- break
- end
- elseif trace_detail then
- report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ report_resolving("quick root scan for %a",pname)
+ end
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local fname=check_subpath(filejoin(pname,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
- end
- end
- if done then
- method="database"
- else
- method="filesystem"
- local scheme=entry.scheme
- if not scheme or scheme=="file" then
- local pname=entry.schemename
- if not find(pname,"*",1,true) then
- if can_be_dir(pname) then
- if not done and not entry.prescanned then
- if trace_detail then
- report_resolving("quick root scan for %a",pname)
- end
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local fname=check_subpath(filejoin(pname,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- if not done and entry.recursive then
- if trace_detail then
- report_resolving("scanning filesystem for %a",pname)
- end
- local files=resolvers.simplescanfiles(pname,false,true)
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local subpath=files[w]
- if not subpath or subpath=="" then
- elseif type(subpath)=="string" then
- local fname=check_subpath(filejoin(pname,subpath,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- else
- for i=1,#subpath do
- local sp=subpath[i]
- if sp=="" then
- else
- local fname=check_subpath(filejoin(pname,sp,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- end
- end
- end
+ end
+ end
+ if not done and entry.recursive then
+ if trace_detail then
+ report_resolving("scanning filesystem for %a",pname)
+ end
+ local files=resolvers.simplescanfiles(pname,false,true)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local subpath=files[w]
+ if not subpath or subpath=="" then
+ elseif type(subpath)=="string" then
+ local fname=check_subpath(filejoin(pname,subpath,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
+ end
else
- end
- else
- for k=1,#wantedfiles do
- local pname=entry.barename
- local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
- if fname then
+ for i=1,#subpath do
+ local sp=subpath[i]
+ if sp=="" then
+ else
+ local fname=check_subpath(filejoin(pname,sp,w))
+ if fname then
result[#result+1]=fname
done=true
if not allresults then
- break
+ break
end
+ end
end
+ end
+ if done and not allresults then
+ break
+ end
end
+ end
end
+ end
end
- if done and not allresults then
+ else
+ end
+ else
+ for k=1,#wantedfiles do
+ local pname=entry.barename
+ local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
break
+ end
end
+ end
end
- if #result>0 then
- return method,result
- end
+ end
+ if done and not allresults then
+ break
+ end
+ end
+ if #result>0 then
+ return method,result
end
+ end
end
local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_detail then
- report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
- local fname=wantedfiles[k]
- if fname and isreadable(fname) then
- filename=fname
- result[#result+1]=filejoin('.',fname)
- if not allresults then
- break
- end
- end
- end
- if #result>0 then
- return "onpath",result
+ if trace_detail then
+ report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
+ end
+ local result={}
+ for k=1,#wantedfiles do
+ local fname=wantedfiles[k]
+ if fname and isreadable(fname) then
+ filename=fname
+ result[#result+1]=filejoin('.',fname)
+ if not allresults then
+ break
+ end
end
+ end
+ if #result>0 then
+ return "onpath",result
+ end
end
local function find_otherwise(filename,filetype,wantedfiles,allresults)
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
- return "otherwise",{ resolveprefix(fl[3]) }
- end
+ local filelist=collect_files(wantedfiles)
+ local fl=filelist and filelist[1]
+ if fl then
+ return "otherwise",{ resolveprefix(fl[3]) }
+ end
end
collect_instance_files=function(filename,askedformat,allresults)
- if not filename or filename=="" then
- return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/")
- if allresults then
- local filetype,wantedfiles=find_analyze(filename,askedformat)
- local results={
- { find_direct (filename,true) },
- { find_wildcard (filename,true) },
- { find_qualified(filename,true,askedformat) },
- { find_intree (filename,filetype,wantedfiles,true) },
- { find_onpath (filename,filetype,wantedfiles,true) },
- { find_otherwise(filename,filetype,wantedfiles,true) },
- }
- local result,status,done={},{},{}
- for k,r in next,results do
- local method,list=r[1],r[2]
- if method and list then
- for i=1,#list do
- local c=collapsepath(list[i])
- if not done[c] then
- result[#result+1]=c
- done[c]=true
- end
- status[#status+1]=formatters["%-10s: %s"](method,c)
- end
- end
- end
- if trace_detail then
- report_resolving("lookup status: %s",table.serialize(status,filename))
+ if not filename or filename=="" then
+ return {}
+ end
+ askedformat=askedformat or ""
+ filename=collapsepath(filename,".")
+ filename=gsub(filename,"^%./",getcurrentdir().."/")
+ if allresults then
+ local filetype,wantedfiles=find_analyze(filename,askedformat)
+ local results={
+ { find_direct (filename,true) },
+ { find_wildcard (filename,true) },
+ { find_qualified(filename,true,askedformat) },
+ { find_intree (filename,filetype,wantedfiles,true) },
+ { find_onpath (filename,filetype,wantedfiles,true) },
+ { find_otherwise(filename,filetype,wantedfiles,true) },
+ }
+ local result,status,done={},{},{}
+ for k,r in next,results do
+ local method,list=r[1],r[2]
+ if method and list then
+ for i=1,#list do
+ local c=collapsepath(list[i])
+ if not done[c] then
+ result[#result+1]=c
+ done[c]=true
+ end
+ status[#status+1]=formatters["%-10s: %s"](method,c)
end
- return result,status
- else
- local method,result,stamp,filetype,wantedfiles
- if instance.remember then
- if askedformat=="" then
- stamp=formatters["%s::%s"](suffixonly(filename),filename)
- else
- stamp=formatters["%s::%s"](askedformat,filename)
- end
- result=stamp and instance.found[stamp]
- if result then
- if trace_locating then
- report_resolving("remembered file %a",filename)
- end
- return result
- end
+ end
+ end
+ if trace_detail then
+ report_resolving("lookup status: %s",table.serialize(status,filename))
+ end
+ return result,status
+ else
+ local method,result,stamp,filetype,wantedfiles
+ if instance.remember then
+ if askedformat=="" then
+ stamp=formatters["%s::%s"](suffixonly(filename),filename)
+ else
+ stamp=formatters["%s::%s"](askedformat,filename)
+ end
+ result=stamp and instance.found[stamp]
+ if result then
+ if trace_locating then
+ report_resolving("remembered file %a",filename)
end
- method,result=find_direct(filename)
+ return result
+ end
+ end
+ method,result=find_direct(filename)
+ if not result then
+ method,result=find_wildcard(filename)
+ if not result then
+ method,result=find_qualified(filename,false,askedformat)
if not result then
- method,result=find_wildcard(filename)
- if not result then
- method,result=find_qualified(filename,false,askedformat)
- if not result then
- filetype,wantedfiles=find_analyze(filename,askedformat)
- method,result=find_intree(filename,filetype,wantedfiles)
- if not result then
- method,result=find_onpath(filename,filetype,wantedfiles)
- if resolve_otherwise and not result then
- method,result=find_otherwise(filename,filetype,wantedfiles)
- end
- end
- end
- end
- end
- if result and #result>0 then
- local foundname=collapsepath(result[1])
- resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
- result={ foundname }
- else
- result={}
- end
- if stamp then
- if trace_locating then
- report_resolving("remembering file %a using hash %a",filename,stamp)
+ filetype,wantedfiles=find_analyze(filename,askedformat)
+ method,result=find_intree(filename,filetype,wantedfiles)
+ if not result then
+ method,result=find_onpath(filename,filetype,wantedfiles)
+ if resolve_otherwise and not result then
+ method,result=find_otherwise(filename,filetype,wantedfiles)
end
- instance.found[stamp]=result
+ end
end
- return result
+ end
+ end
+ if result and #result>0 then
+ local foundname=collapsepath(result[1])
+ resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
+ result={ foundname }
+ else
+ result={}
end
+ if stamp then
+ if trace_locating then
+ report_resolving("remembering file %a using hash %a",filename,stamp)
+ end
+ instance.found[stamp]=result
+ end
+ return result
+ end
end
local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
- return {}
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
- local lowered=lower(filename)
- if filename~=lowered then
- result,status=collect_instance_files(lowered,filetype or "",allresults)
- end
+ if not filename or filename=="" then
+ return {}
+ end
+ local result,status=collect_instance_files(filename,filetype or "",allresults)
+ if not result or #result==0 then
+ local lowered=lower(filename)
+ if filename~=lowered then
+ result,status=collect_instance_files(lowered,filetype or "",allresults)
end
- return result or {},status
+ end
+ return result or {},status
end
function resolvers.findfiles(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,true)
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,true)
+ end
end
function resolvers.findfile(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,false)[1] or ""
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,false)[1] or ""
+ end
end
function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
+ return filedirname(findfiles(filename,filetype,false)[1] or "")
end
local function findgivenfiles(filename,allresults)
- local base=filebasename(filename)
- local result={}
- local hashes=instance.hashes
- local function okay(hash,path,name)
- local found=methodhandler('concatinators',hash.type,hash.name,path,name)
- if found and found~="" then
- result[#result+1]=resolveprefix(found)
- return not allresults
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local content=instance.files[hash.name]
- if content then
- local path,name=lookup(content,base)
- if not path then
- elseif type(path)=="string" then
- if okay(hash,path,name) then
- return result
- end
- else
- for i=1,#path do
- if okay(hash,path[i],name) then
- return result
- end
- end
- end
+ local base=filebasename(filename)
+ local result={}
+ local hashes=instance.hashes
+ local function okay(hash,path,name)
+ local found=methodhandler('concatinators',hash.type,hash.name,path,name)
+ if found and found~="" then
+ result[#result+1]=resolveprefix(found)
+ return not allresults
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local content=instance.files[hash.name]
+ if content then
+ local path,name=lookup(content,base)
+ if not path then
+ elseif type(path)=="string" then
+ if okay(hash,path,name) then
+ return result
+ end
+ else
+ for i=1,#path do
+ if okay(hash,path[i],name) then
+ return result
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
+ return findgivenfiles(filename,true)
end
function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
+ return findgivenfiles(filename,false)[1] or ""
end
local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
+ (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
)
function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
+ return lpegmatch(makewildcard,pattern) or pattern
end
local function findwildcardfiles(filename,allresults,result)
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- local files=instance.files
- if find(name,"*",1,true) then
- local hashes=instance.hashes
- local function okay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
+ local result=result or {}
+ local base=filebasename(filename)
+ local dirn=filedirname(filename)
+ local path=lower(lpegmatch(makewildcard,dirn) or dirn)
+ local name=lower(lpegmatch(makewildcard,base) or base)
+ local files=instance.files
+ if find(name,"*",1,true) then
+ local hashes=instance.hashes
+ local function okay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- for found,base in filtered(files[hashname],name) do
- if type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ for found,base in filtered(files[hashname],name) do
+ if type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
end
- end
- else
- local function okayokay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
+ end
end
+ end
end
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- local found,base=lookup(content,base)
- if not found then
- elseif type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
+ end
+ end
+ else
+ local function okayokay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
+ end
+ end
+ end
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ local found,base=lookup(content,base)
+ if not found then
+ elseif type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
+ end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
end
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
+ return findwildcardfiles(filename,true,result)
end
function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
+ return findwildcardfiles(filename,false)[1] or ""
end
function resolvers.automount()
end
function resolvers.starttiming()
- statistics.starttiming(instance)
+ statistics.starttiming(instance)
end
function resolvers.stoptiming()
- statistics.stoptiming(instance)
+ statistics.stoptiming(instance)
end
function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
- load_databases()
- resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
+ resolvers.starttiming()
+ identify_configuration_files()
+ load_configuration_files()
+ if option~="nofiles" then
+ load_databases()
+ resolvers.automount()
+ end
+ resolvers.stoptiming()
+ local files=instance.files
+ return files and next(files) and true
end
function resolvers.loadtime()
- return statistics.elapsedtime(instance)
+ return statistics.elapsedtime(instance)
end
local function report(str)
- if trace_locating then
- report_resolving(str)
- else
- print(str)
- end
+ if trace_locating then
+ report_resolving(str)
+ else
+ print(str)
+ end
end
function resolvers.dowithfilesandreport(command,files,...)
- if files and #files>0 then
- if trace_locating then
- report('')
- end
- if type(files)=="string" then
- files={ files }
- end
- for f=1,#files do
- local file=files[f]
- local result=command(file,...)
- if type(result)=='string' then
- report(result)
- else
- for i=1,#result do
- report(result[i])
- end
- end
+ if files and #files>0 then
+ if trace_locating then
+ report('')
+ end
+ if type(files)=="string" then
+ files={ files }
+ end
+ for f=1,#files do
+ local file=files[f]
+ local result=command(file,...)
+ if type(result)=='string' then
+ report(result)
+ else
+ for i=1,#result do
+ report(result[i])
end
+ end
end
+ end
end
-function resolvers.showpath(str)
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+function resolvers.showpath(str)
+ return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
end
function resolvers.registerfile(files,name,path)
- if files[name] then
- if type(files[name])=='string' then
- files[name]={ files[name],path }
- else
- files[name]=path
- end
+ if files[name] then
+ if type(files[name])=='string' then
+ files[name]={ files[name],path }
else
- files[name]=path
+ files[name]=path
end
+ else
+ files[name]=path
+ end
end
function resolvers.dowithpath(name,func)
- local pathlist=resolvers.expandedpathlist(name)
- for i=1,#pathlist do
- func("^"..cleanpath(pathlist[i]))
- end
+ local pathlist=resolvers.expandedpathlist(name)
+ for i=1,#pathlist do
+ func("^"..cleanpath(pathlist[i]))
+ end
end
function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
+ func(expandedvariable(name))
end
function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(name)
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
- fmtname=resolvers.findfile(fullname)
- fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
- local barename=removesuffix(fmtname)
- local luaname=addsuffix(barename,luasuffixes.lua)
- local lucname=addsuffix(barename,luasuffixes.luc)
- local luiname=addsuffix(barename,luasuffixes.lui)
- if isfile(luiname) then
- return barename,luiname
- elseif isfile(lucname) then
- return barename,lucname
- elseif isfile(luaname) then
- return barename,luaname
- end
- end
- return nil,nil
+ local engine=environment.ownmain or "luatex"
+ local barename=removesuffix(name)
+ local fullname=addsuffix(barename,"fmt")
+ local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
+ if fmtname=="" then
+ fmtname=resolvers.findfile(fullname)
+ fmtname=cleanpath(fmtname)
+ end
+ if fmtname~="" then
+ local barename=removesuffix(fmtname)
+ local luaname=addsuffix(barename,luasuffixes.lua)
+ local lucname=addsuffix(barename,luasuffixes.luc)
+ local luiname=addsuffix(barename,luasuffixes.lui)
+ if isfile(luiname) then
+ return barename,luiname
+ elseif isfile(lucname) then
+ return barename,lucname
+ elseif isfile(luaname) then
+ return barename,luaname
+ end
+ end
+ return nil,nil
end
function resolvers.booleanvariable(str,default)
- local b=resolvers.expansion(str)
- if b=="" then
- return default
- else
- b=toboolean(b)
- return (b==nil and default) or b
- end
+ local b=resolvers.expansion(str)
+ if b=="" then
+ return default
+ else
+ b=toboolean(b)
+ return (b==nil and default) or b
+ end
end
function resolvers.dowithfilesintree(pattern,handle,before,after)
- local hashes=instance.hashes
- for i=1,#hashes do
- local hash=hashes[i]
- local blobtype=hash.type
- local blobpath=hash.name
- if blobtype and blobpath then
- local total=0
- local checked=0
- local done=0
- if before then
- before(blobtype,blobpath,pattern)
- end
- for path,name in filtered(instance.files[blobpath],pattern) do
- if type(path)=="string" then
- checked=checked+1
- if handle(blobtype,blobpath,path,name) then
- done=done+1
- end
- else
- checked=checked+#path
- for i=1,#path do
- if handle(blobtype,blobpath,path[i],name) then
- done=done+1
- end
- end
- end
- end
- if after then
- after(blobtype,blobpath,pattern,total,checked,done)
+ local hashes=instance.hashes
+ for i=1,#hashes do
+ local hash=hashes[i]
+ local blobtype=hash.type
+ local blobpath=hash.name
+ if blobtype and blobpath then
+ local total=0
+ local checked=0
+ local done=0
+ if before then
+ before(blobtype,blobpath,pattern)
+ end
+ for path,name in filtered(instance.files[blobpath],pattern) do
+ if type(path)=="string" then
+ checked=checked+1
+ if handle(blobtype,blobpath,path,name) then
+ done=done+1
+ end
+ else
+ checked=checked+#path
+ for i=1,#path do
+ if handle(blobtype,blobpath,path[i],name) then
+ done=done+1
end
+ end
end
+ end
+ if after then
+ after(blobtype,blobpath,pattern,checked,done)
+ end
end
+ end
end
local obsolete=resolvers.obsolete or {}
resolvers.obsolete=obsolete
-resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
-resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
+resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
+resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
function resolvers.knownvariables(pattern)
- if instance then
- local environment=instance.environment
- local variables=instance.variables
- local expansions=instance.expansions
- local order=instance.order
- local pattern=upper(pattern or "")
- local result={}
- for i=1,#order do
- for key in next,order[i] do
- if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
- result[key]={
- environment=rawget(environment,key),
- variable=key,
- expansion=expansions[key],
- resolved=resolveprefix(expansions[key]),
- }
- end
- end
+ if instance then
+ local environment=instance.environment
+ local variables=instance.variables
+ local expansions=instance.expansions
+ local order=instance.order
+ local pattern=upper(pattern or "")
+ local result={}
+ for i=1,#order do
+ for key in next,order[i] do
+ if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
+ result[key]={
+ environment=rawget(environment,key),
+ variable=key,
+ expansion=expansions[key],
+ resolved=resolveprefix(expansions[key]),
+ }
end
- return result
- else
- return {}
+ end
end
+ return result
+ else
+ return {}
+ end
end
@@ -19311,14 +22885,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-pre"] = package.loaded["data-pre"] or true
--- original size: 4090, stripped down to: 3059
+-- original size: 4854, stripped down to: 2889
if not modules then modules={} end modules ['data-pre']={
- 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 resolvers=resolvers
local prefixes=resolvers.prefixes
@@ -19331,64 +22905,64 @@ local dirname=file.dirname
local joinpath=file.join
local isfile=lfs.isfile
prefixes.environment=function(str)
- return cleanpath(expansion(str))
+ return cleanpath(expansion(str))
end
local function relative(str,n)
- if not isfile(str) then
- local pstr="./"..str
+ if not isfile(str) then
+ local pstr="./"..str
+ if isfile(pstr) then
+ str=pstr
+ else
+ local p="../"
+ for i=1,n or 2 do
+ local pstr=p..str
if isfile(pstr) then
- str=pstr
+ str=pstr
+ break
else
- local p="../"
- for i=1,n or 2 do
- local pstr=p..str
- if isfile(pstr) then
- str=pstr
- break
- else
- p=p.."../"
- end
- end
+ p=p.."../"
end
+ end
end
- return cleanpath(str)
+ end
+ return cleanpath(str)
end
local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(fullname~="" and fullname or str)
end
prefixes.relative=relative
prefixes.locate=locate
prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
- fullname=locate(str)
- end
- return fullname
+ local fullname=relative(str)
+ if not isfile(fullname) then
+ fullname=locate(str)
+ end
+ return fullname
end
prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(basename((fullname~="" and fullname) or str))
end
prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(dirname((fullname~="" and fullname) or str))
end
prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOLOC')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOPARENT')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTODIR')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('HOME')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.env=prefixes.environment
prefixes.rel=prefixes.relative
@@ -19398,24 +22972,24 @@ prefixes.full=prefixes.locate
prefixes.file=prefixes.filename
prefixes.path=prefixes.pathname
local function toppath()
- local inputstack=resolvers.inputstack
- if not inputstack then
- return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
- return "."
- else
- return pathname
- end
+ local inputstack=resolvers.inputstack
+ if not inputstack then
+ return "."
+ end
+ local pathname=dirname(inputstack[#inputstack] or "")
+ if pathname=="" then
+ return "."
+ else
+ return pathname
+ end
end
local function jobpath()
- local path=resolvers.stackpath()
- if not path or path=="" then
- return "."
- else
- return path
- end
+ local path=resolvers.stackpath()
+ if not path or path=="" then
+ return "."
+ else
+ return path
+ end
end
resolvers.toppath=toppath
resolvers.jobpath=jobpath
@@ -19423,8 +22997,6 @@ prefixes.toppath=function(str) return cleanpath(joinpath(toppath(),str)) end
prefixes.jobpath=function(str) return cleanpath(joinpath(jobpath(),str)) end
resolvers.setdynamic("toppath")
resolvers.setdynamic("jobpath")
-prefixes.jobfile=prefixes.jobpath
-resolvers.setdynamic("jobfile")
end -- of closure
@@ -19433,14 +23005,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-inp"] = package.loaded["data-inp"] or true
--- original size: 910, stripped down to: 823
+-- original size: 910, stripped down to: 818
if not modules then modules={} end modules ['data-inp']={
- 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 allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -19463,14 +23035,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-out"] = package.loaded["data-out"] or true
--- original size: 530, stripped down to: 475
+-- original size: 530, stripped down to: 470
if not modules then modules={} end modules ['data-out']={
- 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 allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -19486,16 +23058,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-fil"] = package.loaded["data-fil"] or true
--- original size: 3863, stripped down to: 3310
+-- original size: 3863, stripped down to: 3170
if not modules then modules={} end modules ['data-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 trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_files=logs.reporter("resolvers","files")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -19503,88 +23075,88 @@ local finders,openers,loaders,savers=resolvers.finders,resolvers.openers,resolve
local locators,hashers,generators,concatinators=resolvers.locators,resolvers.hashers,resolvers.generators,resolvers.concatinators
local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
function locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename)
- if realname and realname~='' and lfs.isdir(realname) then
- if trace_locating then
- report_files("file locator %a found as %a",filename,realname)
- end
- resolvers.appendhash('file',filename,true)
- elseif trace_locating then
- report_files("file locator %a not found",filename)
+ local filename=specification.filename
+ local realname=resolveprefix(filename)
+ if realname and realname~='' and lfs.isdir(realname) then
+ if trace_locating then
+ report_files("file locator %a found as %a",filename,realname)
end
+ resolvers.appendhash('file',filename,true)
+ elseif trace_locating then
+ report_files("file locator %a not found",filename)
+ end
end
function hashers.file(specification)
- local pathname=specification.filename
- local content=caches.loadcontent(pathname,'files')
- resolvers.registerfilehash(pathname,content,content==nil)
+ local pathname=specification.filename
+ local content=caches.loadcontent(pathname,'files')
+ resolvers.registerfilehash(pathname,content,content==nil)
end
function generators.file(specification)
- local pathname=specification.filename
- local content=resolvers.scanfiles(pathname,false,true)
- resolvers.registerfilehash(pathname,content,true)
+ local pathname=specification.filename
+ local content=resolvers.scanfiles(pathname,false,true)
+ resolvers.registerfilehash(pathname,content,true)
end
concatinators.file=file.join
function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=resolvers.findfile(filename,filetype)
- if foundname and foundname~="" then
- if trace_locating then
- report_files("file finder: %a found",filename)
- end
- return foundname
- else
- if trace_locating then
- report_files("file finder: %a not found",filename)
- end
- return finders.notfound()
+ local filename=specification.filename
+ local foundname=resolvers.findfile(filename,filetype)
+ if foundname and foundname~="" then
+ if trace_locating then
+ report_files("file finder: %a found",filename)
+ end
+ return foundname
+ else
+ if trace_locating then
+ report_files("file finder: %a not found",filename)
end
+ return finders.notfound()
+ end
end
function openers.helpers.textopener(tag,filename,f)
- return {
- reader=function() return f:read () end,
- close=function() logs.show_close(filename) return f:close() end,
- }
+ return {
+ reader=function() return f:read () end,
+ close=function() logs.show_close(filename) return f:close() end,
+ }
end
function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"r")
- if f then
- if trace_locating then
- report_files("file opener: %a opened",filename)
- end
- return openers.helpers.textopener("file",filename,f)
- end
- end
- if trace_locating then
- report_files("file opener: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"r")
+ if f then
+ if trace_locating then
+ report_files("file opener: %a opened",filename)
+ end
+ return openers.helpers.textopener("file",filename,f)
end
- return openers.notfound()
+ end
+ if trace_locating then
+ report_files("file opener: %a not found",filename)
+ end
+ return openers.notfound()
end
function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"rb")
- if f then
- logs.show_load(filename)
- if trace_locating then
- report_files("file loader: %a loaded",filename)
- end
- local s=f:read("*a")
- if checkgarbage then
- checkgarbage(#s)
- end
- f:close()
- if s then
- return true,s,#s
- end
- end
- end
- if trace_locating then
- report_files("file loader: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"rb")
+ if f then
+ logs.show_load(filename)
+ if trace_locating then
+ report_files("file loader: %a loaded",filename)
+ end
+ local s=f:read("*a")
+ if checkgarbage then
+ checkgarbage(#s)
+ end
+ f:close()
+ if s then
+ return true,s,#s
+ end
end
- return loaders.notfound()
+ end
+ if trace_locating then
+ report_files("file loader: %a not found",filename)
+ end
+ return loaders.notfound()
end
@@ -19594,116 +23166,116 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-con"] = package.loaded["data-con"] or true
--- original size: 5029, stripped down to: 3607
+-- original size: 5029, stripped down to: 3432
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
- return stored
+ 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
+ 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
+ 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
- return data
+ 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
@@ -19713,97 +23285,101 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-use"] = package.loaded["data-use"] or true
--- original size: 4272, stripped down to: 3289
+-- original size: 4434, stripped down to: 3180
if not modules then modules={} end modules ['data-use']={
- 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 format,lower,gsub,find=string.format,string.lower,string.gsub,string.find
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_mounts=logs.reporter("resolvers","mounts")
local resolvers=resolvers
resolvers.automounted=resolvers.automounted or {}
function resolvers.automount(usecache)
- local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
- if (not mountpaths or #mountpaths==0) and usecache then
- mountpaths=caches.getreadablepaths("mount")
- end
- if mountpaths and #mountpaths>0 then
- resolvers.starttiming()
- for k=1,#mountpaths do
- local root=mountpaths[k]
- local f=io.open(root.."/url.tmi")
- if f then
- for line in f:lines() do
- if line then
- if find(line,"^[%%#%-]") then
- elseif find(line,"^zip://") then
- if trace_locating then
- report_mounts("mounting %a",line)
- end
- table.insert(resolvers.automounted,line)
- resolvers.usezipfile(line)
- end
- end
- end
- f:close()
+ local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
+ if (not mountpaths or #mountpaths==0) and usecache then
+ mountpaths=caches.getreadablepaths("mount")
+ end
+ if mountpaths and #mountpaths>0 then
+ resolvers.starttiming()
+ for k=1,#mountpaths do
+ local root=mountpaths[k]
+ local f=io.open(root.."/url.tmi")
+ if f then
+ for line in f:lines() do
+ if line then
+ if find(line,"^[%%#%-]") then
+ elseif find(line,"^zip://") then
+ if trace_locating then
+ report_mounts("mounting %a",line)
+ end
+ table.insert(resolvers.automounted,line)
+ resolvers.usezipfile(line)
end
+ end
end
- resolvers.stoptiming()
+ f:close()
+ end
end
+ resolvers.stoptiming()
+ end
end
statistics.register("used config file",function() return caches.configfiles() end)
statistics.register("used cache path",function() return caches.usedpaths() end)
function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner)
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
- local luvname=file.replacesuffix(texname,"luv")
- local luvdata={
- enginebanner=enginebanner,
- formatbanner=formatbanner,
- sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
- sourcefile=sourcefile,
- luaversion=LUAVERSION,
- }
- io.savedata(luvname,table.serialize(luvdata,true))
- lua.registerfinalizer(function()
- logs.report("format banner","%s",banner)
- logs.newline()
- end)
- end
+ local enginebanner=status.banner
+ if formatbanner and enginebanner and sourcefile then
+ local luvname=file.replacesuffix(texname,"luv")
+ local luvdata={
+ enginebanner=enginebanner,
+ formatbanner=formatbanner,
+ sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
+ sourcefile=sourcefile,
+ luaversion=LUAVERSION,
+ }
+ io.savedata(luvname,table.serialize(luvdata,true))
+ lua.registerfinalizer(function()
+ 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
end
function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
- local luvname=file.replacesuffix(texname,"luv")
- if lfs.isfile(luvname) then
- local luv=dofile(luvname)
- if luv and luv.sourcefile then
- local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
- local luvbanner=luv.enginebanner or "?"
- if luvbanner~=enginebanner then
- return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
- end
- local luvhash=luv.sourcehash or "?"
- if luvhash~=sourcehash then
- return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
- end
- local luvluaversion=luv.luaversion or 0
- if luvluaversion~=LUAVERSION then
- return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
- end
- else
- return "invalid status file"
- end
- else
- return "missing status file"
- end
+ local enginebanner=status.banner
+ if enginebanner and texname then
+ local luvname=file.replacesuffix(texname,"luv")
+ if lfs.isfile(luvname) then
+ local luv=dofile(luvname)
+ if luv and luv.sourcefile then
+ local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
+ local luvbanner=luv.enginebanner or "?"
+ if luvbanner~=enginebanner then
+ return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+ end
+ local luvhash=luv.sourcehash or "?"
+ if luvhash~=sourcehash then
+ return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
+ end
+ local luvluaversion=luv.luaversion or 0
+ if luvluaversion~=LUAVERSION then
+ return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
+ end
+ else
+ return "invalid status file"
+ end
+ else
+ return "missing status file"
end
- return true
+ end
+ return true
end
@@ -19813,233 +23389,233 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-zip"] = package.loaded["data-zip"] or true
--- original size: 8716, stripped down to: 6795
+-- original size: 8700, stripped down to: 6313
if not modules then modules={} end modules ['data-zip']={
- 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 format,find,match=string.format,string.find,string.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_zip=logs.reporter("resolvers","zip")
local resolvers=resolvers
zip=zip or {}
local zip=zip
-zip.archives=zip.archives or {}
-local archives=zip.archives
-zip.registeredfiles=zip.registeredfiles or {}
-local registeredfiles=zip.registeredfiles
+local archives=zip.archives or {}
+zip.archives=archives
+local registeredfiles=zip.registeredfiles or {}
+zip.registeredfiles=registeredfiles
local function validzip(str)
- if not find(str,"^zip://") then
- return "zip:///"..str
- else
- return str
- end
+ if not find(str,"^zip://") then
+ return "zip:///"..str
+ else
+ return str
+ end
end
function zip.openarchive(name)
- if not name or name=="" then
- return nil
- else
- local arch=archives[name]
- if not arch then
- local full=resolvers.findfile(name) or ""
- arch=full~="" and zip.open(full) or false
- archives[name]=arch
- end
- return arch
+ if not name or name=="" then
+ return nil
+ else
+ local arch=archives[name]
+ if not arch then
+ local full=resolvers.findfile(name) or ""
+ arch=full~="" and zip.open(full) or false
+ archives[name]=arch
end
+ return arch
+ end
end
function zip.closearchive(name)
- if not name or (name=="" and archives[name]) then
- zip.close(archives[name])
- archives[name]=nil
- end
+ if not name or (name=="" and archives[name]) then
+ zip.close(archives[name])
+ archives[name]=nil
+ end
end
function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and zip.openarchive(archive)
- if trace_locating then
- if zipfile then
- report_zip("locator: archive %a found",archive)
- else
- report_zip("locator: archive %a not found",archive)
- end
+ local archive=specification.filename
+ local zipfile=archive and archive~="" and zip.openarchive(archive)
+ if trace_locating then
+ if zipfile then
+ report_zip("locator: archive %a found",archive)
+ else
+ report_zip("locator: archive %a not found",archive)
end
+ end
end
function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
- report_zip("loading file %a",archive)
- end
- resolvers.usezipfile(specification.original)
+ local archive=specification.filename
+ if trace_locating then
+ report_zip("loading file %a",archive)
+ end
+ resolvers.usezipfile(specification.original)
end
function resolvers.concatinators.zip(zipfile,path,name)
- if not path or path=="" then
- return format('%s?name=%s',zipfile,name)
- else
- return format('%s?name=%s/%s',zipfile,path,name)
- end
+ if not path or path=="" then
+ return format('%s?name=%s',zipfile,name)
+ else
+ return format('%s?name=%s/%s',zipfile,path,name)
+ end
end
function resolvers.finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("finder: archive %a found",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- dfile=zfile:close()
- if trace_locating then
- report_zip("finder: file %a found",queryname)
- end
- return specification.original
- elseif trace_locating then
- report_zip("finder: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("finder: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("finder: archive %a found",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ dfile:close()
+ if trace_locating then
+ report_zip("finder: file %a found",queryname)
+ end
+ return specification.original
+ elseif trace_locating then
+ report_zip("finder: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("finder: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("finder: %a not found",original)
- end
- return resolvers.finders.notfound()
+ end
+ if trace_locating then
+ report_zip("finder: %a not found",original)
+ end
+ return resolvers.finders.notfound()
end
function resolvers.openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("opener; archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- if trace_locating then
- report_zip("opener: file %a found",queryname)
- end
- return resolvers.openers.helpers.textopener('zip',original,dfile)
- elseif trace_locating then
- report_zip("opener: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("opener: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("opener; archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ if trace_locating then
+ report_zip("opener: file %a found",queryname)
+ end
+ return resolvers.openers.helpers.textopener('zip',original,dfile)
+ elseif trace_locating then
+ report_zip("opener: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("opener: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("opener: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("opener: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("loader: archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- logs.show_load(original)
- if trace_locating then
- report_zip("loader; file %a loaded",original)
- end
- local s=dfile:read("*all")
- dfile:close()
- return true,s,#s
- elseif trace_locating then
- report_zip("loader: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("loader; unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("loader: archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ logs.show_load(original)
+ if trace_locating then
+ report_zip("loader; file %a loaded",original)
+ end
+ local s=dfile:read("*all")
+ dfile:close()
+ return true,s,#s
+ elseif trace_locating then
+ report_zip("loader: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("loader; unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("loader: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("loader: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.usezipfile(archive)
- local specification=resolvers.splitmethod(archive)
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
- local z=zip.openarchive(archive)
- if z then
- local tree=url.query(specification.query).tree or ""
- if trace_locating then
- report_zip("registering: archive %a",archive)
- end
- resolvers.starttiming()
- resolvers.prependhash('zip',archive)
- resolvers.extendtexmfvariable(archive)
- registeredfiles[archive]=z
- resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
- resolvers.stoptiming()
- elseif trace_locating then
- report_zip("registering: unknown archive %a",archive)
- end
+ local specification=resolvers.splitmethod(archive)
+ local archive=specification.filename
+ if archive and not registeredfiles[archive] then
+ local z=zip.openarchive(archive)
+ if z then
+ local tree=url.query(specification.query).tree or ""
+ if trace_locating then
+ report_zip("registering: archive %a",archive)
+ end
+ resolvers.starttiming()
+ resolvers.prependhash('zip',archive)
+ resolvers.extendtexmfvariable(archive)
+ registeredfiles[archive]=z
+ resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
+ resolvers.stoptiming()
elseif trace_locating then
- report_zip("registering: archive %a not found",archive)
+ report_zip("registering: unknown archive %a",archive)
end
+ elseif trace_locating then
+ report_zip("registering: archive %a not found",archive)
+ end
end
function resolvers.registerzipfile(z,tree)
- local names={}
- local files={}
- local remap={}
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- local register=resolvers.registerfile
- if trace_locating then
- report_zip("registering: using filter %a",filter)
- end
- for i in z:files() do
- local filename=i.filename
- local path,name=match(filename,filter)
- if not path then
- n=n+1
- register(names,filename,"")
- local usedname=lower(filename)
- files[usedname]=""
- if usedname~=filename then
- remap[usedname]=filename
- end
- elseif name and name~="" then
- n=n+1
- register(names,name,path)
- local usedname=lower(name)
- files[usedname]=path
- if usedname~=name then
- remap[usedname]=name
- end
- else
- end
+ local names={}
+ local files={}
+ local remap={}
+ local n=0
+ local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
+ local register=resolvers.registerfile
+ if trace_locating then
+ report_zip("registering: using filter %a",filter)
+ end
+ for i in z:files() do
+ local filename=i.filename
+ local path,name=match(filename,filter)
+ if not path then
+ n=n+1
+ register(names,filename,"")
+ local usedname=lower(filename)
+ files[usedname]=""
+ if usedname~=filename then
+ remap[usedname]=filename
+ end
+ elseif name and name~="" then
+ n=n+1
+ register(names,name,path)
+ local usedname=lower(name)
+ files[usedname]=path
+ if usedname~=name then
+ remap[usedname]=name
+ end
+ else
end
- report_zip("registering: %s files registered",n)
- return {
- files=files,
- remap=remap,
- }
+ end
+ report_zip("registering: %s files registered",n)
+ return {
+ files=files,
+ remap=remap,
+ }
end
@@ -20049,20 +23625,20 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tre"] = package.loaded["data-tre"] or true
--- original size: 8479, stripped down to: 5580
+-- original size: 8478, stripped down to: 5223
if not modules then modules={} end modules ['data-tre']={
- 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 find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file .join
+local basename,dirname,joinname=file.basename,file.dirname,file .join
local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_trees=logs.reporter("resolvers","trees")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -20071,165 +23647,167 @@ local lookup=resolvers.get_from_content
local collectors={}
local found={}
function resolvers.finders.tree(specification)
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
- if spec~="" then
- local path=dirname(spec)
- local name=basename(spec)
- if path=="" then
- path="."
- end
- local names=collectors[path]
- if not names then
- local pattern=find(path,"/%*+$") and path or (path.."/*")
- names=globdir(pattern)
- collectors[path]=names
- end
- local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
- for i=1,#names do
- local fullname=names[i]
- if find(fullname,pattern) then
- found[spec]=fullname
- return fullname
- end
- end
- local pattern=lower(pattern)
- for i=1,#names do
- local fullname=lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
- found[spec]=fullname
- return fullname
- else
- break
- end
- end
- end
+ local spec=specification.filename
+ local okay=found[spec]
+ if okay==nil then
+ if spec~="" then
+ local path=dirname(spec)
+ local name=basename(spec)
+ if path=="" then
+ path="."
+ end
+ local names=collectors[path]
+ if not names then
+ local pattern=find(path,"/%*+$") and path or (path.."/*")
+ names=globdir(pattern)
+ collectors[path]=names
+ end
+ local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
+ for i=1,#names do
+ local fullname=names[i]
+ if find(fullname,pattern) then
+ found[spec]=fullname
+ return fullname
+ end
+ end
+ local pattern=lower(pattern)
+ for i=1,#names do
+ local fullname=lower(names[i])
+ if find(fullname,pattern) then
+ if isfile(fullname) then
+ found[spec]=fullname
+ return fullname
+ else
+ break
+ end
end
- okay=notfound()
- found[spec]=okay
+ end
end
- return okay
+ okay=notfound()
+ found[spec]=okay
+ end
+ return okay
end
function resolvers.locators.tree(specification)
- local name=specification.filename
- local realname=resolveprefix(name)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
- end
- resolvers.appendhash('tree',name,false)
- elseif trace_locating then
- report_trees("locator %a not found",name)
+ local name=specification.filename
+ local realname=resolveprefix(name)
+ if realname and realname~='' and isdir(realname) then
+ if trace_locating then
+ report_trees("locator %a found",realname)
end
+ resolvers.appendhash('tree',name,false)
+ elseif trace_locating then
+ report_trees("locator %a not found",name)
+ end
end
function resolvers.hashers.tree(specification)
- local name=specification.filename
- report_trees("analyzing %a",name)
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+ local name=specification.filename
+ if trace_locating then
+ report_trees("analyzing %a",name)
+ end
+ resolvers.methodhandler("hashers",name)
+ resolvers.generators.file(specification)
end
local collectors={}
local splitter=lpeg.splitat("/**/")
local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=caches.loadcontent(dataname,"files",dataname)
- if not content then
- content=resolvers.scanfiles(rootname,nil,nil,false,true)
- caches.savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
+ local rootname=lpegmatch(stripper,k)
+ local dataname=joinname(rootname,"dirlist")
+ local content=caches.loadcontent(dataname,"files",dataname)
+ if not content then
+ content=resolvers.scanfiles(rootname,nil,nil,false,true)
+ caches.savecontent(dataname,"files",content,dataname)
+ end
+ t[k]=content
+ return content
end)
local function checked(root,p,n)
- if p then
- if type(p)=="table" then
- for i=1,#p do
- local fullname=joinname(root,p[i],n)
- if isfile(fullname) then
- return fullname
- end
- end
- else
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
+ if p then
+ if type(p)=="table" then
+ for i=1,#p do
+ local fullname=joinname(root,p[i],n)
+ if isfile(fullname) then
+ return fullname
end
+ end
+ else
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- return notfound()
+ end
+ return notfound()
end
local function resolve(specification)
- local filename=specification.filename
- if filename~="" then
- local root,rest=lpegmatch(splitter,filename)
- if root and rest then
- local path,name=dirname(rest),basename(rest)
- if name~=rest then
- local content=collectors[root]
- local p,n=lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern=".*/"..path.."$"
- local istable=type(p)=="table"
- if istable then
- for i=1,#p do
- local pi=p[i]
- if pi==path or find(pi,pattern) then
- local fullname=joinname(root,pi,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- elseif p==path or find(p,pattern) then
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- local queries=specification.queries
- if queries and queries.option=="fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
+ local filename=specification.filename
+ if filename~="" then
+ local root,rest=lpegmatch(splitter,filename)
+ if root and rest then
+ local path,name=dirname(rest),basename(rest)
+ if name~=rest then
+ local content=collectors[root]
+ local p,n=lookup(content,name)
+ if not p then
+ return notfound()
+ end
+ local pattern=".*/"..path.."$"
+ local istable=type(p)=="table"
+ if istable then
+ for i=1,#p do
+ local pi=p[i]
+ if pi==path or find(pi,pattern) then
+ local fullname=joinname(root,pi,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
+ end
+ elseif p==path or find(p,pattern) then
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- local path,name=dirname(filename),basename(filename)
- local root=lpegmatch(stripper,path)
- local content=collectors[path]
- local p,n=lookup(content,name)
- if p then
- return checked(root,p,n)
+ local queries=specification.queries
+ if queries and queries.option=="fileonly" then
+ return checked(root,p,n)
+ else
+ return notfound()
end
+ end
end
- return notfound()
+ local path,name=dirname(filename),basename(filename)
+ local root=lpegmatch(stripper,path)
+ local content=collectors[path]
+ local p,n=lookup(content,name)
+ if p then
+ return checked(root,p,n)
+ end
+ end
+ return notfound()
end
-resolvers.finders .dirlist=resolve
-resolvers.locators .dirlist=resolvers.locators .tree
-resolvers.hashers .dirlist=resolvers.hashers .tree
+resolvers.finders .dirlist=resolve
+resolvers.locators .dirlist=resolvers.locators .tree
+resolvers.hashers .dirlist=resolvers.hashers .tree
resolvers.generators.dirlist=resolvers.generators.file
-resolvers.openers .dirlist=resolvers.openers .file
-resolvers.loaders .dirlist=resolvers.loaders .file
+resolvers.openers .dirlist=resolvers.openers .file
+resolvers.loaders .dirlist=resolvers.loaders .file
function resolvers.finders.dirfile(specification)
- local queries=specification.queries
- if queries then
- queries.option="fileonly"
- else
- specification.queries={ option="fileonly" }
- end
- return resolve(specification)
-end
-resolvers.locators .dirfile=resolvers.locators .dirlist
-resolvers.hashers .dirfile=resolvers.hashers .dirlist
+ local queries=specification.queries
+ if queries then
+ queries.option="fileonly"
+ else
+ specification.queries={ option="fileonly" }
+ end
+ return resolve(specification)
+end
+resolvers.locators .dirfile=resolvers.locators .dirlist
+resolvers.hashers .dirfile=resolvers.hashers .dirlist
resolvers.generators.dirfile=resolvers.generators.dirlist
-resolvers.openers .dirfile=resolvers.openers .dirlist
-resolvers.loaders .dirfile=resolvers.loaders .dirlist
+resolvers.openers .dirfile=resolvers.openers .dirlist
+resolvers.loaders .dirfile=resolvers.loaders .dirlist
end -- of closure
@@ -20238,19 +23816,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-sch"] = package.loaded["data-sch"] or true
--- original size: 6753, stripped down to: 5511
+-- original size: 6753, stripped down to: 5268
if not modules then modules={} end modules ['data-sch']={
- 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 load,tonumber=load,tonumber
local gsub,concat,format=string.gsub,table.concat,string.format
local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
+local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
local report_schemes=logs.reporter("resolvers","schemes")
local http=require("socket.http")
local ltn12=require("ltn12")
@@ -20263,27 +23841,27 @@ schemes.cleaners=cleaners
local threshold=24*60*60
directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
function cleaners.none(specification)
- return specification.original
+ return specification.original
end
function cleaners.strip(specification)
- local path,name=file.splitbase(specification.original)
- if path=="" then
- return (gsub(name,"[^%a%d%.]+","-"))
- else
- return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
+ local path,name=file.splitbase(specification.original)
+ if path=="" then
+ return (gsub(name,"[^%a%d%.]+","-"))
+ else
+ return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
+ end
end
function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
+ return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
end
local cleaner=cleaners.strip
directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
+ local hash=cleaner(specification)
+ if trace_schemes then
+ report_schemes("hashing %a to %a",specification.original,hash)
+ end
+ return hash
end
local cached={}
local loaded={}
@@ -20291,139 +23869,139 @@ local reused={}
local thresholds={}
local handlers={}
local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template="--silent --insecure --create-dirs --output %cachename% %original%",
- checkers={
- cachename="cache",
- original="url",
- }
+ name="curl resolver",
+ method="execute",
+ program="curl",
+ template="--silent --insecure --create-dirs --output %cachename% %original%",
+ checkers={
+ cachename="cache",
+ original="url",
+ }
}
local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
- cached[original]=cachename
- local handler=handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
- end
- logs.flush()
- runner {
- original=original,
- cachename=cachename,
- }
- end
- end
- if io.exists(cachename) then
- cached[original]=cachename
- if trace_schemes then
- report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
- end
- else
- cached[original]=""
- if trace_schemes then
- report_schemes("using missing %a, protocol %a",original,scheme)
- end
+ local original=specification.original
+ local scheme=specification.scheme
+ local cleanname=schemes.cleanname(specification)
+ local cachename=caches.setfirstwritablefile(cleanname,"schemes")
+ if not cached[original] then
+ statistics.starttiming(schemes)
+ if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
+ cached[original]=cachename
+ local handler=handlers[scheme]
+ if handler then
+ if trace_schemes then
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
end
- loaded[scheme]=loaded[scheme]+1
- statistics.stoptiming(schemes)
- else
+ logs.flush()
+ handler(specification,cachename)
+ else
if trace_schemes then
- report_schemes("reusing %a, protocol %a",original,scheme)
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
end
- reused[scheme]=reused[scheme]+1
+ logs.flush()
+ runner {
+ original=original,
+ cachename=cachename,
+ }
+ end
+ end
+ if io.exists(cachename) then
+ cached[original]=cachename
+ if trace_schemes then
+ report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
+ end
+ else
+ cached[original]=""
+ if trace_schemes then
+ report_schemes("using missing %a, protocol %a",original,scheme)
+ end
end
- return cached[original]
+ loaded[scheme]=loaded[scheme]+1
+ statistics.stoptiming(schemes)
+ else
+ if trace_schemes then
+ report_schemes("reusing %a, protocol %a",original,scheme)
+ end
+ reused[scheme]=reused[scheme]+1
+ end
+ return cached[original]
end
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",fetch(specification),filetype)
end
local opener=openers.file
local loader=loaders.file
local function install(scheme,handler,newthreshold)
- handlers [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders [scheme]=finder
- openers [scheme]=opener
- loaders [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
+ handlers [scheme]=handler
+ loaded [scheme]=0
+ reused [scheme]=0
+ finders [scheme]=finder
+ openers [scheme]=opener
+ loaders [scheme]=loader
+ thresholds[scheme]=newthreshold or threshold
end
schemes.install=install
local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local f=io.open(tempname,"wb")
- local status,message=http.request {
- url=specification.original,
- sink=ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
+ local tempname=cachename..".tmp"
+ local f=io.open(tempname,"wb")
+ local status,message=http.request {
+ url=specification.original,
+ sink=ltn12.sink.file(f)
+ }
+ if not status then
+ os.remove(tempname)
+ else
+ os.remove(cachename)
+ os.rename(tempname,cachename)
+ end
+ return cachename
end
install('http',http_handler)
install('https')
install('ftp')
statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in table.sortedhash(loaded) do
- if v>0 then
- nl=nl+1
- l[nl]=k..":"..v
- end
- end
- for k,v in table.sortedhash(reused) do
- if v>0 then
- nr=nr+1
- r[nr]=k..":"..v
- end
- end
- local n=nl+nr
- if n>0 then
- l=nl>0 and concat(l) or "none"
- r=nr>0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes),n,threshold,l,r)
- else
- return nil
- end
+ local l,r,nl,nr={},{},0,0
+ for k,v in table.sortedhash(loaded) do
+ if v>0 then
+ nl=nl+1
+ l[nl]=k..":"..v
+ end
+ end
+ for k,v in table.sortedhash(reused) do
+ if v>0 then
+ nr=nr+1
+ r[nr]=k..":"..v
+ end
+ end
+ local n=nl+nr
+ if n>0 then
+ l=nl>0 and concat(l) or "none"
+ r=nr>0 and concat(r) or "none"
+ return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
+ statistics.elapsedtime(schemes),n,threshold,l,r)
+ else
+ return nil
+ end
end)
local httprequest=http.request
local toquery=url.toquery
local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
- url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply
+ local q=data and toquery(data)
+ if q then
+ url=url.."?"..q
+ end
+ local reply=httprequest(url)
+ return reply
end
schemes.fetchstring=fetchstring
function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
- local s=load("return "..reply)
- if s then
- return s()
- end
+ local reply=fetchstring(url,data)
+ if reply then
+ local s=load("return "..reply)
+ if s then
+ return s()
end
+ end
end
@@ -20433,14 +24011,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lua"] = package.loaded["data-lua"] or true
--- original size: 4207, stripped down to: 3137
+-- original size: 4207, stripped down to: 3041
if not modules then modules={} end modules ['data-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 package,lpeg=package,lpeg
local gsub=string.gsub
@@ -20459,20 +24037,20 @@ helpers.report=logs.reporter("resolvers","libraries")
trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
trackers.register("resolvers.locating",function(v) helpers.trace=v end)
helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
+ "already loaded",
+ "preload table",
+ "lua variable format",
+ "lib variable format",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
}
local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
function helpers.cleanpath(path)
- return resolveprefix(lpegmatch(pattern,path))
+ return resolveprefix(lpegmatch(pattern,path))
end
local loadedaslib=helpers.loadedaslib
local registerpath=helpers.registerpath
@@ -20480,56 +24058,56 @@ local lualibfile=helpers.lualibfile
local luaformatpaths
local libformatpaths
local function getluaformatpaths()
- if not luaformatpaths then
- luaformatpaths={}
- for i=1,#luaformats do
- registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
- end
+ if not luaformatpaths then
+ luaformatpaths={}
+ for i=1,#luaformats do
+ registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
end
- return luaformatpaths
+ end
+ return luaformatpaths
end
local function getlibformatpaths()
- if not libformatpaths then
- libformatpaths={}
- for i=1,#libformats do
- registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
- end
+ if not libformatpaths then
+ libformatpaths={}
+ for i=1,#libformats do
+ registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
end
- return libformatpaths
+ end
+ return libformatpaths
end
local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do
- local format=suffixes[i]
- local resolved=resolvers.findfile(name,format) or ""
- if trace then
- report("%s format, identifying %a using format %a",what,name,format)
- end
- if resolved~="" then
- if trace then
- report("%s format, %a found on %a",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ local report=helpers.report
+ for i=1,#suffixes do
+ local format=suffixes[i]
+ local resolved=resolvers.findfile(name,format) or ""
+ if trace then
+ report("%s format, identifying %a using format %a",what,name,format)
+ end
+ if resolved~="" then
+ if trace then
+ report("%s format, %a found on %a",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbyformat=loadedbyformat
methods["lua variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
end
methods["lib variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
end
resolvers.loadlualib=require
@@ -20540,64 +24118,64 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-aux"] = package.loaded["data-aux"] or true
--- original size: 2438, stripped down to: 2003
+-- original size: 2452, stripped down to: 1877
if not modules then modules={} end modules ['data-aux']={
- 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 find=string.find
local type,next=type,next
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local resolvers=resolvers
local report_scripts=logs.reporter("resolvers","scripts")
function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- newname=file.addsuffix(newname,"lua")
- local oldscript=resolvers.cleanpath(oldname)
+ local scriptpath="context/lua"
+ newname=file.addsuffix(newname,"lua")
+ local oldscript=resolvers.cleanpath(oldname)
+ if trace_locating then
+ report_scripts("to be replaced old script %a",oldscript)
+ end
+ local newscripts=resolvers.findfiles(newname) or {}
+ if #newscripts==0 then
if trace_locating then
- report_scripts("to be replaced old script %a",oldscript)
+ report_scripts("unable to locate new script")
end
- local newscripts=resolvers.findfiles(newname) or {}
- if #newscripts==0 then
+ else
+ for i=1,#newscripts do
+ local newscript=resolvers.cleanpath(newscripts[i])
+ if trace_locating then
+ report_scripts("checking new script %a",newscript)
+ end
+ if oldscript==newscript then
if trace_locating then
- report_scripts("unable to locate new script")
+ report_scripts("old and new script are the same")
end
- else
- for i=1,#newscripts do
- local newscript=resolvers.cleanpath(newscripts[i])
- if trace_locating then
- report_scripts("checking new script %a",newscript)
- end
- if oldscript==newscript then
- if trace_locating then
- report_scripts("old and new script are the same")
- end
- elseif not find(newscript,scriptpath,1,true) then
- if trace_locating then
- report_scripts("new script should come from %a",scriptpath)
- end
- elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
- if trace_locating then
- report_scripts("invalid new script name")
- end
- else
- local newdata=io.loaddata(newscript)
- if newdata then
- if trace_locating then
- report_scripts("old script content replaced by new content")
- end
- io.savedata(oldscript,newdata)
- break
- elseif trace_locating then
- report_scripts("unable to load new script")
- end
- end
+ elseif not find(newscript,scriptpath,1,true) then
+ if trace_locating then
+ report_scripts("new script should come from %a",scriptpath)
end
+ elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+ if trace_locating then
+ report_scripts("invalid new script name")
+ end
+ else
+ local newdata=io.loaddata(newscript)
+ if newdata then
+ if trace_locating then
+ report_scripts("old script content replaced by new content: %s",oldscript)
+ end
+ io.savedata(oldscript,newdata)
+ break
+ elseif trace_locating then
+ report_scripts("unable to load new script")
+ end
+ end
end
+ end
end
@@ -20607,53 +24185,53 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
--- original size: 2601, stripped down to: 1627
+-- original size: 2601, stripped down to: 1549
if not modules then modules={} end modules ['data-tmf']={
- 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 resolvers=resolvers
local report_tds=logs.reporter("resolvers","tds")
function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
- local getenv,setenv=resolvers.getenv,resolvers.setenv
- local texos="texmf-"..os.platform
- local oldroot=environment.texroot
- local newroot=file.collapsepath(tree)
- local newtree=file.join(newroot,texos)
- local newpath=file.join(newtree,"bin")
- if not lfs.isdir(newtree) then
- report_tds("no %a under tree %a",texos,tree)
- os.exit()
- end
- if not lfs.isdir(newpath) then
- report_tds("no '%s/bin' under tree %a",texos,tree)
- os.exit()
- end
- local texmfos=newtree
- environment.texroot=newroot
- environment.texos=texos
- environment.texmfos=texmfos
- if resolve then
- resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
- end
- setenv('SELFAUTOPARENT',newroot)
- setenv('SELFAUTODIR',newtree)
- setenv('SELFAUTOLOC',newpath)
- setenv('TEXROOT',newroot)
- setenv('TEXOS',texos)
- setenv('TEXMFOS',texmfos)
- setenv('TEXMFCNF',resolvers.luacnfspec,true)
- setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
- report_tds("changing from root %a to %a",oldroot,newroot)
- report_tds("prepending %a to PATH",newpath)
- report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
- report_tds()
- end
+ if type(tree)=="string" and tree~="" then
+ local getenv,setenv=resolvers.getenv,resolvers.setenv
+ local texos="texmf-"..os.platform
+ local oldroot=environment.texroot
+ local newroot=file.collapsepath(tree)
+ local newtree=file.join(newroot,texos)
+ local newpath=file.join(newtree,"bin")
+ if not lfs.isdir(newtree) then
+ report_tds("no %a under tree %a",texos,tree)
+ os.exit()
+ end
+ if not lfs.isdir(newpath) then
+ report_tds("no '%s/bin' under tree %a",texos,tree)
+ os.exit()
+ end
+ local texmfos=newtree
+ environment.texroot=newroot
+ environment.texos=texos
+ environment.texmfos=texmfos
+ if resolve then
+ resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
+ end
+ setenv('SELFAUTOPARENT',newroot)
+ setenv('SELFAUTODIR',newtree)
+ setenv('SELFAUTOLOC',newpath)
+ setenv('TEXROOT',newroot)
+ setenv('TEXOS',texos)
+ setenv('TEXMFOS',texmfos)
+ setenv('TEXMFCNF',resolvers.luacnfspec,true)
+ setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
+ report_tds("changing from root %a to %a",oldroot,newroot)
+ report_tds("prepending %a to PATH",newpath)
+ report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
+ report_tds()
+ end
end
@@ -20663,14 +24241,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lst"] = package.loaded["data-lst"] or true
--- original size: 1823, stripped down to: 1591
+-- original size: 1823, stripped down to: 1542
if not modules then modules={} end modules ['data-lst']={
- 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=type
local concat,sortedhash=table.concat,table.sortedhash
@@ -20681,37 +24259,37 @@ local resolveprefix=resolvers.resolve
local report_lists=logs.reporter("resolvers","lists")
local report_resolved=logs.reporter("system","resolved")
local function tabstr(str)
- if type(str)=='table' then
- return concat(str," | ")
- else
- return str
- end
+ if type(str)=='table' then
+ return concat(str," | ")
+ else
+ return str
+ end
end
function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
- report_lists(key)
- report_lists(" env: %s",tabstr(value.environment or "unset"))
- report_lists(" var: %s",tabstr(value.variable or "unset"))
- report_lists(" exp: %s",tabstr(value.expansion or "unset"))
- report_lists(" res: %s",tabstr(value.resolved or "unset"))
- end
+ local result=resolvers.knownvariables(pattern)
+ for key,value in sortedhash(result) do
+ report_lists(key)
+ report_lists(" env: %s",tabstr(value.environment or "unset"))
+ report_lists(" var: %s",tabstr(value.variable or "unset"))
+ report_lists(" exp: %s",tabstr(value.expansion or "unset"))
+ report_lists(" res: %s",tabstr(value.resolved or "unset"))
+ end
end
function listers.configurations()
- local configurations=resolvers.configurationfiles()
- for i=1,#configurations do
- report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
- for i=1,#list do
- local li=resolveprefix(list[i])
- if lfs.isdir(li) then
- report_resolved("path - %s",li)
- else
- report_resolved("path + %s",li)
- end
+ local configurations=resolvers.configurationfiles()
+ for i=1,#configurations do
+ report_resolved("file : %s",resolveprefix(configurations[i]))
+ end
+ report_resolved("")
+ local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+ for i=1,#list do
+ local li=resolveprefix(list[i])
+ if lfs.isdir(li) then
+ report_resolved("path - %s",li)
+ else
+ report_resolved("path + %s",li)
end
+ end
end
@@ -20721,14 +24299,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 14943, stripped down to: 8305
+-- original size: 16094, stripped down to: 8443
if not modules then modules={} end modules ['util-lib']={
- 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=type
local next=next
@@ -20748,256 +24326,291 @@ local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
local done=false
local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
- end
- found_library=required
- else
- if trace then
- report("qualified name %a not found",required)
- end
- end
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ local required_full=gsub(required,"%.","/")
+ local required_path=pathpart(required_full)
+ local required_base=nameonly(required_full)
+ if qualifiedpath(required) then
+ if isfile(addsuffix(required,os.libsuffix)) then
+ if trace then
+ report("qualified name %a found",required)
+ end
+ found_library=required
else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine="luatex"
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ if trace then
+ report("qualified name %a not found",required)
+ end
+ end
+ else
+ local required_name=required_base.."."..os.libsuffix
+ local version=type(version)=="string" and version~="" and version or false
+ local engine="luatex"
+ if trace and not done then
+ local list=expandpaths("lib")
+ for i=1,#list do
+ report("tds path %i: %s",i,list[i])
+ end
+ end
+ local function found(locate,asked_library,how,...)
+ if trace then
+ report("checking %s: %a",how,asked_library)
+ end
+ return locate(asked_library,...)
+ end
+ local function check(locate,...)
+ local found=nil
+ if version then
+ local asked_library=joinfile(required_path,version,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
- end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
+ found=locate(asked_library,...)
+ end
+ if not found or found=="" then
+ local asked_library=joinfile(required_path,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
+ found=locate(asked_library,...)
+ end
+ return found and found~="" and found or false
+ end
+ local function attempt(checkpattern)
+ if trace then
+ report("checking tds lib paths strictly")
+ end
+ local found=findfile and check(findfile,"lib")
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
+ end
+ if trace then
+ report("checking tds lib paths with wildcard")
+ end
+ local asked_library=joinfile(required_path,".*",required_name)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
+ end
+ local list=findfiles(asked_library,"lib",true)
+ if list and #list>0 then
+ sort(list)
+ local found=list[#list]
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
- end
- found_library=attempt()
- end
- else
- found_library=attempt()
+ end
+ if trace then
+ report("checking lib paths")
+ end
+ package.extralibpath(environment.ownpath)
+ local paths=package.libpaths()
+ local pattern="/[^/]+%."..os.libsuffix.."$"
+ for i=1,#paths do
+ required_path=gsub(paths[i],pattern,"")
+ local found=check(lfs.isfound)
+ if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
+ return found
end
+ end
+ return false
end
- if not found_library then
+ if engine then
+ if trace then
+ report("attemp 1, engine %a",engine)
+ end
+ found_library=attempt("/"..engine.."/")
+ if not found_library then
if trace then
- report("not found: %a",required)
+ report("attemp 2, no engine",asked_library)
end
- library=false
+ found_library=attempt()
+ end
else
- if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
- end
+ found_library=attempt()
end
+ end
+ if not found_library then
if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
+ report("not found: %a",required)
end
- return library
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local result,message=action(found_library,required_base)
+ if result then
+ library=result
+ else
+ library=false
+ report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
+ end
+ end
+ if trace then
+ if not library then
+ report("unknown library: %a",required)
+ else
+ report("stored library: %a",required)
+ end
+ end
+ return library or nil
end
do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
- else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
- end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ local loadlib=package.loadlib
+ local pushdir=dir.push
+ local popdir=dir.pop
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ pushdir(pathpart(name))
+ local opener="luaopen_"..base
+ if trace_swiglib then
+ report_swiglib("opening: %a with %a",name,opener)
+ end
+ local library,message=loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
+ else
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
end
+ popdir()
return library
+ end)
+ loadedlibs[required]=library or false
end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
- end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
+ else
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
+ if trace_swiglib then
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
+ else
+ fullname="swiglib."..name
+ end
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
- end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
- end
- return library
+ return library
+ end
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
+ end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- 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
- l=library
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ local loaded={}
+ local function locateindeed(name)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l==nil 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
+ loaded[name]=l
+ elseif trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- elseif version=="system" then
- return locateindeed(name)
- else
- return locate(name,version,trace_ffilib,report_ffilib,locateindeed)
+ 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
- function ffi.load(name)
- local library=ffilib(name)
+ return { required }
+ end
+ function ffilib(name,version)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l~=nil then
+ if trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
+ end
+ return l
+ 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
+ return library
end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
+ end
+ else
+ for i=1,#list do
+ local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
+ if type(library)=="userdata" then
+ return library
end
- return savedffiload(name)
+ end
end
+ end
+ function ffi.load(name)
+ 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
+ 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
@@ -21007,13 +24620,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
--- original size: 5703, stripped down to: 2507
+-- original size: 5703, stripped down to: 2321
if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gmatch,match=string.gmatch,string.match
local type=type
@@ -21026,81 +24639,81 @@ local hash=states.hash
states.tag=states.tag or ""
states.filename=states.filename or ""
function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
- "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
+ tag=tag or states.tag
+ filename=file.addsuffix(filename or states.filename,'lus')
+ io.savedata(filename,
+ "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
+ )
end
function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
+ states.filename=filename
+ states.tag=tag or "whatever"
+ states.filename=file.addsuffix(states.filename,'lus')
+ data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
end
local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
- if type(d)=="table" then
- local dkey,hkey=key,key
- local pre,post=match(key,"(.+)%.([^%.]+)$")
- if pre and post then
- for k in gmatch(pre,"[^%.]+") do
- local dk=d[k]
- if not dk then
- dk={}
- d[k]=dk
- elseif type(dk)=="string" then
- break
- end
- d=dk
- end
- dkey,hkey=post,key
- end
- if value==nil then
- value=default
- elseif value==false then
- elseif persistent then
- value=value or d[dkey] or default
- else
- value=value or default
- end
- d[dkey],h[hkey]=value,value
- elseif type(d)=="string" then
- data[tag],hash[tag]=value,value
+ local d,h=data[tag],hash[tag]
+ if d then
+ if type(d)=="table" then
+ local dkey,hkey=key,key
+ local pre,post=match(key,"(.+)%.([^%.]+)$")
+ if pre and post then
+ for k in gmatch(pre,"[^%.]+") do
+ local dk=d[k]
+ if not dk then
+ dk={}
+ d[k]=dk
+ elseif type(dk)=="string" then
+ break
+ end
+ d=dk
end
+ dkey,hkey=post,key
+ end
+ if value==nil then
+ value=default
+ elseif value==false then
+ elseif persistent then
+ value=value or d[dkey] or default
+ else
+ value=value or default
+ end
+ d[dkey],h[hkey]=value,value
+ elseif type(d)=="string" then
+ data[tag],hash[tag]=value,value
end
+ end
end
local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
- return h[key]
- else
- local d=data[tag]
- if d then
- for k in gmatch(key,"[^%.]+") do
- local dk=d[k]
- if dk~=nil then
- d=dk
- else
- return default
- end
- end
- if d==false then
- return false
- else
- return d or default
- end
+ local h=hash[tag]
+ if h and h[key] then
+ return h[key]
+ else
+ local d=data[tag]
+ if d then
+ for k in gmatch(key,"[^%.]+") do
+ local dk=d[k]
+ if dk~=nil then
+ d=dk
+ else
+ return default
end
+ end
+ if d==false then
+ return false
+ else
+ return d or default
+ end
end
+ end
end
states.set_by_tag=set_by_tag
states.get_by_tag=get_by_tag
function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
+ set_by_tag(states.tag,key,value,default,persistent)
end
function states.get(key,default)
- return get_by_tag(states.tag,key,default)
+ return get_by_tag(states.tag,key,default)
end
@@ -21110,14 +24723,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
--- original size: 9268, stripped down to: 7401
+-- original size: 9418, stripped down to: 7087
if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- 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 mtxrun",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format=string.format
local concat=table.concat
@@ -21125,229 +24738,232 @@ local quoted=string.quoted
local luasuffixes=utilities.lua.suffixes
local report_format=logs.reporter("resolvers","formats")
local function primaryflags()
- local arguments=environment.arguments
- local flags={}
- if arguments.silent then
- flags[#flags+1]="--interaction=batchmode"
- end
- if arguments.jit then
- flags[#flags+1]="--jiton"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local flags={}
+ if arguments.silent then
+ flags[#flags+1]="--interaction=batchmode"
+ end
+ return concat(flags," ")
end
local function secondaryflags()
- local arguments=environment.arguments
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
- flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
- flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
- flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
- flags[#flags+1]="--c:errors"
- end
- if arguments.jit then
- flags[#flags+1]="--c:jiton"
- end
- if arguments.ansi then
- flags[#flags+1]="--c:ansi"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local trackers=arguments.trackers
+ local directives=arguments.directives
+ local flags={}
+ if trackers and trackers~="" then
+ flags[#flags+1]="--c:trackers="..quoted(trackers)
+ end
+ if directives and directives~="" then
+ flags[#flags+1]="--c:directives="..quoted(directives)
+ end
+ if arguments.silent then
+ flags[#flags+1]="--c:silent"
+ end
+ if arguments.errors then
+ flags[#flags+1]="--c:errors"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--c:jiton"
+ end
+ 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
local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
local checkers={
- primaryflags="string",
- secondaryflags="string",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
+ primaryflags="string",
+ secondaryflags="string",
+ luafile="readable",
+ texfile="readable",
+ redirect="string",
+ dump="string",
}
local runners={
- luatex=sandbox.registerrunner {
- name="make luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="make luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="make luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="make luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.make_format(name,arguments)
- local engine=environment.ownmain or "luatex"
- local silent=environment.arguments.silent
- local errors=environment.arguments.errors
- local olddir=dir.current()
- local path=caches.getwritablepath("formats",engine) or ""
- if path~="" then
- lfs.chdir(path)
- end
- report_format("using format path %a",dir.current())
- local texsourcename=file.addsuffix(name,"mkiv")
- local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(name,"tex")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- report_format("no tex source file with name %a (mkiv or tex)",name)
- lfs.chdir(olddir)
- return
- else
- report_format("using tex source file %a",fulltexsourcename)
- end
- local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
- local specificationname=file.replacesuffix(fulltexsourcename,"lus")
- local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- if fullspecificationname=="" then
- specificationname=file.join(texsourcepath,"context.lus")
- fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- end
- if fullspecificationname=="" then
- report_format("unknown stub specification %a",specificationname)
- lfs.chdir(olddir)
- return
- end
- local specificationpath=file.dirname(fullspecificationname)
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
- usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
- elseif type(usedlualibs)=="table" then
- report_format("using stub specification %a",fullspecificationname)
- local texbasename=file.basename(name)
- local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
- local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
- report_format("creating initialization file %a",luastubname)
- utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
- if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
- report_format("using compiled initialization file %a",lucstubname)
- usedluastub=lucstubname
- else
- report_format("using uncompiled initialization file %a",luastubname)
- usedluastub=luastubname
- end
- else
- report_format("invalid stub specification %a",fullspecificationname)
- lfs.chdir(olddir)
- return
- end
- local specification={
- primaryflags=primaryflags(),
- secondaryflags=secondaryflags(),
- luafile=quoted(usedluastub),
- texfile=quoted(fulltexsourcename),
- dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
- elseif silent then
- statistics.starttiming()
- specification.redirect="> temp.log"
- local result=runner(specification)
- local runtime=statistics.stoptiming()
- if result~=0 then
- print(format("%s silent make > fatal error when making format %q",engine,name))
- else
- print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
- end
- os.remove("temp.log")
- else
- runner(specification)
- end
- local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
- local mp=dir.glob(pattern)
- if mp then
- for i=1,#mp do
- local name=mp[i]
- report_format("removing related mplib format %a",file.basename(name))
- os.remove(name)
- end
- end
+ local engine=environment.ownmain or "luatex"
+ local silent=environment.arguments.silent
+ local errors=environment.arguments.errors
+ local olddir=dir.current()
+ local path=caches.getwritablepath("formats",engine) or ""
+ if path~="" then
+ lfs.chdir(path)
+ end
+ report_format("using format path %a",dir.current())
+ local texsourcename=file.addsuffix(name,"mkiv")
+ local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ if fulltexsourcename=="" then
+ texsourcename=file.addsuffix(name,"tex")
+ fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ end
+ if fulltexsourcename=="" then
+ report_format("no tex source file with name %a (mkiv or tex)",name)
+ lfs.chdir(olddir)
+ return
+ else
+ report_format("using tex source file %a",fulltexsourcename)
+ end
+ local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
+ local specificationname=file.replacesuffix(fulltexsourcename,"lus")
+ local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ if fullspecificationname=="" then
+ specificationname=file.join(texsourcepath,"context.lus")
+ fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ end
+ if fullspecificationname=="" then
+ report_format("unknown stub specification %a",specificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specificationpath=file.dirname(fullspecificationname)
+ local usedluastub=nil
+ local usedlualibs=dofile(fullspecificationname)
+ if type(usedlualibs)=="string" then
+ usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
+ elseif type(usedlualibs)=="table" then
+ report_format("using stub specification %a",fullspecificationname)
+ local texbasename=file.basename(name)
+ local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
+ local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
+ report_format("creating initialization file %a",luastubname)
+ utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
+ report_format("using compiled initialization file %a",lucstubname)
+ usedluastub=lucstubname
+ else
+ report_format("using uncompiled initialization file %a",luastubname)
+ usedluastub=luastubname
+ end
+ else
+ report_format("invalid stub specification %a",fullspecificationname)
lfs.chdir(olddir)
+ return
+ end
+ local specification={
+ primaryflags=primaryflags(),
+ secondaryflags=secondaryflags(),
+ luafile=quoted(usedluastub),
+ texfile=quoted(fulltexsourcename),
+ dump=os.platform=="unix" and "\\\\dump" or "\\dump",
+ }
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
+ elseif silent then
+ statistics.starttiming()
+ specification.redirect="> temp.log"
+ local result=runner(specification)
+ local runtime=statistics.stoptiming()
+ if result~=0 then
+ print(format("%s silent make > fatal error when making format %q",engine,name))
+ else
+ print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
+ end
+ os.remove("temp.log")
+ else
+ runner(specification)
+ end
+ local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
+ local mp=dir.glob(pattern)
+ if mp then
+ for i=1,#mp do
+ local name=mp[i]
+ report_format("removing related mplib format %a",file.basename(name))
+ os.remove(name)
+ end
+ end
+ lfs.chdir(olddir)
end
local template=[[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
local checkers={
- flags="string",
- more="string",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
+ flags="string",
+ more="string",
+ fmtfile="readable",
+ luafile="readable",
+ texfile="readable",
}
local runners={
- luatex=sandbox.registerrunner {
- name="run luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="run luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="run luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="run luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.run_format(name,data,more)
- if name and name~="" then
- local engine=environment.ownmain or "luatex"
- local barename=file.removesuffix(name)
- local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
- if fmtname=="" then
- fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
- end
- fmtname=resolvers.cleanpath(fmtname)
- if fmtname=="" then
- report_format("no format with name %a",name)
+ if name and name~="" then
+ local engine=environment.ownmain or "luatex"
+ local barename=file.removesuffix(name)
+ local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
+ if fmtname=="" then
+ fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
+ end
+ fmtname=resolvers.cleanpath(fmtname)
+ if fmtname=="" then
+ report_format("no format with name %a",name)
+ else
+ local barename=file.removesuffix(name)
+ local luaname=file.addsuffix(barename,"luc")
+ if not lfs.isfile(luaname) then
+ luaname=file.addsuffix(barename,"lua")
+ end
+ if not lfs.isfile(luaname) then
+ report_format("using format name %a",fmtname)
+ report_format("no luc/lua file with name %a",barename)
+ else
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be run, no runner available for engine %a",name,engine)
else
- local barename=file.removesuffix(name)
- local luaname=file.addsuffix(barename,"luc")
- if not lfs.isfile(luaname) then
- luaname=file.addsuffix(barename,"lua")
- end
- if not lfs.isfile(luaname) then
- report_format("using format name %a",fmtname)
- report_format("no luc/lua file with name %a",barename)
- else
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be run, no runner available for engine %a",name,engine)
- else
- runner {
- flags=primaryflags(),
- fmtfile=quoted(barename),
- luafile=quoted(luaname),
- texfile=quoted(data),
- more=more,
- }
- end
- end
+ runner {
+ flags=primaryflags(),
+ fmtfile=quoted(barename),
+ luafile=quoted(luaname),
+ texfile=quoted(data),
+ more=more,
+ }
end
+ end
end
+ end
end
end -- of closure
--- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
+-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 877962
--- stripped bytes : 317771
+-- original bytes : 994864
+-- stripped bytes : 395007
-- end library merge
@@ -21370,6 +24986,7 @@ local owntree = environment and environment.ownpath or ownpath
local ownlibs = { -- order can be made better
+ 'l-bit32.lua',
'l-lua.lua',
'l-macro.lua',
'l-sandbox.lua',
@@ -21385,6 +25002,7 @@ local ownlibs = { -- order can be made better
'l-file.lua',
'l-gzip.lua',
'l-md5.lua',
+ 'l-sha.lua',
'l-url.lua',
'l-dir.lua',
'l-boolean.lua',
@@ -21399,6 +25017,19 @@ local ownlibs = { -- order can be made better
'util-prs.lua',
'util-fmt.lua',
+ 'util-soc-imp-reset.lua',
+ 'util-soc-imp-socket.lua',
+ 'util-soc-imp-copas.lua',
+ 'util-soc-imp-ltn12.lua',
+ -- 'util-soc-imp-mbox.lua',
+ 'util-soc-imp-mime.lua',
+ 'util-soc-imp-url.lua',
+ 'util-soc-imp-headers.lua',
+ 'util-soc-imp-tp.lua',
+ 'util-soc-imp-http.lua',
+ 'util-soc-imp-ftp.lua',
+ 'util-soc-imp-smtp.lua',
+
'trac-set.lua',
'trac-log.lua',
'trac-inf.lua', -- was before trac-set
@@ -21601,9 +25232,7 @@ local helpinfo = [[
<flag name="locate"><short>locate given filename in database (default) or system (<ref name="first"/> <ref name="all"/> <ref name="detail"/>)</short></flag>
</subcategory>
<subcategory>
- <flag name="autotree"><short>use texmf tree cf. env texmfstart_tree or texmfstarttree</short></flag>
<flag name="tree" value="pathtotree"><short>use given texmf tree (default file: setuptex.tmf)</short></flag>
- <flag name="environment" value="name"><short>use given (tmf) environment file</short></flag>
<flag name="path" value="runpath"><short>go to given path before execution</short></flag>
<flag name="ifchanged" value="filename"><short>only execute when given file has changed (md checksum)</short></flag>
<flag name="iftouched" value="old,new"><short>only execute when given file has changed (time stamp)</short></flag>
@@ -21623,7 +25252,7 @@ local helpinfo = [[
</subcategory>
<subcategory>
<flag name="edit"><short>launch editor with found file</short></flag>
- <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>)</short></flag>
+ <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>,<ref name="list"/>)</short></flag>
</subcategory>
<subcategory>
<flag name="timedrun"><short>run a script and time its run</short></flag>
@@ -22022,9 +25651,9 @@ function resolvers.launch(str)
end
function runners.launch_file(filename)
- trackers.enable("resolvers.locating")
local allresults = environment.arguments["all"]
- local pattern = environment.arguments["pattern"]
+ local pattern = environment.arguments["pattern"]
+ local listonly = environment.arguments["list"]
if not pattern or pattern == "" then
pattern = filename
end
@@ -22039,14 +25668,32 @@ function runners.launch_file(filename)
t = resolvers.findfiles("*/" .. pattern .. "*",nil,allresults)
end
if t and #t > 0 then
- if allresults then
- for _, v in pairs(t) do
- report("launching %s", v)
- resolvers.launch(v)
+ for i=1,#t do
+ local name = t[i]
+ if listonly then
+ report("% 3i: %-30s %s",i,file.basename(name),file.dirname(name))
+ else
+ report("launching: %s",name)
+ resolvers.launch(name)
+ if not allresults then
+ break
+ end
+ end
+ end
+ if listonly then
+ io.write("\n")
+ io.write("\n[select number]\n\n>> ")
+ local answer = tonumber(io.read())
+ if answer then
+ io.write("\n")
+ local name = t[answer]
+ if name then
+ report("launching: %s",name)
+ resolvers.launch(name)
+ else
+ report("invalid number")
+ end
end
- else
- report("launching %s", t[1])
- resolvers.launch(t[1])
end
else
report("no match for %s", pattern)
@@ -22166,12 +25813,9 @@ function runners.execute_ctx_script(filename,...)
dofile(fullname)
local savename = environment.arguments['save']
if savename then
- local save_list = runners.save_list
- if save_list and next(save_list) then
- if type(savename) ~= "string" then savename = file.basename(fullname) end
- savename = file.replacesuffix(savename,"cfg")
- runners.save_script_session(savename,save_list)
- end
+ if type(savename) ~= "string" then savename = file.basename(fullname) end
+ savename = file.replacesuffix(savename,"cfg")
+ runners.save_script_session(savename,save_list)
end
return true
end
@@ -22188,22 +25832,22 @@ function runners.execute_ctx_script(filename,...)
local scriptbase = match(scriptname,".*mtx%-([^%-]-)%.lua")
if scriptbase then
local data = io.loaddata(scriptname)
-local application = match(data,"local application.-=.-(%{.-%})")
-if application then
- application = loadstring("return " .. application)
- if application then
- application = application()
- local banner = application.banner
- if banner then
- local description, version = match(banner,"^(.-) ([%d.]+)$")
- if description then
- valid[#valid+1] = { scriptbase, version, description }
- else
- valid[#valid+1] = { scriptbase, "", banner }
- end
- end
- end
-end
+ local application = match(data,"local application.-=.-(%{.-%})")
+ if application then
+ application = loadstring("return " .. application)
+ if application then
+ application = application()
+ local banner = application.banner
+ if banner then
+ local description, version = match(banner,"^(.-) ([%d.]+)$")
+ if description then
+ valid[#valid+1] = { scriptbase, version, description }
+ else
+ valid[#valid+1] = { scriptbase, "", banner }
+ end
+ end
+ end
+ end
end
end
if #valid > 0 then
@@ -22243,7 +25887,7 @@ function runners.timedrun(filename) -- just for me
end
function runners.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
function runners.associate(filename)
diff --git a/scripts/context/stubs/setup/setuptex b/scripts/context/stubs/setup/setuptex
index 9808140e4..fb65788b6 100644
--- a/scripts/context/stubs/setup/setuptex
+++ b/scripts/context/stubs/setup/setuptex
@@ -24,9 +24,23 @@ cpu=`uname -m`
case "$system" in
# linux
Linux)
+ if command -v ldd >/dev/null && ldd --version 2>&1 | grep -E '^musl' >/dev/null
+ then
+ libc=musl
+ else
+ libc=glibc
+ fi
case "$cpu" in
- i*86) platform="linux" ;;
- x86_64|ia64) platform="linux-64" ;;
+ i*86)
+ case "$libc" in
+ glibc) platform="linux" ;;
+ musl) platform="linuxmusl" ;;
+ esac ;;
+ x86_64|ia64)
+ case "$libc" in
+ glibc) platform="linux-64" ;;
+ musl) platform="linuxmusl-64" ;;
+ esac ;;
# a little bit of cheating with ppc64 (won't work on Gentoo)
ppc|ppc64) platform="linux-ppc" ;;
diff --git a/scripts/context/stubs/setup/setuptex.csh b/scripts/context/stubs/setup/setuptex.csh
index c1160675f..62ca03569 100644
--- a/scripts/context/stubs/setup/setuptex.csh
+++ b/scripts/context/stubs/setup/setuptex.csh
@@ -82,6 +82,19 @@ switch ( $system )
set platform="unknown"
endsw
breaksw
+ # OpenBSD
+ case OpenBSD:
+ switch ( $cpu )
+ case i*86:
+ set platform="openbsd"
+ breaksw
+ case amd64:
+ set platform="openbsd-amd64"
+ breaksw
+ default:
+ set platform="unknown"
+ endsw
+ breaksw
# cygwin
case CYGWIN:
switch ( $cpu )
diff --git a/scripts/context/stubs/unix/metatex b/scripts/context/stubs/unix/metatex
deleted file mode 100644
index f0c6b65d4..000000000
--- a/scripts/context/stubs/unix/metatex
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-mtxrun --script metatex "$@"
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 0f4767d91..569a7f2e1 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -1,16 +1,5 @@
#!/usr/bin/env texlua
--- for k, v in next, _G.string do
--- local tv = type(v)
--- if tv == "table" then
--- for kk, vv in next, v do
--- print(k,kk,vv)
--- end
--- else
--- print(tv,k,v)
--- end
--- end
-
if not modules then modules = { } end modules ['mtxrun'] = {
version = 1.001,
comment = "runner, lua replacement for texmfstart.rb",
@@ -20,25 +9,43 @@ if not modules then modules = { } end modules ['mtxrun'] = {
}
-- one can make a stub:
+
+-- mtxrun :
--
-- #!/bin/sh
-- env LUATEXDIR=/....../texmf/scripts/context/lua luatex --luaonly mtxrun.lua "$@"
+-- mtxrun.cmd :
+--
+-- @luatex --luaonly %~d0%~p0mtxrun.lua %*
+
-- filename : mtxrun.lua
-- comment : companion to context.tex
-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
-- copyright: PRAGMA ADE / ConTeXt Development Team
-- license : see context related readme files
--- This script is based on texmfstart.rb but does not use kpsewhich to
--- locate files. Although kpse is a library it never came to opening up
--- its interface to other programs (esp scripting languages) and so we
--- do it ourselves. The lua variant evolved out of an experimental ruby
--- one. Interesting is that using a scripting language instead of c does
--- not have a speed penalty. Actually the lua variant is more efficient,
--- especially when multiple calls to kpsewhich are involved. The lua
+-- This script is based on texmfstart.rb but does not use kpsewhich to locate files.
+-- Although kpse is a library it never came to opening up its interface to other
+-- programs (esp scripting languages) and so we do it ourselves. The lua variant
+-- evolved out of an experimental ruby one. Interesting is that using a scripting
+-- language instead of c does not have a speed penalty. Actually the lua variant is
+-- more efficient, especially when multiple calls to kpsewhich are involved. The lua
-- library also gives way more control.
+-- When libraries used here are updates you can run
+--
+-- mtxrun --selfmerge
+--
+-- to update the embedded code. After that you might need to run
+--
+-- mtxrun --selfupdate
+--
+-- to copy the new script (from scripts/context/lua) to location where
+-- binaries are expected. If you want to remove the embedded code you can run
+--
+-- mtxxun --selfclean
+
-- to be done / considered
--
-- support for --exec or make it default
@@ -54,16 +61,147 @@ if not modules then modules = { } end modules ['mtxrun'] = {
do -- create closure to overcome 200 locals limit
+package.loaded["l-bit32"] = package.loaded["l-bit32"] or true
+
+-- original size: 3607, stripped down to: 3009
+
+if not modules then modules={} end modules ['l-bit32']={
+ version=1.001,
+ license="the same as regular Lua",
+ source="bitwise.lua, v 1.24 2014/12/26 17:20:53 roberto",
+ comment="drop-in for bit32, adapted a bit by Hans Hagen",
+}
+if bit32 then
+elseif utf8 then
+ load ([[
+local select = select -- instead of: arg = { ... }
+bit32 = {
+ bnot = function (a)
+ return ~a & 0xFFFFFFFF
+ end,
+ band = function (x, y, z, ...)
+ if not z then
+ return ((x or -1) & (y or -1)) & 0xFFFFFFFF
+ else
+ local res = x & y & z
+ for i=1,select("#",...) do
+ res = res & select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ bor = function (x, y, z, ...)
+ if not z then
+ return ((x or 0) | (y or 0)) & 0xFFFFFFFF
+ else
+ local res = x | y | z
+ for i=1,select("#",...) do
+ res = res | select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ bxor = function (x, y, z, ...)
+ if not z then
+ return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF
+ else
+ local res = x ~ y ~ z
+ for i=1,select("#",...) do
+ res = res ~ select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ btest = function (x, y, z, ...)
+ if not z then
+ return (((x or -1) & (y or -1)) & 0xFFFFFFFF) ~= 0
+ else
+ local res = x & y & z
+ for i=1,select("#",...) do
+ res = res & select(i,...)
+ end
+ return (res & 0xFFFFFFFF) ~= 0
+ end
+ end,
+ lshift = function (a, b)
+ return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF
+ end,
+ rshift = function (a, b)
+ return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF
+ end,
+ arshift = function (a, b)
+ a = a & 0xFFFFFFFF
+ if b <= 0 or (a & 0x80000000) == 0 then
+ return (a >> b) & 0xFFFFFFFF
+ else
+ return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
+ end
+ end,
+ lrotate = function (a ,b)
+ b = b & 31
+ a = a & 0xFFFFFFFF
+ a = (a << b) | (a >> (32 - b))
+ return a & 0xFFFFFFFF
+ end,
+ rrotate = function (a, b)
+ b = -b & 31
+ a = a & 0xFFFFFFFF
+ a = (a << b) | (a >> (32 - b))
+ return a & 0xFFFFFFFF
+ end,
+ extract = function (a, f, w)
+ return (a >> f) & ~(-1 << (w or 1))
+ end,
+ replace = function (a, v, f, w)
+ local mask = ~(-1 << (w or 1))
+ return ((a & ~(mask << f)) | ((v & mask) << f)) & 0xFFFFFFFF
+ end,
+}
+ ]] ) ()
+elseif bit then
+ load ([[
+local band, bnot, rshift, lshift = bit.band, bit.bnot, bit.rshift, bit.lshift
+bit32 = {
+ arshift = bit.arshift,
+ band = band,
+ bnot = bnot,
+ bor = bit.bor,
+ bxor = bit.bxor,
+ btest = function(...)
+ return band(...) ~= 0
+ end,
+ extract = function(a,f,w)
+ return band(rshift(a,f),2^(w or 1)-1)
+ end,
+ lrotate = bit.rol,
+ lshift = lshift,
+ replace = function(a,v,f,w)
+ local mask = 2^(w or 1)-1
+ return band(a,bnot(lshift(mask,f)))+lshift(band(v,mask),f)
+ end,
+ rrotate = bit.ror,
+ rshift = rshift,
+}
+ ]] ) ()
+else
+ xpcall(function() local _,t=require("bit32") if t then bit32=t end return end,function() end)
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 6230, stripped down to: 3662
+-- original size: 6281, stripped down to: 2863
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+).*$")
@@ -71,122 +209,111 @@ 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
+ ffi.number=tonumber
end
-if not bit32 then
- bit32=require("l-bit32")
+if LUAVERSION>5.3 then
+ collectgarbage("generational")
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
end -- of closure
@@ -195,25 +322,27 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-macro"] = package.loaded["l-macro"] or true
--- original size: 8260, stripped down to: 5213
+-- original size: 10131, stripped down to: 5991
if not modules then modules={} end modules ['l-macros']={
- 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 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)
@@ -230,172 +359,214 @@ local definitions={}
local resolve
local subparser
local report_lua=function(...)
- if logs and logs.reporter then
- report_lua=logs.reporter("system","lua")
- report_lua(...)
- else
- print(format(...))
- end
-end
-resolve=C(C(name)*arguments^-1)/function(raw,s,a)
- local d=definitions[s]
- if d then
- if a then
- local n=#a
- local p=patterns[s][n]
- if p then
- local d=d[n]
- for i=1,n do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return lpegmatch(p,d,1,a) or d
- else
- return raw
- end
- else
- return d[0] or raw
- end
- elseif a then
- for i=1,#a do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return s.."("..concat(a,",")..")"
- else
- return raw
- end
-end
-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 n=0
+ if logs and logs.reporter then
+ report_lua=logs.reporter("system","lua")
+ report_lua(...)
+ else
+ print(format(...))
+ end
+end
+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
- n=#a
- local pattern=P(false)
+ local n=#a
+ local p=patterns[s][n]
+ if p then
+ local d=d[n]
for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- p[n]=pattern
+ return lpegmatch(p,d,1,a) or d
+ else
+ return raw
+ end
+ else
+ return d[0] or raw
end
- local d=definitions[k]
- if not d then
- d={ [0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
+ elseif a then
+ for i=1,#a do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ return s.."("..concat(a,",")..")"
+ else
+ return raw
+ end
end
-local register=(C(name)*spaces^0*(arguments+Cc(false))*spaces^0*C(body))/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ [0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+subparser=Cs((resolve+P(1))^1)
+local enddefine=P("#enddefine")/""
+local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ 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=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ 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 unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
- n=#a
- local p=patterns[k]
- if p then
- p[n]=false
- end
- end
- local d=definitions[k]
- if d then
- d[n]=false
+ local n=0
+ if a then
+ n=#a
+ local p=patterns[k]
+ if p then
+ p[n]=false
end
- return ""
+ end
+ local d=definitions[k]
+ if d then
+ d[n]=false
+ end
+ return ""
end
local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define" )*spaces^0/"")*register
-local undefine=(P("undefine" )*spaces^0/"")*unregister
+local define=(P("define" )*spaces^0/"")*register
+local undefine=(P("undefine" )*spaces^0/"")*unregister
local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
function macros.reset()
- definitions={}
- patterns={}
+ definitions={}
+ patterns={}
+end
+function macros.showdefinitions()
+ 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
+ return lpegmatch(parser,str) or str
end
function macros.resolving()
- return next(patterns)
-end
-local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
- return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
- return false,format("file '%s' is invalid",name)
- end
+ 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 n=lpegmatch(parser,c)
- if trace then
- if #n~=#c then
- report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
- if detail then
- report_lua()
- report_lua(n)
- report_lua()
- end
- elseif detail then
- report_lua("no macros expanded in '%s'",name)
- end
+ local f=loadfile(name)
+ os.remove(name)
+ return f
+ end
+end
+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
- if #name>30 then
- n="--[["..sub(name,-30).."]] "..n
- else
- n="--[["..name.."]] "..n
+ end
+ return load(data,name)
+end
+local function loaded(name,trace,detail)
+ local f=io.open(name,"rb")
+ if not f then
+ return false,format("file '%s' not found",name)
+ end
+ local c=f:read("*a")
+ if not c then
+ return false,format("file '%s' is invalid",name)
+ end
+ f:close()
+ local n=lpegmatch(parser,c)
+ if trace then
+ if #n~=#c then
+ report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
+ if detail then
+ report_lua()
+ report_lua(n)
+ report_lua()
+ end
+ elseif detail then
+ report_lua("no macros expanded in '%s'",name)
end
- return load(n)
+ end
+ return reload(lfs and lfs.currentdir(),name,n)
end
macros.loaded=loaded
function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.find_file(filename) or filename
- if not fullname or fullname=="" then
- return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
- return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
- code=code()
- else
- report_lua("error when loading '%s'",fullname)
- return false,message
- end
- if code==nil then
- code=false
- end
- package.loaded[fullname]=code
- return code
+ local filename=file.addsuffix(name,"lua")
+ local fullname=resolvers and resolvers.find_file(filename) or filename
+ if not fullname or fullname=="" then
+ return false
+ end
+ local codeblob=package.loaded[fullname]
+ if codeblob then
+ return codeblob
+ end
+ local code,message=loaded(fullname,macros,trace,trace)
+ if type(code)=="function" then
+ code=code()
+ else
+ report_lua("error when loading '%s'",fullname)
+ return false,message
+ end
+ if code==nil then
+ code=false
+ end
+ package.loaded[fullname]=code
+ return code
end
macros.required=required
@@ -406,14 +577,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
--- original size: 9678, stripped down to: 6688
+-- original size: 9747, stripped down to: 6313
if not modules then modules={} end modules ['l-sandbox']={
- 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 global=_G
local next=next
@@ -439,231 +610,234 @@ local trace=false
local logger=false
local blocked={}
local function report(...)
- tprint("sandbox ! "..format(...))
+ tprint("sandbox ! "..format(...))
end
sandbox.report=report
function sandbox.setreporter(r)
- report=r
- sandbox.report=r
+ report=r
+ sandbox.report=r
end
function sandbox.settrace(v)
- trace=v
+ trace=v
end
function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
+ logger=type(l)=="function" and l or false
end
local function register(func,overload,comment)
- if type(func)=="function" then
- if type(overload)=="string" then
- comment=overload
- overload=nil
- end
- local function f(...)
- if sandboxed then
- local overload=overloads[f]
- if overload then
- if logger then
- local result={ overload(func,...) }
- logger {
- comment=comments[f] or tostring(f),
- arguments={... },
- result=result[1] and true or false,
- }
- return unpack(result)
- else
- return overload(func,...)
- end
- else
- end
- else
- return func(...)
- end
- end
- if comment then
- comments[f]=comment
- if trace then
- report("registering function: %s",comment)
- end
+ if type(func)=="function" then
+ if type(overload)=="string" then
+ comment=overload
+ overload=nil
+ end
+ local function f(...)
+ if sandboxed then
+ local overload=overloads[f]
+ if overload then
+ if logger then
+ local result={ overload(func,...) }
+ logger {
+ comment=comments[f] or tostring(f),
+ arguments={... },
+ result=result[1] and true or false,
+ }
+ return unpack(result)
+ else
+ return overload(func,...)
+ end
+ else
end
- overloads[f]=overload or false
- originals[f]=func
- return f
+ else
+ return func(...)
+ end
end
+ if comment then
+ comments[f]=comment
+ if trace then
+ report("registering function: %s",comment)
+ end
+ end
+ overloads[f]=overload or false
+ originals[f]=func
+ return f
+ end
end
local function redefine(func,comment)
- if type(func)=="function" then
- skiploads[func]=comment or comments[func] or "unknown"
- if overloads[func]==false then
- overloads[func]=nil
- end
+ if type(func)=="function" then
+ skiploads[func]=comment or comments[func] or "unknown"
+ if overloads[func]==false then
+ overloads[func]=nil
end
+ end
end
sandbox.register=register
sandbox.redefine=redefine
function sandbox.original(func)
- return originals and originals[func] or func
+ return originals and originals[func] or func
end
function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
- if trace then
- report("overloading unknown function: %s",comment)
- end
- elseif type(overload)~="function" then
- if trace then
- report("overloading function with bad overload: %s",comment)
- end
- elseif overloads[func]==nil then
- if trace then
- report("function is not registered: %s",comment)
- end
- elseif skiploads[func] then
- if trace then
- report("function is not skipped: %s",comment)
- end
- else
- if trace then
- report("overloading function: %s",comment)
- end
- overloads[func]=overload
+ comment=comment or comments[func] or "?"
+ if type(func)~="function" then
+ if trace then
+ report("overloading unknown function: %s",comment)
+ end
+ elseif type(overload)~="function" then
+ if trace then
+ report("overloading function with bad overload: %s",comment)
+ end
+ elseif overloads[func]==nil then
+ if trace then
+ report("function is not registered: %s",comment)
+ end
+ elseif skiploads[func] then
+ if trace then
+ report("function is not skipped: %s",comment)
end
- return func
+ else
+ if trace then
+ report("overloading function: %s",comment)
+ end
+ overloads[func]=overload
+ end
+ return func
end
local function whatever(specification,what,target)
- if type(specification)~="table" then
- report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
- report("%s needs a category and action",what)
- elseif not sandboxed then
- target[#target+1]=specification
- elseif trace then
- report("already enabled, discarding %s",what)
- end
+ if type(specification)~="table" then
+ report("%s needs a specification",what)
+ elseif type(specification.category)~="string" or type(specification.action)~="function" then
+ report("%s needs a category and action",what)
+ elseif not sandboxed then
+ target[#target+1]=specification
+ elseif trace then
+ report("already enabled, discarding %s",what)
+ end
end
function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
+ whatever(specification,"initializer",initializers)
end
function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
+ whatever(specification,"finalizer",finalizers)
end
function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
- return nil
- elseif b then
- if trace then
- report("using blocked: %s",n)
- end
- return b
- else
- if trace then
- report("requiring: %s",name)
- end
- return requiem(name)
+ local n=gsub(name,"^.*[\\/]","")
+ local n=gsub(n,"[%.].*$","")
+ local b=blocked[n]
+ if b==false then
+ return nil
+ elseif b then
+ if trace then
+ report("using blocked: %s",n)
end
-end
-function blockrequire(name,lib)
+ return b
+ else
if trace then
- report("preventing reload of: %s",name)
+ report("requiring: %s",name)
end
- blocked[name]=lib or _G[name] or false
+ return requiem(name)
+ end
+end
+function blockrequire(name,lib)
+ if trace then
+ report("preventing reload of: %s",name)
+ end
+ blocked[name]=lib or _G[name] or false
end
function sandbox.enable()
- if not sandboxed then
- for i=1,#initializers do
- initializers[i].action()
- end
- for i=1,#finalizers do
- finalizers[i].action()
- end
- local nnot=0
- local nyes=0
- local cnot={}
- local cyes={}
- local skip={}
- for k,v in next,overloads do
- local c=comments[k]
- if v then
- if c then
- cyes[#cyes+1]=c
- else
- nyes=nyes+1
- end
- else
- if c then
- cnot[#cnot+1]=c
- else
- nnot=nnot+1
- end
- end
- end
- for k,v in next,skiploads do
- skip[#skip+1]=v
- end
- if #cyes>0 then
- sort(cyes)
- report("overloaded known: %s",concat(cyes," | "))
- end
- if nyes>0 then
- report("overloaded unknown: %s",nyes)
- end
- if #cnot>0 then
- sort(cnot)
- report("not overloaded known: %s",concat(cnot," | "))
- end
- if nnot>0 then
- report("not overloaded unknown: %s",nnot)
+ if not sandboxed then
+ debug={
+ traceback=debug.traceback,
+ }
+ for i=1,#initializers do
+ initializers[i].action()
+ end
+ for i=1,#finalizers do
+ finalizers[i].action()
+ end
+ local nnot=0
+ local nyes=0
+ local cnot={}
+ local cyes={}
+ local skip={}
+ for k,v in next,overloads do
+ local c=comments[k]
+ if v then
+ if c then
+ cyes[#cyes+1]=c
+ else
+ nyes=nyes+1
end
- if #skip>0 then
- sort(skip)
- report("not overloaded redefined: %s",concat(skip," | "))
+ else
+ if c then
+ cnot[#cnot+1]=c
+ else
+ nnot=nnot+1
end
- initializers=nil
- finalizers=nil
- originals=nil
- sandboxed=true
+ end
+ end
+ for k,v in next,skiploads do
+ skip[#skip+1]=v
+ end
+ if #cyes>0 then
+ sort(cyes)
+ report("overloaded known: %s",concat(cyes," | "))
+ end
+ if nyes>0 then
+ report("overloaded unknown: %s",nyes)
end
+ if #cnot>0 then
+ sort(cnot)
+ report("not overloaded known: %s",concat(cnot," | "))
+ end
+ if nnot>0 then
+ report("not overloaded unknown: %s",nnot)
+ end
+ if #skip>0 then
+ sort(skip)
+ report("not overloaded redefined: %s",concat(skip," | "))
+ end
+ initializers=nil
+ finalizers=nil
+ originals=nil
+ sandboxed=true
+ end
end
blockrequire("lfs",lfs)
blockrequire("io",io)
blockrequire("os",os)
blockrequire("ffi",ffi)
local function supported(library)
- local l=_G[library]
- return l
+ local l=_G[library]
+ return l
end
loadfile=register(loadfile,"loadfile")
if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen")
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
+ io.open=register(io.open,"io.open")
+ io.popen=register(io.popen,"io.popen")
+ io.lines=register(io.lines,"io.lines")
+ io.output=register(io.output,"io.output")
+ io.input=register(io.input,"io.input")
end
if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
+ os.execute=register(os.execute,"os.execute")
+ os.spawn=register(os.spawn,"os.spawn")
+ os.exec=register(os.exec,"os.exec")
+ os.rename=register(os.rename,"os.rename")
+ os.remove=register(os.remove,"os.remove")
end
if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
+ lfs.chdir=register(lfs.chdir,"lfs.chdir")
+ lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
+ lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
+ lfs.isfile=register(lfs.isfile,"lfs.isfile")
+ lfs.isdir=register(lfs.isdir,"lfs.isdir")
+ lfs.attributes=register(lfs.attributes,"lfs.attributes")
+ lfs.dir=register(lfs.dir,"lfs.dir")
+ lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
+ lfs.touch=register(lfs.touch,"lfs.touch")
+ lfs.link=register(lfs.link,"lfs.link")
+ lfs.setmode=register(lfs.setmode,"lfs.setmode")
+ lfs.readlink=register(lfs.readlink,"lfs.readlink")
+ lfs.shortname=register(lfs.shortname,"lfs.shortname")
+ lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
end
@@ -673,14 +847,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-package"] = package.loaded["l-package"] or true
--- original size: 11562, stripped down to: 8625
+-- original size: 11605, stripped down to: 8299
if not modules then modules={} end modules ['l-package']={
- 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=type
local gsub,format,find=string.gsub,string.format,string.find
@@ -688,40 +862,40 @@ local insert,remove=table.insert,table.remove
local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
local package=package
local searchers=package.searchers or package.loaders
-local filejoin=file and file.join or function(path,name) return path.."/"..name end
-local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join or function(path,name) return path.."/"..name end
+local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
local function cleanpath(path)
- return path
+ return path
end
local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
local function lualibfile(name)
- return lpegmatch(pattern,name) or name
+ return lpegmatch(pattern,name) or name
end
local offset=luarocks and 1 or 0
local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
- ["preload table"]=searchers[1+offset],
- ["path specification"]=searchers[2+offset],
- ["cpath specification"]=searchers[3+offset],
- ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
- "already loaded",
- "preload table",
- "qualified path",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
- }
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+ ["preload table"]=searchers[1+offset],
+ ["path specification"]=searchers[2+offset],
+ ["cpath specification"]=searchers[3+offset],
+ ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+ "already loaded",
+ "preload table",
+ "qualified path",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
}
package.helpers=helpers
local methods=helpers.methods
@@ -737,253 +911,256 @@ local nofextralib=-1
local nofpathlua=-1
local nofpathlib=-1
local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
- for i=1,nofpaths do
- helpers.report("using %s path %i: %s",what,i,paths[i])
- end
- else
- helpers.report("no %s paths defined",what)
+ local nofpaths=#paths
+ if nofpaths>0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
end
- return nofpaths
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
end
local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
- nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
+ if helpers.trace and #extraluapaths~=nofextralua then
+ nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
end
local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
- nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
+ if helpers.trace and #extralibpaths~=nofextralib then
+ nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
end
local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
- luapaths=file.splitpath(luapath,";")
- oldluapath=luapath
- nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
- nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+ luapaths=file.splitpath(luapath,";")
+ oldluapath=luapath
+ nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+ nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
end
local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
- libpaths=file.splitpath(libpath,";")
- oldlibpath=libpath
- nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
- nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+ libpaths=file.splitpath(libpath,";")
+ oldlibpath=libpath
+ nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+ nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
end
package.luapaths=getluapaths
package.libpaths=getlibpaths
package.extraluapaths=getextraluapaths
package.extralibpaths=getextralibpaths
local hashes={
- lua={},
- lib={},
+ lua={},
+ lib={},
}
local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
- local path=cleanpath(path)
- if not hash[path] then
- target[#target+1]=path
- hash[path]=true
- if trace then
- report("registered %s path %s: %s",tag,#target,path)
- end
- else
- if trace then
- report("duplicate %s path: %s",tag,path)
- end
- end
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+ local path=cleanpath(path)
+ if not hash[path] then
+ target[#target+1]=path
+ hash[path]=true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
end
- for p=1,#pathlist do
- local path=pathlist[p]
- if type(path)=="table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
+ end
+ for p=1,#pathlist do
+ local path=pathlist[p]
+ if type(path)=="table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
end
+ end
end
local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
- helpers.report("pushing %s path in front: %s",tag,path)
- end
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
end
local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
- if path then
- helpers.report("popping %s path from front: %s",tag,path)
- else
- helpers.report("no %s path to pop",tag)
- end
+ local path=remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
end
+ end
end
helpers.registerpath=registerpath
function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
+ registerpath("extra lua","lua",extraluapaths,...)
end
function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
+ pushpath("extra lua","lua",extraluapaths,path)
end
function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
+ poppath("extra lua","lua",extraluapaths)
end
function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
+ registerpath("extra lib","lib",extralibpaths,...)
end
function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
+ pushpath("extra lib","lib",extralibpaths,path)
end
function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
+ poppath("extra lib","lua",extralibpaths)
end
local function loadedaslib(resolved,rawname)
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
end
helpers.loadedaslib=loadedaslib
local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
- local path=paths[p]
- local resolved=filejoin(path,name)
- if trace then
- helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
- end
- if isreadable(resolved) then
- if trace then
- helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ for p=1,#paths do
+ local path=paths[p]
+ local resolved=filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbypath=loadedbypath
local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
- local trace=helpers.trace
- if trace then
- helpers.report("qualified name, identifying '%s'",what,name)
- end
- if isreadable(name) then
- if trace then
- helpers.report("qualified name, '%s' found",what,name)
- end
- return loadfile(name)
- end
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
+ end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
end
+ end
end
helpers.loadedbyname=loadedbyname
methods["already loaded"]=function(name)
- return package.loaded[name]
+ return package.loaded[name]
end
methods["preload table"]=function(name)
- return builtin["preload table"](name)
+ return builtin["preload table"](name)
end
methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
end
methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
end
methods["lib extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
end
methods["path specification"]=function(name)
- getluapaths()
- return builtin["path specification"](name)
+ getluapaths()
+ return builtin["path specification"](name)
end
methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
+ getlibpaths()
+ return builtin["cpath specification"](name)
end
methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+ return builtin["all in one fallback"](name)
end
methods["not loaded"]=function(name)
- if helpers.trace then
- helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
end
local level=0
local used={}
helpers.traceused=false
function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
- local method=sequence[i]
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
- end
- local result,rest=methods[method](name)
- if type(result)=="function" then
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
- end
- if helpers.traceused then
- used[#used+1]={ level=level,name=name }
- end
- level=level-1
- return result,rest
- end
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+ local method=sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
end
- level=level-1
- return nil
+ local result,rest=methods[method](name)
+ if type(result)=="function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1]={ level=level,name=name }
+ end
+ level=level-1
+ return result,rest
+ end
+ end
+ level=level-1
+ return nil
end
function helpers.showused()
- local n=#used
- if n>0 then
- helpers.report("%s libraries loaded:",n)
- helpers.report()
- for i=1,n do
- local u=used[i]
- helpers.report("%i %a",u.level,u.name)
- end
- helpers.report()
- end
+ local n=#used
+ if n>0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u=used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
end
function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading, name '%s', %s",name,"done")
- else
- helpers.report("unloading, name '%s', %s",name,"not loaded")
- end
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
end
- package.loaded[name]=nil
+ end
+ package.loaded[name]=nil
end
table.insert(searchers,1,helpers.loaded)
+if context then
+ package.path=""
+end
end -- of closure
@@ -992,14 +1169,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38582, stripped down to: 20518
+-- original size: 38434, stripped down to: 19310
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
@@ -1010,7 +1187,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
@@ -1033,7 +1210,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('"')
@@ -1042,9 +1219,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")
@@ -1076,7 +1253,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
@@ -1085,15 +1262,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
@@ -1150,7 +1327,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
@@ -1160,76 +1337,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("")
@@ -1239,505 +1424,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
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
+ 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
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ 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
+ 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
- pattern=(1-pattern)^0*pattern
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ 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
+ 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
- return p
+ 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
+ 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
- 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
+ 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
- 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
+ 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
- return (insensitive and make2 or make1)(tree)
+ 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
+ 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
@@ -1756,32 +1899,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
@@ -1791,14 +1949,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-function"] = package.loaded["l-function"] or true
--- original size: 361, stripped down to: 322
+-- original size: 361, stripped down to: 317
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
@@ -1810,14 +1968,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-string"] = package.loaded["l-string"] or true
--- original size: 6461, stripped down to: 3341
+-- original size: 6461, stripped down to: 3255
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
@@ -1825,25 +1983,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
@@ -1851,81 +2009,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
@@ -1935,166 +2093,172 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 40197, stripped down to: 23561
+-- original size: 41298, stripped down to: 21498
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 a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
end
- return tostring(a)<tostring(b)
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
+ end
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt={}
+ local category=0
+ local s=0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- 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)=="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
@@ -2102,907 +2266,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 n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ 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 n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ if not t then
+ t={}
+ end
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp={}
+ local ntmp=0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
+ end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
+ if not tables then
+ tables={}
+ end
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh={}
+ local h=0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- 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
+ 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
- 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 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"))
- else
- handle(format("%s{",depth))
- end
+ 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
- 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
- end
- if last>0 then
- first=1
- 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
- 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
+ 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
- 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
+ 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 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
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
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 {")
+ 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(name.."={")
+ handle(format("%s [%q]=%q,",depth,k,v))
end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
+ 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
- handle("["..name.."]={")
+ do_serialize(v,k,depth,level+1)
end
- elseif tname=="boolean" then
- if name then
- handle("return {")
+ 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("{")
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
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
+ 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
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
+ 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
- handle("}")
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
end
-function table.serialize(root,name,specification)
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
+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
+ 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
+ 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
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ 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)
+ 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
- f:close()
- io.flush()
+ 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
+ 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
- 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
+ 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
+ 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
- return f
+ 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
- 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
+ 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 ""
+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
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- s[i]=tostring(t[i])
+ 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 n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ 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 n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
- else
- return nothing
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
@@ -3012,14 +3213,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11823, stripped down to: 6945
+-- original size: 11823, stripped down to: 6325
if not modules then modules={} end modules ['l-io']={
- 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 io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -3027,334 +3228,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 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
- f:close()
- flush()
+ if data then
+ g:write(data)
+ end
+ 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
+ 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
+ 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
+ [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
@@ -3364,14 +3565,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5645, stripped down to: 2253
+-- original size: 5720, stripped down to: 2176
if not modules then modules={} end modules ['l-number']={
- 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 tostring,tonumber=tostring,tonumber
local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -3381,99 +3582,107 @@ local floor=math.floor
number=number or {}
local number=number
if bit32 then
- local bextract=bit32.extract
- local t={
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m)
- local n=32
- for i=0,31 do
- local v=bextract(b,i)
- local k=32-i
- if v==1 then
- n=k
- t[k]="1"
- else
- t[k]="0"
- end
- end
- if m then
- m=33-m*8
- if m<1 then
- m=1
- end
- return concat(t,"",m)
- elseif n<8 then
- return concat(t)
- elseif n<16 then
- return concat(t,"",9)
- elseif n<24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
+ local bextract=bit32.extract
+ local t={
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ }
+ 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=w-i
+ if v==1 then
+ n=k
+ t[k]="1"
+ else
+ t[k]="0"
+ end
+ end
+ 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,"",1,m)
+ elseif n<8 then
+ return concat(t)
+ elseif n<16 then
+ return concat(t,"",9)
+ elseif n<24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
end
+ end
else
- function number.tobitstring(n,m)
- if n>0 then
- local t={}
- while n>0 do
- insert(t,1,n%2>0 and 1 or 0)
- n=floor(n/2)
- end
- local nn=8-#t%8
- if nn>0 and nn<8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m=m*8-#t
- if m>0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
+ function number.tobitstring(n,m)
+ if n>0 then
+ local t={}
+ while n>0 do
+ insert(t,1,n%2>0 and 1 or 0)
+ n=floor(n/2)
+ end
+ local nn=8-#t%8
+ if nn>0 and nn<8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m=m*8-#t
+ if m>0 then
+ insert(t,1,rep("0",m))
end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
end
+ end
end
function number.valid(str,default)
- return tonumber(str) or default or nil
+ return tonumber(str) or default or nil
end
function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
- return s
- else
- return "0"..s
- end
+ local s=format("%X",n)
+ if #s%2==0 then
+ return s
+ else
+ return "0"..s
+ end
end
function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
- return 100
- elseif d<-100 then
- return -100
- else
- return d
- end
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+ return 100
+ elseif d<-100 then
+ return -100
+ else
+ return d
+ end
end
function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
- return 255
- elseif b<-255 then
- return -255
- else
- return b
- end
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+ return 255
+ elseif b<-255 then
+ return -255
+ else
+ return b
+ end
+end
+function number.idiv(i,d)
+ return floor(i/d)
end
@@ -3483,14 +3692,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-set"] = package.loaded["l-set"] or true
--- original size: 1923, stripped down to: 1133
+-- original size: 1923, stripped down to: 1044
if not modules then modules={} end modules ['l-set']={
- 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"
}
set=set or {}
local nums={}
@@ -3499,54 +3708,54 @@ local concat=table.concat
local next,type=next,type
set.create=table.tohash
function set.tonumber(t)
- if next(t) then
- local s=""
- for k,v in next,t do
- if v then
- s=s.." "..k
- end
- end
- local n=nums[s]
- if not n then
- n=#tabs+1
- tabs[n]=t
- nums[s]=n
- end
- return n
- else
- return 0
+ if next(t) then
+ local s=""
+ for k,v in next,t do
+ if v then
+ s=s.." "..k
+ end
end
+ local n=nums[s]
+ if not n then
+ n=#tabs+1
+ tabs[n]=t
+ nums[s]=n
+ end
+ return n
+ else
+ return 0
+ end
end
function set.totable(n)
- if n==0 then
- return {}
- else
- return tabs[n] or {}
- end
+ if n==0 then
+ return {}
+ else
+ return tabs[n] or {}
+ end
end
function set.tolist(n)
- if n==0 or not tabs[n] then
- return ""
- else
- local t,n={},0
- for k,v in next,tabs[n] do
- if v then
- n=n+1
- t[n]=k
- end
- end
- return concat(t," ")
+ if n==0 or not tabs[n] then
+ return ""
+ else
+ local t,n={},0
+ for k,v in next,tabs[n] do
+ if v then
+ n=n+1
+ t[n]=k
+ end
end
+ return concat(t," ")
+ end
end
function set.contains(n,s)
- if type(n)=="table" then
- return n[s]
- elseif n==0 then
- return false
- else
- local t=tabs[n]
- return t and t[s]
- end
+ if type(n)=="table" then
+ return n[s]
+ elseif n==0 then
+ return false
+ else
+ local t=tabs[n]
+ return t and t[s]
+ end
end
@@ -3556,14 +3765,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 16268, stripped down to: 9246
+-- original size: 19347, stripped down to: 10258
if not modules then modules={} end modules ['l-os']={
- 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 os=os
local date,time=os.date,os.time
@@ -3571,357 +3780,434 @@ local find,format,gsub,upper,gmatch=string.find,string.format,string.gsub,string
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
-math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
-randomseed(math.initialseed)
-if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
- local osgetenv=os.getenv
- local ossetenv=os.setenv
- local osenv=os.env local _=osenv.PATH
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- if type(v)=="table" then
- v=concat(v,";")
- end
- ossetenv(K,v)
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
+do
+ local selfdir=os.selfdir
+ if selfdir=="" then
+ selfdir=nil
+ end
+ if not selfdir then
+ if arg then
+ for i=1,#arg do
+ local a=arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir=gsub(a,"^.-=","")
+ break
end
- else
- local ossetenv=os.setenv
- local osgetenv=os.getenv
- local osenv={}
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
+ 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
+ local attributes=lfs.attributes
+ isfile=function(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+ end
+ else
+ local open=io.open
+ isfile=function(name)
+ local f=open(name)
+ if f then
+ f:close()
+ return true
end
+ end
end
- local function __index(t,k)
- return os.getenv(k)
- end
- local function __newindex(t,k,v)
- os.setenv(k,v)
+ for p in gmatch(path,patt) do
+ if isfile(p.."/"..name) then
+ selfdir=p
+ break
+ end
end
- os.env={}
- setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
+ os.selfdir=selfdir or "."
+ end
+end
+math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
+randomseed(math.initialseed)
+if not os.__getenv__ then
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+ local osgetenv=os.getenv
+ local ossetenv=os.setenv
+ local osenv=os.env local _=osenv.PATH
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ if type(v)=="table" then
+ v=concat(v,";")
+ end
+ ossetenv(K,v)
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ else
+ local ossetenv=os.setenv
+ local osgetenv=os.getenv
+ local osenv={}
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+ os.env={}
+ setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
local execute=os.execute
local iopopen=io.popen
local function resultof(command)
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- else
- return ""
- end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
end
os.resultof=resultof
function os.pipeto(command)
- return iopopen(command,"w")
+ return iopopen(command,"w")
end
if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
- io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+ io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
end
os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
end
local launchers={
- windows="start %s",
- macosx="open %s",
- unix="$BROWSER %s &> /dev/null &",
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
}
function os.launch(str)
- execute(format(launchers[os.name] or launchers.unix,str))
+ execute(format(launchers[os.name] or launchers.unix,str))
end
if not os.times then
- function os.times()
- return {
- utime=os.gettimeofday(),
- stime=0,
- cutime=0,
- cstime=0,
- }
- end
+ function os.times()
+ return {
+ utime=os.gettimeofday(),
+ stime=0,
+ cutime=0,
+ cstime=0,
+ }
+ end
end
local gettimeofday=os.gettimeofday or os.clock
os.gettimeofday=gettimeofday
local startuptime=gettimeofday()
function os.runtime()
- return gettimeofday()-startuptime
+ return gettimeofday()-startuptime
end
local resolvers=os.resolvers or {}
os.resolvers=resolvers
setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil
+ local r=resolvers[k]
+ return r and r(t,k) or nil
end })
local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
if platform~="" then
- os.platform=platform
+ os.platform=platform
elseif os.type=="windows" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("PROCESSOR_ARCHITECTURE") or ""
- if find(architecture,"AMD64",1,true) then
- platform="win64"
- else
- platform="mswin"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform=""
+ if find(architecture,"AMD64",1,true) then
+ platform="win64"
+ else
+ platform="mswin"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="linux" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- if find(architecture,"x86_64",1,true) then
- platform="linux-64"
- elseif find(architecture,"ppc",1,true) then
- platform="linux-ppc"
- else
- platform="linux"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ 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
+ 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=musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="macosx" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("echo $HOSTTYPE") or ""
- if architecture=="" then
- platform="osx-intel"
- elseif find(architecture,"i386",1,true) then
- platform="osx-intel"
- elseif find(architecture,"x86_64",1,true) then
- platform="osx-64"
- else
- platform="osx-ppc"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=resultof("echo $HOSTTYPE") or ""
+ local platform=""
+ if architecture=="" then
+ platform="osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform="osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform="osx-64"
+ else
+ platform="osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="sunos" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("uname -m") or ""
- if find(architecture,"sparc",1,true) then
- platform="solaris-sparc"
- else
- platform="solaris-intel"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"sparc",1,true) then
+ platform="solaris-sparc"
+ else
+ platform="solaris-intel"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="freebsd" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("uname -m") or ""
- if find(architecture,"amd64",1,true) then
- platform="freebsd-amd64"
- else
- platform="freebsd"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"amd64",1,true) then
+ platform="freebsd-amd64"
+ else
+ platform="freebsd"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- if find(architecture,"x86_64",1,true) then
- platform="kfreebsd-amd64"
- else
- platform="kfreebsd-i386"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"x86_64",1,true) then
+ platform="kfreebsd-amd64"
+ else
+ platform="kfreebsd-i386"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
else
- function resolvers.platform(t,k)
- local platform="linux"
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local platform="linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
end
os.newline=name=="windows" and "\013\010" or "\010"
function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
end
local t={ 8,9,"a","b" }
function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
- random(0xFFFF),random(0xFFFF),
- random(0x0FFF),
- t[ceil(random(4))] or 8,random(0x0FFF),
- random(0xFFFF),
- random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
end
local d
function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
- if delta then
- if d>0 then
- return format("+%02i:00",d)
- else
- return format("-%02i:00",-d)
- end
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d>0 then
+ return format("+%02i:00",d)
else
- return 1
+ return format("-%02i:00",-d)
end
+ else
+ return 1
+ end
end
local timeformat=format("%%s%s",os.timezone(true))
local dateformat="!%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
end
local dateformat="%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=date(dateformat,t)
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=date(dateformat,t)
+ end
+ return lastdate
end
function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
+ local t=tonumber(t)
+ if t and t>0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
end
local memory={}
local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
- local suffix=file.suffix(filename)
- local suffixes=suffix=="" and os.binsuffixes or { suffix }
- for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local df=file.join(directory,filename)
- for i=1,#suffixes do
- local dfs=file.addsuffix(df,suffixes[i])
- if io.exists(dfs) then
- fullname=dfs
- break
- end
- end
- end
- if not fullname then
- fullname=false
+ local fullname=memory[filename]
+ if fullname==nil then
+ local suffix=file.suffix(filename)
+ local suffixes=suffix=="" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local df=file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs=file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname=dfs
+ break
end
- memory[filename]=fullname
+ end
end
- return fullname
+ if not fullname then
+ fullname=false
+ end
+ memory[filename]=fullname
+ end
+ return fullname
end
os.which=which
os.where=which
function os.today()
- return date("!*t")
+ return date("!*t")
end
function os.now()
- return date("!%Y-%m-%d %H:%M:%S")
+ return date("!%Y-%m-%d %H:%M:%S")
end
if not os.sleep then
- local socket=socket
- function os.sleep(n)
- if not socket then
- socket=require("socket")
- end
- socket.sleep(n)
+ local socket=socket
+ function os.sleep(n)
+ if not socket then
+ socket=require("socket")
end
+ socket.sleep(n)
+ end
end
local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
+ return (year%4==0) and (year%100~=0 or year%400==0)
end
os.isleapyear=isleapyear
local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
local function nofdays(year,month)
- if not month then
- return isleapyear(year) and 365 or 364
- else
- return month==2 and isleapyear(year) and 29 or days[month]
- end
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month==2 and isleapyear(year) and 29 or days[month]
+ end
end
os.nofdays=nofdays
function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
+ return date("%w",time { year=year,month=month,day=day })+1
end
function os.validdate(year,month,day)
- if month<1 then
- month=1
- elseif month>12 then
- month=12
- end
- if day<1 then
- day=1
- else
- local max=nofdays(year,month)
- if day>max then
- day=max
- end
- end
- return year,month,day
+ if month<1 then
+ month=1
+ elseif month>12 then
+ month=12
+ end
+ if day<1 then
+ day=1
+ else
+ local max=nofdays(year,month)
+ if day>max then
+ day=max
+ end
+ 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
@@ -3931,19 +4217,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-file"] = package.loaded["l-file"] or true
--- original size: 21616, stripped down to: 10359
+-- original size: 21804, stripped down to: 9980
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
@@ -3951,24 +4237,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(".")
@@ -3982,27 +4266,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
@@ -4011,7 +4295,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)
@@ -4027,142 +4311,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)
- else
- return "",str
- end
+ 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 {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ 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
+ 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)
@@ -4172,30 +4456,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)
- 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
- else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
- end
+ 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
+ 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
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
@@ -4205,56 +4489,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
+ n=n-1
end
- 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)
@@ -4262,26 +4546,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("://")
@@ -4290,40 +4574,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
+ 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
- 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
+ if l<0 then
+ return false
end
- return true
+ end
+ return true
+end
+local symlinkattributes=lfs.symlinkattributes
+function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
end
@@ -4333,51 +4621,51 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
--- original size: 1211, stripped down to: 1002
+-- original size: 1211, stripped down to: 951
if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not gzip then
- return
+ return
end
local suffix,suffixes=file.suffix,file.suffixes
function gzip.load(filename)
- local f=io.open(filename,"rb")
- if not f then
- elseif suffix(filename)=="gz" then
- f:close()
- local g=gzip.open(filename,"rb")
- if g then
- local str=g:read("*all")
- g:close()
- return str
- end
- else
- local str=f:read("*all")
- f:close()
- return str
- end
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+ f:close()
+ local g=gzip.open(filename,"rb")
+ if g then
+ local str=g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str=f:read("*all")
+ f:close()
+ return str
+ end
end
function gzip.save(filename,data)
- if suffix(filename)~="gz" then
- filename=filename..".gz"
- end
- local f=io.open(filename,"wb")
- if f then
- local s=zlib.compress(data or "",9,nil,15+16)
- f:write(s)
- f:close()
- return #s
- end
+ if suffix(filename)~="gz" then
+ filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+ local s=zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
end
function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
end
@@ -4387,87 +4675,119 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-md5"] = package.loaded["l-md5"] or true
--- original size: 3309, stripped down to: 2314
+-- original size: 3309, stripped down to: 2218
if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not md5 then
- md5=optionalrequire("md5")
+ md5=optionalrequire("md5")
end
if not md5 then
- md5={
- sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
- sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
+ md5={
+ sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
end
local md5,file=md5,file
local gsub=string.gsub
do
- local patterns=lpeg and lpeg.patterns
- if patterns then
- local bytestoHEX=patterns.bytestoHEX
- local bytestohex=patterns.bytestohex
- local bytestodec=patterns.bytestodec
- local lpegmatch=lpeg.match
- local md5sum=md5.sum
- if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
- if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
- if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
- md5.sumhexa=md5.hex
- md5.sumHEXA=md5.HEX
- end
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+ local bytestoHEX=patterns.bytestoHEX
+ local bytestohex=patterns.bytestohex
+ local bytestodec=patterns.bytestodec
+ local lpegmatch=lpeg.match
+ local md5sum=md5.sum
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+ md5.sumhexa=md5.hex
+ md5.sumHEXA=md5.HEX
+ end
end
function file.needsupdating(oldname,newname,threshold)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime=lfs.attributes(newname,"modification")
- if not newtime then
- return true
- elseif newtime>=oldtime then
- return false
- elseif oldtime-newtime<(threshold or 1) then
- return false
- else
- return true
- end
- else
- return false
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime=lfs.attributes(newname,"modification")
+ if not newtime then
+ return true
+ elseif newtime>=oldtime then
+ return false
+ elseif oldtime-newtime<(threshold or 1) then
+ return false
+ else
+ return true
+ end
+ else
+ return false
+ end
end
file.needs_updating=file.needsupdating
function file.syncmtimes(oldname,newname)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
end
function file.checksum(name)
- if md5 then
- local data=io.loaddata(name)
- if data then
- return md5.HEX(data)
- end
+ if md5 then
+ local data=io.loaddata(name)
+ if data then
+ return md5.HEX(data)
end
- return nil
+ end
+ return nil
end
function file.loadchecksum(name)
- if md5 then
- local data=io.loaddata(name..".md5")
- return data and (gsub(data,"%s",""))
- end
- return nil
+ if md5 then
+ local data=io.loaddata(name..".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
end
function file.savechecksum(name,checksum)
- if not checksum then checksum=file.checksum(name) end
- if checksum then
- io.savedata(name..".md5",checksum)
- return checksum
- end
- return nil
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+ io.savedata(name..".md5",checksum)
+ return checksum
+ end
+ return nil
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["l-sha"] = package.loaded["l-sha"] or true
+
+-- original size: 1085, stripped down to: 969
+
+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
@@ -4477,14 +4797,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 14755, stripped down to: 7236
+-- original size: 14755, stripped down to: 6981
if not modules then modules={} end modules ['l-url']={
- 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 char,format,byte=string.char,string.format,string.byte
local concat=table.concat
@@ -4497,14 +4817,14 @@ local url=url
local unescapes={}
local escapes={}
setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
end })
setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
end })
local colon=P(":")
local qmark=P("?")
@@ -4523,21 +4843,21 @@ local escaped=(plus/" ")+escapedchar
local noslash=P("/")/""
local plustospace=P("+")/" "
local decoder=Cs((
- plustospace+escapedchar+P("\r\n")/"\n"+P(1)
- )^0 )
+ plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+ )^0 )
local encoder=Cs((
- R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
- )^0 )
+ R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+ )^0 )
lpegpatterns.urldecoder=decoder
lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1- qmark-hash))^0)
-local querystr=Cs(((1- hash))^0)
-local fragmentstr=Cs((escaped+(1- endofstring))^0)
+local pathstr=Cs((escaped+(1- qmark-hash))^0)
+local querystr=Cs(((1- hash))^0)
+local fragmentstr=Cs((escaped+(1- endofstring))^0)
local scheme=schemestr*colon+nothing
local authority=slash*slash*authoritystr+nothing
local path=slash*pathstr+nothing
@@ -4555,19 +4875,19 @@ lpegpatterns.urlescaper=escaper
lpegpatterns.urlunescaper=unescaper
lpegpatterns.urlgetcleaner=getcleaner
function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
+ return lpegmatch(getcleaner,str)
end
local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
end
local isscheme=schemestr*colon*slash*slash
local function hasscheme(str)
- if str then
- local scheme=lpegmatch(isscheme,str)
- return scheme~="" and scheme or false
- else
- return false
- end
+ if str then
+ local scheme=lpegmatch(isscheme,str)
+ return scheme~="" and scheme or false
+ else
+ return false
+ end
end
local rootletter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4577,161 +4897,161 @@ local barswapper=replacer("|",":")
local backslashswapper=replacer("\\","/")
local equal=P("=")
local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal )^0)
local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
},rawset)
local userpart=(1-atsign-colon)^1
local serverpart=(1-colon)^1
local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
local function hashed(str)
- if not str or str=="" then
- return {
- scheme="invalid",
- original=str,
- }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
- rawscheme=detailed[1]
- rawquery=detailed[4]
- somescheme=rawscheme~=""
- somequery=rawquery~=""
- end
- if not somescheme and not somequery then
- return {
- scheme="file",
- authority="",
- path=str,
- query="",
- fragment="",
- original=str,
- noscheme=true,
- filename=str,
- }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename
- local username
- local password
- local host
- local port
- if authority~="" then
- username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
- filename=path
- elseif path=="" then
- filename=""
- else
- filename=authority.."/"..path
- end
+ if not str or str=="" then
return {
- scheme=rawscheme,
- authority=authority,
- path=path,
- query=lpegmatch(unescaper,rawquery),
- queries=lpegmatch(splitquery,rawquery),
- fragment=detailed[5],
- original=str,
- noscheme=false,
- filename=filename,
- host=host,
- port=port,
+ scheme="invalid",
+ original=str,
}
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+ rawscheme=detailed[1]
+ rawquery=detailed[4]
+ somescheme=rawscheme~=""
+ somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme="file",
+ authority="",
+ path=str,
+ query="",
+ fragment="",
+ original=str,
+ noscheme=true,
+ filename=str,
+ }
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename
+ local username
+ local password
+ local host
+ local port
+ if authority~="" then
+ username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+ filename=path
+ elseif path=="" then
+ filename=""
+ else
+ filename=authority.."/"..path
+ end
+ return {
+ scheme=rawscheme,
+ authority=authority,
+ path=path,
+ query=lpegmatch(unescaper,rawquery),
+ queries=lpegmatch(splitquery,rawquery),
+ fragment=detailed[5],
+ original=str,
+ noscheme=false,
+ filename=filename,
+ host=host,
+ port=port,
+ }
end
url.split=split
url.hasscheme=hasscheme
url.hashed=hashed
function url.addscheme(str,scheme)
- if hasscheme(str) then
- return str
- elseif not scheme then
- return "file:///"..str
- else
- return scheme..":///"..str
- end
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///"..str
+ else
+ return scheme..":///"..str
+ end
end
function url.construct(hash)
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
- r=r+1;result[r]=lpegmatch(escaper,scheme)
- r=r+1;result[r]="://"
- end
- if authority and authority~="" then
- r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
- r=r+1;result[r]="/"
- r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
- local done=false
- for k,v in sortedhash(queries) do
- r=r+1;result[r]=done and "&" or "?"
- r=r+1;result[r]=lpegmatch(escaper,k)
- r=r+1;result[r]="="
- r=r+1;result[r]=lpegmatch(escaper,v)
- done=true
- end
- end
- if fragment and fragment~="" then
- r=r+1;result[r]="#"
- r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+ r=r+1;result[r]=lpegmatch(escaper,scheme)
+ r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+ r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+ r=r+1;result[r]="/"
+ r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+ local done=false
+ for k,v in sortedhash(queries) do
+ r=r+1;result[r]=done and "&" or "?"
+ r=r+1;result[r]=lpegmatch(escaper,k)
+ r=r+1;result[r]="="
+ r=r+1;result[r]=lpegmatch(escaper,v)
+ done=true
+ end
+ end
+ if fragment and fragment~="" then
+ r=r+1;result[r]="#"
+ r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
end
local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
end
local function escapestring(str)
- return lpegmatch(escaper,str)
+ return lpegmatch(escaper,str)
end
url.escape=escapestring
function url.query(str)
- if type(str)=="string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
+ if type(str)=="string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
end
function url.toquery(data)
- local td=type(data)
- if td=="string" then
- return #str and escape(data) or nil
- elseif td=="table" then
- if next(data) then
- local t={}
- for k,v in next,data do
- t[#t+1]=format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
- end
- else
+ local td=type(data)
+ if td=="string" then
+ return #str and escape(data) or nil
+ elseif td=="table" then
+ if next(data) then
+ local t={}
+ for k,v in next,data do
+ t[#t+1]=format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
end
+ else
+ end
end
local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
function url.barepath(path)
- if not path or path=="" then
- return ""
- else
- return lpegmatch(pattern,path)
- end
+ if not path or path=="" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
end
@@ -4741,14 +5061,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 17703, stripped down to: 11691
+-- original size: 18002, stripped down to: 10681
if not modules then modules={} end modules ['l-dir']={
- 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,select=type,select
local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -4760,471 +5080,478 @@ local dir=dir
local lfs=lfs
local attributes=lfs.attributes
local walkdir=lfs.dir
-local isdir=lfs.isdir
+local isdir=lfs.isdir
local isfile=lfs.isfile
local currentdir=lfs.currentdir
local chdir=lfs.chdir
local mkdir=lfs.mkdir
local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
- if lpegmatch(tricky,name) then
- return attributes(name,"mode")=="directory"
- else
- return attributes(name.."/.","mode")=="directory"
- end
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode")=="directory"
+ else
+ return attributes(name.."/.","mode")=="directory"
end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
else
- isdir=function(name)
- return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ isdir=function(name)
+ return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
end
function dir.current()
- return (gsub(currentdir(),"\\","/"))
+ return (gsub(currentdir(),"\\","/"))
end
local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- action(full)
- end
- elseif recurse and mode=="directory" then
- if not dirs then
- dirs={ full }
- else
- dirs[#dirs+1]=full
- end
- end
- end
- end
- if dirs then
- for i=1,#dirs do
- glob_pattern_function(dirs[i],patt,recurse,action)
- end
+ if isdir(path) then
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ for name in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ action(full)
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
end
+ end
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
end
+ end
end
local function glob_pattern_table(path,patt,recurse,result)
- if not result then
- result={}
- end
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- result[#result+1]=full
- end
- elseif recurse and mode=="directory" then
- if not dirs then
- dirs={ full }
- else
- dirs[#dirs+1]=full
- end
- end
- end
- end
+ if not result then
+ result={}
+ end
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,a in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ noffiles=noffiles+1
+ result[noffiles]=full
+ end
+ elseif recurse and mode=="directory" then
if dirs then
- for i=1,#dirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
end
+ end
end
- return result
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
+ end
+ end
+ return result
end
local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
- patt=false
- end
- if kind=="function" then
- return glob_pattern_function(path,patt,recurse,method)
- elseif kind=="table" then
- return glob_pattern_table(path,patt,recurse,method)
- else
- return glob_pattern_table(path,patt,recurse,{})
- end
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+ patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
end
dir.globpattern=globpattern
local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
- ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
- else
- ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
- end
- if ok and type(scanner)=="function" then
- if not find(path,"/$") then
- path=path..'/'
- end
- for name in scanner,first do
- if name=="." then
- elseif name==".." then
- else
- local full=path..name
- local attr=attributes(full)
- local mode=attr.mode
- if mode=='file' then
- if find(full,patt) then
- result[name]=attr
- end
- elseif recurse and mode=="directory" then
- attr.list=collectpattern(full,patt,recurse)
- result[name]=attr
- end
- end
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+ ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
+ else
+ ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
+ end
+ if ok and type(scanner)=="function" then
+ if not find(path,"/$") then
+ path=path..'/'
+ end
+ for name in scanner,first do
+ if name=="." then
+ elseif name==".." then
+ else
+ local full=path..name
+ local attr=attributes(full)
+ local mode=attr.mode
+ if mode=='file' then
+ if find(full,patt) then
+ result[name]=attr
+ end
+ elseif recurse and mode=="directory" then
+ attr.list=collectpattern(full,patt,recurse)
+ result[name]=attr
end
+ end
end
- return result
+ end
+ return result
end
dir.collectpattern=collectpattern
local separator,pattern
if onwindows then
- local slash=S("/\\")/"/"
- pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
- }
+ local slash=S("/\\")/"/"
+ pattern={
+ [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+ [3]=Cs(P(1)^0)
+ }
else
- pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
- }
+ pattern={
+ [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ [2]=C(((1-S("*?/"))^0*P("/"))^0),
+ [3]=C(P(1)^0)
+ }
end
local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
)^0 )
local function glob(str,t)
- if type(t)=="function" then
- if type(str)=="table" then
- for s=1,#str do
- glob(str[s],t)
- end
- elseif isfile(str) then
- t(str)
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- globpattern(start,result,recurse,t)
- end
- end
+ if type(t)=="function" then
+ if type(str)=="table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str)=="table" then
+ local t=t or {}
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1]=str
+ return t
+ else
+ return { str }
+ end
else
- if type(str)=="table" then
- local t=t or {}
- for s=1,#str do
- glob(str[s],t)
- end
- return t
- elseif isfile(str) then
- if t then
- t[#t+1]=str
- return t
- else
- return { str }
- end
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- return globpattern(start,result,recurse,t)
- else
- return {}
- end
- end
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ return globpattern(start,result,recurse,t)
+ else
+ return {}
+ end
end
+ end
end
dir.glob=glob
local function globfiles(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if recurse then
- globfiles(path.."/"..name,recurse,func,files)
- end
- elseif mode=="file" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if recurse then
+ globfiles(path.."/"..name,recurse,func,files)
+ end
+ elseif mode=="file" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
end
+ end
end
- return files
+ end
+ return files
end
dir.globfiles=globfiles
local function globdirs(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- if recurse then
- globdirs(path.."/"..name,recurse,func,files)
- end
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ if recurse then
+ globdirs(path.."/"..name,recurse,func,files)
+ end
end
+ end
end
- return files
+ end
+ return files
end
dir.globdirs=globdirs
function dir.ls(pattern)
- return concat(glob(pattern),"\n")
+ return concat(glob(pattern),"\n")
end
local make_indeed=true
if onwindows then
- function dir.mkdirs(...)
- local n=select("#",...)
- local str
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s=="" then
+ elseif str=="" then
+ str=s
else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s=="" then
- elseif str=="" then
- str=s
- else
- str=str.."/"..s
- end
- end
+ str=str.."/"..s
end
- local pth=""
- local drive=false
- local first,middle,last=match(str,"^(//)(//*)(.*)$")
- if first then
+ end
+ end
+ local pth=""
+ local drive=false
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ else
+ first,last=match(str,"^(//)/*(.-)$")
+ if first then
+ middle,last=match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth="//"..middle
else
- first,last=match(str,"^(//)/*(.-)$")
- if first then
- middle,last=match(str,"([^/]+)/+(.-)$")
- if middle then
- pth="//"..middle
- else
- pth="//"..last
- last=""
- end
- else
- first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth,drive=first..middle,true
- else
- middle,last=match(str,"^(/*)(.-)$")
- if not middle then
- last=str
- end
- end
- end
+ pth="//"..last
+ last=""
end
- for s in gmatch(last,"[^/]+") do
- if pth=="" then
- pth=s
- elseif drive then
- pth,drive=pth..s,false
- else
- pth=pth.."/"..s
- end
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
+ else
+ first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth,drive=first..middle,true
+ else
+ middle,last=match(str,"^(/*)(.-)$")
+ if not middle then
+ last=str
+ end
end
- return pth,(isdir(pth)==true)
+ end
end
+ for s in gmatch(last,"[^/]+") do
+ if pth=="" then
+ pth=s
+ elseif drive then
+ pth,drive=pth..s,false
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
else
- function dir.mkdirs(...)
- local n=select("#",...)
- local str,pth
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s and s~="" then
- if str~="" then
- str=str.."/"..s
- else
- str=s
- end
- end
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str,pth
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s and s~="" then
+ if str~="" then
+ str=str.."/"..s
+ else
+ str=s
+ end
end
- str=gsub(str,"/+","/")
- if find(str,"^/") then
- pth="/"
- for s in gmatch(str,"[^/]+") do
- local first=(pth=="/")
- if first then
- pth=pth..s
- else
- pth=pth.."/"..s
- end
- if make_indeed and not first and not isdir(pth) then
- mkdir(pth)
- end
- end
+ end
+ end
+ str=gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth="/"
+ for s in gmatch(str,"[^/]+") do
+ local first=(pth=="/")
+ if first then
+ pth=pth..s
else
- pth="."
- for s in gmatch(str,"[^/]+") do
- pth=pth.."/"..s
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
+ pth=pth.."/"..s
end
- return pth,(isdir(pth)==true)
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth="."
+ for s in gmatch(str,"[^/]+") do
+ pth=pth.."/"..s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
end
+ return pth,(isdir(pth)==true)
+ end
end
dir.makedirs=dir.mkdirs
do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
- local xcurrentdir=dir.current
- function dir.expandname(str)
- local first,nothing,last=match(str,"^(//)(//*)(.*)$")
- if first then
- first=xcurrentdir().."/"
- end
- if not first then
- first,last=match(str,"^(//)/*(.*)$")
- end
- if not first then
- first,last=match(str,"^([a-zA-Z]:)(.*)$")
- if first and not find(last,"^/") then
- local d=currentdir()
- if chdir(first) then
- first=xcurrentdir()
- end
- chdir(d)
- end
- end
- if not first then
- first,last=xcurrentdir(),str
- end
- last=gsub(last,"//","/")
- last=gsub(last,"/%./","/")
- last=gsub(last,"^/*","")
- first=gsub(first,"/*$","")
- if last=="" or last=="." then
- return first
- else
- return first.."/"..last
- end
- end
- else
- function dir.expandname(str)
- if not find(str,"^/") then
- str=currentdir().."/"..str
- end
- str=gsub(str,"//","/")
- str=gsub(str,"/%./","/")
- str=gsub(str,"(.)/%.$","%1")
- return str
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+ local xcurrentdir=dir.current
+ function dir.expandname(str)
+ local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ first=xcurrentdir().."/"
+ end
+ if not first then
+ first,last=match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first,last=match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d=currentdir()
+ if chdir(first) then
+ first=xcurrentdir()
+ end
+ chdir(d)
end
+ end
+ if not first then
+ first,last=xcurrentdir(),str
+ end
+ last=gsub(last,"//","/")
+ last=gsub(last,"/%./","/")
+ last=gsub(last,"^/*","")
+ first=gsub(first,"/*$","")
+ if last=="" or last=="." then
+ return first
+ else
+ return first.."/"..last
+ end
end
+ else
+ function dir.expandname(str)
+ if not find(str,"^/") then
+ str=currentdir().."/"..str
+ end
+ str=gsub(str,"//","/")
+ str=gsub(str,"/%./","/")
+ str=gsub(str,"(.)/%.$","%1")
+ return str
+ end
+ end
end
file.expandname=dir.expandname
local stack={}
function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" then
- chdir(newdir)
- return newdir
- else
- return curdir
- end
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" then
+ chdir(newdir)
+ return newdir
+ else
+ return curdir
+ end
end
function dir.pop()
- local d=remove(stack)
- if d then
- chdir(d)
- end
- return d
+ local d=remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
end
local function found(...)
- for i=1,select("#",...) do
- local path=select(i,...)
- local kind=type(path)
- if kind=="string" then
- if isdir(path) then
- return path
- end
- elseif kind=="table" then
- local path=found(unpack(path))
- if path then
- return path
- end
- end
+ for i=1,select("#",...) do
+ local path=select(i,...)
+ local kind=type(path)
+ if kind=="string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind=="table" then
+ local path=found(unpack(path))
+ if path then
+ return path
+ end
end
+ end
end
dir.found=found
@@ -5235,69 +5562,69 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
--- original size: 1850, stripped down to: 1568
+-- original size: 1850, stripped down to: 1498
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
@@ -5307,18 +5634,24 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 40036, stripped down to: 17837
+-- original size: 41047, stripped down to: 17171
if not modules then modules={} end modules ['l-unicode']={
- 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"
}
-utf=utf or (unicode and unicode.utf8) or {}
-utf.characters=utf.characters or string.utfcharacters
-utf.values=utf.values or string.utfvalues
+utf=utf or {}
+unicode=nil
+if not string.utfcharacters then
+ local gmatch=string.gmatch
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
+end
+utf.characters=string.utfcharacters
local type=type
local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch
local concat=table.concat
@@ -5329,345 +5662,340 @@ local tabletopattern=lpeg.utfchartabletopattern
local bytepairs=string.bytepairs
local finder=lpeg.finder
local replacer=lpeg.replacer
-local utfvalues=utf.values
-local utfgmatch=utf.gmatch
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 }
-end
if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+ local char=string.char
+ if bit32 then
+ local rshift=bit32.rshift
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+rshift(n,6),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+rshift(n,12),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+rshift(n,18),
+ 0x80+(rshift(n,12)%0x40),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
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
+ 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
end
+ end
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
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
end
+ end
end
local utfchar,utfbyte=utf.char,utf.byte
function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
+ return data and lpegmatch(p_utftype,data) or "unknown"
end
local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
)
patterns.toentities=toentities
function utf.toentities(str)
- return lpegmatch(toentities,str)
+ 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 )
+ 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
+ return lpegmatch(pattern,s) or s
end
local validatedutf=Cs (
- (
- patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
- )^0
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
)
patterns.validatedutf=validatedutf
function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
+ 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
+ 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
+ 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
- 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
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
end
- local function slide_two(s,p)
- n=n+1
- if n==first then
- b=p
- else
- return true
- end
+ if n>=last then
+ e=p-1
+ else
+ return p
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
+ 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_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(p_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
- 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)
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
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)
+ 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
+ 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)
+ 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
- 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
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
end
- elseif variant=="function" then
- if option=="pattern" then
- return Cs((p_utf8char/mapping+p_utf8char)^0)
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
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
+ return lpegmatch(pattern,str)
end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8character/mapping+p_utf8character)^0)
else
- return function(str)
- return str or ""
+ local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
end
+ end,pattern
end
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
+ else
return function(str)
- return lpegmatch(r,str)
+ return str or ""
end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
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
+ 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
end
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
function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
+ return lpegmatch(utflinesplitter,str or "")
end
function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
end
function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
+ return lpegmatch(utfcharsplitter_raw,str)
end
function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
end
local utf16_to_utf8_be,utf16_to_utf8_le
local utf32_to_utf8_be,utf32_to_utf8_le
@@ -5681,36 +6009,36 @@ local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_n
local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
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
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ 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
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 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
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))
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
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))
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
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)
@@ -5721,88 +6049,88 @@ 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
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ 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
+ 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
- return t
+ end
+ return t
end
utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -5813,189 +6141,225 @@ 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
+ 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
+ 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
+ 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
+ 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
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
+ 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
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
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
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
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
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
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
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
+ (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 " ")
+ return lpegmatch(pattern,str,1,separator or " ")
end
function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
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
-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
+ 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
end
-if not utf.characters then
- function utf.characters(str)
- return gmatch(str,".[\128-\191]*")
+do
+ local p_nany=p_utf8character/""
+ 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
- string.utfcharacters=utf.characters
+ end
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
+if not string.utfvalues then
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(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
- string.utfvalues=utf.values
+ end
end
+utf.values=string.utfvalues
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
+ 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
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 extract=bit32.extract
+ local char=string.char
+ function utf.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
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
+ 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
- return s
+ end
+ return s
+end
+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)
+ 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
+ end
+ if 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 p_utf8byte/f
+ end
+ end
end
@@ -6005,93 +6369,93 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-math"] = package.loaded["l-math"] or true
--- original size: 2555, stripped down to: 1900
+-- original size: 2555, stripped down to: 1831
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)<floor(n)
- end
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
@@ -6101,14 +6465,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 38734, stripped down to: 22142
+-- original size: 43539, stripped down to: 21641
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"
+ 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 {}
@@ -6121,624 +6485,657 @@ 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 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
if not number then number={} end
-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 ptf=1/65536
+local bpf=(7200/7227)/65536
local function points(n)
- n=tonumber(n)
- return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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)
+ return lpegmatch(pattern,str)
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
+ 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
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((
+ 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
+ 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)
+ extra,start=0,position
+ end+anything
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
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 space=spacer^0
-local nospace=space/""
+ 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-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 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,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["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
+ return str and lpegmatch(striplinepatterns[how],str) or str
+end
+function strings.collapse(str)
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return 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)..'"')
+ 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).."'")
+ 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]",
+ "[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
+ 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
+ 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))*(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==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
if sep1==true then
- return lpegmatch(splitter,s,1,".",",")
+ return lpegmatch(splitter,n,1,".",",")
elseif sep1=="." then
- return lpegmatch(splitter,s,1,sep1,sep2 or ",")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
elseif sep1=="," then
- return lpegmatch(splitter,s,1,sep1,sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ 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
- )
+ 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
+ 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 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
- 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))
+ 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
- return tostring(n)
+ 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
+ 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
+ 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 #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
%s
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,
+}
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ 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)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
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
+ 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 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
+ 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 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ 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)
+ 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
+ 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
+ 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
+ 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
+ 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)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ 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
+ 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
+ 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)
+ 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)
+ 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()
+ 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(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))
+ 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")
@@ -6750,160 +7147,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("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
-patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
+patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+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
@@ -6913,14 +7306,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 27741, stripped down to: 17085
+-- original size: 28772, stripped down to: 16111
if not modules then modules={} end modules ['util-tab']={
- 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"
}
utilities=utilities or {}
utilities.tables=utilities.tables or {}
@@ -6935,219 +7328,220 @@ local formatters=string.formatters
local utftoeight=utf.toeight
local splitter=lpeg.tsplitat(".")
function utilities.tables.definetable(target,nofirst,nolast)
- local composed,t=nil,{}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
- local name=snippets[i]
- if composed then
- composed=composed.."."..name
- t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
- else
- composed=name
- if not nofirst then
- t[#t+1]=formatters["%s = %s or { }"](composed,composed)
- end
- end
- end
+ local composed=nil
+ local t={}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+ local name=snippets[i]
if composed then
- if nolast then
- composed=composed.."."..snippets[#snippets]
- end
- return concat(t,"\n"),composed
+ composed=composed.."."..name
+ t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
else
- return "",target
+ composed=name
+ if not nofirst then
+ t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+ end
+ end
+ end
+ if composed then
+ if nolast then
+ composed=composed.."."..snippets[#snippets]
end
+ return concat(t,"\n"),composed
+ else
+ return "",target
+ end
end
function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
- local li=select(i,...)
- local tl=t[li]
- if not tl then
- tl={}
- t[li]=tl
- end
- t=tl
- end
- return t
+ local t=_G
+ for i=1,select("#",...) do
+ local li=select(i,...)
+ local tl=t[li]
+ if not tl then
+ tl={}
+ t[li]=tl
+ end
+ t=tl
+ end
+ return t
end
function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t=t[name]
+ if not t then
+ return
end
- return t
+ end
+ return t
end
function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
- local name=names[i]
- t[name]=t[name] or {}
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name=names[i]
+ t[name]=t[name] or {}
+ t=t[name]
+ if not t then
+ return
end
- t[names[#names]]=v
+ end
+ t[names[#names]]=v
end
function tables.removevalue(t,value)
- if value then
- for i=1,#t do
- if t[i]==value then
- remove(t,i)
- end
- end
+ if value then
+ for i=1,#t do
+ if t[i]==value then
+ remove(t,i)
+ end
end
+ end
end
function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
- for i=1,#t do
- if t[i]==oldvalue then
- t[i]=newvalue
- end
- end
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i]==oldvalue then
+ t[i]=newvalue
+ end
end
+ end
end
function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i,extra)
+ return
end
- insert(t,1,extra)
+ end
+ insert(t,1,extra)
end
function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i+1,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i+1,extra)
+ return
end
- insert(t,#t+1,extra)
+ end
+ insert(t,#t+1,extra)
end
local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
function table.tocsv(t,specification)
- if t and #t>0 then
- local result={}
- local r={}
- specification=specification or {}
- local fields=specification.fields
- if type(fields)~="string" then
- fields=sortedkeys(t[1])
- end
- local separator=specification.separator or ","
- local noffields=#fields
- if specification.preamble==true then
- for f=1,noffields do
- r[f]=lpegmatch(escape,tostring(fields[f]))
- end
- result[1]=concat(r,separator)
- end
- for i=1,#t do
- local ti=t[i]
- for f=1,noffields do
- local field=ti[fields[f]]
- if type(field)=="string" then
- r[f]=lpegmatch(escape,field)
- else
- r[f]=tostring(field)
- end
- end
- result[i+1]=concat(r,separator)
+ if t and #t>0 then
+ local result={}
+ local r={}
+ specification=specification or {}
+ local fields=specification.fields
+ if type(fields)~="string" then
+ fields=sortedkeys(t[1])
+ end
+ local separator=specification.separator or ","
+ local noffields=#fields
+ if specification.preamble==true then
+ for f=1,noffields do
+ r[f]=lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1]=concat(r,separator)
+ end
+ for i=1,#t do
+ local ti=t[i]
+ for f=1,noffields do
+ local field=ti[fields[f]]
+ if type(field)=="string" then
+ r[f]=lpegmatch(escape,field)
+ else
+ r[f]=tostring(field)
end
- return concat(result,"\n")
- else
- return ""
+ end
+ result[i+1]=concat(r,separator)
end
+ return concat(result,"\n")
+ else
+ return ""
+ end
end
local nspaces=utilities.strings.newrepeater(" ")
local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
- local s=nspaces[d]
- local tk=type(k)
- local tv=type(v)
- if tv=="table" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</entry>"](s,k)
- else
- r=r+1 result[r]=formatters["%s<%s>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</%s>"](s,k)
- end
- elseif tv=="string" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
- end
- elseif tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
- end
+ local r=#result
+ for k,v in sortedpairs(t) do
+ local s=nspaces[d]
+ local tk=type(k)
+ local tv=type(v)
+ if tv=="table" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</entry>"](s,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</%s>"](s,k)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
end
+ end
end
function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
- toxml(t,indent,result,spaces)
- else
- toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+ toxml(t,indent,result,spaces)
+ else
+ toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
end
function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
- protect=true
- capsule={}
- end
+ if type(capsule)~="table" then
+ protect=true
+ capsule={}
+ end
+ for key,value in next,core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key]=value
+ end
+ end
+ if protect then
for key,value in next,core do
+ core[key]=nil
+ end
+ setmetatable(core,{
+ __index=capsule,
+ __newindex=function(t,key,value)
if capsule[key] then
- print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
- os.exit()
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
else
- capsule[key]=value
+ rawset(t,key,value)
end
- end
- if protect then
- for key,value in next,core do
- core[key]=nil
- end
- setmetatable(core,{
- __index=capsule,
- __newindex=function(t,key,value)
- if capsule[key] then
- print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
- os.exit()
- else
- rawset(t,key,value)
- end
- end
- } )
- end
+ end
+ } )
+ end
end
local f_hashed_string=formatters["[%q]=%q,"]
local f_hashed_number=formatters["[%q]=%s,"]
@@ -7161,157 +7555,157 @@ local f_ordered_string=formatters["%q,"]
local f_ordered_number=formatters["%s,"]
local f_ordered_boolean=formatters["%l,"]
function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- for i=0,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
- end
- end
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ for i=0,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
- end
- end
- else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
- end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ else
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_hashed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_hashed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_hashed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
- return r
+ end
end
- return concat(fastserialize(t,true))
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
- if not str or str=="" then
- return
- end
- local code=load(str)
- if not code then
- return
- end
- code=code()
- if not code then
- return
- end
- return code
+ if not str or str=="" then
+ return
+ end
+ local code=load(str)
+ if not code then
+ return
+ end
+ code=code()
+ if not code then
+ return
+ end
+ return code
end
function table.load(filename,loader)
- if filename then
- local t=(loader or io.loaddata)(filename)
- if t and t~="" then
- local t=utftoeight(t)
- t=load(t)
- if type(t)=="function" then
- t=t()
- if type(t)=="table" then
- return t
- end
- end
+ if filename then
+ local t=(loader or io.loaddata)(filename)
+ if t and t~="" then
+ local t=utftoeight(t)
+ t=load(t)
+ if type(t)=="function" then
+ t=t()
+ if type(t)=="table" then
+ return t
end
+ end
end
+ end
end
function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...))
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...))
end
local f_key_value=formatters["%s=%q"]
local f_add_table=formatters[" {%t},\n"]
local f_return_table=formatters["return {\n%t}"]
local function slowdrop(t)
- local r={}
- local l={}
- for i=1,#t do
- local ti=t[i]
- local j=0
- for k,v in next,ti do
- j=j+1
- l[j]=f_key_value(k,v)
- end
- r[i]=f_add_table(l)
- end
- return f_return_table(r)
+ local r={}
+ local l={}
+ for i=1,#t do
+ local ti=t[i]
+ local j=0
+ for k,v in next,ti do
+ j=j+1
+ l[j]=f_key_value(k,v)
+ end
+ r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
end
local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
- local ti=t[i]
- m=m+1 r[m]=" {"
- for k,v in next,ti do
- m=m+1 r[m]=f_key_value(k,v)
- end
- m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+ local ti=t[i]
+ m=m+1 r[m]=" {"
+ for k,v in next,ti do
+ m=m+1 r[m]=f_key_value(k,v)
+ end
+ m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
end
function table.drop(t,slow)
- if #t==0 then
- return "return { }"
- elseif slow==true then
- return slowdrop(t)
- else
- return fastdrop(t)
- end
+ if #t==0 then
+ return "return { }"
+ elseif slow==true then
+ return slowdrop(t)
+ else
+ return fastdrop(t)
+ end
end
local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)
- if not t then
- t={}
- else
- local zero=rawget(t,0)
- for i=zero and 0 or 1,#t do
- local ti=t[i]
- if ti then
- local i=tostring(i)
- t[i]=ti
- t[ti]=i
- end
- end
+function table.twowaymapper(t)
+ if not t then
+ t={}
+ else
+ local zero=rawget(t,0)
+ for i=zero and 0 or 1,#t do
+ local ti=t[i]
+ if ti then
+ local i=tostring(i)
+ t[i]=ti
+ t[ti]=i
+ end
end
- setmetatable(t,selfmapper)
- return t
+ end
+ setmetatable(t,selfmapper)
+ return t
end
local f_start_key_idx=formatters["%w{"]
local f_start_key_num=formatters["%w[%s]={"]
@@ -7349,187 +7743,223 @@ local spaces=utilities.strings.newrepeater(" ")
local original_serialize=table.serialize
local is_simple_table=table.is_simple_table
local function serialize(root,name,specification)
- if type(specification)=="table" then
- return original_serialize(root,name,specification)
- end
- local t
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- n=n+1
- if indexed then
- t[n]=f_start_key_idx(depth)
+ if type(specification)=="table" then
+ return original_serialize(root,name,specification)
+ end
+ local t
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ n=n+1
+ if indexed then
+ t[n]=f_start_key_idx(depth)
+ else
+ local tn=type(name)
+ if tn=="number" then
+ t[n]=f_start_key_num(depth,name)
+ elseif tn=="string" then
+ t[n]=f_start_key_str(depth,name)
+ elseif tn=="boolean" then
+ t[n]=f_start_key_boo(depth,name)
+ else
+ t[n]=f_start_key_nop(depth)
+ end
+ end
+ depth=depth+1
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ 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
+ 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 first and tk=="number" and k<=last and k>=first then
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v)==nil then
+ n=n+1 t[n]=f_val_not(depth)
else
- local tn=type(name)
- if tn=="number" then
- t[n]=f_start_key_num(depth,name)
- elseif tn=="string" then
- t[n]=f_start_key_str(depth,name)
- elseif tn=="boolean" then
- t[n]=f_start_key_boo(depth,name)
- else
- t[n]=f_start_key_nop(depth)
- end
- end
- depth=depth+1
- end
- if root and next(root)~=nil then
- local first=nil
- local last=0
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
end
- if last>0 then
- first=1
+ elseif tv=="boolean" then
+ n=n+1 t[n]=f_val_boo(depth,v)
+ elseif unknown then
+ n=n+1 t[n]=f_val_str(depth,tostring(v))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_not(depth,k)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_not(depth,k)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
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 first and tk=="number" and k<=last and k>=first then
- if tv=="number" then
- n=n+1 t[n]=f_val_num(depth,v)
- elseif tv=="string" then
- n=n+1 t[n]=f_val_str(depth,v)
- elseif tv=="table" then
- if next(v)==nil then
- n=n+1 t[n]=f_val_not(depth)
- else
- local st=is_simple_table(v)
- if st then
- n=n+1 t[n]=f_val_seq(depth,st)
- else
- do_serialize(v,k,depth,level+1,true)
- end
- end
- elseif tv=="boolean" then
- n=n+1 t[n]=f_val_boo(depth,v)
- elseif unknown then
- n=n+1 t[n]=f_val_str(depth,tostring(v))
- end
- elseif tv=="number" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_num(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_num(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
- end
- elseif tv=="string" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_not(depth,k)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_not(depth,k)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_not(depth,k)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
- end
- else
- local st=is_simple_table(v)
- if not st then
- do_serialize(v,k,depth,level+1)
- elseif tk=="number" then
- n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
- end
- end
- elseif tv=="boolean" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
- end
- else
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
- end
- end
+ else
+ local st=is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
end
- end
- if level>0 then
- n=n+1 t[n]=f_stop(depth-1)
- end
- end
- local tname=type(name)
- if tname=="string" then
- if name=="return" then
- t={ f_table_return() }
- else
- t={ f_table_name(name) }
- end
- elseif tname=="number" then
- t={ f_table_entry(name) }
- elseif tname=="boolean" then
- if name then
- t={ f_table_return() }
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+ end
else
- t={ f_table_direct() }
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
end
+ end
+ end
+ if level>0 then
+ n=n+1 t[n]=f_stop(depth-1)
+ end
+ end
+ local tname=type(name)
+ if tname=="string" then
+ if name=="return" then
+ t={ f_table_return() }
else
- t={ f_table_name("t") }
+ t={ f_table_name(name) }
end
- if root then
- if 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
- local st=is_simple_table(root)
- if st then
- return t[1]..f_fin_seq(st)
- else
- do_serialize(root,name,1,0)
- end
- end
+ elseif tname=="number" then
+ t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+ if name then
+ t={ f_table_return() }
+ else
+ t={ f_table_direct() }
+ end
+ else
+ t={ f_table_name("t") }
+ end
+ if root then
+ if 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
+ local st=is_simple_table(root)
+ if st then
+ return t[1]..f_fin_seq(st)
+ else
+ do_serialize(root,name,1,0)
+ end
end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
end
table.serialize=serialize
if setinspector then
- setinspector("table",function(v)
- if type(v)=="table" then
- print(serialize(v,"table",{ metacheck=false }))
- return true
- end
- end)
+ setinspector("table",function(v)
+ if type(v)=="table" then
+ print(serialize(v,"table",{ metacheck=false }))
+ return true
+ end
+ end)
+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
@@ -7539,15 +7969,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 7787, stripped down to: 5858
+-- original size: 8607, stripped down to: 6727
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 {}
@@ -7555,251 +7986,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
@@ -7809,338 +8269,412 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 8716, stripped down to: 6754
+-- original size: 11065, stripped down to: 8209
if not modules then modules={} end modules ['util-sac']={
- 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 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)
+ 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()
end
function streams.size(f)
- return f and f[3] or 0
+ return f and f[3] or 0
end
function streams.setposition(f,i)
- if f[4] then
- if i<=0 then
- f[2]=1
- else
- f[2]=i+1
- end
+ if f[4] then
+ if i<=0 then
+ f[2]=1
else
- if i<=1 then
- f[2]=1
- else
- f[2]=i
- end
+ f[2]=i+1
end
-end
-function streams.getposition(f)
- if f[4] then
- return f[2]-1
+ else
+ if i<=1 then
+ f[2]=1
else
- return f[2]
+ f[2]=i
end
+ end
+end
+function streams.getposition(f)
+ if f[4] then
+ return f[2]-1
+ else
+ return f[2]
+ end
end
function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
- return sub(f[1],b,e)
- else
- return byte(f[1],b,e)
- end
+ local b=f[2]
+ local e=b+n-1
+ if chars then
+ return sub(f[1],b,e)
+ else
+ return byte(f[1],b,e)
+ end
end
function streams.skip(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
+ local i=f[2]
+ f[2]=i+1
+ return byte(f[1],i)
end
function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return byte(f[1],i,j-1)
end
function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return { byte(f[1],i,j-1) }
end
function streams.skipbytes(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
+ local i=f[2]
+ f[2]=i+1
+ return sub(f[1],i,i)
end
function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
-end
-function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return sub(f[1],i,j-1)
+end
+function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ local n=byte(f[1],i)
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-streams.readcardinal1=streams.readbyte
+streams.readcardinal1=streams.readbyte
streams.readcardinal=streams.readcardinal1
streams.readinteger=streams.readinteger1
function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readcardinal2LE(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ 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 streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local d,c,b,a=byte(f[1],i,j)
+ 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 streams.readfixed2(f)
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function streams.readfixed4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
- else
- return (0x100*a+b )+(0x100*c+d)/0x10000
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
end
-function streams.readfixed2(f)
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function streams.read2dot14(f)
local i=f[2]
local j=i+1
f[2]=j+1
local a,b=byte(f[1],i,j)
if a>=0x80 then
- return (a-0x100)+b/0x100
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
else
- return (a )+b/0x100
- end
-end
-if extract then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- 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 n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
+ f[2]=f[2]+2*(n or 1)
end
function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
+ f[2]=f[2]+4*(n or 1)
end
if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
- local i=f[2]
- f[2]=i+1
- return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
- local i=f[2]
- f[2]=i+2
- return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
- local i=f[2]
- f[2]=i+3
- return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
- local i=f[2]
- f[2]=i+4
- return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
- local i=f[2]
- f[2]=i+2
- return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
- local i=f[2]
- f[2]=i+3
- return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
- local i=f[2]
- f[2]=i+4
- return readinteger4(f[1],i)
- end
- function streams.read2dot4(f)
- local i=f[2]
- f[2]=i+2
- return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytes(f[1],i,n)
+ local readcardinal1=sio.readcardinal1
+ local readcardinal2=sio.readcardinal2
+ local readcardinal3=sio.readcardinal3
+ local readcardinal4=sio.readcardinal4
+ local readinteger1=sio.readinteger1
+ local readinteger2=sio.readinteger2
+ local readinteger3=sio.readinteger3
+ local readinteger4=sio.readinteger4
+ local readfixed2=sio.readfixed2
+ local readfixed4=sio.readfixed4
+ local read2dot14=sio.read2dot14
+ local readbytes=sio.readbytes
+ local readbytetable=sio.readbytetable
+ function streams.readcardinal1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readcardinal1(f[1],i)
+ end
+ function streams.readcardinal2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readcardinal2(f[1],i)
+ end
+ function streams.readcardinal3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readcardinal3(f[1],i)
+ end
+ function streams.readcardinal4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readcardinal4(f[1],i)
+ end
+ function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readinteger1(f[1],i)
+ end
+ function streams.readinteger2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readinteger2(f[1],i)
+ end
+ function streams.readinteger3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readinteger3(f[1],i)
+ end
+ function streams.readinteger4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readinteger4(f[1],i)
+ end
+ function streams.read2dot4(f)
+ local i=f[2]
+ f[2]=i+2
+ return read2dot4(f[1],i)
+ end
+ function streams.readbytes(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function streams.readbytetable(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytetable(f[1],i,n)
+ return readbytes(f[1],i,n)
+ end
+ function streams.readbytetable(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readbytetable(f[1],i,n)
+ end
+ streams.readbyte=streams.readcardinal1
+ streams.readsignedbyte=streams.readinteger1
+ streams.readcardinal=streams.readcardinal1
+ 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
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
+ 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
@@ -8150,156 +8684,168 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sto"] = package.loaded["util-sto"] or true
--- original size: 6449, stripped down to: 3069
+-- original size: 6661, stripped down to: 3074
if not modules then modules={} end modules ['util-sto']={
- 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 setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
utilities=utilities or {}
utilities.storage=utilities.storage or {}
local storage=utilities.storage
function storage.mark(t)
- if not t then
- print("\nfatal error: storage cannot be marked\n")
- os.exit()
- return
- end
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
+ local m=getmetatable(t)
+ return m and m.__storage__
end
function storage.checked(t)
- if not t then
- report("\nfatal error: storage has not been allocated\n")
- os.exit()
- return
- end
- return t
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
end
function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
- m.__index=nil
- initialize()
- return data[k]
- end
- setmetatable(data,m)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+ m.__index=nil
+ initialize()
+ return data[k]
+ end
+ setmetatable(data,m)
end
local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
+ t[k]=k
+ return k
end }
function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
-end
-local function f_empty () return "" end
-local function f_self (t,k) t[k]=k return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0 return 0 end
-local function f_ignore() end
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
+end
+local function f_empty () return "" end
+local function f_self (t,k) t[k]=k return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0 return 0 end
+local function f_ignore() end
local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
}
function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- else
- setmetatable(t,{ __index=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ else
+ setmetatable(t,{ __index=i })
+ end
+ return t
end
local f_index={
- ["ignore"]=f_ignore,
+ ["ignore"]=f_ignore,
}
function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__newindex=i
- else
- setmetatable(t,{ __newindex=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__newindex=i
+ else
+ setmetatable(t,{ __newindex=i })
+ end
+ return t
end
function table.setmetatablecall(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
- m.__call=f
- else
- setmetatable(t,{ __call=f })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__call=f
+ else
+ setmetatable(t,{ __call=f })
+ end
+ return t
end
function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- m.__newindex=n
- m.__call=c
- else
- setmetatable(t,{
- __index=i,
- __newindex=n,
- __call=c,
- })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ m.__newindex=n
+ m.__call=c
+ else
+ setmetatable(t,{
+ __index=i,
+ __newindex=n,
+ __call=c,
+ })
+ end
+ return t
end
function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m[key]=value
- return t
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m[key]=value
+ return t
end
function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
+ local m=getmetatable(t)
+ 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
@@ -8309,14 +8855,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 22956, stripped down to: 16106
+-- original size: 23460, stripped down to: 15834
if not modules then modules={} end modules ['util-prs']={
- 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 lpeg,table,string=lpeg,table,string
local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -8338,6 +8884,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("}")
@@ -8357,8 +8904,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -8366,311 +8913,329 @@ local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
local spaces=space^0
local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces
+lpegpatterns.nestedbraces=nestedbraces
lpegpatterns.nestedparents=nestedparents
-lpegpatterns.nested=nestedbraces
+lpegpatterns.nested=nestedbraces
lpegpatterns.argument=argument
lpegpatterns.content=content
-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("")))
local hash={}
local function set(key,value)
- hash[key]=value
+ hash[key]=value
end
local pattern_a_s=(pattern_a/set)^1
local pattern_b_s=(pattern_b/set)^1
local pattern_c_s=(pattern_c/set)^1
+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
- return (pattern_c/set)^1
- elseif how=="tolerant" then
- return (pattern_b/set)^1
- else
- return (pattern_a/set)^1
- end
+ if how=="strict" then
+ return (pattern_c/set)^1
+ elseif how=="tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
end
function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_a_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_a_s,str)
+ return hash
+ 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 {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_b_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
- return nil
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- elseif str and str~="" then
- hash=existing or {}
- lpegmatch(pattern_c_s,str)
- return next(hash) and hash
+ if not str or str=="" then
+ return nil
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
end
+ elseif str and str~="" then
+ hash=existing or {}
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
end
local separator=comma*space^0
-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 pattern=spaces*Ct(value*(separator*value)^0)
patterns.settings_to_array=pattern
function parsers.settings_to_array(str,strict)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- elseif strict then
- if find(str,"{",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
- elseif find(str,",",1,true) then
- return lpegmatch(pattern,str)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
else
- return { str }
+ return { str }
end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
end
function parsers.settings_to_numbers(str)
- if not str or str=="" then
- return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
- str=lpegmatch(pattern,str)
- else
- return { tonumber(str) }
- end
- for i=1,#str do
- str[i]=tonumber(str[i])
- end
- return str
-end
-local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
+ if not str or str=="" then
+ return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+ str=lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i]=tonumber(str[i])
+ end
+ return str
+end
+local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache_a={}
local cache_b={}
function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
- symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
- local symbols=S(symbol)
- local separator=space^0*symbols*space^0
- local value=P(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
- pattern=spaces*withvalue*(separator*withvalue)^0
- cache_b[symbol]=pattern
- else
- pattern=spaces*Ct(value*(separator*value)^0)
- cache_a[symbol]=pattern
- end
- end
- return pattern
+ if not symbol then
+ symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols=S(symbol)
+ local separator=space^0*symbols*space^0
+ 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
+ pattern=spaces*withvalue*(separator*withvalue)^0
+ cache_b[symbol]=pattern
+ else
+ pattern=spaces*Ct(value*(separator*value)^0)
+ cache_a[symbol]=pattern
+ end
+ end
+ return pattern
end
local pattern_a=parsers.groupedsplitat(",",false)
local pattern_b=parsers.groupedsplitat(",",true)
function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_a,str)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_a,str)
+ end
end
function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_b,str,1,action)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
end
local function set(t,v)
- t[#t+1]=v
+ t[#t+1]=v
end
local value=P(Carg(1)*value)/set
local pattern=value*(separator*value)^0*Carg(1)
function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
+ return lpegmatch(pattern,str,nil,t)
end
function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
- local t,tn,s={},0,sortedkeys(h)
- omit=omit and tohash(omit)
- for i=1,#s do
- local key=s[i]
- if not omit or not omit[key] then
- local value=h[key]
- if type(value)=="boolean" then
- if yes and no then
- if value then
- tn=tn+1
- t[tn]=key..'='..yes
- elseif not strict then
- tn=tn+1
- t[tn]=key..'='..no
- end
- elseif value or not strict then
- tn=tn+1
- t[tn]=key..'='..tostring(value)
- end
- else
- tn=tn+1
- t[tn]=key..'='..value
- end
- end
+ if h then
+ local t={}
+ local tn=0
+ local s=sortedkeys(h)
+ omit=omit and tohash(omit)
+ for i=1,#s do
+ local key=s[i]
+ if not omit or not omit[key] then
+ local value=h[key]
+ if type(value)=="boolean" then
+ if yes and no then
+ if value then
+ tn=tn+1
+ t[tn]=key..'='..yes
+ elseif not strict then
+ tn=tn+1
+ t[tn]=key..'='..no
+ end
+ elseif value or not strict then
+ tn=tn+1
+ t[tn]=key..'='..tostring(value)
+ end
+ else
+ tn=tn+1
+ t[tn]=key..'='..value
end
- return concat(t,separator or ",")
- else
- return ""
+ end
end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
end
function parsers.array_to_string(a,separator)
- if a then
- return concat(a,separator or ",")
- else
- return ""
- end
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
end
local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
function utilities.parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
+ return str and lpegmatch(pattern,str) or {}
end
hashes.settings_to_set=table.setmetatableindex(function(t,k)
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
end)
getmetatable(hashes.settings_to_set).__mode="kv"
function parsers.simple_hash_to_string(h,separator)
- local t,tn={},0
- for k,v in sortedhash(h) do
- if v then
- tn=tn+1
- t[tn]=k
- end
+ local t={}
+ local tn=0
+ for k,v in sortedhash(h) do
+ if v then
+ tn=tn+1
+ t[tn]=k
end
- return concat(t,separator or ",")
+ end
+ return concat(t,separator or ",")
end
local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
local splitter=setting^1
function utilities.parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
end
local splitter=lpeg.tsplitat(" ")
function utilities.parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
+ return str and lpegmatch(splitter,str) or {}
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
local pattern_a=spaces*Ct(value*(separator*value)^0)
local function repeater(n,str)
- if not n then
- return str
+ if not n then
+ return str
+ else
+ local s=lpegmatch(pattern_a,str)
+ if n==1 then
+ return unpack(s)
else
- local s=lpegmatch(pattern_a,str)
- if n==1 then
- return unpack(s)
- else
- local t,tn={},0
- for i=1,n do
- for j=1,#s do
- tn=tn+1
- t[tn]=s[j]
- end
- end
- return unpack(t)
+ local t={}
+ local tn=0
+ for i=1,n do
+ for j=1,#s do
+ tn=tn+1
+ t[tn]=s[j]
end
+ end
+ return unpack(t)
end
+ end
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
local pattern_b=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_with_repeat(str,expand)
- if expand then
- return lpegmatch(pattern_b,str) or {}
- else
- return lpegmatch(pattern_a,str) or {}
- end
+ if expand then
+ return lpegmatch(pattern_b,str) or {}
+ else
+ return lpegmatch(pattern_a,str) or {}
+ end
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
local pattern=Ct((space+value)^0)
function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
- sc={}
- self[class]=sc
- if parentclass then
- local sp=self[parentclass]
- if not sp then
- sp={}
- self[parentclass]=sp
- end
- setmetatableindex(sc,sp)
- end
+ local sc=self[class]
+ if not sc then
+ sc={}
+ self[class]=sc
+ if parentclass then
+ local sp=self[parentclass]
+ if not sp then
+ sp={}
+ self[parentclass]=sp
+ end
+ setmetatableindex(sc,sp)
end
- parsers.settings_to_hash(settings,sc)
+ end
+ parsers.settings_to_hash(settings,sc)
end
function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
+ return gmatch(str,"[^, ]+")
end
local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
}
lpegpatterns.splitthousands=pattern
function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local optionalwhitespace=whitespace^0
lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -8684,75 +9249,75 @@ local key=C((1-equal)^1)
local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
function parsers.keq_to_hash(str)
- if str and str~="" then
- return lpegmatch(pattern,str)
- else
- return {}
- end
+ if str and str~="" then
+ return lpegmatch(pattern,str)
+ else
+ return {}
+ end
end
local defaultspecification={ separator=",",quote='"' }
function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
- local quotedata=nil
- for chr in gmatch(quotechar,".") do
- local quotechar=P(chr)
- local quoteword=quotechar*C((1-quotechar)^0)*quotechar
- if quotedata then
- quotedata=quotedata+quoteword
- else
- quotedata=quoteword
- end
- end
- whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
- return lpegmatch(parser,data)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+ local quotedata=nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar=P(chr)
+ local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+ if quotedata then
+ quotedata=quotedata+quoteword
+ else
+ quotedata=quoteword
+ end
end
+ whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
end
function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=P(specification.quote)
- local dquotechar=quotechar*quotechar
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=P(specification.quote)
+ local dquotechar=quotechar*quotechar
/specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
- if getheader then
- local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(headeryes,data,position)
- return data,header
- else
- return lpegmatch(headernop,data)
- end
- end
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header,position=lpegmatch(headerline,data)
+ local data=lpegmatch(headeryes,data,position)
+ return data,header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
end
local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
- for i=first,n or first do
- action(i)
- end
- elseif last then
- for i=first,last do
- action(i)
- end
- else
- action(first)
+ if not first then
+ elseif last==true then
+ for i=first,n or first do
+ action(i)
end
+ elseif last then
+ for i=first,last do
+ action(i)
+ end
+ else
+ action(first)
+ end
end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
@@ -8760,89 +9325,89 @@ local endofstring=lpegpatterns.endofstring
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
- if type(n)=="function" then
- lpegmatch(stepper,str,1,false,n or print)
- else
- lpegmatch(stepper,str,1,n,action or print)
- end
+ if type(n)=="function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
end
local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
patterns.unittotex=pattern
function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
end
local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache={}
local spaces=lpegpatterns.space^0
local dummy=function() end
setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
end)
local commalistiterator=cache[","]
function utilities.parsers.iterator(str,separator)
- local n=#str
- if n==0 then
- return dummy
- else
- local pattern=separator and cache[separator] or commalistiterator
- local p=1
- return function()
- if p<=n then
- local s,e=lpegmatch(pattern,str,p)
- if e then
- p=e
- return s
- end
- end
+ local n=#str
+ if n==0 then
+ return dummy
+ else
+ local pattern=separator and cache[separator] or commalistiterator
+ local p=1
+ return function()
+ if p<=n then
+ local s,e=lpegmatch(pattern,str,p)
+ if e then
+ p=e
+ return s
end
+ end
end
+ end
end
local function initialize(t,name)
- local source=t[name]
- if source then
- local result={}
- for k,v in next,t[name] do
- result[k]=v
- end
- return result
- else
- return {}
+ local source=t[name]
+ if source then
+ local result={}
+ for k,v in next,t[name] do
+ result[k]=v
end
+ return result
+ else
+ return {}
+ end
end
local function fetch(t,name)
- return t[name] or {}
+ return t[name] or {}
end
local function process(result,more)
- for k,v in next,more do
- result[k]=v
- end
- return result
+ for k,v in next,more do
+ result[k]=v
+ end
+ return result
end
local name=C((1-S(", "))^1)
local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
local merge=Cf(parser,process)
function utilities.parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
+ return lpegmatch(merge,list,1,hash)
end
function utilities.parsers.runtime(time)
- if not time then
- time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
+ if not time then
+ time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
end
local spacing=whitespace^0
local apply=P("->")
@@ -8850,11 +9415,11 @@ local method=C((1-apply)^1)
local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
function utilities.parsers.splitmethod(str,default)
- if str then
- return lpegmatch(pattern,str,1,default or false)
- else
- return default or false,""
- end
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false,""
+ end
end
@@ -8864,14 +9429,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
--- original size: 2274, stripped down to: 1781
+-- original size: 2541, stripped down to: 1624
if not modules then modules={} end modules ['util-fmt']={
- 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"
}
utilities=utilities or {}
utilities.formatters=utilities.formatters or {}
@@ -8882,61 +9447,2887 @@ local strip=string.strip
local lpegmatch=lpeg.match
local stripper=lpeg.patterns.stripzeros
function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
+ return lpegmatch(stripper,str)
end
function formatters.formatcolumns(result,between)
- if result and #result>0 then
- between=between or " "
- local widths,numbers={},{}
- local first=result[1]
- local n=#first
- for i=1,n do
- widths[i]=0
+ if result and #result>0 then
+ between=between or " "
+ local widths,numbers={},{}
+ local first=result[1]
+ local n=#first
+ for i=1,n do
+ widths[i]=0
+ end
+ for i=1,#result do
+ local r=result[i]
+ for j=1,n do
+ local rj=r[j]
+ local tj=type(rj)
+ if tj=="number" then
+ numbers[j]=true
+ rj=tostring(rj)
+ elseif tj~="string" then
+ rj=tostring(rj)
+ r[j]=rj
+ end
+ local w=#rj
+ if w>widths[j] then
+ widths[j]=w
end
- for i=1,#result do
- local r=result[i]
- 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
- local w=#rj
- if w>widths[j] then
- widths[j]=w
- end
+ end
+ end
+ for i=1,n do
+ local w=widths[i]
+ if numbers[i] then
+ if w>80 then
+ widths[i]="%s"..between
+ else
+ widths[i]="%0"..w.."i"..between
+ end
+ else
+ if w>80 then
+ widths[i]="%s"..between
+ elseif w>0 then
+ widths[i]="%-"..w.."s"..between
+ else
+ widths[i]="%s"
+ end
+ end
+ end
+ local template=strip(concat(widths))
+ for i=1,#result do
+ local str=format(template,unpack(result[i]))
+ result[i]=strip(str)
+ end
+ end
+ return result
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true
+
+-- original size: 374, stripped down to: 282
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
+
+-- original size: 4870, stripped down to: 3527
+
+
+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
+ 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
+ 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
+package.loaded["socket"]=socket
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
+
+-- original size: 25844, stripped down to: 14821
+
+
+local socket=socket or require("socket")
+local ssl=ssl or nil
+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
+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
+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
+ 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
- for i=1,n do
- local w=widths[i]
- if numbers[i] then
- if w>80 then
- widths[i]="%s"..between
- else
- widths[i]="%0"..w.."i"..between
- end
- else
- if w>80 then
- widths[i]="%s"..between
- elseif w>0 then
- widths[i]="%-"..w.."s"..between
- else
- widths[i]="%s"
- end
+ }
+ } )
+ return set
+end
+local _sleeping={
+ times={},
+ cos={},
+ lethargy={},
+ insert=function()
+ end,
+ remove=function()
+ end,
+ push=function(self,sleeptime,co)
+ if not co then
+ return
+ end
+ if sleeptime<0 then
+ 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=
+ 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=
+ 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
- local template=strip(concat(widths))
- for i=1,#result do
- local str=format(template,unpack(result[i]))
- result[i]=strip(str)
+ end
+}
+local _servers=newset()
+local _reading=newset()
+local _writing=newset()
+local _reading_log={}
+local _writing_log={}
+local _is_timeout={
+ timeout=true,
+ wantread=true,
+ wantwrite=true,
+}
+local function isTCP(socket)
+ return not find(tostring(socket),"^udp")
+end
+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
+local function copasreceivefrom(client,size)
+ local s,err,port
+ if not size or size==0 then
+ size=UDP_DATAGRAM_MAX
+ end
+ repeat
+ 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
+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
+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)
+ 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
+local function copassendto(client,data,ip,port)
+ repeat
+ local s,err=client:sendto(data,ip,port)
+ 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
+local function copasconnect(skt,host,port)
+ skt:settimeout(0)
+ local ret,err,tried_more_than_once
+ repeat
+ ret,err=skt:connect (host,port)
+ if ret or (err~="timeout" and err~="Operation already in progress") then
+ 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
+local function copasdohandshake(skt,sslt)
+ 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
+local function copasflush(client)
+end
+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
+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,
+ 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,
+ bind=function(self,...)
+ return self.socket:bind(...)
+ end,
+ 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,
+ 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,
+}
+local _skt_mt_udp_index={
+ 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,
+ setpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ setsockname=function(self,...)
+ return self.socket:setsockname(...)
+ end,
+ 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
+local function wrap(skt,sslt)
+ if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
+ return skt
+ 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
+function copas.handler(handler,sslparams)
+ return function (skt,...)
+ skt=wrap(skt)
+ if sslparams then
+ skt:dohandshake(sslparams)
+ end
+ return handler(skt,...)
+ end
+end
+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
+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
+ if skt and copas.autoclose and isTCP(skt) then
+ skt:close()
+ end
+ _errhandlers[co]=nil
+ end
+end
+local function _accept(input,handler)
+ local client=input:accept()
+ if client then
+ client:settimeout(0)
+ local co=createcoroutine(handler)
+ _doTick (co,client)
+ end
+ return client
+end
+local function _tickRead(skt)
+ _doTick(_reading:pop(skt),skt)
+end
+local function _tickWrite(skt)
+ _doTick(_writing:pop(skt),skt)
+end
+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
+function copas.addthread(handler,...)
+ local thread=createcoroutine(function(_,...) return handler(...) end)
+ _doTick(thread,nil,...)
+ return thread
+end
+local _tasks={}
+local function addtaskRead(task)
+ task.def_tick=_tickRead
+ _tasks[task]=true
+end
+local function addtaskWrite(task)
+ task.def_tick=_tickWrite
+ _tasks[task]=true
+end
+local function tasks()
+ return next,_tasks
+end
+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)
+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)
+local _sleeping_t={
+ tick=function(self,time,...)
+ _doTick(_sleeping:pop(time),...)
+ end
+}
+function copas.sleep(sleeptime)
+ yieldcoroutine((sleeptime or 0),_sleeping)
+end
+function copas.wakeup(co)
+ _sleeping:wakeup(co)
+end
+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
+ for skt,time in next,_reading_log do
+ if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#r_evs+1
+ _reading_log[skt]=nil
+ r_evs[n]=skt
+ r_evs[skt]=n
+ end
+ end
+ 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
+local function copasfinished()
+ return not (next(_reading) or next(_writing) or _sleeping:getnext())
+end
+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
+function copas.loop(timeout)
+ copas.running=true
+ while not copasfinished() do
+ copasstep(timeout)
+ end
+ copas.running=false
+end
+package.loaded["copas"]=copas
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
+
+-- original size: 8709, stripped down to: 5411
+
+
+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,
+}
+function filter.cycle(low,ctx,extra)
+ if low then
+ return function(chunk)
+ return (low(ctx,chunk,extra))
+ end
+ end
+end
+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
- return result
+ end
+end
+local function empty()
+ return nil
+end
+function source.empty()
+ return empty
+end
+local function sourceerror(err)
+ return function()
+ return nil,err
+ end
+end
+source.error=sourceerror
+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
+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
+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
+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
+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
+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
+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
+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
+local function null()
+ return 1
+end
+function sink.null()
+ return null
+end
+local function sinkerror(err)
+ return function()
+ return nil,err
+ end
+end
+sink.error=sinkerror
+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
+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
+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
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
+
+-- original size: 2328, stripped down to: 1874
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
+
+-- original size: 6863, stripped down to: 5269
+
+
+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)
+ 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
+ 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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
+
+-- original size: 5721, stripped down to: 3754
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
+
+-- original size: 3116, stripped down to: 2533
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
+
+-- original size: 12577, stripped down to: 9577
+
+
+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
+local http={
+ TIMEOUT=60,
+ USERAGENT=socket._VERSION,
+}
+socket.http=http
+local PORT=80
+local SCHEMES={
+ http=true,
+}
+local function receiveheaders(sock,headers)
+ if not headers then
+ headers={}
+ end
+ local line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while line~="" do
+ local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
+ if not (name and value) then
+ return nil,"malformed reponse headers"
+ end
+ name=lower(name)
+ line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while find(line,"^%s") do
+ value=value..line
+ line=sock:receive()
+ if err then
+ return nil,err
+ end
+ end
+ local found=headers[name]
+ if found then
+ value=found..", "..value
+ end
+ headers[name]=value
+ end
+ return headers
+end
+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
+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
+ 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"]
+ local mode="default"
+ if encoding and encoding~="identity" then
+ mode="http-chunked"
+ elseif length then
+ mode="by-length"
+ end
+ 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
+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
+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
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
+
+-- original size: 10357, stripped down to: 8548
+
+
+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
+ 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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
+
+-- original size: 7018, stripped down to: 5883
+
+
+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
end -- of closure
@@ -8945,14 +12336,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-set"] = package.loaded["trac-set"] or true
--- original size: 13044, stripped down to: 9231
+-- original size: 13340, stripped down to: 8826
if not modules then modules={} end modules ['trac-set']={
- 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=type,next,tostring,tonumber
local concat,sortedhash=table.concat,table.sortedhash
@@ -8967,305 +12358,318 @@ utilities.setters=setters
local data={}
local trace_initialize=false
function setters.initialize(filename,name,values)
- local setter=data[name]
- if setter then
- frozen=true
- local data=setter.data
- if data then
- for key,newvalue in sortedhash(values) do
- local newvalue=is_boolean(newvalue,newvalue,true)
- local functions=data[key]
- if functions then
- local oldvalue=functions.value
- if functions.frozen then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
- end
- elseif #functions>0 and not oldvalue then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
- end
- for i=1,#functions do
- functions[i](newvalue)
- end
- functions.value=newvalue
- functions.frozen=functions.frozen or frozen
- else
- if trace_initialize then
- setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
- end
- end
- else
- functions={ default=newvalue,frozen=frozen }
- data[key]=functions
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
- end
- end
+ local setter=data[name]
+ if setter then
+ frozen=true
+ local data=setter.data
+ if data then
+ for key,newvalue in sortedhash(values) do
+ local newvalue=is_boolean(newvalue,newvalue,true)
+ local functions=data[key]
+ if functions then
+ local oldvalue=functions.value
+ if functions.frozen then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+ end
+ elseif #functions>0 and not oldvalue then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
+ end
+ for i=1,#functions do
+ functions[i](newvalue)
+ end
+ functions.value=newvalue
+ functions.frozen=functions.frozen or frozen
+ else
+ if trace_initialize then
+ setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
end
- return true
+ end
+ else
+ functions={ default=newvalue,frozen=frozen }
+ data[key]=functions
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
+ end
end
+ end
+ return true
end
+ end
end
local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
- local done=t.done
- if type(what)=="string" then
- what=settings_to_hash(what)
- end
- if type(what)~="table" then
- return
- end
- if not done then
- done={}
- t.done=done
- end
- for w,value in sortedhash(what) do
- if value=="" then
- value=newvalue
- elseif not value then
- value=false
- else
- value=is_boolean(value,value,true)
- end
- w=topattern(w,true,true)
- for name,functions in sortedhash(data) do
- if done[name] then
- elseif find(name,w) then
- done[name]=true
- for i=1,#functions do
- functions[i](value)
- end
- functions.value=value
- end
- end
+ local data=t.data
+ if not data.frozen then
+ local done=t.done
+ if type(what)=="string" then
+ what=settings_to_hash(what)
+ end
+ if type(what)~="table" then
+ return
+ end
+ if not done then
+ done={}
+ t.done=done
+ end
+ for w,value in sortedhash(what) do
+ if value=="" then
+ value=newvalue
+ elseif not value then
+ value=false
+ else
+ value=is_boolean(value,value,true)
+ end
+ w=topattern(w,true,true)
+ for name,functions in sortedhash(data) do
+ if done[name] then
+ elseif find(name,w) then
+ done[name]=true
+ for i=1,#functions do
+ functions[i](value)
+ end
+ functions.value=value
end
+ end
end
+ end
end
local function reset(t)
- local data=t.data
- if not data.frozen then
- for name,functions in sortedthash(data) do
- for i=1,#functions do
- functions[i](false)
- end
- functions.value=false
- end
+ local data=t.data
+ if not data.frozen then
+ for name,functions in sortedthash(data) do
+ for i=1,#functions do
+ functions[i](false)
+ end
+ functions.value=false
end
+ end
end
local function enable(t,what)
- set(t,what,true)
+ set(t,what,true)
end
local function disable(t,what)
- local data=t.data
- if not what or what=="" then
- t.done={}
- reset(t)
- else
- set(t,what,false)
- end
+ local data=t.data
+ if not what or what=="" then
+ t.done={}
+ reset(t)
+ else
+ set(t,what,false)
+ end
end
function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
- functions={}
- data[what]=functions
- if trace_initialize then
- t.report("defining %a",what)
- end
- end
- local default=functions.default
- for i=1,select("#",...) do
- local fnc=select(i,...)
- local typ=type(fnc)
- if typ=="string" then
- if trace_initialize then
- t.report("coupling %a to %a",what,fnc)
- end
- local s=fnc
- fnc=function(value) set(t,s,value) end
- elseif typ~="function" then
- fnc=nil
- end
- if fnc then
- functions[#functions+1]=fnc
- local value=functions.value or default
- if value~=nil then
- fnc(value)
- functions.value=value
- end
- end
+ local data=t.data
+ what=lower(what)
+ local functions=data[what]
+ if not functions then
+ functions={}
+ data[what]=functions
+ if trace_initialize then
+ t.report("defining %a",what)
+ end
+ end
+ local default=functions.default
+ for i=1,select("#",...) do
+ local fnc=select(i,...)
+ local typ=type(fnc)
+ if typ=="string" then
+ if trace_initialize then
+ t.report("coupling %a to %a",what,fnc)
+ end
+ local s=fnc
+ fnc=function(value) set(t,s,value) end
+ elseif typ~="function" then
+ fnc=nil
+ end
+ if fnc then
+ functions[#functions+1]=fnc
+ local value=functions.value or default
+ if value~=nil then
+ fnc(value)
+ functions.value=value
+ end
end
- return false
+ end
+ return false
end
function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
+ local e=t.enable
+ t.enable,t.done=enable,{}
+ enable(t,what)
+ t.enable,t.done=e,{}
end
function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
+ local e=t.disable
+ t.disable,t.done=disable,{}
+ disable(t,what)
+ t.disable,t.done=e,{}
end
function setters.reset(t)
- t.done={}
- reset(t)
+ t.done={}
+ reset(t)
end
function setters.list(t)
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
- local what=list[l]
- if find(what,"^%*") then
- system[#system+1]=what
- else
- user[#user+1]=what
- end
+ local list=table.sortedkeys(t.data)
+ local user,system={},{}
+ for l=1,#list do
+ local what=list[l]
+ if find(what,"^%*") then
+ system[#system+1]=what
+ else
+ user[#user+1]=what
end
- return user,system
+ end
+ return user,system
end
function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
- local name=list[k]
- local functions=t.data[name]
- if functions then
- local value=functions.value
- local default=functions.default
- local modules=#functions
- if default==nil then
- default="unset"
- elseif type(default)=="table" then
- default=concat(default,"|")
- else
- default=tostring(default)
- end
- if value==nil then
- value="unset"
- elseif type(value)=="table" then
- value=concat(value,"|")
- else
- value=tostring(value)
- end
- t.report(name)
- t.report(" modules : %i",modules)
- t.report(" default : %s",default)
- t.report(" value : %s",value)
- t.report()
- end
+ local list=setters.list(t)
+ t.report()
+ for k=1,#list do
+ local name=list[k]
+ local functions=t.data[name]
+ if functions then
+ local value=functions.value
+ local default=functions.default
+ local modules=#functions
+ if default==nil then
+ default="unset"
+ elseif type(default)=="table" then
+ default=concat(default,"|")
+ else
+ default=tostring(default)
+ end
+ if value==nil then
+ value="unset"
+ elseif type(value)=="table" then
+ value=concat(value,"|")
+ else
+ value=tostring(value)
+ end
+ t.report(name)
+ t.report(" modules : %i",modules)
+ t.report(" default : %s",default)
+ t.report(" value : %s",value)
+ t.report()
end
+ end
end
local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
function setters.report(setter,...)
- print(format("%-15s : %s\n",setter.name,format(...)))
+ print(format("%-15s : %s\n",setter.name,format(...)))
end
local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
+ local d=setter.data[name]
+ return d and d.default
end
local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
+ local d=setter.data[name]
+ return d and (d.value or d.default)
end
function setters.new(name)
- local setter
- setter={
- data=allocate(),
- name=name,
- report=function(...) setters.report (setter,...) end,
- enable=function(...) enable (setter,...) end,
- disable=function(...) disable (setter,...) end,
- reset=function(...) reset (setter,...) end,
- register=function(...) register(setter,...) end,
- list=function(...) list (setter,...) end,
- show=function(...) show (setter,...) end,
- default=function(...) return default (setter,...) end,
- value=function(...) return value (setter,...) end,
- }
- data[name]=setter
- return setter
+ local setter
+ setter={
+ data=allocate(),
+ name=name,
+ report=function(...) setters.report (setter,...) end,
+ enable=function(...) enable (setter,...) end,
+ disable=function(...) disable (setter,...) end,
+ reset=function(...) reset (setter,...) end,
+ register=function(...) register(setter,...) end,
+ list=function(...) list (setter,...) end,
+ show=function(...) show (setter,...) end,
+ default=function(...) return default (setter,...) end,
+ value=function(...) return value (setter,...) end,
+ }
+ data[name]=setter
+ return setter
end
trackers=setters.new("trackers")
directives=setters.new("directives")
experiments=setters.new("experiments")
-local t_enable,t_disable=trackers .enable,trackers .disable
+local t_enable,t_disable=trackers .enable,trackers .disable
local d_enable,d_disable=directives .enable,directives .disable
local e_enable,e_disable=experiments.enable,experiments.disable
-local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
-local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
+local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
+local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
function directives.enable(...)
- if trace_directives then
- directives.report("enabling: % t",{...})
- end
- d_enable(...)
+ if trace_directives then
+ directives.report("enabling: % t",{...})
+ end
+ d_enable(...)
end
function directives.disable(...)
- if trace_directives then
- directives.report("disabling: % t",{...})
- end
- d_disable(...)
+ if trace_directives then
+ directives.report("disabling: % t",{...})
+ end
+ d_disable(...)
end
function experiments.enable(...)
- if trace_experiments then
- experiments.report("enabling: % t",{...})
- end
- e_enable(...)
+ if trace_experiments then
+ experiments.report("enabling: % t",{...})
+ end
+ e_enable(...)
end
function experiments.disable(...)
- if trace_experiments then
- experiments.report("disabling: % t",{...})
- end
- e_disable(...)
+ if trace_experiments then
+ experiments.report("disabling: % t",{...})
+ end
+ e_disable(...)
end
directives.register("system.nostatistics",function(v)
- if statistics then
- statistics.enable=not v
- else
- end
+ if statistics then
+ statistics.enable=not v
+ else
+ end
end)
directives.register("system.nolibraries",function(v)
- if libraries then
- libraries=nil
- else
- end
+ if libraries then
+ libraries=nil
+ else
+ end
end)
if environment then
- local engineflags=environment.engineflags
- if engineflags then
- local list=engineflags["c:trackers"] or engineflags["trackers"]
- if type(list)=="string" then
- setters.initialize("commandline flags","trackers",settings_to_hash(list))
- end
- local list=engineflags["c:directives"] or engineflags["directives"]
- if type(list)=="string" then
- setters.initialize("commandline flags","directives",settings_to_hash(list))
- end
+ local engineflags=environment.engineflags
+ if engineflags then
+ local list=engineflags["c:trackers"] or engineflags["trackers"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","trackers",settings_to_hash(list))
end
-end
-if texconfig then
- local function set(k,v)
- v=tonumber(v)
- if v then
- texconfig[k]=v
- end
+ local list=engineflags["c:directives"] or engineflags["directives"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","directives",settings_to_hash(list))
end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v) end)
- directives.register("luatex.savesize",function(v) set("save_size",v) end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+ end
end
+if texconfig then
+ local function set(k,v)
+ v=tonumber(v)
+ if v then
+ texconfig[k]=v
+ end
+ end
+ directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
+ directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
+ directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
+ directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
+ directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
+ directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
+ directives.register("luatex.paramsize",function(v) set("param_size",v) end)
+ directives.register("luatex.savesize",function(v) set("save_size",v) end)
+ directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+end
+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,
+}
end -- of closure
@@ -9274,14 +12678,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-log"] = package.loaded["trac-log"] or true
--- original size: 32922, stripped down to: 23011
+-- original size: 32608, stripped down to: 20925
if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.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 trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,select,print=next,type,select,print
local format,gmatch,find=string.format,string.gmatch,string.find
@@ -9292,7 +12696,7 @@ local datetime=os.date
local openfile=io.open
local runningtex=tex and (tex.jobname or tex.formatname)
local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
+local write=runningtex and texio and texio.write or io.write
local setmetatableindex=table.setmetatableindex
local formatters=string.formatters
local settings_to_hash=utilities.parsers.settings_to_hash
@@ -9308,404 +12712,404 @@ webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
wiki : http://contextgarden.net
]]
formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
+ formatters,"unichr",
+ [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
)
formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
+ formatters,"chruni",
+ [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
)
local function ignore() end
setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
local report,subreport,status,settarget,setformats,settranslations
local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
if runningtex then
- if texio.setescape then
- texio.setescape(0)
- end
- if arg then
- for k,v in next,arg do
- if v=="--ansi" or v=="--c:ansi" then
- variant="ansi"
- break
- end
- end
- end
- local function useluawrites()
- local texio_write_nl=texio.write_nl
- local texio_write=texio.write
- local io_write=io.write
- write_nl=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write_nl("log",...)
- texio_write_nl("term","")
- io_write(...)
- elseif target=="log" then
- texio_write_nl("log",...)
- elseif target=="term" then
- texio_write_nl("term","")
- io_write(...)
- elseif type(target)=="number" then
- texio_write_nl(target,...)
- elseif target~="none" then
- texio_write_nl("log",target,...)
- texio_write_nl("term","")
- io_write(target,...)
- end
- end
- write=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write("log",...)
- io_write(...)
- elseif target=="log" then
- texio_write("log",...)
- elseif target=="term" then
- io_write(...)
- elseif type(target)=="number" then
- texio_write(target,...)
- elseif target~="none" then
- texio_write("log",target,...)
- io_write(target,...)
- end
- end
- texio.write=write
- texio.write_nl=write_nl
- useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="log",
- log="log",
- file="log",
- console="term",
- terminal="term",
- both="term and log",
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="none",
- log="none",
- file="none",
- console="term",
- terminal="term",
- both="term",
- },
- }
- }
- logs.flush=io.flush
- writer=function(...)
- write_nl(target,...)
- end
- newline=function()
- write_nl(target,"\n")
- end
- report=function(a,b,c,...)
- if c~=nil then
- write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,report_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,report_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- direct=function(a,b,c,...)
- if c~=nil then
- return direct_yes(translations[a],formatters[formats[b]](c,...))
- elseif b then
- return direct_yes(translations[a],formats[b])
- elseif a then
- return direct_nop(translations[a])
- else
- return ""
- end
- end
- subreport=function(a,s,b,c,...)
- if c~=nil then
- write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
- elseif a then
- write_nl(target,subreport_nop(translations[a],translations[s]))
- else
- write_nl(target,"\n")
- end
- end
- subdirect=function(a,s,b,c,...)
- if c~=nil then
- return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
- elseif b then
- return subdirect_yes(translations[a],translations[s],formats[b])
- elseif a then
- return subdirect_nop(translations[a],translations[s])
- else
- return ""
- end
+ if texio.setescape then
+ texio.setescape(0)
+ end
+ if arg then
+ for k,v in next,arg do
+ if v=="--ansi" or v=="--c:ansi" then
+ variant="ansi"
+ break
+ end
end
- status=function(a,b,c,...)
- if c~=nil then
- write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,status_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,status_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
+ end
+ local function useluawrites()
+ local texio_write_nl=texio.write_nl
+ local texio_write=texio.write
+ local io_write=io.write
+ write_nl=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write_nl("log",...)
+ texio_write_nl("term","")
+ io_write(...)
+ elseif target=="log" then
+ texio_write_nl("log",...)
+ elseif target=="term" then
+ texio_write_nl("term","")
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write_nl(target,...)
+ elseif target~="none" then
+ texio_write_nl("log",target,...)
+ texio_write_nl("term","")
+ io_write(target,...)
+ end
end
- settarget=function(askedwhereto)
- whereto=askedwhereto or whereto or "both"
- target=targets[whereto]
- if not target then
- whereto="both"
- target=targets[whereto]
- end
- if target=="term" or target=="term and log" then
- logs.flush=io.flush
- else
- logs.flush=ignore
- end
+ write=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write("log",...)
+ io_write(...)
+ elseif target=="log" then
+ texio_write("log",...)
+ elseif target=="term" then
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write(target,...)
+ elseif target~="none" then
+ texio_write("log",target,...)
+ io_write(target,...)
+ end
end
- local stack={}
- pushtarget=function(newtarget)
- insert(stack,target)
- settarget(newtarget)
+ texio.write=write
+ texio.write_nl=write_nl
+ useluawrites=ignore
+ end
+ local whereto="both"
+ local target=nil
+ local targets=nil
+ local formats=table.setmetatableindex("self")
+ local translations=table.setmetatableindex("self")
+ local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
+ local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="log",
+ log="log",
+ file="log",
+ console="term",
+ terminal="term",
+ both="term and log",
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="none",
+ log="none",
+ file="none",
+ console="term",
+ terminal="term",
+ both="term",
+ },
+ }
+ }
+ logs.flush=io.flush
+ writer=function(...)
+ write_nl(target,...)
+ end
+ newline=function()
+ write_nl(target,"\n")
+ end
+ report=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,report_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,report_nop(translations[a]))
+ else
+ write_nl(target,"\n")
end
- poptarget=function()
- if #stack>0 then
- settarget(remove(stack))
- end
+ end
+ direct=function(a,b,c,...)
+ if c~=nil then
+ return direct_yes(translations[a],formatters[formats[b]](c,...))
+ elseif b then
+ return direct_yes(translations[a],formats[b])
+ elseif a then
+ return direct_nop(translations[a])
+ else
+ return ""
end
- setformats=function(f)
- formats=f
+ end
+ subreport=function(a,s,b,c,...)
+ if c~=nil then
+ write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
+ elseif a then
+ write_nl(target,subreport_nop(translations[a],translations[s]))
+ else
+ write_nl(target,"\n")
end
- settranslations=function(t)
- translations=t
+ end
+ subdirect=function(a,s,b,c,...)
+ if c~=nil then
+ return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
+ elseif b then
+ return subdirect_yes(translations[a],translations[s],formats[b])
+ elseif a then
+ return subdirect_nop(translations[a],translations[s])
+ else
+ return ""
end
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(target,...)
- writeline(target,f(...))
- end
+ end
+ status=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,status_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,status_nop(translations[a]))
+ else
+ write_nl(target,"\n")
+ end
+ end
+ settarget=function(askedwhereto)
+ whereto=askedwhereto or whereto or "both"
+ target=targets[whereto]
+ if not target then
+ whereto="both"
+ target=targets[whereto]
+ end
+ if target=="term" or target=="term and log" then
+ logs.flush=io.flush
+ else
+ logs.flush=ignore
+ end
+ end
+ local stack={}
+ pushtarget=function(newtarget)
+ insert(stack,target)
+ settarget(newtarget)
+ end
+ poptarget=function()
+ if #stack>0 then
+ settarget(remove(stack))
+ end
+ end
+ setformats=function(f)
+ formats=f
+ end
+ settranslations=function(t)
+ translations=t
+ end
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(target,...)
+ writeline(target,f(...))
+ end
+ end
+ setformatters=function(specification)
+ local t=nil
+ local f=nil
+ local d=variants.default
+ if not specification then
+ elseif type(specification)=="table" then
+ t=specification.targets
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ t=v.targets
+ f=v.formats
+ variant=specification
+ end
end
- setformatters=function(specification)
- local t=nil
- local f=nil
- local d=variants.default
- if not specification then
- elseif type(specification)=="table" then
- t=specification.targets
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- t=v.targets
- f=v.formats
- variant=specification
- end
- end
- targets=t or d.targets
- target=targets[whereto] or target
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- direct_yes=f.direct_yes
- direct_nop=f.direct_nop
- subdirect_yes=f.subdirect_yes
- subdirect_nop=f.subdirect_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- if variant=="ansi" then
- useluawrites()
- end
- settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
+ targets=t or d.targets
+ target=targets[whereto] or target
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ direct_yes=f.direct_yes
+ direct_nop=f.direct_nop
+ subdirect_yes=f.subdirect_yes
+ subdirect_nop=f.subdirect_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ if variant=="ansi" then
+ useluawrites()
+ end
+ settarget(whereto)
+ end
+ setformatters(variant)
+ setlogfile=ignore
+ settimedlog=ignore
else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- }
- logs.flush=ignore
- writer=function(s)
- write_nl(s)
- end
- newline=function()
- write_nl("\n")
+ local report_yes,subreport_yes,status_yes
+ local report_nop,subreport_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ }
+ logs.flush=ignore
+ writer=function(s)
+ write_nl(s)
+ end
+ newline=function()
+ write_nl("\n")
+ end
+ report=function(a,b,c,...)
+ if c then
+ write_nl(report_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(report_yes(a,b))
+ elseif a then
+ write_nl(report_nop(a))
+ else
+ write_nl("")
end
- report=function(a,b,c,...)
- if c then
- write_nl(report_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(report_yes(a,b))
- elseif a then
- write_nl(report_nop(a))
- else
- write_nl("")
- end
+ end
+ subreport=function(a,sub,b,c,...)
+ if c then
+ write_nl(subreport_yes(a,sub,formatters[b](c,...)))
+ elseif b then
+ write_nl(subreport_yes(a,sub,b))
+ elseif a then
+ write_nl(subreport_nop(a,sub))
+ else
+ write_nl("")
end
- subreport=function(a,sub,b,c,...)
- if c then
- write_nl(subreport_yes(a,sub,formatters[b](c,...)))
- elseif b then
- write_nl(subreport_yes(a,sub,b))
- elseif a then
- write_nl(subreport_nop(a,sub))
- else
- write_nl("")
+ end
+ status=function(a,b,c,...)
+ if c then
+ write_nl(status_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(status_yes(a,b))
+ elseif a then
+ write_nl(status_nop(a))
+ else
+ write_nl("\n")
+ end
+ end
+ direct=ignore
+ subdirect=ignore
+ settarget=ignore
+ pushtarget=ignore
+ poptarget=ignore
+ setformats=ignore
+ settranslations=ignore
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(f(s))
+ end
+ end
+ setformatters=function(specification)
+ local f=nil
+ local d=variants.default
+ if specification then
+ if type(specification)=="table" then
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ f=v.formats
end
+ end
end
- status=function(a,b,c,...)
- if c then
- write_nl(status_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(status_yes(a,b))
- elseif a then
- write_nl(status_nop(a))
- else
- write_nl("\n")
- end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
- local writeline=write_nl
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ end
+ setformatters(variant)
+ setlogfile=function(name,keepopen)
+ if name and name~="" then
+ local localtime=os.localtime
+ local writeline=write_nl
+ if keepopen then
+ local f=io.open(name,"ab")
write_nl=function(s)
- writeline(f(s))
- end
- end
- setformatters=function(specification)
- local f=nil
- local d=variants.default
- if specification then
- if type(specification)=="table" then
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- f=v.formats
- end
- end
- end
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
- if name and name~="" then
- local localtime=os.localtime
- local writeline=write_nl
- if keepopen then
- local f=io.open(name,"ab")
- write_nl=function(s)
- writeline(s)
- f:write(localtime()," | ",s,"\n")
- end
- else
- write_nl=function(s)
- writeline(s)
- local f=io.open(name,"ab")
- f:write(localtime()," | ",s,"\n")
- f:close()
- end
- end
+ writeline(s)
+ f:write(localtime()," | ",s,"\n")
end
- setlogfile=ignore
- end
- settimedlog=function()
- local localtime=os.localtime
- local writeline=write_nl
+ else
write_nl=function(s)
- writeline(localtime().." | "..s)
+ writeline(s)
+ local f=io.open(name,"ab")
+ f:write(localtime()," | ",s,"\n")
+ f:close()
end
- settimedlog=ignore
+ end
end
+ setlogfile=ignore
+ end
+ settimedlog=function()
+ local localtime=os.localtime
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(localtime().." | "..s)
+ end
+ settimedlog=ignore
+ end
end
logs.report=report
logs.subreport=subreport
@@ -9727,198 +13131,186 @@ local data={}
local states=nil
local force=false
function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
- local state=states==true
- if not state and type(states)=="table" then
- for c,_ in next,states do
- if find(category,c) then
- state=true
- break
- end
- end
+ local logger=data[category]
+ if not logger then
+ local state=states==true
+ if not state and type(states)=="table" then
+ for c,_ in next,states do
+ if find(category,c) then
+ state=true
+ break
end
- logger={
- reporters={},
- state=state,
- }
- data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
- if subcategory then
- reporter=function(...)
- if force or not logger.state then
- subreport(category,subcategory,...)
- end
- end
- logger.reporters[subcategory]=reporter
- else
- local tag=category
- reporter=function(...)
- if force or not logger.state then
- report(category,...)
- end
- end
- logger.reporters.default=reporter
+ end
+ end
+ logger={
+ reporters={},
+ state=state,
+ }
+ data[category]=logger
+ end
+ local reporter=logger.reporters[subcategory or "default"]
+ if not reporter then
+ if subcategory then
+ reporter=function(...)
+ if force or not logger.state then
+ subreport(category,subcategory,...)
end
+ end
+ logger.reporters[subcategory]=reporter
+ else
+ local tag=category
+ reporter=function(...)
+ if force or not logger.state then
+ report(category,...)
+ end
+ end
+ logger.reporters.default=reporter
end
- return reporter
+ end
+ return reporter
end
logs.new=logs.reporter
local ctxreport=logs.writer
function logs.setmessenger(m)
- ctxreport=m
+ ctxreport=m
end
function logs.messenger(category,subcategory)
- if subcategory then
- return function(...)
- ctxreport(subdirect(category,subcategory,...))
- end
- else
- return function(...)
- ctxreport(direct(category,...))
- end
+ if subcategory then
+ return function(...)
+ ctxreport(subdirect(category,subcategory,...))
end
+ else
+ return function(...)
+ ctxreport(direct(category,...))
+ end
+ end
end
local function setblocked(category,value)
- if category==true or category=="all" then
- category,value="*",true
- elseif category==false then
- category,value="*",false
- elseif value==nil then
- value=true
- end
- if category=="*" then
- states=value
+ if category==true or category=="all" then
+ category,value="*",true
+ elseif category==false then
+ category,value="*",false
+ elseif value==nil then
+ value=true
+ end
+ if category=="*" then
+ states=value
+ for k,v in next,data do
+ v.state=value
+ end
+ else
+ alllocked=false
+ states=settings_to_hash(category,type(states)=="table" and states or nil)
+ for c in next,states do
+ local v=data[c]
+ if v then
+ v.state=value
+ else
+ c=topattern(c,true,true)
for k,v in next,data do
+ if find(k,c) then
v.state=value
+ end
end
- else
- alllocked=false
- states=settings_to_hash(category,type(states)=="table" and states or nil)
- for c in next,states do
- local v=data[c]
- if v then
- v.state=value
- else
- c=topattern(c,true,true)
- for k,v in next,data do
- if find(k,c) then
- v.state=value
- end
- end
- end
- end
+ end
end
+ end
end
function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
+ setblocked(category,value==nil and true or value)
end
function logs.enable(category)
- setblocked(category,false)
+ setblocked(category,false)
end
function logs.categories()
- return sortedkeys(data)
+ return sortedkeys(data)
end
function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
- n=n+1
- local state=v.state
- local reporters=v.reporters
- local nc=#category
- if nc>c then
- c=nc
- end
- for subcategory,_ in next,reporters do
- local ns=#subcategory
- if ns>c then
- s=ns
- end
- local m=nc+ns
- if m>max then
- max=m
- end
- end
- local subcategories=concat(sortedkeys(reporters),", ")
- if state==true then
- state="disabled"
- elseif state==false then
- state="enabled"
- else
- state="unknown"
- end
- report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ local n,c,s,max=0,0,0,0
+ for category,v in table.sortedpairs(data) do
+ n=n+1
+ local state=v.state
+ local reporters=v.reporters
+ local nc=#category
+ if nc>c then
+ c=nc
+ end
+ for subcategory,_ in next,reporters do
+ local ns=#subcategory
+ if ns>c then
+ s=ns
+ end
+ local m=nc+ns
+ if m>max then
+ max=m
+ end
+ end
+ local subcategories=concat(sortedkeys(reporters),", ")
+ if state==true then
+ state="disabled"
+ elseif state==false then
+ state="enabled"
+ else
+ state="unknown"
end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
+ report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ end
+ report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
end
local delayed_reporters={}
setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
+ local v=logs.reporter(k.name)
+ t[k]=v
+ return v
end)
function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
+ delayed_reporters[setter](...)
end
directives.register("logs.blocked",function(v)
- setblocked(v,true)
+ setblocked(v,true)
end)
directives.register("logs.target",function(v)
- settarget(v)
+ settarget(v)
end)
if tex then
- local report=logs.reporter("pages")
- local texgetcount=tex and tex.getcount
- local real,user,sub
- function logs.start_page_number()
- real=texgetcount("realpageno")
- user=texgetcount("userpageno")
- sub=texgetcount("subpageno")
- end
- local timing=false
- local starttime=nil
- local lasttime=nil
- trackers.register("pages.timing",function(v)
- starttime=os.clock()
- timing=true
- end)
- function logs.stop_page_number()
- if timing then
- local elapsed,average
- local stoptime=os.clock()
- 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)
- else
- report("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average)
- end
- 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
- end
- logs.flush()
+ local report=logs.reporter("pages")
+ local texgetcount=tex and tex.getcount
+ local real,user,sub=0,0,0
+ function logs.start_page_number()
+ real=texgetcount("realpageno")
+ user=texgetcount("userpageno")
+ sub=texgetcount("subpageno")
+ end
+ local timing=false
+ local lasttime=nil
+ trackers.register("pages.timing",function(v)
+ timing=""
+ end)
+ function logs.stop_page_number()
+ if timing then
+ local elapsed=statistics.currenttime(statistics)
+ local average,page
+ if not lasttime or real<2 then
+ average=elapsed
+ page=elapsed
+ else
+ 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
+ report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
+ end
+ logs.flush()
+ end
end
local nesting=0
local verbose=false
@@ -9942,222 +13334,222 @@ logs.help=ignore
local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
local p_newline=lpeg.patterns.newline
local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
+ Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
)^1
local function reportlines(t,str)
- if str then
- lpegmatch(linewise,str,1,t)
- end
+ if str then
+ lpegmatch(linewise,str,1,t)
+ end
end
local function reportbanner(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- t.report()
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ t.report()
+ end
end
local function reportversion(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ end
end
local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
- reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
- for i=1,select("#",...) do
- reportlines(t,t.helpinfo[select(i,...)])
- if i<n then
- t.report()
- end
- end
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="string" then
+ reportlines(t,helpinfo)
+ elseif type(helpinfo)=="table" then
+ for i=1,select("#",...) do
+ reportlines(t,t.helpinfo[select(i,...)])
+ if i<n then
+ t.report()
+ end
end
+ end
end
local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
+ t.report()
+ reportlines(t,t.moreinfo)
end
local function reportexport(t,method)
- report(t.helpinfo)
+ report(t.helpinfo)
end
local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
+ lines=reportlines,
+ banner=reportbanner,
+ version=reportversion,
+ help=reporthelp,
+ info=reportinfo,
+ export=reportexport,
}
local exporters={
}
logs.reporters=reporters
logs.exporters=exporters
function logs.application(t)
- t.name=t.name or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
- reporters.banner(t)
- reporters.help(t,...)
- reporters.info(t)
- end
- t.export=function(...)
- reporters.export(t,...)
- end
- t.identify=function()
- reporters.banner(t)
- end
- t.version=function()
- reporters.version(t)
- end
- return t
+ t.name=t.name or "unknown"
+ t.banner=t.banner
+ t.moreinfo=moreinfo
+ t.report=logs.reporter(t.name)
+ t.help=function(...)
+ reporters.banner(t)
+ reporters.help(t,...)
+ reporters.info(t)
+ end
+ t.export=function(...)
+ reporters.export(t,...)
+ end
+ t.identify=function()
+ reporters.banner(t)
+ end
+ t.version=function()
+ reporters.version(t)
+ end
+ return t
end
local f_syslog=formatters["%s %s => %s => %s => %s\r"]
function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
- local f=openfile(whereto,"a")
- if f then
- f:write(message)
- f:close()
- break
- else
- sleep(0.1)
- end
+ local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
+ for i=1,10 do
+ local f=openfile(whereto,"a")
+ if f then
+ f:write(message)
+ f:close()
+ break
+ else
+ sleep(0.1)
end
+ end
end
local report_system=logs.reporter("system","logs")
function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
- return function(...)
- report_system("function %a is obsolete, use %a",old,new)
- loadstring(old.."="..new.." return "..old)()(...)
- end
- elseif type(o)=="table" then
- local t,m={},{}
- m.__index=function(t,k)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- return o[k]
- end
- m.__newindex=function(t,k,v)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- o[k]=v
- end
- if libraries then
- libraries.obsolete[old]=t
- end
- setmetatable(t,m)
- return t
+ local o=loadstring("return "..new)()
+ if type(o)=="function" then
+ return function(...)
+ report_system("function %a is obsolete, use %a",old,new)
+ loadstring(old.."="..new.." return "..old)()(...)
+ end
+ elseif type(o)=="table" then
+ local t,m={},{}
+ m.__index=function(t,k)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ return o[k]
+ end
+ m.__newindex=function(t,k,v)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ o[k]=v
+ end
+ if libraries then
+ libraries.obsolete[old]=t
end
+ setmetatable(t,m)
+ return t
+ end
end
if utilities then
- utilities.report=report_system
+ utilities.report=report_system
end
if tex and tex.error then
- function logs.texerrormessage(...)
- tex.error(format(...),{})
- end
+ function logs.texerrormessage(...)
+ tex.error(format(...))
+ end
else
- function logs.texerrormessage(...)
- print(format(...))
- end
+ function logs.texerrormessage(...)
+ print(format(...))
+ end
end
io.stdout:setvbuf('no')
io.stderr:setvbuf('no')
if package.helpers.report then
- package.helpers.report=logs.reporter("package loader")
+ package.helpers.report=logs.reporter("package loader")
end
if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
- return loggingerrors
- end
- directives.register("logs.errors",function(v)
- loggingerrors=v
- if type(v)=="string" then
- fatalerrors=settings_to_hash(v)
- else
- fatalerrors={}
- end
- end)
- function logs.registerfinalactions(...)
- insert(finalactions,...)
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
- target=t
- state=force
- force=true
- report=type(r)=="function" and r or logs.reporter(r)
- what=w
- pushtarget(target)
+ local finalactions={}
+ local fatalerrors={}
+ local possiblefatal={}
+ local loggingerrors=false
+ function logs.loggingerrors()
+ return loggingerrors
+ end
+ directives.register("logs.errors",function(v)
+ loggingerrors=v
+ if type(v)=="string" then
+ fatalerrors=settings_to_hash(v)
+ else
+ fatalerrors={}
+ end
+ end)
+ function logs.registerfinalactions(...)
+ insert(finalactions,...)
+ end
+ local what=nil
+ local report=nil
+ local state=nil
+ local target=nil
+ local function startlogging(t,r,w,s)
+ target=t
+ state=force
+ force=true
+ report=type(r)=="function" and r or logs.reporter(r)
+ what=w
+ pushtarget(target)
+ newline()
+ if s then
+ report("start %s: %s",what,s)
+ else
+ report("start %s",what)
+ end
+ if target=="logfile" then
+ newline()
+ end
+ return report
+ end
+ local function stoplogging()
+ if target=="logfile" then
+ newline()
+ end
+ report("stop %s",what)
+ if target=="logfile" then
+ newline()
+ end
+ poptarget()
+ state=oldstate
+ end
+ function logs.startfilelogging(...)
+ return startlogging("logfile",...)
+ end
+ logs.stopfilelogging=stoplogging
+ local done=false
+ function logs.starterrorlogging(r,w,...)
+ if not done then
+ pushtarget("terminal")
+ newline()
+ logs.report("error logging","start possible issues")
+ poptarget()
+ done=true
+ end
+ if fatalerrors[w] then
+ possiblefatal[w]=true
+ end
+ return startlogging("terminal",r,w,...)
+ end
+ logs.stoperrorlogging=stoplogging
+ function logs.finalactions()
+ if #finalactions>0 then
+ for i=1,#finalactions do
+ finalactions[i]()
+ end
+ if done then
+ pushtarget("terminal")
newline()
- if s then
- report("start %s: %s",what,s)
- else
- report("start %s",what)
- end
- if target=="logfile" then
- newline()
- end
- return report
- end
- local function stoplogging()
- if target=="logfile" then
- newline()
- end
- report("stop %s",what)
- if target=="logfile" then
- newline()
- end
+ logs.report("error logging","stop possible issues")
poptarget()
- state=oldstate
- end
- function logs.startfilelogging(...)
- return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
- if not done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","start possible issues")
- poptarget()
- done=true
- end
- if fatalerrors[w] then
- possiblefatal[w]=true
- end
- return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
- if #finalactions>0 then
- for i=1,#finalactions do
- finalactions[i]()
- end
- if done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","stop possible issues")
- poptarget()
- end
- return next(possiblefatal) and sortedkeys(possiblefatal) or false
- end
+ end
+ return next(possiblefatal) and sortedkeys(possiblefatal) or false
end
+ end
end
@@ -10167,14 +13559,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
--- original size: 8097, stripped down to: 5534
+-- original size: 9072, stripped down to: 6055
if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.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 trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber,select=type,tonumber,select
local format,lower,find=string.format,string.lower,string.find
@@ -10189,161 +13581,191 @@ statistics.enable=true
statistics.threshold=0.01
local statusinfo,n,registered,timers={},0,{},{}
setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0 }
- t[k]=v
- return v
+ local v={ timing=0,loadtime=0 }
+ t[k]=v
+ return v
end)
local function hastiming(instance)
- return instance and timers[instance]
+ return instance and timers[instance]
end
local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0 }
+ timers[instance or "notimer"]={ timing=0,loadtime=0 }
end
local ticks=clock
local seconds=function(n) return n or 0 end
-local function starttiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it==0 then
- timer.starttime=ticks()
- if not timer.loadtime then
- timer.loadtime=0
- end
- end
- timer.timing=it+1
+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
+ timer.loadtime=0
+ end
+ end
+ timer.timing=it+1
end
local function stoptiming(instance)
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ local stoptime=ticks()
+ local loadtime=stoptime-starttime
+ timer.stoptime=stoptime
+ timer.loadtime=timer.loadtime+loadtime
+ timer.timing=0
+ timer.starttime=0
+ return loadtime
+ end
+ end
+ return 0
+end
+local function elapsed(instance)
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime) or 0
+ 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
- timer.timing=it-1
else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- local stoptime=ticks()
- local loadtime=stoptime-starttime
- timer.stoptime=stoptime
- timer.loadtime=timer.loadtime+loadtime
- timer.timing=0
- timer.starttime=0
- return loadtime
- end
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ return seconds(timer.loadtime+ticks()-starttime)
+ end
end
return 0
-end
-local function elapsed(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- return timer and seconds(timer.loadtime) or 0
- end
+ end
end
local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
+ return format("%0.3f",elapsed(instance))
end
local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
+ return elapsed(instance)>statistics.threshold
end
local function elapsedseconds(instance,rest)
- if elapsedindeed(instance) then
- return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
end
statistics.hastiming=hastiming
statistics.resettiming=resettiming
statistics.starttiming=starttiming
statistics.stoptiming=stoptiming
+statistics.currenttime=currenttime
statistics.elapsed=elapsed
statistics.elapsedtime=elapsedtime
statistics.elapsedindeed=elapsedindeed
statistics.elapsedseconds=elapsedseconds
function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
- local rt=registered[tag] or (#statusinfo+1)
- statusinfo[rt]={ tag,fnc }
- registered[tag]=rt
- if #tag>n then n=#tag end
- end
+ if statistics.enable and type(fnc)=="function" then
+ local rt=registered[tag] or (#statusinfo+1)
+ statusinfo[rt]={ tag,fnc }
+ registered[tag]=rt
+ if #tag>n then n=#tag end
+ end
end
local report=logs.reporter("mkiv lua stats")
function statistics.show()
- if statistics.enable then
- local register=statistics.register
- register("used platform",function()
- return format("%s, type: %s, binary subtree: %s",
- os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
- end)
- register("used engine",function()
- return format("%s version %s with functionality level %s, banner: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
- end)
- register("control sequences",function()
- return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
- end)
- register("callbacks",statistics.callbacks)
- if TEXENGINE=="luajittex" and JITSUPPORTED then
- local jitstatus=jit.status
- if jitstatus then
- local jitstatus={ jitstatus() }
- if jitstatus[1] then
- register("luajit options",concat(jitstatus," ",2))
- end
- end
- end
- register("lua properties",function()
- local hashchar=tonumber(status.luatex_hashchars)
- local hashtype=status.luatex_hashtype
- local mask=lua.mask or "ascii"
- return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
- jit and "luajit" or "lua",
- LUAVERSION,
- statistics.memused(),
- hashtype or "default",
- hashchar and 2^hashchar or "unknown",
- mask,
- mask=="utf" and "τεχ" or "tex")
- end)
- register("runtime",statistics.runtime)
- logs.newline()
- for i=1,#statusinfo do
- local s=statusinfo[i]
- local r=s[2]()
- if r then
- report("%s: %s",s[1],r)
- end
+ if statistics.enable then
+ local register=statistics.register
+ register("used platform",function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+ end)
+ register("used engine",function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+ end)
+ register("control sequences",function()
+ return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+ end)
+ register("callbacks",statistics.callbacks)
+ if TEXENGINE=="luajittex" and JITSUPPORTED then
+ local jitstatus=jit.status
+ if jitstatus then
+ local jitstatus={ jitstatus() }
+ if jitstatus[1] then
+ register("luajit options",concat(jitstatus," ",2))
end
- statistics.enable=false
+ end
end
+ register("lua properties",function()
+ local hashchar=tonumber(status.luatex_hashchars)
+ local hashtype=status.luatex_hashtype
+ local mask=lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashtype or "default",
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask=="utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline()
+ for i=1,#statusinfo do
+ local s=statusinfo[i]
+ local r=s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
+ end
+ statistics.enable=false
+ end
end
function statistics.memused()
- local round=math.round or math.floor
- return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+ local round=math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
end
starttiming(statistics)
function statistics.formatruntime(runtime)
- return format("%s seconds",runtime)
+ return format("%s seconds",runtime)
end
function statistics.runtime()
- stoptiming(statistics)
- return statistics.formatruntime(elapsedtime(statistics))
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report=logs.reporter("system")
-function statistics.timed(action)
- starttiming("run")
- action()
- stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("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
function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
- local name=select(i,...)
- local stat={}
- local func=base[name]
- setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
- base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
- statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
+ for i=1,select("#",...) do
+ local name=select(i,...)
+ local stat={}
+ local func=base[name]
+ setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+ base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
end
@@ -10353,144 +13775,144 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5841, stripped down to: 3511
+-- original size: 5841, stripped down to: 3352
if not modules then modules={} end modules ['trac-pro']={
- 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 getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
+local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
local namespaces=namespaces
local registered={}
local function report_index(k,name)
- if trace_namespaces then
- report_system("reference to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("reference to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("reference to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("reference to %a in protected namespace %a",k,name)
+ end
end
local function report_newindex(k,name)
- if trace_namespaces then
- report_system("assignment to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("assignment to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("assignment to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("assignment to %a in protected namespace %a",k,name)
+ end
end
local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
- return
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
- m={}
- setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
- if not index[k] then
- index[k]=true
- report_index(k,name)
- end
- return nil
+ local data=name=="global" and _G or _G[name]
+ if not data then
+ return
+ end
+ registered[name]=data
+ local m=getmetatable(data)
+ if not m then
+ m={}
+ setmetatable(data,m)
+ end
+ local index,newindex={},{}
+ m.__saved__index=m.__index
+ m.__no__index=function(t,k)
+ if not index[k] then
+ index[k]=true
+ report_index(k,name)
end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
- if not newindex[k] then
- newindex[k]=true
- report_newindex(k,name)
- end
- rawset(t,k,v)
+ return nil
+ end
+ m.__saved__newindex=m.__newindex
+ m.__no__newindex=function(t,k,v)
+ if not newindex[k] then
+ newindex[k]=true
+ report_newindex(k,name)
end
- m.__protection__depth=0
+ rawset(t,k,v)
+ end
+ m.__protection__depth=0
end
local function private(name)
- local data=registered[name]
+ local data=registered[name]
+ if not data then
+ data=_G[name]
if not data then
- data=_G[name]
- if not data then
- data={}
- _G[name]=data
- end
- register(name)
+ data={}
+ _G[name]=data
end
- return data
+ register(name)
+ end
+ return data
end
local function protect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
- m.__protection__depth=pd+1
- else
- m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
- m.__index,m.__newindex=m.__no__index,m.__no__newindex
- m.__protection__depth=1
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>0 then
+ m.__protection__depth=pd+1
+ else
+ m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
+ m.__index,m.__newindex=m.__no__index,m.__no__newindex
+ m.__protection__depth=1
+ end
end
local function unprotect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
- m.__protection__depth=pd-1
- else
- m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
- m.__protection__depth=0
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>1 then
+ m.__protection__depth=pd-1
+ else
+ m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
+ m.__protection__depth=0
+ end
end
local function protectall()
- for name,_ in next,registered do
- if name~="global" then
- protect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ protect(name)
end
+ end
end
local function unprotectall()
- for name,_ in next,registered do
- if name~="global" then
- unprotect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ unprotect(name)
end
+ end
end
-namespaces.register=register
-namespaces.private=private
+namespaces.register=register
+namespaces.private=private
namespaces.protect=protect
namespaces.unprotect=unprotect
namespaces.protectall=protectall
namespaces.unprotectall=unprotectall
namespaces.private("namespaces") registered={} register("global")
directives.register("system.protect",function(v)
- if v then
- protectall()
- else
- unprotectall()
- end
+ if v then
+ protectall()
+ else
+ unprotectall()
+ end
end)
directives.register("system.checkglobals",function(v)
- if v then
- report_system("enabling global namespace guard")
- protect("global")
- else
- report_system("disabling global namespace guard")
- unprotect("global")
- end
+ if v then
+ report_system("enabling global namespace guard")
+ protect("global")
+ else
+ report_system("disabling global namespace guard")
+ unprotect("global")
+ end
end)
@@ -10500,15 +13922,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lua"] = package.loaded["util-lua"] or true
--- original size: 6621, stripped down to: 4764
+-- original size: 6664, stripped down to: 4589
if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -10519,150 +13941,151 @@ local report_lua=logs.reporter("system","lua")
local report_mem=logs.reporter("system","lua memory")
local tracestripping=false
local tracememory=false
-luautilities.stripcode=true
+luautilities.stripcode=true
luautilities.alwaysstripcode=false
luautilities.nofstrippedchunks=0
luautilities.nofstrippedbytes=0
local strippedchunks={}
luautilities.strippedchunks=strippedchunks
luautilities.suffixes={
- tma="tma",
- tmc=jit and "tmb" or "tmc",
- lua="lua",
- luc=jit and "lub" or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc="tuc",
+ tma="tma",
+ tmc=jit and "tmb" or "tmc",
+ lua="lua",
+ luc=jit and "lub" or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
}
local function register(name)
- if tracestripping then
- report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
end
local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
- code=load(code)
- if code then
- code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
- if code and code~="" then
- register(name)
- io.savedata(lucfile,code)
- return true,0
- end
- else
- report_lua("fatal error %a in file %a",1,luafile)
- end
- else
- report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
-end
-function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
- macros=lua.macros
- end
- local code,message
- if macros then
- code,message=macros.loaded(fullname,true,false)
- else
- code,message=loadfile(fullname)
- end
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+ code=load(code)
if code then
- code()
- else
- report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip)=="function" then
- forcestrip=forcestrip(fullname)
- end
- if forcestrip or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
- elseif luautilities.alwaysstripcode then
+ code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code~="" then
register(name)
- return load(dump(code,true)),0
+ io.savedata(lucfile,code)
+ return true,0
+ end
else
- return code,0
+ report_lua("fatal error %a in file %a",1,luafile)
end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
+end
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ name=name or fullname
+ if macros then
+ macros=lua.macros
+ end
+ local code,message
+ if macros then
+ code,message=macros.loaded(fullname,true,false)
+ else
+ code,message=loadfile(fullname)
+ end
+ if code then
+ 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
+ forcestrip=forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.strippedloadstring(code,name,forcestrip)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.loadstring(code,name)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
end
function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
- report_lua("dumping %a into %a stripped",luafile,lucfile)
- if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
- report_lua("removing %a",luafile)
- os.remove(luafile)
- end
- end
- return done
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
end
function luautilities.loadstripped(...)
- local l=load(...)
- if l then
- return load(dump(l,true))
- end
+ local l=load(...)
+ if l then
+ return load(dump(l,true))
+ end
end
local finalizers={}
setmetatable(finalizers,{
- __gc=function(t)
- for i=1,#t do
- pcall(t[i])
- end
+ __gc=function(t)
+ for i=1,#t do
+ pcall(t[i])
end
+ end
} )
function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
+ finalizers[#finalizers+1]=f
end
function luautilities.checkmemory(previous,threshold,trace)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- local delta=current-previous
- if current-previous>checked then
- 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",
- 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",
- previous/1024,current/1024,delta/1024,threshold)
- end
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ local delta=current-previous
+ if current-previous>checked then
+ collectgarbage("collect")
+ local afterwards=collectgarbage("count")
+ if trace or tracememory then
+ 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 %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
end
- return current
+ end
+ return current
end
@@ -10672,17 +14095,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 8984, stripped down to: 6573
+-- original size: 9955, stripped down to: 6693
if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- 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 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
@@ -10700,228 +14121,266 @@ local names={}
local initialize=false
if not (FFISUPPORTED and ffi) then
elseif os.type=="windows" then
- initialize=function()
- local kernel=ffilib("kernel32","system")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
+ initialize=function()
+ local kernel=ffilib("kernel32","system")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
int QueryPerformanceFrequency(int64_t *lpFrequency);
int QueryPerformanceCounter(int64_t *lpPerformanceCount);
]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
end
- initialize=false
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
end
+ initialize=false
+ end
elseif os.type=="unix" then
- initialize=function()
- local C=ffi.C
- local tonumber=ffi.number or tonumber
- ffi.cdef [[
+ initialize=function()
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ ffi.cdef [[
/* what a mess */
typedef int clk_id_t;
typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
typedef struct timespec { long sec; long nsec; } ctx_timespec;
int clock_gettime(clk_id_t timerid, struct timespec *t);
]]
- local target=ffi.new("ctx_timespec[?]",1)
- local clock=C.CLOCK_PROCESS_CPUTIME_ID
- ticks=function ()
- C.clock_gettime(clock,target)
- return tonumber(target[0].sec*1000000000+target[0].nsec)
- end
- seconds=function(ticks)
- return ticks/1000000000
- end
- initialize=false
+ local target=ffi.new("ctx_timespec[?]",1)
+ local clock=C.CLOCK_PROCESS_CPUTIME_ID
+ ticks=function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
+ end
+ seconds=function(ticks)
+ return ticks/1000000000
end
+ initialize=false
+ end
end
setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
- local v=setmetatableindex(function(t,line)
- local v={ total=0,count=0 }
- t[line]=v
- return v
- end)
- t[source]=v
- return v
+ local v=setmetatableindex(function(t,source)
+ local v=setmetatableindex(function(t,line)
+ local v={ total=0,count=0,nesting=0 }
+ t[line]=v
+ return v
end)
- t[name]=v
+ t[source]=v
return v
+ end)
+ t[name]=v
+ return v
end)
+local getinfo=nil
+local sethook=nil
local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
- local source=f.short_src
- if not source then
- return
- end
- local line=f.linedefined or 0
- local name=f.name
- if not name then
- local what=f.what
- if what=="C" then
- name="<anonymous>"
- else
- name=f.namewhat or what or "<unknown>"
- end
- end
- local data=names[name][source][line]
- if where=="call" then
- data.count=data.count+1
- insert(data,ticks())
- elseif where=="return" then
- local t=remove(data)
- if t then
- data.total=data.total+ticks()-t
- end
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
+ end
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ 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 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
end
function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
- for source,lines in next,sources do
- for line,data in next,lines do
- local count=data.count
- if count>threshold then
- if #name>length then
- length=#name
- end
- local total=data.total
- local real=total
- if real>0 then
- real=total-(count*overhead/dummycalls)
- if real<0 then
- real=0
- end
- realtime=realtime+real
- end
- totaltime=totaltime+total
- if line<0 then
- line=0
- end
- dataset[#dataset+1]={ real,total,count,name,source,line }
- end
- end
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ local count=data.count
+ if count>threshold then
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ realtime=realtime+real
+ end
+ totaltime=totaltime+total
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
end
+ end
end
- sort(dataset,function(a,b)
- if a[1]==b[1] then
- if a[2]==b[2] then
- if a[3]==b[3] then
- if a[4]==b[4] then
- if a[5]==b[5] then
- return a[6]<b[6]
- else
- return a[5]<b[5]
- end
- else
- return a[4]<b[4]
- end
- else
- return b[3]<a[3]
- end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
else
- return b[2]<a[2]
+ return a[5]<b[5]
end
+ else
+ return a[4]<b[4]
+ end
else
- return b[1]<a[1]
+ return b[3]<a[3]
end
- end)
- if length>50 then
- length=50
- end
- local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
- for i=1,#dataset do
- local data=dataset[i]
- local real=data[1]
- local total=data[2]
- local count=data[3]
- local name=data[4]
- local source=data[5]
- local line=data[6]
- calls=calls+count
- functions=functions+1
- name=gsub(name,"%s+"," ")
- if #name>length then
- name=sub(name,1,length)
- end
- printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls : %i",calls))
- printer(format("overhead : %f",seconds(overhead/1000)))
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
+ end
+ local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
+ for i=1,#dataset do
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ calls=calls+count
+ functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
+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
- debugger.showstats(function(str) f:write(str,"\n") end,threshold)
- f:close()
- end
+ local f=io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
end
function debugger.enable()
- if nesting==0 then
- running=true
- if initialize then
- initialize()
- end
- sethook(hook,"cr")
- local function dummy() end
- local t=ticks()
- for i=1,dummycalls do
- dummy()
- end
- overhead=ticks()-t
- end
- if nesting>0 then
- nesting=nesting+1
- end
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- if nesting>0 then
- nesting=nesting-1
- end
- if nesting==0 then
- sethook()
- end
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
+ getdebug()
+ if getinfo then
local level=2
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
+ 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
+ end
end
debugger.showtraceback=showtraceback
@@ -10932,91 +14391,91 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7112, stripped down to: 3988
+-- original size: 7112, stripped down to: 3887
if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ 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.templates=utilities.templates or {}
local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
- if trace_template then
- report_template("unknown key %a",k)
- end
- return ""
+ local v=t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v=tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
else
- v=tostring(v)
- if trace_template then
- report_template("setting key %a to value %a",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t,how,recursive)
- else
- return v
- end
+ return v
end
+ end
end
local sqlescape=lpeg.replacer {
- { "'","''" },
- { "\\","\\\\" },
- { "\r\n","\\n" },
- { "\r","\\n" },
+ { "'","''" },
+ { "\\","\\\\" },
+ { "\r\n","\\n" },
+ { "\r","\\n" },
}
local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
lpegpatterns.sqlescape=sqlescape
lpegpatterns.sqlquoted=sqlquoted
local luaescape=lpegpatterns.luaescape
local escapers={
- lua=function(s)
- return lpegmatch(luaescape,s)
- end,
- sql=function(s)
- return lpegmatch(sqlescape,s)
- end,
+ lua=function(s)
+ return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlescape,s)
+ end,
}
local quotedescapers={
- lua=function(s)
- return format("%q",s)
- end,
- sql=function(s)
- return lpegmatch(sqlquoted,s)
- end,
+ lua=function(s)
+ return format("%q",s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
}
local luaescaper=escapers.lua
local quotedluaescaper=quotedescapers.lua
local function replacekeyunquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and escapers[how] or luaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replacekeyquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and quotedescapers[how] or quotedluaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
end
-local single=P("%")
+local single=P("%")
local double=P("%%")
local lquoted=P("%[")
local rquoted=P("]%")
@@ -11033,41 +14492,41 @@ local noloptional=P("%?")/''
local noroptional=P("?%")/''
local nomoptional=P(":")/''
local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
local any=P(1)
replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
local function replace(str,mapping,how,recurse)
- if mapping and str then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
end
templates.replace=replace
function templates.replacer(str,how,recurse)
- return function(mapping)
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
end
function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
end
function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping=t
- end
- for k,v in next,t do
- t[k]=replace(v,mapping,how,recurse)
- end
- return t
+ if not mapping then
+ mapping=t
+ end
+ for k,v in next,t do
+ t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
end
@@ -11077,14 +14536,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
--- original size: 20393, stripped down to: 13924
+-- original size: 20393, stripped down to: 13121
if not modules then modules={} end modules ['util-sbx']={
- 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 sandbox then require("l-sandbox") end
local next,type=next,type
@@ -11117,144 +14576,144 @@ local report=logs.reporter("sandbox")
trackers.register("sandbox",function(v) trace=v end)
sandbox.setreporter(report)
sandbox.finalizer {
- category="files",
- action=function()
- finalized=true
- end
+ category="files",
+ action=function()
+ finalized=true
+ end
}
local function registerroot(root,what)
- if finalized then
- report("roots are already finalized")
- else
- if type(root)=="table" then
- root,what=root[1],root[2]
- end
- if type(root)=="string" and root~="" then
- root=collapsepath(expandname(root))
- if what=="r" or what=="ro" or what=="readable" then
- what="read"
- elseif what=="w" or what=="wo" or what=="writable" then
- what="write"
- end
- validroots[root]=what=="write" or false
- end
+ if finalized then
+ report("roots are already finalized")
+ else
+ if type(root)=="table" then
+ root,what=root[1],root[2]
+ end
+ if type(root)=="string" and root~="" then
+ root=collapsepath(expandname(root))
+ if what=="r" or what=="ro" or what=="readable" then
+ what="read"
+ elseif what=="w" or what=="wo" or what=="writable" then
+ what="write"
+ end
+ validroots[root]=what=="write" or false
end
+ end
end
sandbox.finalizer {
- category="files",
- action=function()
+ category="files",
+ action=function()
+ if p_validroot then
+ report("roots are already initialized")
+ else
+ sandbox.registerroot(".","write")
+ for name in sortedhash(validroots) do
if p_validroot then
- report("roots are already initialized")
+ p_validroot=P(name)+p_validroot
else
- sandbox.registerroot(".","write")
- for name in sortedhash(validroots) do
- if p_validroot then
- p_validroot=P(name)+p_validroot
- else
- p_validroot=P(name)
- end
- end
- p_validroot=p_validroot/validroots
+ p_validroot=P(name)
end
+ end
+ p_validroot=p_validroot/validroots
end
+ end
}
local function registerbinary(name)
- if finalized then
- report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validbinaries then
- return
- end
- if validbinaries==true then
- validbinaries={ [name]=true }
- else
- validbinaries[name]=true
- end
- elseif name==true then
- validbinaries={}
+ if finalized then
+ report("binaries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validbinaries then
+ return
+ end
+ if validbinaries==true then
+ validbinaries={ [name]=true }
+ else
+ validbinaries[name]=true
end
+ elseif name==true then
+ validbinaries={}
+ end
end
local function registerlibrary(name)
- if finalized then
- report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validlibraries then
- return
- end
- if validlibraries==true then
- validlibraries={ [nameonly(name)]=true }
- else
- validlibraries[nameonly(name)]=true
- end
- elseif name==true then
- validlibraries={}
+ if finalized then
+ report("libraries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validlibraries then
+ return
+ end
+ if validlibraries==true then
+ validlibraries={ [nameonly(name)]=true }
+ else
+ validlibraries[nameonly(name)]=true
end
+ elseif name==true then
+ validlibraries={}
+ end
end
local p_write=S("wa") p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
+local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
local function normalized(name)
- if platform=="windows" then
- name=gsub(name,"/","\\")
- end
- return name
+ if platform=="windows" then
+ name=gsub(name,"/","\\")
+ end
+ return name
end
function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
+ return lpegmatch(p_path,name) and true or false
end
local filenamelogger=false
function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
+ filenamelogger=type(l)=="function" and l or false
end
local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
- local asked=collapsepath(expandname(name))
- local okay=lpegmatch(p_validroot,asked)
- if okay==true then
- if filenamelogger then
- filenamelogger(name,"w",asked,true)
- end
- return name
- elseif okay==false then
- if not what then
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- elseif lpegmatch(p_write,what) then
- if filenamelogger then
- filenamelogger(name,"w",asked,false)
- end
- return
- else
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- end
- elseif filenamelogger then
- filenamelogger(name,"*",name,false)
+ if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
+ local asked=collapsepath(expandname(name))
+ local okay=lpegmatch(p_validroot,asked)
+ if okay==true then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,true)
+ end
+ return name
+ elseif okay==false then
+ if not what then
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
end
- else
return name
+ elseif lpegmatch(p_write,what) then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,false)
+ end
+ return
+ else
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
+ end
+ return name
+ end
+ elseif filenamelogger then
+ filenamelogger(name,"*",name,false)
end
+ else
+ return name
+ end
end
local function readable(name,finalized)
- return validfilename(name,"r")
+ return validfilename(name,"r")
end
local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"r")
+ if valid then
+ return normalized(valid)
+ end
end
local function writeable(name,finalized)
- return validfilename(name,"w")
+ return validfilename(name,"w")
end
local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"w")
+ if valid then
+ return normalized(valid)
+ end
end
validators.readable=readable
validators.writeable=normalizedwriteable
@@ -11262,316 +14721,316 @@ validators.normalizedreadable=normalizedreadable
validators.normalizedwriteable=writeable
validators.filename=readable
table.setmetatableindex(validators,function(t,k)
- if k then
- t[k]=readable
- end
- return readable
+ if k then
+ t[k]=readable
+ end
+ return readable
end)
function validators.string(s,finalized)
- if finalized and suspicious(s) then
- return ""
- else
- return s
- end
+ if finalized and suspicious(s) then
+ return ""
+ else
+ return s
+ end
end
function validators.cache(s)
- if finalized then
- return basename(s)
- else
- return s
- end
+ if finalized then
+ return basename(s)
+ else
+ return s
+ end
end
function validators.url(s)
- if finalized and find("^file:") then
- return ""
- else
- return s
- end
+ if finalized and find("^file:") then
+ return ""
+ else
+ return s
+ end
end
local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
+ else
+ end
end
local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
- local checkedtwo=validfilename(two)
- if checkedtwo then
- return action(one,two,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ local checkedtwo=validfilename(two)
+ if checkedtwo then
+ return action(one,two,...)
else
end
+ else
+ end
end
local function iohandler(action,one,...)
- if type(one)=="string" then
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- end
- elseif one then
- return action(one,...)
- else
- return action()
+ if type(one)=="string" then
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
end
+ elseif one then
+ return action(one,...)
+ else
+ return action()
+ end
end
local osexecute=sandbox.original(os.execute)
local iopopen=sandbox.original(io.popen)
local reported={}
local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
- if variables then
- for variable,value in next,variables do
- local checker=validators[checkers[variable]]
- if checker then
- value=checker(unquoted(value),strict)
- if value then
- variables[variable]=optionalquoted(value)
- else
- report("variable %a with value %a fails the check",variable,value)
- return
- end
- else
- report("variable %a has no checker",variable)
- return
- end
- end
- for variable,default in next,defaults do
- local value=variables[variable]
- if not value or value=="" then
- local checker=validators[checkers[variable]]
- if checker then
- default=checker(unquoted(default),strict)
- if default then
- variables[variable]=optionalquoted(default)
- else
- report("variable %a with default %a fails the check",variable,default)
- return
- end
- end
- end
- end
- end
- local command=program.." "..replace(template,variables)
- if reporter then
- reporter("executing runner %a: %s",name,command)
- elseif trace then
- report("executing runner %a: %s",name,command)
- end
- return command
- elseif not reported[name] then
- report("executing program %a of runner %a is not permitted",program,name)
- reported[name]=true
- end
-end
-local runners={
- resultof=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("resultof: %s",command)
- end
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- end
- end
- end,
- execute=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("execute: %s",command)
- end
- return osexecute(command)
+ if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
+ if variables then
+ for variable,value in next,variables do
+ local checker=validators[checkers[variable]]
+ if checker then
+ value=checker(unquoted(value),strict)
+ if value then
+ variables[variable]=optionalquoted(value)
+ else
+ report("variable %a with value %a fails the check",variable,value)
+ return
+ end
+ else
+ report("variable %a has no checker",variable)
+ return
end
- end,
- pipeto=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("pipeto: %s",command)
+ end
+ for variable,default in next,defaults do
+ local value=variables[variable]
+ if not value or value=="" then
+ local checker=validators[checkers[variable]]
+ if checker then
+ default=checker(unquoted(default),strict)
+ if default then
+ variables[variable]=optionalquoted(default)
+ else
+ report("variable %a with default %a fails the check",variable,default)
+ return
end
- return iopopen(command,"w")
- end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
- local wrapped=validrunners[specification]
- inspect(table.sortedkeys(validrunners))
- if wrapped then
- return wrapped
- else
- report("unknown predefined runner %a",specification)
- return
+ end
end
+ end
end
- if type(specification)~="table" then
- report("specification should be a table (or string)")
- return
- end
- local name=specification.name
- if type(name)~="string" then
- report("invalid name, string expected",name)
- return
- end
- if validrunners[name] then
- report("invalid name, runner %a already defined")
- return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
- program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
- report("invalid runner %a specified for platform %a",name,platform)
- return
+ local command=program.." "..replace(template,variables)
+ if reporter then
+ reporter("executing runner %a: %s",name,command)
+ elseif trace then
+ report("executing runner %a: %s",name,command)
end
- local template=specification.template
- if not template then
- report("missing template for runner %a",name)
- return
+ return command
+ elseif not reported[name] then
+ report("executing program %a of runner %a is not permitted",program,name)
+ reported[name]=true
+ end
+end
+local runners={
+ resultof=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("resultof: %s",command)
+ end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ end
end
- local method=specification.method or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
- local finalized=finalized
- local wrapped=function(variables)
- return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
- end
- validrunners[name]=wrapped
- return wrapped
- else
- validrunners[name]=nil
- report("invalid method for runner %a",name)
+ end,
+ execute=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("execute: %s",command)
+ end
+ return osexecute(command)
+ end
+ end,
+ pipeto=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("pipeto: %s",command)
+ end
+ return iopopen(command,"w")
end
+ end,
+}
+function sandbox.registerrunner(specification)
+ if type(specification)=="string" then
+ local wrapped=validrunners[specification]
+ inspect(table.sortedkeys(validrunners))
+ if wrapped then
+ return wrapped
+ else
+ report("unknown predefined runner %a",specification)
+ return
+ end
+ end
+ if type(specification)~="table" then
+ report("specification should be a table (or string)")
+ return
+ end
+ local name=specification.name
+ if type(name)~="string" then
+ report("invalid name, string expected",name)
+ return
+ end
+ if validrunners[name] then
+ report("invalid name, runner %a already defined")
+ return
+ end
+ local program=specification.program
+ if type(program)=="string" then
+ elseif type(program)=="table" then
+ program=program[platform] or program.default or program.unix
+ end
+ if type(program)~="string" or program=="" then
+ report("invalid runner %a specified for platform %a",name,platform)
+ return
+ end
+ local template=specification.template
+ if not template then
+ report("missing template for runner %a",name)
+ return
+ end
+ local method=specification.method or "execute"
+ local checkers=specification.checkers or {}
+ local defaults=specification.defaults or {}
+ local runner=runners[method]
+ if runner then
+ local finalized=finalized
+ local wrapped=function(variables)
+ return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
+ end
+ validrunners[name]=wrapped
+ return wrapped
+ else
+ validrunners[name]=nil
+ report("invalid method for runner %a",name)
+ end
end
function sandbox.getrunner(name)
- return name and validrunners[name]
+ return name and validrunners[name]
end
local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
+ return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
end
local function binaryrunner(action,command,...)
- if validbinaries==false then
- report("no binaries permitted, ignoring command: %s",command)
- return
- end
- if type(command)~="string" then
- report("command should be a string")
- return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
- report("unable to filter binary from command: %s",command)
- return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
- report("binary not permitted, ignoring command: %s",command)
- return
- elseif suspicious(command) then
- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
- return
- end
- return action(command,...)
+ if validbinaries==false then
+ report("no binaries permitted, ignoring command: %s",command)
+ return
+ end
+ if type(command)~="string" then
+ report("command should be a string")
+ return
+ end
+ local program=lpegmatch(p_split,command)
+ if not program or program=="" then
+ report("unable to filter binary from command: %s",command)
+ return
+ end
+ if validbinaries==true then
+ elseif not validbinaries[program] then
+ report("binary not permitted, ignoring command: %s",command)
+ return
+ elseif suspicious(command) then
+ report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
+ return
+ end
+ return action(command,...)
end
local function dummyrunner(action,command,...)
- if type(command)=="table" then
- command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
+ if type(command)=="table" then
+ command=concat(command," ",command[0] and 0 or 1)
+ end
+ report("ignoring command: %s",command)
end
sandbox.filehandlerone=filehandlerone
sandbox.filehandlertwo=filehandlertwo
sandbox.iohandler=iohandler
function sandbox.disablerunners()
- validbinaries=false
+ validbinaries=false
end
function sandbox.disablelibraries()
- validlibraries=false
+ validlibraries=false
end
if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
- validlibraries=false
- for k,v in next,ffi do
- if k~="gc" then
- ffi[k]=nil
- end
- end
+ function sandbox.disablelibraries()
+ validlibraries=false
+ for k,v in next,ffi do
+ if k~="gc" then
+ ffi[k]=nil
+ end
end
- local fiiload=ffi.load
- if fiiload then
- local reported={}
- function ffi.load(name,...)
- if validlibraries==false then
- elseif validlibraries==true then
- return fiiload(name,...)
- elseif validlibraries[nameonly(name)] then
- return fiiload(name,...)
- else
- end
- if not reported[name] then
- report("using library %a is not permitted",name)
- reported[name]=true
- end
- return nil
- end
+ end
+ local fiiload=ffi.load
+ if fiiload then
+ local reported={}
+ function ffi.load(name,...)
+ if validlibraries==false then
+ elseif validlibraries==true then
+ return fiiload(name,...)
+ elseif validlibraries[nameonly(name)] then
+ return fiiload(name,...)
+ else
+ end
+ if not reported[name] then
+ report("using library %a is not permitted",name)
+ reported[name]=true
+ end
+ return nil
end
+ end
end
local overload=sandbox.overload
local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile")
+ overload(loadfile,filehandlerone,"loadfile")
if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
+ overload(io.open,filehandlerone,"io.open")
+ overload(io.popen,binaryrunner,"io.popen")
+ overload(io.input,iohandler,"io.input")
+ overload(io.output,iohandler,"io.output")
+ overload(io.lines,filehandlerone,"io.lines")
end
if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
+ overload(os.execute,binaryrunner,"os.execute")
+ overload(os.spawn,dummyrunner,"os.spawn")
+ overload(os.exec,dummyrunner,"os.exec")
+ overload(os.resultof,binaryrunner,"os.resultof")
+ overload(os.pipeto,binaryrunner,"os.pipeto")
+ overload(os.rename,filehandlertwo,"os.rename")
+ overload(os.remove,filehandlerone,"os.remove")
end
if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
+ overload(lfs.chdir,filehandlerone,"lfs.chdir")
+ overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
+ overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
+ overload(lfs.isfile,filehandlerone,"lfs.isfile")
+ overload(lfs.isdir,filehandlerone,"lfs.isdir")
+ overload(lfs.attributes,filehandlerone,"lfs.attributes")
+ overload(lfs.dir,filehandlerone,"lfs.dir")
+ overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
+ overload(lfs.touch,filehandlerone,"lfs.touch")
+ overload(lfs.link,filehandlertwo,"lfs.link")
+ overload(lfs.setmode,filehandlerone,"lfs.setmode")
+ overload(lfs.readlink,filehandlerone,"lfs.readlink")
+ overload(lfs.shortname,filehandlerone,"lfs.shortname")
+ overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
end
if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
+ zip.open=register(zip.open,filehandlerone,"zip.open")
end
if fontloader then
- fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
- fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
+ fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
+ fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
end
if epdf then
- epdf.open=register(epdf.open,filehandlerone,"epdf.open")
+ epdf.open=register(epdf.open,filehandlerone,"epdf.open")
end
sandbox.registerroot=registerroot
sandbox.registerbinary=registerbinary
@@ -11585,14 +15044,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
--- original size: 7757, stripped down to: 6015
+-- original size: 7819, stripped down to: 5881
if not modules then modules={} end modules ['util-mrg']={
- 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 gsub,format=string.gsub,string.format
local concat=table.concat
@@ -11620,19 +15079,19 @@ local m_report=[[
]]
local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
local function self_fake()
- return m_faked
+ return m_faked
end
local function self_nothing()
- return ""
+ return ""
end
local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
- report("unknown file %a",name)
- else
- report("inserting file %a",name)
- end
- return data or ""
+ local data=io.loaddata(name) or ""
+ if data=="" then
+ report("unknown file %a",name)
+ else
+ report("inserting file %a",name)
+ end
+ return data or ""
end
local space=patterns.space
local eol=patterns.newline
@@ -11661,98 +15120,99 @@ local mandatespacing=(eol+space)^1/""
local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
local lines=emptyline^2/"\n"
local spaces=(space*space)/" "
+local spaces=(space*space*space*space)/" "
local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
+ ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
)^1 )
local strip=Cs((emptyline^2/"\n"+1)^0)
local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
+ return lpegmatch(strip,lpegmatch(compact,data))
end
local function self_compact(data)
- local delta=0
- if merger.strip_comment then
- local before=#data
- data=lpegmatch(compact,data)
- data=lpegmatch(strip,data)
- local after=#data
- delta=before-after
- report("original size %s, compacted to %s, stripped %s",before,after,delta)
- data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
+ local delta=0
+ if merger.strip_comment then
+ local before=#data
+ data=lpegmatch(compact,data)
+ data=lpegmatch(strip,data)
+ local after=#data
+ delta=before-after
+ report("original size %s, compacted to %s, stripped %s",before,after,delta)
+ data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
+ end
+ return lpegmatch(stripreturn,data) or data,delta
end
local function self_save(name,data)
- if data~="" then
- io.savedata(name,data)
- report("saving %s with size %s",name,#data)
- end
+ if data~="" then
+ io.savedata(name,data)
+ report("saving %s with size %s",name,#data)
+ end
end
local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
+ return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
end
local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
+ local result,f,frozen,foundpath={},nil,false,nil
+ result[#result+1]="\n"
+ if type(libs)=='string' then libs={ libs } end
+ if type(list)=='string' then list={ list } end
+ for i=1,#libs do
+ local lib=libs[i]
+ for j=1,#list do
+ local pth=gsub(list[j],"\\","/")
+ report("checking library path %a",pth)
+ local name=pth.."/"..lib
+ if lfs.isfile(name) then
+ foundpath=pth
+ end
+ end
+ if foundpath then break end
+ end
+ if foundpath then
+ report("using library path %a",foundpath)
+ local right,wrong,original,stripped={},{},0,0
for i=1,#libs do
- local lib=libs[i]
- for j=1,#list do
- local pth=gsub(list[j],"\\","/")
- report("checking library path %a",pth)
- local name=pth.."/"..lib
- if lfs.isfile(name) then
- foundpath=pth
- end
- end
- if foundpath then break end
- end
- if foundpath then
- report("using library path %a",foundpath)
- local right,wrong,original,stripped={},{},0,0
- for i=1,#libs do
- local lib=libs[i]
- local fullname=foundpath.."/"..lib
- if lfs.isfile(fullname) then
- report("using library %a",fullname)
- local preloaded=file.nameonly(lib)
- local data=io.loaddata(fullname,true)
- original=original+#data
- local data,delta=self_compact(data)
- right[#right+1]=lib
- result[#result+1]=m_begin_closure
- result[#result+1]=format(m_preloaded,preloaded,preloaded)
- result[#result+1]=data
- result[#result+1]=m_end_closure
- stripped=stripped+delta
- else
- report("skipping library %a",fullname)
- wrong[#wrong+1]=lib
- end
- end
- right=#right>0 and concat(right," ") or "-"
- wrong=#wrong>0 and concat(wrong," ") or "-"
- report("used libraries: %a",right)
- report("skipped libraries: %a",wrong)
- report("original bytes: %a",original)
- report("stripped bytes: %a",stripped)
- result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
- report("no valid library path found")
+ local lib=libs[i]
+ local fullname=foundpath.."/"..lib
+ if lfs.isfile(fullname) then
+ report("using library %a",fullname)
+ local preloaded=file.nameonly(lib)
+ local data=io.loaddata(fullname,true)
+ original=original+#data
+ local data,delta=self_compact(data)
+ right[#right+1]=lib
+ result[#result+1]=m_begin_closure
+ result[#result+1]=format(m_preloaded,preloaded,preloaded)
+ result[#result+1]=data
+ result[#result+1]=m_end_closure
+ stripped=stripped+delta
+ else
+ report("skipping library %a",fullname)
+ wrong[#wrong+1]=lib
+ end
end
- return concat(result,"\n\n")
+ right=#right>0 and concat(right," ") or "-"
+ wrong=#wrong>0 and concat(wrong," ") or "-"
+ report("used libraries: %a",right)
+ report("skipped libraries: %a",wrong)
+ report("original bytes: %a",original)
+ report("stripped bytes: %a",stripped)
+ result[#result+1]=format(m_report,right,wrong,original,stripped)
+ else
+ report("no valid library path found")
+ end
+ return concat(result,"\n\n")
end
function merger.selfcreate(libs,list,target)
- if target then
- self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
+ if target then
+ self_save(target,self_swap(self_fake(),self_libs(libs,list)))
+ end
end
function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
+ self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
end
function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
+ self_save(name,self_swap(self_load(name),self_nothing()))
end
@@ -11762,14 +15222,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9400, stripped down to: 5499
+-- original size: 9738, stripped down to: 5531
if not modules then modules={} end modules ['util-env']={
- 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 allocate,mark=utilities.storage.allocate,utilities.storage.mark
local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
@@ -11781,178 +15241,193 @@ local setlocale=os.setlocale
setlocale(nil,nil)
local report=logs.reporter("system")
function os.setlocale(a,b)
- if a or b then
- if report then
- report()
- report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
- report("now on are on your own and without support. Crashes or unexpected side effects")
- report("can happen but don't bother the luatex and context developer team with it.")
- report()
- report=nil
- end
- setlocale(a,b)
- end
+ if a or b then
+ if report then
+ report()
+ report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+ report("now on are on your own and without support. Crashes or unexpected side effects")
+ report("can happen but don't bother the luatex and context developer team with it.")
+ report()
+ report=nil
+ end
+ setlocale(a,b)
+ end
end
local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
+ ["luatex"]=true,
+ ["luajittex"]=true,
}
local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
+ ["luatex"]="luatex",
+ ["texlua"]="luatex",
+ ["texluac"]="luatex",
+ ["luajittex"]="luajittex",
+ ["texluajit"]="luajittex",
}
local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
+ ["lua"]=true,
+ ["luajit"]=true,
}
environment.validengines=validengines
environment.basicengines=basicengines
if not arg then
- environment.used_as_library=true
+ environment.used_as_library=true
elseif luaengines[file.removesuffix(arg[-1])] then
elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
- arg[-1]=arg[0]
- arg[ 0]=arg[2]
- for k=3,#arg do
- arg[k-2]=arg[k]
- end
- remove(arg)
- remove(arg)
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
+ if arg[1]=="--luaonly" then
+ arg[-1]=arg[0]
+ arg[ 0]=arg[2]
+ for k=3,#arg do
+ arg[k-2]=arg[k]
+ end
+ remove(arg)
+ remove(arg)
+ else
+ end
+ local originalzero=file.basename(arg[0])
+ local specialmapping={ luatools=="base" }
+ if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
arg[0]=specialmapping[originalzero] or originalzero
insert(arg,0,"--script")
insert(arg,0,"mtxrun")
- end
+ end
end
environment.arguments=allocate()
environment.files=allocate()
environment.sortedflags=nil
function environment.initializearguments(arg)
- local arguments,files={},{}
- environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
- for index=1,#arg do
- local argument=arg[index]
- if index>0 then
- local flag,value=match(argument,"^%-+(.-)=(.-)$")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=unquoted(value or "")
- else
- flag=match(argument,"^%-+(.+)")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=true
- else
- files[#files+1]=argument
- end
- end
+ 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
+ local flag,value=match(argument,"^%-+(.-)=(.-)$")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=unquoted(value or "")
+ else
+ flag=match(argument,"^%-+(.+)")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=true
+ else
+ files[#files+1]=argument
end
+ 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
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
+ end
+ environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
end
function environment.setargument(name,value)
- environment.arguments[name]=value
+ environment.arguments[name]=value
end
function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
- return arguments[name]
- elseif partial then
- if not sortedflags then
- sortedflags=allocate(table.sortedkeys(arguments))
- for k=1,#sortedflags do
- sortedflags[k]="^"..sortedflags[k]
- end
- environment.sortedflags=sortedflags
- end
- for k=1,#sortedflags do
- local v=sortedflags[k]
- if find(name,v) then
- return arguments[sub(v,2,#v)]
- end
- end
+ local arguments,sortedflags=environment.arguments,environment.sortedflags
+ if arguments[name] then
+ return arguments[name]
+ elseif partial then
+ if not sortedflags then
+ sortedflags=allocate(table.sortedkeys(arguments))
+ for k=1,#sortedflags do
+ sortedflags[k]="^"..sortedflags[k]
+ end
+ environment.sortedflags=sortedflags
end
- return nil
+ for k=1,#sortedflags do
+ local v=sortedflags[k]
+ if find(name,v) then
+ return arguments[sub(v,2,#v)]
+ end
+ end
+ end
+ return nil
end
environment.argument=environment.getargument
function environment.splitarguments(separator)
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
- local v=originalarguments[k]
- if not done and v==separator then
- done=true
- elseif done then
- after[#after+1]=v
- else
- before[#before+1]=v
- end
+ local done,before,after=false,{},{}
+ local originalarguments=environment.originalarguments
+ for k=1,#originalarguments do
+ local v=originalarguments[k]
+ if not done and v==separator then
+ done=true
+ elseif done then
+ after[#after+1]=v
+ else
+ before[#before+1]=v
end
- return before,after
+ end
+ return before,after
end
function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
- return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
- local result={}
- for i=1,#arg do
- result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
- end
- return concat(result," ")
- else
- return ""
+ local resolveprefix=resolvers.resolve
+ arg=arg or environment.originalarguments
+ if noquote and #arg==1 then
+ return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
+ elseif #arg>0 then
+ local result={}
+ for i=1,#arg do
+ result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
end
+ return concat(result," ")
+ else
+ return ""
+ end
end
function environment.relativepath(path,root)
- if not path then
- path=""
+ if not path then
+ path=""
+ end
+ if not file.is_rootbased_path(path) then
+ if not root then
+ root=file.pathpart(environment.ownscript or environment.ownname or ".")
end
- if not file.is_rootbased_path(path) then
- if not root then
- root=file.pathpart(environment.ownscript or environment.ownname or ".")
- end
- if root=="" then
- root="."
- end
- path=root.."/"..path
+ if root=="" then
+ root="."
end
- return file.collapsepath(path,true)
+ path=root.."/"..path
+ end
+ return file.collapsepath(path,true)
end
if arg then
- local newarg,instring={},false
- for index=1,#arg do
- local argument=arg[index]
- if find(argument,"^\"") then
- newarg[#newarg+1]=gsub(argument,"^\"","")
- if not find(argument,"\"$") then
- instring=true
- end
- elseif find(argument,"\"$") then
- newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
- instring=false
- elseif instring then
- newarg[#newarg]=newarg[#newarg].." "..argument
- else
- newarg[#newarg+1]=argument
- end
- end
- for i=1,-5,-1 do
- newarg[i]=arg[i]
+ local newarg,instring={},false
+ for index=1,#arg do
+ local argument=arg[index]
+ if 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
+ 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
+ newarg[#newarg+1]=argument
end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={}
+ end
+ for i=1,-5,-1 do
+ newarg[i]=arg[i]
+ end
+ environment.initializearguments(newarg)
+ environment.originalarguments=mark(newarg)
+ environment.rawarguments=mark(arg)
+ arg={}
end
@@ -11962,17 +15437,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-env"] = package.loaded["luat-env"] or true
--- original size: 5820, stripped down to: 4155
+-- original size: 6134, stripped down to: 4118
if not modules then modules={} end modules ['luat-env']={
- 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 rawset,rawget,loadfile,assert=rawset,rawget,loadfile,assert
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+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)
local report_lua=logs.reporter("resolvers","lua")
local luautilities=utilities.lua
local luasuffixes=luautilities.suffixes
@@ -11980,133 +15456,146 @@ local texgettoks=tex and tex.gettoks
environment=environment or {}
local environment=environment
local mt={
- __index=function(_,k)
- if k=="version" then
- local version=texgettoks and texgettoks("contextversiontoks")
- if version and version~="" then
- rawset(environment,"version",version)
- return version
- else
- return "unknown"
- end
- elseif k=="kind" then
- local kind=texgettoks and texgettoks("contextkindtoks")
- if kind and kind~="" then
- rawset(environment,"kind",kind)
- return kind
- else
- return "unknown"
- end
- elseif k=="jobname" or k=="formatname" then
- local name=tex and tex[k]
- if name or name=="" then
- rawset(environment,k,name)
- return name
- else
- return "unknown"
- end
- elseif k=="outputfilename" then
- local name=environment.jobname
- rawset(environment,k,name)
- return name
- end
+ __index=function(_,k)
+ if k=="version" then
+ local version=texgettoks and texgettoks("contextversiontoks")
+ if version and version~="" then
+ rawset(environment,"version",version)
+ return version
+ else
+ return "unknown"
+ end
+ elseif k=="kind" then
+ local kind=texgettoks and texgettoks("contextkindtoks")
+ if kind and kind~="" then
+ rawset(environment,"kind",kind)
+ return kind
+ else
+ return "unknown"
+ end
+ elseif k=="jobname" or k=="formatname" then
+ local name=tex and tex[k]
+ if name or name=="" then
+ rawset(environment,k,name)
+ return name
+ else
+ return "unknown"
+ end
+ elseif k=="outputfilename" then
+ local name=environment.jobname
+ rawset(environment,k,name)
+ return name
end
+ end
}
setmetatable(environment,mt)
function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
+ return resolvers.findfile(filename,'tex')
end
function environment.luafile(filename)
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
- return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
- return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
-end
-local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
+ local resolved=resolvers.findfile(filename,'tex') or ""
+ if resolved~="" then
+ return resolved
+ end
+ resolved=resolvers.findfile(filename,'texmfscripts') or ""
+ if resolved~="" then
+ return resolved
+ end
+ return resolvers.findfile(filename,'luatexlibs') or ""
+end
+local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
local function strippable(filename)
- if stripindeed then
- local modu=modules[file.nameonly(filename)]
- return modu and modu.dataonly
- else
- return false
- end
+ if stripindeed then
+ local modu=modules[file.nameonly(filename)]
+ return modu and modu.dataonly
+ else
+ return false
+ end
end
function environment.luafilechunk(filename,silent,macros)
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
- local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
- if not silent then
- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- end
- return data
- else
- if not silent then
- report_lua("unknown file %a",filename)
- end
- return nil
+ filename=file.replacesuffix(filename,"lua")
+ local fullname=environment.luafile(filename)
+ if fullname and fullname~="" then
+ local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
+ if not silent then
+ report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+ end
+ return data
+ else
+ if not silent then
+ report_lua("unknown file %a",filename)
end
+ return nil
+ end
end
function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
- luaname=file.addsuffix(basename,luasuffixes.lua)
- lucname=file.addsuffix(basename,luasuffixes.luc)
- else
- luaname=basename
- lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
+ local lucname,luaname,chunk
+ local basename=file.removesuffix(filename)
+ if basename==filename then
+ luaname=file.addsuffix(basename,luasuffixes.lua)
+ lucname=file.addsuffix(basename,luasuffixes.luc)
+ else
+ luaname=filename
+ lucname=nil
+ end
+ local fullname=(lucname and environment.luafile(lucname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
+ end
+ chunk=loadfile(fullname)
+ end
+ if chunk then
+ chunk()
+ if version then
+ local v=version
+ if modules and modules[filename] then
+ v=modules[filename].version
+ elseif versions and versions[filename] then
+ v=versions[filename]
+ end
+ if v==version then
+ return true
+ else
if trace_locating then
- report_lua("loading %a",fullname)
+ report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
end
- chunk=loadfile(fullname)
+ environment.loadluafile(filename)
+ end
+ else
+ return true
end
- if chunk then
- assert(chunk)()
- if version then
- local v=version
- if modules and modules[filename] then
- v=modules[filename].version
- elseif versions and versions[filename] then
- v=versions[filename]
- end
- if v==version then
- return true
- else
- if trace_locating then
- report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
- end
- environment.loadluafile(filename)
- end
- else
- return true
- end
+ end
+ fullname=(luaname and environment.luafile(luaname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- if not chunk then
- if trace_locating then
- report_lua("unknown file %a",filename)
- end
- else
- assert(chunk)()
- return true
- end
+ chunk=loadfile(fullname)
+ if not chunk then
+ if trace_locating then
+ report_lua("unknown file %a",filename)
+ end
+ else
+ chunk()
+ return true
end
- return false
+ 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)
+ end,
+ __len=function(t)
+ return #environment.files
+ end,
+} )
end -- of closure
@@ -12115,16 +15604,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
--- original size: 60383, stripped down to: 38562
+-- original size: 60383, stripped down to: 35698
if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
+local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
xml=xml or {}
@@ -12142,17 +15631,17 @@ xml.xmlns=xml.xmlns or {}
local check=P(false)
local parse=check
function xml.registerns(namespace,pattern)
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
+ check=check+C(P(lower(pattern)))/namespace
+ parse=P { P(check)+1*V(1) }
end
function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
- xml.xmlns[namespace]=ns
- end
+ local ns=lpegmatch(parse,lower(url))
+ if ns and namespace~=ns then
+ xml.xmlns[namespace]=ns
+ end
end
function xml.resolvens(url)
- return lpegmatch(parse,lower(url)) or ""
+ return lpegmatch(parse,lower(url)) or ""
end
end
local nsremap,resolvens=xml.xmlns,xml.resolvens
@@ -12170,661 +15659,661 @@ local handle_dec_entity
local handle_any_entity_dtd
local handle_any_entity_text
local function preparexmlstate(settings)
- if settings then
- linenumbers=settings.linenumbers
- stack={}
- level=0
- top={}
- at={}
- mt={}
- dt={}
- nt=0
- xmlns={}
- errorstr=nil
- strip=settings.strip_cm_and_dt
- utfize=settings.utfize_entities
- resolve=settings.resolve_entities
- resolve_predefined=settings.resolve_predefined_entities
- unify_predefined=settings.unify_predefined_entities
- cleanup=settings.text_cleanup
- entities=settings.entities or {}
- currentfilename=settings.currentresource
- currentline=1
- parameters={}
- reported_at_errors={}
- dcache={}
- hcache={}
- acache={}
- if utfize==nil then
- settings.utfize_entities=true
- utfize=true
- end
- if resolve_predefined==nil then
- settings.resolve_predefined_entities=true
- resolve_predefined=true
- end
- else
- linenumbers=false
- stack=nil
- level=nil
- top=nil
- at=nil
- mt=nil
- dt=nil
- nt=nil
- xmlns=nil
- errorstr=nil
- strip=nil
- utfize=nil
- resolve=nil
- resolve_predefined=nil
- unify_predefined=nil
- cleanup=nil
- entities=nil
- parameters=nil
- reported_at_errors=nil
- dcache=nil
- hcache=nil
- acache=nil
- currentfilename=nil
- currentline=1
- end
+ if settings then
+ linenumbers=settings.linenumbers
+ stack={}
+ level=0
+ top={}
+ at={}
+ mt={}
+ dt={}
+ nt=0
+ xmlns={}
+ errorstr=nil
+ strip=settings.strip_cm_and_dt
+ utfize=settings.utfize_entities
+ resolve=settings.resolve_entities
+ resolve_predefined=settings.resolve_predefined_entities
+ unify_predefined=settings.unify_predefined_entities
+ cleanup=settings.text_cleanup
+ entities=settings.entities or {}
+ currentfilename=settings.currentresource
+ currentline=1
+ parameters={}
+ reported_at_errors={}
+ dcache={}
+ hcache={}
+ acache={}
+ if utfize==nil then
+ settings.utfize_entities=true
+ utfize=true
+ end
+ if resolve_predefined==nil then
+ settings.resolve_predefined_entities=true
+ resolve_predefined=true
+ end
+ else
+ linenumbers=false
+ stack=nil
+ level=nil
+ top=nil
+ at=nil
+ mt=nil
+ dt=nil
+ nt=nil
+ xmlns=nil
+ errorstr=nil
+ strip=nil
+ utfize=nil
+ resolve=nil
+ resolve_predefined=nil
+ unify_predefined=nil
+ cleanup=nil
+ entities=nil
+ parameters=nil
+ reported_at_errors=nil
+ dcache=nil
+ hcache=nil
+ acache=nil
+ currentfilename=nil
+ currentline=1
+ end
end
local function initialize_mt(root)
- mt={ __index=root }
+ mt={ __index=root }
end
function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
+ getmetatable(root).__index[k]=v
end
function xml.checkerror(top,toclose)
- return ""
+ return ""
end
local checkns=xml.checkns
local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
- value=cleanup(value)
- end
- if tag=="xmlns" then
- xmlns[#xmlns+1]=resolvens(value)
- at[tag]=value
- elseif namespace=="" then
- at[tag]=value
- elseif namespace=="xmlns" then
- checkns(tag,value)
- at["xmlns:"..tag]=value
- else
- at[namespace..":"..tag]=value
- end
+ if cleanup and value~="" then
+ value=cleanup(value)
+ end
+ if tag=="xmlns" then
+ xmlns[#xmlns+1]=resolvens(value)
+ at[tag]=value
+ elseif namespace=="" then
+ at[tag]=value
+ elseif namespace=="xmlns" then
+ checkns(tag,value)
+ at["xmlns:"..tag]=value
+ else
+ at[namespace..":"..tag]=value
+ end
end
local function add_empty(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- cf=currentfilename,
- cl=currentline,
- __p__=top,
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
- remove(xmlns)
- end
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ top=stack[level]
+ dt=top.dt
+ nt=#dt+1
+ local t=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=top,
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ __p__=top,
+ }
+ dt[nt]=t
+ setmetatable(t,mt)
+ if at.xmlns then
+ remove(xmlns)
+ end
+ at={}
end
local function add_begin(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- cf=currentfilename,
- cl=currentline,
- __p__=stack[level],
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ dt={}
+ top=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=stack[level],
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ __p__=stack[level],
+ }
+ setmetatable(top,mt)
+ nt=0
+ level=level+1
+ stack[level]=top
+ at={}
end
local function add_end(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
- errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- elseif toclose.tg~=tag then
- errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt
- if toclose.at.xmlns then
- remove(xmlns)
- end
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local toclose=stack[level]
+ level=level-1
+ top=stack[level]
+ if level<1 then
+ errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ elseif toclose.tg~=tag then
+ errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ end
+ dt=top.dt
+ nt=#dt+1
+ dt[nt]=toclose
+ toclose.ni=nt
+ if toclose.at.xmlns then
+ remove(xmlns)
+ end
end
local function add_text(text)
- if text=="" then
- return
- end
- if cleanup then
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..cleanup(text)
- else
- nt=nt+1
- dt[nt]=cleanup(text)
- end
- else
- nt=1
- dt[1]=cleanup(text)
- end
+ if text=="" then
+ return
+ end
+ if cleanup then
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..cleanup(text)
+ else
+ nt=nt+1
+ dt[nt]=cleanup(text)
+ end
else
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..text
- else
- nt=nt+1
- dt[nt]=text
- end
- else
- nt=1
- dt[1]=text
- end
+ nt=1
+ dt[1]=cleanup(text)
end
-end
-local function add_special(what,spacing,text)
- if spacing~="" then
+ else
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..text
+ else
nt=nt+1
- dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
+ dt[nt]=text
+ end
else
- nt=nt+1
- dt[nt]=linenumbers and {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- cf=currentfilename,
- cl=currentline,
- } or {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- }
+ nt=1
+ dt[1]=text
end
+ end
+end
+local function add_special(what,spacing,text)
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ if strip and (what=="@cm@" or what=="@dt@") then
+ else
+ nt=nt+1
+ dt[nt]=linenumbers and {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ cf=currentfilename,
+ cl=currentline,
+ } or {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ }
+ end
end
local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
+ errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
end
local function attribute_value_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute value %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute value %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
local function attribute_specification_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute specification %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute specification %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
do
- local badentity="&"
- xml.placeholders={
- unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
- unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
- unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return formatters["h:%s"](s),true
+ local badentity="&"
+ xml.placeholders={
+ unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
+ unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
+ unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
+ }
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local p_rest=(1-P(";"))^0
+ local p_many=P(1)^0
+ local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
+ xml.parsedentitylpeg=parsedentity
+ local predefined_unified={
+ [38]="&amp;",
+ [42]="&quot;",
+ [47]="&apos;",
+ [74]="&lt;",
+ [76]="&gt;",
+ }
+ local predefined_simplified={
+ [38]="&",amp="&",
+ [42]='"',quot='"',
+ [47]="'",apos="'",
+ [74]="<",lt="<",
+ [76]=">",gt=">",
+ }
+ local nofprivates=0xF0000
+ local privates_u={
+ [ [[&]] ]="&amp;",
+ [ [["]] ]="&quot;",
+ [ [[']] ]="&apos;",
+ [ [[<]] ]="&lt;",
+ [ [[>]] ]="&gt;",
+ }
+ local privates_p={
+ }
+ local privates_s={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[&]] ]="&U+26;",
+ [ [[']] ]="&U+27;",
+ [ [[<]] ]="&U+3C;",
+ [ [[>]] ]="&U+3E;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_x={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[']] ]="&U+27;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_n={
+ }
+ local escaped=utf.remapper(privates_u,"dynamic")
+ local unprivatized=utf.remapper(privates_p,"dynamic")
+ local unspecialized=utf.remapper(privates_s,"dynamic")
+ local despecialized=utf.remapper(privates_x,"dynamic")
+ xml.unprivatized=unprivatized
+ xml.unspecialized=unspecialized
+ xml.despecialized=despecialized
+ xml.escaped=escaped
+ local function unescaped(s)
+ local p=privates_n[s]
+ if not p then
+ nofprivates=nofprivates+1
+ p=utfchar(nofprivates)
+ privates_n[s]=p
+ s="&"..s..";"
+ privates_u[p]=s
+ privates_p[p]=s
+ privates_s[p]=s
+ end
+ return p
+ end
+ xml.privatetoken=unescaped
+ xml.privatecodes=privates_n
+ xml.specialcodes=privates_s
+ function xml.addspecialcode(key,value)
+ privates_s[key]=value or "&"..s..";"
+ end
+ handle_hex_entity=function(str)
+ local h=hcache[str]
+ if not h then
+ local n=tonumber(str,16)
+ h=unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ elseif utfize then
+ h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring hex entity &#x%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#x%s;",str)
end
+ h="&#x"..str..";"
+ end
+ hcache[str]=h
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return utfchar(n)
- else
- return formatters["d:%s"](s),true
- end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
- [38]="&amp;",
- [42]="&quot;",
- [47]="&apos;",
- [74]="&lt;",
- [76]="&gt;",
- }
- local predefined_simplified={
- [38]="&",amp="&",
- [42]='"',quot='"',
- [47]="'",apos="'",
- [74]="<",lt="<",
- [76]=">",gt=">",
- }
- local nofprivates=0xF0000
- local privates_u={
- [ [[&]] ]="&amp;",
- [ [["]] ]="&quot;",
- [ [[']] ]="&apos;",
- [ [[<]] ]="&lt;",
- [ [[>]] ]="&gt;",
- }
- local privates_p={
- }
- local privates_s={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[&]] ]="&U+26;",
- [ [[']] ]="&U+27;",
- [ [[<]] ]="&U+3C;",
- [ [[>]] ]="&U+3E;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_x={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[']] ]="&U+27;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_n={
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
- local p=privates_n[s]
- if not p then
- nofprivates=nofprivates+1
- p=utfchar(nofprivates)
- privates_n[s]=p
- s="&"..s..";"
- privates_u[p]=s
- privates_p[p]=s
- privates_s[p]=s
- end
- return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
- privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
- local h=hcache[str]
- if not h then
- local n=tonumber(str,16)
- h=unify_predefined and predefined_unified[n]
- if h then
- if trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- elseif utfize then
- h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring hex entity &#x%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- else
- if trace_entities then
- report_xml("found entity &#x%s;",str)
- end
- h="&#x"..str..";"
- end
- hcache[str]=h
- end
- return h
- end
- handle_dec_entity=function(str)
- local d=dcache[str]
- if not d then
- local n=tonumber(str)
- d=unify_predefined and predefined_unified[n]
- if d then
- if trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- elseif utfize then
- d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring dec entity &#%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- else
- if trace_entities then
- report_xml("found entity &#%s;",str)
- end
- d="&#"..str..";"
- end
- dcache[str]=d
+ return h
+ end
+ handle_dec_entity=function(str)
+ local d=dcache[str]
+ if not d then
+ local n=tonumber(str)
+ d=unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ elseif utfize then
+ d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring dec entity &#%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#%s;",str)
end
- return d
+ d="&#"..str..";"
+ end
+ dcache[str]=d
end
- handle_any_entity_dtd=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
+ return d
+ end
+ handle_any_entity_dtd=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
+ a=entities[str]
end
- end
- handle_any_entity_text=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(grammar_parsed_text_two,a) or a
- if type(a)=="number" then
- return ""
- else
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- end
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
end
- return a
+ a=a(str) or ""
+ end
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
end
- return a
- end
- end
- local p_rest=(1-P(";"))^1
- local spec={
- [0x23]="\\Ux{23}",
- [0x24]="\\Ux{24}",
- [0x25]="\\Ux{25}",
- [0x5C]="\\Ux{5C}",
- [0x7B]="\\Ux{7B}",
- [0x7C]="\\Ux{7C}",
- [0x7D]="\\Ux{7D}",
- [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
+ end
+ return a
+ end
+ end
+ handle_any_entity_text=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- return formatters["d:%s"](s),true
+ a=entities[str]
end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- local hash=table.setmetatableindex(function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
+ end
+ a=a(str) or ""
+ end
+ a=lpegmatch(grammar_parsed_text_two,a) or a
+ if type(a)=="number" then
+ return ""
+ else
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
+ end
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- return formatters["u:%s"](s),true
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
+ end
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
+ end
+ return a
+ end
+ end
+ local p_rest=(1-P(";"))^1
+ local spec={
+ [0x23]="\\Ux{23}",
+ [0x24]="\\Ux{24}",
+ [0x25]="\\Ux{25}",
+ [0x5C]="\\Ux{5C}",
+ [0x7B]="\\Ux{7B}",
+ [0x7C]="\\Ux{7C}",
+ [0x7D]="\\Ux{7D}",
+ [0x7E]="\\Ux{7E}",
+ }
+ local hash=table.setmetatableindex(spec,function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- xml.reparsedentitylpeg=reparsedentity
- xml.unescapedentitylpeg=unescapedentity
+ end
+ local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ local hash=table.setmetatableindex(function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
+ end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ xml.reparsedentitylpeg=reparsedentity
+ xml.unescapedentitylpeg=unescapedentity
end
local escaped=xml.escaped
local unescaped=xml.unescaped
local placeholders=xml.placeholders
local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
+ report_xml("error in entity, %a found without ending %a",str,";")
+ return str
end
local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
+ report_xml("error in parsing, unexpected %a found ",chr)
+ add_text(chr)
+ return chr
end
local function handlenewline()
- currentline=currentline+1
+ currentline=currentline+1
end
local spacetab=S(' \t')
local space=S(' \r\n\t')
@@ -12849,141 +16338,141 @@ local space_nl=spacetab+newline
local spacing_nl=Cs((space_nl)^0)
local anything_nl=newline+P(1)
local function weirdentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","weird",k,v)
+ end
+ parameters[k]=v
end
local function normalentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","normal",k,v)
+ end
+ entities[k]=v
end
local function systementity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","system",k,v)
+ end
+ entities[k]=v
end
local function publicentity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","public",k,v)
+ end
+ entities[k]=v
end
local function entityfile(pattern,k,v,n)
- if n then
- local okay,data
- if resolvers then
- okay,data=resolvers.loadbinfile(n)
- else
- data=io.loaddata(n)
- okay=data and data~=""
- end
- if okay then
- if trace_entities then
- report_xml("loading public entities %a as %a from %a",k,v,n)
- end
- lpegmatch(pattern,data)
- return
- end
+ if n then
+ local okay,data
+ if resolvers then
+ okay,data=resolvers.loadbinfile(n)
+ else
+ data=io.loaddata(n)
+ okay=data and data~=""
end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
+ if okay then
+ if trace_entities then
+ report_xml("loading public entities %a as %a from %a",k,v,n)
+ end
+ lpegmatch(pattern,data)
+ return
+ end
+ end
+ report_xml("ignoring public entities %a as %a from %a",k,v,n)
end
local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_dtd)
- local parsedentity_text=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_text)
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
- local endofattributes=slash*close+close
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
- entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
- lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
- lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1
- local somedoctype=C((somespace*(
+ local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
+ local hexentitycontent=R("AF","af","09")^1
+ local decentitycontent=R("09")^1
+ local parsedentity=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_dtd)
+ local parsedentity_text=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_text)
+ local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local text_unparsed=Cs((anything-open)^1)
+ local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
+ local somespace=(spacenewline)^1
+ local optionalspace=(spacenewline)^0
+ local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
+ local endofattributes=slash*close+close
+ local whatever=space*name*optionalspace*equal
+ local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
+ local attributevalue=value+wrongvalue
+ local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
+ local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
+ local parsedtext=text_parsed
+ local unparsedtext=text_unparsed/add_text
+ local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
+ local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
+ local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
+ local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
+ local begincomment=open*P("!--")
+ local endcomment=P("--")*close
+ local begininstruction=open*P("?")
+ local endinstruction=P("?")*close
+ local begincdata=open*P("![CDATA[")
+ local endcdata=P("]]")*close
+ local someinstruction=C((anything-endinstruction)^0)
+ local somecomment=C((anything-endcomment )^0)
+ local somecdata=C((anything-endcdata )^0)
+ local begindoctype=open*P("!DOCTYPE")
+ local enddoctype=close
+ local beginset=P("[")
+ local endset=P("]")
+ local wrdtypename=C((anything-somespace-P(";"))^1)
+ local doctypename=C((anything-somespace-close)^0)
+ local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
+ local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
+ local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
+ local normalentitytype=(doctypename*somespace*value)/normalentity
+ local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
+ local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
+ local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
+ local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
+ entityfile(entitydoctype,...)
+ end
+ local function weirdresolve(s)
+ lpegmatch(entitydoctype,parameters[s])
+ end
+ local function normalresolve(s)
+ lpegmatch(entitydoctype,entities[s])
+ end
+ local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
+ entitydoctype=entitydoctype+entityresolve
+ local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
+ local definitiondoctype=doctypename*somespace*doctypeset
+ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
+ local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
+ local simpledoctype=(anything-close)^1
+ local somedoctype=C((somespace*(
publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
- followup=V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
+ local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
+ local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
+ local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
+ local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
+ local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
+ local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
+ local trailer=space^0*(text_unparsed/set_message)^0
+ local grammar_parsed_text_one=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
+ }
+ local grammar_parsed_text_two=P { "followup",
+ followup=V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
+ }
+ local grammar_unparsed_text=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
+ }
+ return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
end
grammar_parsed_text_one_nop,
grammar_parsed_text_two_nop,
@@ -12992,576 +16481,576 @@ grammar_parsed_text_one_yes,
grammar_parsed_text_two_yes,
grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
local function _xmlconvert_(data,settings,detail)
- settings=settings or {}
- preparexmlstate(settings)
- if settings.linenumbers then
- grammar_parsed_text_one=grammar_parsed_text_one_yes
- grammar_parsed_text_two=grammar_parsed_text_two_yes
- grammar_unparsed_text=grammar_unparsed_text_yes
- else
- grammar_parsed_text_one=grammar_parsed_text_one_nop
- grammar_parsed_text_two=grammar_parsed_text_two_nop
- grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
- data=preprocessor(data,settings) or data
+ settings=settings or {}
+ preparexmlstate(settings)
+ if settings.linenumbers then
+ grammar_parsed_text_one=grammar_parsed_text_one_yes
+ grammar_parsed_text_two=grammar_parsed_text_two_yes
+ grammar_unparsed_text=grammar_unparsed_text_yes
+ else
+ grammar_parsed_text_one=grammar_parsed_text_one_nop
+ grammar_parsed_text_two=grammar_parsed_text_two_nop
+ grammar_unparsed_text=grammar_unparsed_text_nop
+ end
+ local preprocessor=settings.preprocessor
+ if data and data~="" and type(preprocessor)=="function" then
+ data=preprocessor(data,settings) or data
+ end
+ if settings.parent_root then
+ mt=getmetatable(settings.parent_root)
+ else
+ initialize_mt(top)
+ end
+ level=level+1
+ stack[level]=top
+ top.dt={}
+ dt=top.dt
+ nt=0
+ if not data or data=="" then
+ errorstr="empty xml file"
+ elseif data==true then
+ errorstr=detail or "problematic xml file"
+ elseif utfize or resolve then
+ local m=lpegmatch(grammar_parsed_text_one,data)
+ if m then
+ m=lpegmatch(grammar_parsed_text_two,data,m)
end
- if settings.parent_root then
- mt=getmetatable(settings.parent_root)
- else
- initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
- errorstr="empty xml file"
- elseif data==true then
- errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
- local m=lpegmatch(grammar_parsed_text_one,data)
- if m then
- m=lpegmatch(grammar_parsed_text_two,data,m)
- end
- if m then
- else
- errorstr="invalid xml file - parsed text"
- end
- elseif type(data)=="string" then
- if lpegmatch(grammar_unparsed_text,data) then
- errorstr=""
- else
- errorstr="invalid xml file - unparsed text"
- end
+ if m then
else
- errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
- result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
- setmetatable(result,mt)
- setmetatable(result.dt[1],mt)
- setmetatable(stack,mt)
- local errorhandler=settings.error_handler
- if errorhandler==false then
+ errorstr="invalid xml file - parsed text"
+ end
+ elseif type(data)=="string" then
+ if lpegmatch(grammar_unparsed_text,data) then
+ errorstr=""
+ else
+ errorstr="invalid xml file - unparsed text"
+ end
+ else
+ errorstr="invalid xml file - no text at all"
+ end
+ local result
+ if errorstr and errorstr~="" then
+ result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
+ setmetatable(result,mt)
+ setmetatable(result.dt[1],mt)
+ setmetatable(stack,mt)
+ local errorhandler=settings.error_handler
+ if errorhandler==false then
+ else
+ errorhandler=errorhandler or xml.errorhandler
+ if errorhandler then
+ local currentresource=settings.currentresource
+ if currentresource and currentresource~="" then
+ xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
else
- errorhandler=errorhandler or xml.errorhandler
- if errorhandler then
- local currentresource=settings.currentresource
- if currentresource and currentresource~="" then
- xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
- else
- xml.errorhandler(formatters["load error: %s"](errorstr))
- end
- end
- end
- else
- result=stack[1]
- end
- if not settings.no_root then
- result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
- setmetatable(result,mt)
- local rdt=result.dt
- for k=1,#rdt do
- local v=rdt[k]
- if type(v)=="table" and not v.special then
- result.ri=k
- v.__p__=result
- break
- end
+ xml.errorhandler(formatters["load error: %s"](errorstr))
end
+ end
end
- if errorstr and errorstr~="" then
- result.error=true
- else
- errorstr=nil
- end
- result.statistics={
- errormessage=errorstr,
- entities={
- decimals=dcache,
- hexadecimals=hcache,
- names=acache,
- intermediates=parameters,
- }
+ else
+ result=stack[1]
+ end
+ if not settings.no_root then
+ result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
+ setmetatable(result,mt)
+ local rdt=result.dt
+ for k=1,#rdt do
+ local v=rdt[k]
+ if type(v)=="table" and not v.special then
+ result.ri=k
+ v.__p__=result
+ break
+ end
+ end
+ end
+ if errorstr and errorstr~="" then
+ result.error=true
+ else
+ errorstr=nil
+ end
+ result.statistics={
+ errormessage=errorstr,
+ entities={
+ decimals=dcache,
+ hexadecimals=hcache,
+ names=acache,
+ intermediates=parameters,
}
- preparexmlstate()
- return result
+ }
+ preparexmlstate()
+ return result
end
local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
- return result
- elseif type(result)=="string" then
- return _xmlconvert_(true,settings,result)
- else
- return _xmlconvert_(true,settings)
- end
+ local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
+ if ok then
+ return result
+ elseif type(result)=="string" then
+ return _xmlconvert_(true,settings,result)
+ else
+ return _xmlconvert_(true,settings)
+ end
end
xml.convert=xmlconvert
function xml.inheritedconvert(data,xmldata)
- local settings=xmldata.settings
- if settings then
- settings.parent_root=xmldata
- end
- local xc=xmlconvert(data,settings)
- return xc
+ local settings=xmldata.settings
+ if settings then
+ settings.parent_root=xmldata
+ end
+ local xc=xmlconvert(data,settings)
+ return xc
end
function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
+ return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
end
function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
+ local ns,tg=match(tag,"^(.-):?([^:]+)$")
+ local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
+ setmetatable(t,mt)
+ return t
end
function xml.is_valid(root)
- return root and not root.error
+ return root and not root.error
end
xml.errorhandler=report_xml
function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
- local f=io.open(filename,'r')
- if f then
- data=f:read("*all")
- f:close()
- end
- elseif filename then
- data=filename:read("*all")
- end
- if settings then
- settings.currentresource=filename
- local result=xmlconvert(data,settings)
- settings.currentresource=nil
- return result
- else
- return xmlconvert(data,{ currentresource=filename })
- end
+ local data=""
+ if type(filename)=="string" then
+ local f=io.open(filename,'r')
+ if f then
+ data=f:read("*all")
+ f:close()
+ end
+ elseif filename then
+ data=filename:read("*all")
+ end
+ if settings then
+ settings.currentresource=filename
+ local result=xmlconvert(data,settings)
+ settings.currentresource=nil
+ return result
+ else
+ return xmlconvert(data,{ currentresource=filename })
+ end
end
local no_root={ no_root=true }
function xml.toxml(data)
- if type(data)=="string" then
- local root={ xmlconvert(data,no_root) }
- return (#root>1 and root) or root[1]
- else
- return data
- end
+ if type(data)=="string" then
+ local root={ xmlconvert(data,no_root) }
+ return (#root>1 and root) or root[1]
+ else
+ return data
+ end
end
local function copy(old,p)
- if old then
- local new={}
- for k,v in next,old do
- local t=type(v)=="table"
- if k=="at" then
- local t={}
- for k,v in next,v do
- t[k]=v
- end
- new[k]=t
- elseif k=="dt" then
- v.__p__=nil
- v=copy(v,new)
- new[k]=v
- v.__p__=p
- else
- new[k]=v
- end
- end
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ local t=type(v)=="table"
+ if k=="at" then
+ local t={}
+ for k,v in next,v do
+ t[k]=v
+ end
+ new[k]=t
+ elseif k=="dt" then
+ v.__p__=nil
+ v=copy(v,new)
+ new[k]=v
+ v.__p__=p
+ else
+ new[k]=v
+ end
end
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ return new
+ else
+ return {}
+ end
end
xml.copy=copy
function xml.checkbom(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
- return
- end
- end
- insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
- insert(dt,2,"\n" )
+ if root.ri then
+ local dt=root.dt
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
+ return
+ end
end
+ insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
+ insert(dt,2,"\n" )
+ end
end
local f_attribute=formatters['%s=%q']
local function verbose_element(e,handlers,escape)
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
- local n=0
- for k in next,eat do
- n=n+1
- ats[n]=k
- end
- if n==1 then
- local k=ats[1]
- ats=f_attribute(k,escaped(eat[k]))
- else
- sort(ats)
- for i=1,n do
- local k=ats[i]
- ats[i]=f_attribute(k,escaped(eat[k]))
- end
- ats=concat(ats," ")
- end
- end
- if ern and trace_entities and ern~=ens then
- ens=ern
+ local handle=handlers.handle
+ local serialize=handlers.serialize
+ local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
+ local ats=eat and next(eat) and {}
+ if ats then
+ local n=0
+ for k in next,eat do
+ n=n+1
+ ats[n]=k
end
- local n=edt and #edt
- if ens~="" then
- if n and n>0 then
- if ats then
- handle("<",ens,":",etg," ",ats,">")
- else
- handle("<",ens,":",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",ens,":",etg,">")
+ if n==1 then
+ local k=ats[1]
+ ats=f_attribute(k,escaped(eat[k]))
+ else
+ sort(ats)
+ for i=1,n do
+ local k=ats[i]
+ ats[i]=f_attribute(k,escaped(eat[k]))
+ end
+ ats=concat(ats," ")
+ end
+ end
+ if ern and trace_entities and ern~=ens then
+ ens=ern
+ end
+ local n=edt and #edt
+ if ens~="" then
+ if n and n>0 then
+ if ats then
+ handle("<",ens,":",etg," ",ats,">")
+ else
+ handle("<",ens,":",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",ens,":",etg," ",ats,"/>")
- else
- handle("<",ens,":",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",ens,":",etg,">")
else
- if n and n>0 then
- if ats then
- handle("<",etg," ",ats,">")
- else
- handle("<",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",etg,">")
+ if ats then
+ handle("<",ens,":",etg," ",ats,"/>")
+ else
+ handle("<",ens,":",etg,"/>")
+ end
+ end
+ else
+ if n and n>0 then
+ if ats then
+ handle("<",etg," ",ats,">")
+ else
+ handle("<",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",etg," ",ats,"/>")
- else
- handle("<",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",etg,">")
+ else
+ if ats then
+ handle("<",etg," ",ats,"/>")
+ else
+ handle("<",etg,"/>")
+ end
end
+ end
end
local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
+ handlers.handle("<?",e.dt[1],"?>")
end
local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
+ handlers.handle("<!--",e.dt[1],"-->")
end
local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
+ handlers.handle("<![CDATA[",e.dt[1],"]]>")
end
local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">")
+ handlers.handle("<!DOCTYPE",e.dt[1],">")
end
local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
+ handlers.serialize(e.dt,handlers)
end
local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
+ handlers.handle(escaped(e))
end
local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
- local ei=e[i]
- if type(ei)=="string" then
- functions["@tx@"](ei,handlers)
- else
- serialize(ei,handlers)
- end
+ local serialize=handlers.serialize
+ local functions=handlers.functions
+ for i=1,#e do
+ local ei=e[i]
+ if type(ei)=="string" then
+ functions["@tx@"](ei,handlers)
+ else
+ serialize(ei,handlers)
end
+ end
end
local function serialize(e,handlers,...)
- if e then
- local initialize=handlers.initialize
- local finalize=handlers.finalize
- local functions=handlers.functions
- if initialize then
- local state=initialize(...)
- if not state==true then
- return state
- end
- end
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- if finalize then
- return finalize()
- end
+ if e then
+ local initialize=handlers.initialize
+ local finalize=handlers.finalize
+ local functions=handlers.functions
+ if initialize then
+ local state=initialize(...)
+ if not state==true then
+ return state
+ end
end
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
+ end
+ if finalize then
+ return finalize()
+ end
+ end
end
local function xserialize(e,handlers)
- if e then
- local functions=handlers.functions
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
+ if e then
+ local functions=handlers.functions
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ end
end
local handlers={}
local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
- if settings then
- for k,v in next,settings do
- if type(v)=="table" then
- local tk=t[k] if not tk then tk={} t[k]=tk end
- for kk,vv in next,v do
- tk[kk]=vv
- end
- else
- t[k]=v
- end
- end
- if settings.name then
- handlers[settings.name]=t
- end
+ local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
+ if settings then
+ for k,v in next,settings do
+ if type(v)=="table" then
+ local tk=t[k] if not tk then tk={} t[k]=tk end
+ for kk,vv in next,v do
+ tk[kk]=vv
+ end
+ else
+ t[k]=v
+ end
end
- utilities.storage.mark(t)
- return t
+ if settings.name then
+ handlers[settings.name]=t
+ end
+ end
+ utilities.storage.mark(t)
+ return t
end
local nofunction=function() end
function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
+ handler.functions[name]=fnc or nofunction
end
function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
+ return handler.functions[name]
end
function xml.gethandlers(name)
- return handlers[name]
+ return handlers[name]
end
newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
- ["@dc@"]=verbose_document,
- ["@dt@"]=verbose_doctype,
- ["@rt@"]=verbose_root,
- ["@el@"]=verbose_element,
- ["@pi@"]=verbose_pi,
- ["@cm@"]=verbose_comment,
- ["@cd@"]=verbose_cdata,
- ["@tx@"]=verbose_text,
- }
+ name="verbose",
+ initialize=false,
+ finalize=false,
+ serialize=xserialize,
+ handle=print,
+ functions={
+ ["@dc@"]=verbose_document,
+ ["@dt@"]=verbose_doctype,
+ ["@rt@"]=verbose_root,
+ ["@el@"]=verbose_element,
+ ["@pi@"]=verbose_pi,
+ ["@cm@"]=verbose_comment,
+ ["@cd@"]=verbose_cdata,
+ ["@tx@"]=verbose_text,
+ }
}
local result
local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
- result=io.open(name,"wb")
- return result
- end,
- finalize=function()
- result:close()
- return true
- end,
- handle=function(...)
- result:write(...)
- end,
+ name="file",
+ initialize=function(name)
+ result=io.open(name,"wb")
+ return result
+ end,
+ finalize=function()
+ result:close()
+ return true
+ end,
+ handle=function(...)
+ result:write(...)
+ end,
}
function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
+ serialize(root,xmlfilehandler,name)
end
local result,r,threshold={},0,512
local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
- r=0
- return result
- end,
- finalize=function()
- local done=concat(result,"",1,r)
- r=0
- if r>threshold then
- result={}
- end
- return done
- end,
- handle=function(...)
- for i=1,select("#",...) do
- r=r+1
- result[r]=select(i,...)
- end
- end,
+ name="string",
+ initialize=function()
+ r=0
+ return result
+ end,
+ finalize=function()
+ local done=concat(result,"",1,r)
+ r=0
+ if r>threshold then
+ result={}
+ end
+ return done
+ end,
+ handle=function(...)
+ for i=1,select("#",...) do
+ r=r+1
+ result[r]=select(i,...)
+ end
+ end,
}
local function xmltostring(root)
- if not root then
- return ""
- elseif type(root)=="string" then
- return root
- else
- return serialize(root,xmlstringhandler) or ""
- end
+ if not root then
+ return ""
+ elseif type(root)=="string" then
+ return root
+ else
+ return serialize(root,xmlstringhandler) or ""
+ end
end
local function __tostring(root)
- return (root and xmltostring(root)) or ""
+ return (root and xmltostring(root)) or ""
end
initialize_mt=function(root)
- mt={ __tostring=__tostring,__index=root }
+ mt={ __tostring=__tostring,__index=root }
end
xml.defaulthandlers=handlers
xml.newhandlers=newhandlers
xml.serialize=serialize
xml.tostring=xmltostring
local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- xmlstring(edt[i],handle)
- end
- end
- else
- handle(e)
+ if not handle or (e.special and e.tg~="@rt@") then
+ elseif e.tg then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ xmlstring(edt[i],handle)
+ end
end
+ else
+ handle(e)
+ end
end
xml.string=xmlstring
function xml.settings(e)
- while e do
- local s=e.settings
- if s then
- return s
- else
- e=e.__p__
- end
+ while e do
+ local s=e.settings
+ if s then
+ return s
+ else
+ e=e.__p__
end
- return nil
+ end
+ return nil
end
function xml.root(e)
- local r=e
- while e do
- e=e.__p__
- if e then
- r=e
- end
+ local r=e
+ while e do
+ e=e.__p__
+ if e then
+ r=e
end
- return r
+ end
+ return r
end
function xml.parent(root)
- return root.__p__
+ return root.__p__
end
function xml.body(root)
- return root.ri and root.dt[root.ri] or root
+ return root.ri and root.dt[root.ri] or root
end
function xml.name(root)
- if not root then
- return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
- return tg
- else
- return ns..":"..tg
- end
+ if not root then
+ return ""
+ end
+ local ns=root.ns
+ local tg=root.tg
+ if ns=="" then
+ return tg
+ else
+ return ns..":"..tg
+ end
end
function xml.erase(dt,k)
- if dt then
- if k then
- dt[k]=""
- else for k=1,#dt do
- dt[1]={ "" }
- end end
- end
+ if dt then
+ if k then
+ dt[k]=""
+ else for k=1,#dt do
+ dt[1]={ "" }
+ end end
+ end
end
function xml.assign(dt,k,root)
- if dt and k then
- dt[k]=type(root)=="table" and xml.body(root) or root
- return dt[k]
- else
- return xml.body(root)
- end
+ if dt and k then
+ dt[k]=type(root)=="table" and xml.body(root) or root
+ return dt[k]
+ else
+ return xml.body(root)
+ end
end
function xml.tocdata(e,wrapper)
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
- whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
+ local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
+ if wrapper then
+ whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
+ end
+ local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
+ setmetatable(t,getmetatable(e))
+ e.dt={ t }
end
function xml.makestandalone(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" then
- local txt=v.dt[1]
- if find(txt,"xml.*version=") then
- v.dt[1]=txt.." standalone='yes'"
- break
- end
- end
+ if root.ri then
+ local dt=root.dt
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="table" and v.special and v.tg=="@pi@" then
+ local txt=v.dt[1]
+ if find(txt,"xml.*version=") then
+ v.dt[1]=txt.." standalone='yes'"
+ break
end
+ end
end
- return root
+ end
+ return root
end
function xml.kind(e)
- local dt=e and e.dt
- if dt then
- local n=#dt
- if n==1 then
- local d=dt[1]
- if d.special then
- local tg=d.tg
- if tg=="@cd@" then
- return "cdata"
- elseif tg=="@cm" then
- return "comment"
- elseif tg=="@pi@" then
- return "instruction"
- elseif tg=="@dt@" then
- return "declaration"
- end
- elseif type(d)=="string" then
- return "text"
- end
- return "element"
- elseif n>0 then
- return "mixed"
- end
+ local dt=e and e.dt
+ if dt then
+ local n=#dt
+ if n==1 then
+ local d=dt[1]
+ if d.special then
+ local tg=d.tg
+ if tg=="@cd@" then
+ return "cdata"
+ elseif tg=="@cm" then
+ return "comment"
+ elseif tg=="@pi@" then
+ return "instruction"
+ elseif tg=="@dt@" then
+ return "declaration"
+ end
+ elseif type(d)=="string" then
+ return "text"
+ end
+ return "element"
+ elseif n>0 then
+ return "mixed"
end
- return "empty"
+ end
+ return "empty"
end
@@ -13571,14 +17060,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
--- original size: 53301, stripped down to: 32477
+-- original size: 55145, stripped down to: 30992
if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local concat,remove,insert=table.concat,table.remove,table.insert
local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
@@ -13591,21 +17080,21 @@ local trace_lparse=false
local trace_lprofile=false
local report_lpath=logs.reporter("xml","lpath")
if trackers then
- trackers.register("xml.path",function(v)
- trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
- trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
- trace_lpath=v
- trace_lparse=v
- trace_lprofile=v
- end)
+ trackers.register("xml.path",function(v)
+ trace_lpath=v
+ end)
+ trackers.register("xml.parse",function(v)
+ trace_lparse=v
+ end)
+ trackers.register("xml.profile",function(v)
+ trace_lpath=v
+ trace_lparse=v
+ trace_lprofile=v
+ end)
end
local xml=xml
-local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
-local lpathcached=0 function xml.lpathcached() return lpathcached end
+local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
+local lpathcached=0 function xml.lpathcached() return lpathcached end
xml.functions=xml.functions or {}
local functions=xml.functions
xml.expressions=xml.expressions or {}
@@ -13619,216 +17108,271 @@ local xmlpatterns=lpegpatterns.xml
finalizers.xml=finalizers.xml or {}
finalizers.tex=finalizers.tex or {}
local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
- t[name]=fn
- else
- report_lpath("unknown sub finalizer %a",name)
- fn=function() end
- end
- return fn
+ local fn=finalizers[name]
+ if fn then
+ t[name]=fn
+ else
+ report_lpath("unknown sub finalizer %a",name)
+ fn=function() end
+ end
+ return fn
end
setmetatableindex(finalizers.xml,fallback)
setmetatableindex(finalizers.tex,fallback)
xml.defaultprotocol="xml"
local apply_axis={}
apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
- local ll=list[l]
- local rt=ll
- while ll do
- ll=ll.__p__
- if ll then
- rt=ll
- end
- end
- collected[l]=rt
+ local collected={}
+ for l=1,#list do
+ local ll=list[l]
+ local rt=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
+ rt=ll
+ end
end
- return collected
+ collected[l]=rt
+ end
+ return collected
end
apply_axis['self']=function(list)
- return list
+ return list
end
apply_axis['child']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local dt=ll.dt
- if dt then
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- end
- end
- ll.en=en
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ local dt=ll.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ end
end
+ ll.en=en
+ end
end
- return collected
+ end
+ return collected
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]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- c=collect(dk,collected,c)
- end
+ local dt=list.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ c=collect(dk,collected,c)
end
- list.en=en
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant']=function(list)
- local collected,c={},0
- for l=1,#list do
- c=collect(list[l],collected,c)
- end
- return collected
+ local collected={}
+ local c=0
+ for l=1,#list do
+ c=collect(list[l],collected,c)
+ end
+ return collected
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]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- c=collect(dk,collected,c)
- end
+ local dt=list.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ c=collect(dk,collected,c)
end
- list.en=en
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- if ll.special~=true then
- c=c+1
- collected[c]=ll
- end
- c=collect(ll,collected,c)
- end
- return collected
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ if ll.special~=true then
+ c=c+1
+ collected[c]=ll
+ end
+ c=collect(ll,collected,c)
+ end
+ return collected
end
apply_axis['ancestor']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ while ll do
+ ll=ll.__p__
+ if ll then
+ c=c+1
+ collected[c]=ll
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['ancestor-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ c=c+1
+ collected[c]=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
c=c+1
collected[c]=ll
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['parent']=function(list)
- local collected,c={},0
- for l=1,#list do
- local pl=list[l].__p__
- if pl then
- c=c+1
- collected[c]=pl
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local pl=list[l].__p__
+ if pl then
+ c=c+1
+ collected[c]=pl
end
- return collected
+ end
+ return collected
end
apply_axis['attribute']=function(list)
- return {}
+ return {}
end
apply_axis['namespace']=function(list)
- return {}
+ return {}
end
apply_axis['following']=function(list)
- return {}
+ return {}
end
apply_axis['preceding']=function(list)
- return {}
+ return {}
end
apply_axis['following-sibling']=function(list)
- 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
- end
- end
+ 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,#d do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['preceding-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=1,ll.ni-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=1,ll.ni-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['reverse-sibling']=function(list)
- 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
- end
- end
+ 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
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
apply_axis['auto-descendant']=apply_axis['descendant']
@@ -13836,130 +17380,147 @@ apply_axis['auto-child']=apply_axis['child']
apply_axis['auto-self']=apply_axis['self']
apply_axis['initial-child']=apply_axis['child']
local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then
- local nns,ntg=nodes[2],nodes[3]
- if not nns and not ntg then
+ local maxn=#nodes
+ if maxn==3 then
+ local nns=nodes[2]
+ local ntg=nodes[3]
+ if not nns and not ntg then
+ if directive then
+ return list
+ else
+ return {}
+ end
+ else
+ local collected={}
+ local c=0
+ local m=0
+ local p=nil
+ if not nns then
+ for l=1,#list do
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
if directive then
- return list
- else
- return {}
+ if ntg==ltg then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif ntg~=ltg then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- else
- local collected,c,m,p={},0,0,nil
- if not nns then
- for l=1,#list do
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif ntg~=ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- elseif not ntg then
- for l=1,#list do
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif lns~=nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- else
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
+ end
+ end
+ elseif not ntg then
+ for l=1,#list do
+ 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=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif lns~=nns then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- return collected
+ end
end
- else
- local collected,c,m,p={},0,0,nil
+ else
for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=false
- for n=1,maxn,3 do
- local nns,ntg=nodes[n+1],nodes[n+2]
- ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
- if ok then
- break
- end
- end
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=ltg==ntg and lns==nns
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
+ end
end
- return collected
+ end
+ return collected
end
-end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected,c={},0
- quit_expression=false
+ else
+ local collected={}
+ local c=0
+ local m=0
+ local p=nil
for l=1,#list do
- local ll=list[l]
- if expression(list,ll,l,order) then
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=false
+ for n=1,maxn,3 do
+ 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
+ end
+ end
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
c=c+1
collected[c]=ll
+ ll.mi=m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- if quit_expression then
- break
- end
+ end
end
return collected
+ end
end
-local function apply_selector(list,specification)
- if xml.applyselector then
- apply_selector=xml.applyselector
- return apply_selector(list,specification)
- else
- return list
+local quit_expression=false
+local function apply_expression(list,expression,order)
+ local collected={}
+ local c=0
+ quit_expression=false
+ for l=1,#list do
+ local ll=list[l]
+ if expression(list,ll,l,order) then
+ c=c+1
+ collected[c]=ll
+ end
+ if quit_expression then
+ break
end
+ end
+ return collected
+end
+local function apply_selector(list,specification)
+ if xml.applyselector then
+ apply_selector=xml.applyselector
+ return apply_selector(list,specification)
+ else
+ return list
+ end
end
local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
local spaces=S(" \n\r\t\f")^0
@@ -13970,24 +17531,24 @@ local lp_doequal=P("=")/"=="
local lp_or=P("|")/" or "
local lp_and=P("&")/" and "
local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
+ text="(ll.dt[1] or '')",
+ content="ll.dt",
+ name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
+ tag="ll.tg",
+ position="l",
+ firstindex="1",
+ firstelement="1",
+ first="1",
+ lastindex="(#ll.__p__.dt or 1)",
+ lastelement="(ll.__p__.en or 1)",
+ last="#list",
+ rootposition="order",
+ order="order",
+ element="(ll.ei or 1)",
+ index="(ll.ni or 1)",
+ match="(ll.mi or 1)",
+ namespace="ll.ns",
+ ns="ll.ns",
}
local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
@@ -13997,11 +17558,11 @@ local lp_fastpos=lp_fastpos_n+lp_fastpos_p
local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t)
- if expressions[t] then
- return "expr."..t.."("
- else
- return "expr.error("
- end
+ if expressions[t] then
+ return "expr."..t.."("
+ else
+ return "expr.error("
+ end
end
local lparent=P("(")
local rparent=P(")")
@@ -14014,24 +17575,24 @@ local lp_string=Cc("'")*R("az","AZ","--","__")^1*Cc("'")
local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
local cleaner
local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
- s=s and s~="" and lpegmatch(cleaner,s)
- if s and s~="" then
- return "expr."..t.."(ll,"..s..")"
- else
- return "expr."..t.."(ll)"
- end
+ if expressions[t] then
+ s=s and s~="" and lpegmatch(cleaner,s)
+ if s and s~="" then
+ return "expr."..t.."(ll,"..s..")"
else
- return "expr.error("..t..")"
+ return "expr."..t.."(ll)"
end
+ else
+ return "expr.error("..t..")"
+ end
end
local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
+ lp_child+lp_any
local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
+ lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
)
cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
+ lp_reserved+lp_number+lp_string+1 )^1 )
local template_e=[[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -14047,75 +17608,75 @@ local template_f_y=[[
local template_f_n=[[
return xml.finalizers['%s']['%s']
]]
-local register_last_match={ kind="axis",axis="last-match" }
-local register_self={ kind="axis",axis="self" }
-local register_parent={ kind="axis",axis="parent" }
-local register_descendant={ kind="axis",axis="descendant" }
-local register_child={ kind="axis",axis="child" }
+local register_last_match={ kind="axis",axis="last-match" }
+local register_self={ kind="axis",axis="self" }
+local register_parent={ kind="axis",axis="parent" }
+local register_descendant={ kind="axis",axis="descendant" }
+local register_child={ kind="axis",axis="child" }
local register_descendant_or_self={ kind="axis",axis="descendant-or-self" }
-local register_root={ kind="axis",axis="root" }
-local register_ancestor={ kind="axis",axis="ancestor" }
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
-local register_attribute={ kind="axis",axis="attribute" }
-local register_namespace={ kind="axis",axis="namespace" }
-local register_following={ kind="axis",axis="following" }
+local register_root={ kind="axis",axis="root" }
+local register_ancestor={ kind="axis",axis="ancestor" }
+local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
+local register_attribute={ kind="axis",axis="attribute" }
+local register_namespace={ kind="axis",axis="namespace" }
+local register_following={ kind="axis",axis="following" }
local register_following_sibling={ kind="axis",axis="following-sibling" }
-local register_preceding={ kind="axis",axis="preceding" }
+local register_preceding={ kind="axis",axis="preceding" }
local register_preceding_sibling={ kind="axis",axis="preceding-sibling" }
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
+local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" }
-local register_auto_descendant={ kind="axis",axis="auto-descendant" }
-local register_auto_self={ kind="axis",axis="auto-self" }
-local register_auto_child={ kind="axis",axis="auto-child" }
-local register_initial_child={ kind="axis",axis="initial-child" }
+local register_auto_descendant={ kind="axis",axis="auto-descendant" }
+local register_auto_self={ kind="axis",axis="auto-self" }
+local register_auto_child={ kind="axis",axis="auto-child" }
+local register_initial_child={ kind="axis",axis="initial-child" }
local register_all_nodes={ kind="nodes",nodetest=true,nodes={ true,false,false } }
local skip={}
local function errorrunner_e(str,cnv)
- if not skip[str] then
- report_lpath("error in expression: %s => %s",str,cnv)
- skip[str]=cnv or str
- end
- return false
+ if not skip[str] then
+ report_lpath("error in expression: %s => %s",str,cnv)
+ skip[str]=cnv or str
+ end
+ return false
end
local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
+ report_lpath("error in finalizer: %s(%s)",str,arg or "")
+ return false
end
local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
+ return { kind="nodes",nodetest=nodetest,nodes=nodes }
end
local function register_selector(specification)
- return { kind="selector",specification=specification }
+ return { kind="selector",specification=specification }
end
local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local runner=load(format(template_e,converted))
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
+ local converted=lpegmatch(converter,expression)
+ local runner=load(format(template_e,converted))
+ runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
+ return { kind="expression",expression=expression,converted=converted,evaluator=runner }
end
local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
- runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
- runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
+ local runner
+ if arguments and arguments~="" then
+ runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+ else
+ runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
+ end
+ runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
+ return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
end
local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
+ ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
+ sq="'"*(1-S("'"))^0*"'",
+ dq='"'*(1-S('"'))^0*'"',
}
local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
+ ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
+ nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
+ sq=P("'")*(1-P("'"))^0*P("'"),
+ dq=P('"')*(1-P('"'))^0*P('"'),
}
local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
+ return { kind="error",error=format("unparsed: %s",str) }
end
local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes)
local special_2=P("/")*Cc(register_auto_self)
@@ -14123,367 +17684,368 @@ local special_3=P("")*Cc(register_auto_self)
local no_nextcolon=P(-1)+#(1-P(":"))
local no_nextlparent=P(-1)+#(1-P("("))
local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
- (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
- ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
+ patterns=spaces*V("protocol")*spaces*(
+ (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
+ ),
+ protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
+ step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
+ axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
+ special=special_1+special_2+special_3,
+ initial=(P("/")*spaces*Cc(register_initial_child))^-1,
+ error=(P(1)^1)/register_error,
+ shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
+ shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
+ s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
+ s_descendant=P("**")*Cc(register_descendant),
+ s_child=P("*")*no_nextcolon*Cc(register_child),
+ s_parent=P("..")*Cc(register_parent),
+ s_self=P("." )*Cc(register_self),
+ s_root=P("^^")*Cc(register_root),
+ s_ancestor=P("^")*Cc(register_ancestor),
+ s_lastmatch=P("=")*Cc(register_last_match),
+ descendant=P("descendant::")*Cc(register_descendant),
+ child=P("child::")*Cc(register_child),
+ parent=P("parent::")*Cc(register_parent),
+ self=P("self::")*Cc(register_self),
+ root=P('root::')*Cc(register_root),
+ ancestor=P('ancestor::')*Cc(register_ancestor),
+ descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
+ ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
+ following=P('following::')*Cc(register_following),
+ following_sibling=P('following-sibling::')*Cc(register_following_sibling),
+ preceding=P('preceding::')*Cc(register_preceding),
+ preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
+ reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
+ last_match=P('last-match::')*Cc(register_last_match),
+ selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
+ nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
+ expressions=expression/register_expression,
+ letters=R("az")^1,
+ name=(1-S("/[]()|:*!"))^1,
+ negate=P("!")*Cc(false),
+ nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
+ nodetest=V("negate")+Cc(true),
+ nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
+ wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
+ nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
+ finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
}
xmlpatterns.pathparser=pathparser
local cache={}
local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
- local directive,ns,tg=set[i],set[i+1],set[i+2]
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
- return format("not(%s)",concat(t,"|"))
- else
- return concat(t,"|")
- end
+ local t={}
+ for i=1,#set,3 do
+ local directive,ns,tg=set[i],set[i+1],set[i+2]
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+ t[#t+1]=(directive and tg) or format("not(%s)",tg)
+ end
+ if nodetest==false then
+ return format("not(%s)",concat(t,"|"))
+ else
+ return concat(t,"|")
+ end
end
local function tagstostring(list)
- if #list==0 then
- return "no elements"
- else
- local t={}
- for i=1,#list do
- local li=list[i]
- local ns,tg=li.ns,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)
- end
- return concat(t," ")
+ if #list==0 then
+ return "no elements"
+ else
+ local t={}
+ for i=1,#list do
+ local li=list[i]
+ 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)
end
+ return concat(t," ")
+ end
end
xml.nodesettostring=nodesettostring
local lpath
local function lshow(parsed)
- if type(parsed)=="string" then
- parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
- table.serialize(parsed,false))
+ if type(parsed)=="string" then
+ parsed=lpath(parsed)
+ end
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+ table.serialize(parsed,false))
end
xml.lshow=lshow
local function add_comment(p,str)
- local pc=p.comment
- if not pc then
- p.comment={ str }
- else
- pc[#pc+1]=str
- end
+ local pc=p.comment
+ if not pc then
+ p.comment={ str }
+ else
+ pc[#pc+1]=str
+ end
end
lpath=function (pattern)
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
- return pattern
- else
- local parsed=cache[pattern]
- if parsed then
- lpathcached=lpathcached+1
+ lpathcalls=lpathcalls+1
+ if type(pattern)=="table" then
+ return pattern
+ else
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcached=lpathcached+1
+ else
+ parsed=lpegmatch(pathparser,pattern)
+ if parsed then
+ parsed.pattern=pattern
+ local np=#parsed
+ if np==0 then
+ parsed={ pattern=pattern,register_self,state="parsing error" }
+ report_lpath("parsing error in pattern: %s",pattern)
+ lshow(parsed)
else
- parsed=lpegmatch(pathparser,pattern)
- if parsed then
- parsed.pattern=pattern
- local np=#parsed
- if np==0 then
- parsed={ pattern=pattern,register_self,state="parsing error" }
- report_lpath("parsing error in pattern: %s",pattern)
- lshow(parsed)
- else
- local pi=parsed[1]
- if pi.axis=="auto-child" then
- if false then
- add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
- parsed[1]=register_auto_descendant_or_self
- else
- add_comment(parsed,"auto-child replaced by auto-descendant")
- parsed[1]=register_auto_descendant
- end
- elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
- add_comment(parsed,"initial-child removed")
- remove(parsed,1)
- end
- local np=#parsed
- if np>1 then
- local pnp=parsed[np]
- if pnp.kind=="nodes" and pnp.nodetest==true then
- local nodes=pnp.nodes
- if nodes[1]==true and nodes[2]==false and nodes[3]==false then
- add_comment(parsed,"redundant final wildcard filter removed")
- remove(parsed,np)
- end
- end
- end
- end
+ local pi=parsed[1]
+ if pi.axis=="auto-child" then
+ if false then
+ add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
+ parsed[1]=register_auto_descendant_or_self
else
- parsed={ pattern=pattern }
+ add_comment(parsed,"auto-child replaced by auto-descendant")
+ parsed[1]=register_auto_descendant
end
- cache[pattern]=parsed
- if trace_lparse and not trace_lprofile then
- lshow(parsed)
+ elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
+ add_comment(parsed,"initial-child removed")
+ remove(parsed,1)
+ end
+ local np=#parsed
+ if np>1 then
+ local pnp=parsed[np]
+ if pnp.kind=="nodes" and pnp.nodetest==true then
+ local nodes=pnp.nodes
+ if nodes[1]==true and nodes[2]==false and nodes[3]==false then
+ add_comment(parsed,"redundant final wildcard filter removed")
+ remove(parsed,np)
+ end
end
+ end
end
- return parsed
+ else
+ parsed={ pattern=pattern }
+ end
+ cache[pattern]=parsed
+ if trace_lparse and not trace_lprofile then
+ lshow(parsed)
+ end
end
+ return parsed
+ end
end
xml.lpath=lpath
do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil
- local keepmatch=nil
- if directives then
- directives.register("xml.path.keeplastmatch",function(v)
- keepmatch=v
- lastmatch=nil
- end)
- end
- apply_axis["last-match"]=function()
- return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
- local p=profiled[parsed.pattern]
- if p then
- p.tested=p.tested+1
- else
- p={ tested=1,matched=0,finalized=0 }
- profiled[parsed.pattern]=p
- end
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- p.matched=p.matched+1
- p.finalized=p.finalized+1
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- p.finalized=p.finalized+1
- return collected
- end
- return nil
- end
- end
- if collected then
- p.matched=p.matched+1
- end
- return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
- if trace_lparse then
- lshow(parsed)
- end
- report_lpath("collecting: %s",parsed.pattern)
- report_lpath("root tags : %s",tagstostring(list))
- report_lpath("order : %s",order or "unset")
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
- return collected
- end
- return nil
- end
- end
+ local profiled={}
+ xml.profiled=profiled
+ local lastmatch=nil
+ local keepmatch=nil
+ if directives then
+ directives.register("xml.path.keeplastmatch",function(v)
+ keepmatch=v
+ lastmatch=nil
+ end)
+ end
+ apply_axis["last-match"]=function()
+ return lastmatch or {}
+ end
+ local function profiled_apply(list,parsed,nofparsed,order)
+ local p=profiled[parsed.pattern]
+ if p then
+ p.tested=p.tested+1
+ else
+ p={ tested=1,matched=0,finalized=0 }
+ profiled[parsed.pattern]=p
+ end
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ p.matched=p.matched+1
+ p.finalized=p.finalized+1
return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- local axis=pi.axis
- if axis~="self" then
- collected=apply_axis[axis](collected)
- end
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- return pi.finalizer(collected)
- end
- if not collected or #collected==0 then
- local pf=i<nofparsed and parsed[nofparsed].finalizer
- if pf then
- return pf(collected)
- end
- return nil
- end
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ p.finalized=p.finalized+1
+ return collected
end
- return collected
+ return nil
+ end
end
- local apply=normal_apply
- if trackers then
- trackers.register("xml.path,xml.parse,xml.profile",function()
- if trace_lprofile then
- apply=profiled_apply
- elseif trace_lpath then
- apply=traced_apply
- else
- apply=normal_apply
- end
- end)
+ if collected then
+ p.matched=p.matched+1
end
- function xml.applylpath(list,pattern)
- if not list then
- lastmatch=nil
- return
- end
- local parsed=cache[pattern]
- if parsed then
- lpathcalls=lpathcalls+1
- lpathcached=lpathcached+1
- elseif type(pattern)=="table" then
- lpathcalls=lpathcalls+1
- parsed=pattern
- else
- parsed=lpath(pattern) or pattern
- end
- if not parsed then
- lastmatch=nil
- return
- end
- local nofparsed=#parsed
- if nofparsed==0 then
- lastmatch=nil
- return
- end
- local collected=apply({ list },parsed,nofparsed,list.mi)
- lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ local function traced_apply(list,parsed,nofparsed,order)
+ if trace_lparse then
+ lshow(parsed)
+ end
+ report_lpath("collecting: %s",parsed.pattern)
+ report_lpath("root tags : %s",tagstostring(list))
+ report_lpath("order : %s",order or "unset")
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
return collected
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+ return collected
+ end
+ return nil
+ end
end
- function xml.lastmatch()
- return lastmatch
- end
- local stack={}
- function xml.pushmatch()
- insert(stack,lastmatch)
- end
- function xml.popmatch()
- lastmatch=remove(stack)
+ return collected
+ end
+ local function normal_apply(list,parsed,nofparsed,order)
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ local axis=pi.axis
+ if axis~="self" then
+ collected=apply_axis[axis](collected)
+ end
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ return pi.finalizer(collected)
+ end
+ if not collected or #collected==0 then
+ local pf=i<nofparsed and parsed[nofparsed].finalizer
+ if pf then
+ return pf(collected)
+ end
+ return nil
+ end
end
+ return collected
+ end
+ local apply=normal_apply
+ if trackers then
+ trackers.register("xml.path,xml.parse,xml.profile",function()
+ if trace_lprofile then
+ apply=profiled_apply
+ elseif trace_lpath then
+ apply=traced_apply
+ else
+ apply=normal_apply
+ end
+ end)
+ end
+ function xml.applylpath(list,pattern)
+ if not list then
+ lastmatch=nil
+ return
+ end
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcalls=lpathcalls+1
+ lpathcached=lpathcached+1
+ elseif type(pattern)=="table" then
+ lpathcalls=lpathcalls+1
+ parsed=pattern
+ else
+ parsed=lpath(pattern) or pattern
+ end
+ if not parsed then
+ lastmatch=nil
+ return
+ end
+ local nofparsed=#parsed
+ if nofparsed==0 then
+ lastmatch=nil
+ return
+ end
+ local collected=apply({ list },parsed,nofparsed,list.mi)
+ lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ function xml.lastmatch()
+ return lastmatch
+ end
+ local stack={}
+ function xml.pushmatch()
+ insert(stack,lastmatch)
+ end
+ function xml.popmatch()
+ lastmatch=remove(stack)
+ end
end
local applylpath=xml.applylpath
function xml.filter(root,pattern)
- return applylpath(root,pattern)
+ return applylpath(root,pattern)
end
expressions.child=function(e,pattern)
- return applylpath(e,pattern)
+ return applylpath(e,pattern)
end
expressions.count=function(e,pattern)
- local collected=applylpath(e,pattern)
- return pattern and (collected and #collected) or 0
+ local collected=applylpath(e,pattern)
+ return pattern and (collected and #collected) or 0
end
expressions.oneof=function(s,...)
- for i=1,select("#",...) do
- if s==select(i,...) then
- return true
- end
+ for i=1,select("#",...) do
+ if s==select(i,...) then
+ return true
end
- return false
+ end
+ return false
end
expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
+ xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
+ return false
end
expressions.undefined=function(s)
- return s==nil
+ return s==nil
end
expressions.quit=function(s)
- if s or s==nil then
- quit_expression=true
- end
- return true
+ if s or s==nil then
+ quit_expression=true
+ end
+ return true
end
expressions.print=function(...)
- print(...)
- return true
+ print(...)
+ return true
end
expressions.find=find
expressions.upper=upper
@@ -14491,233 +18053,238 @@ expressions.lower=lower
expressions.number=tonumber
expressions.boolean=toboolean
function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
- if find(str,pattern) then
- return true
- end
- elseif t=="table" then
- for i=1,#str do
- local d=str[i]
- if type(d)=="string" and find(d,pattern) then
- return true
- end
- end
+ local t=type(str)
+ if t=="string" then
+ if find(str,pattern) then
+ return true
end
- return false
+ elseif t=="table" then
+ for i=1,#str do
+ local d=str[i]
+ if type(d)=="string" and find(d,pattern) then
+ return true
+ end
+ end
+ end
+ return false
end
function xml.expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
+ return type(str)=="string" and gsub(str,"^#","") or ""
end
local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local r=e.__p__
- handle(r,r.dt,e.ni)
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local r=e.__p__
+ handle(r,r.dt,e.ni)
end
+ end
end
local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- if handle then
- for c=1,#collected do
- handle(collected[c])
- end
- else
- return collected
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ if handle then
+ for c=1,#collected do
+ handle(collected[c])
+ end
+ else
+ return collected
end
+ end
end
-xml.traverse=traverse
+xml.traverse=traverse
xml.selection=selection
local function dofunction(collected,fnc,...)
- if collected then
- local f=functions[fnc]
- if f then
- for c=1,#collected do
- f(collected[c],...)
- end
- else
- report_lpath("unknown function %a",fnc)
- end
+ if collected then
+ local f=functions[fnc]
+ if f then
+ for c=1,#collected do
+ f(collected[c],...)
+ end
+ else
+ report_lpath("unknown function %a",fnc)
end
+ end
end
finalizers.xml["function"]=dofunction
finalizers.tex["function"]=dofunction
expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
+ local rdt=e.__p__.dt
+ return rdt and rdt[n] or ""
end
expressions.name=function(e,n)
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=type(e)=="table" and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=type(e)=="table" and e
+ elseif n<0 then
+ 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
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
end
+ end
end
- if found then
- local ns,tg=found.rn or found.ns or "",found.tg
- if ns~="" then
- return ns..":"..tg
+ else
+ 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
+ if n==1 then
+ found=di
+ break
else
- return tg
+ n=n-1
end
+ end
+ end
+ end
+ if found then
+ local ns=found.rn or found.ns or ""
+ local tg=found.tg
+ if ns~="" then
+ return ns..":"..tg
else
- return ""
+ return tg
end
+ else
+ return ""
+ end
end
expressions.tag=function(e,n)
- if not e then
- return ""
+ if not e then
+ return ""
+ else
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=(type(e)=="table") and e
+ elseif n<0 then
+ 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
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
+ end
+ end
+ end
else
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=(type(e)=="table") and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
+ 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
+ if n==1 then
+ found=di
+ break
+ else
+ n=n-1
+ end
end
- return (found and found.tg) or ""
+ end
end
+ return (found and found.tg) or ""
+ end
end
local dummy=function() end
function xml.elements(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
+ end
end
function xml.collected(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ return collected[c]
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- return collected[c]
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- return collected[c]
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ return collected[c]
+ end
end
+ end
end
function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
- report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
+ pattern=pattern or "."
+ for e in xml.collected(collection,pattern or ".") do
+ report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+ end
end
local function split(e)
- local dt=e.dt
- if dt then
- for i=1,#dt do
- local dti=dt[i]
- if type(dti)=="string" then
- dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti=gsub(dti,"[\n\r]+","\n\n")
- dt[i]=dti
- else
- split(dti)
- end
- end
+ local dt=e.dt
+ if dt then
+ for i=1,#dt do
+ local dti=dt[i]
+ if type(dti)=="string" then
+ dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+ dti=gsub(dti,"[\n\r]+","\n\n")
+ dt[i]=dti
+ else
+ split(dti)
+ end
end
- return e
+ end
+ return e
end
function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
+ for i=1,#c do
+ split(c[i])
+ end
+ return c
end
@@ -14727,14 +18294,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
--- original size: 3574, stripped down to: 1863
+-- original size: 3574, stripped down to: 1808
if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local xml,lpeg,string=xml,lpeg,string
local type=type
@@ -14745,26 +18312,26 @@ local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs
lpegpatterns.xml=lpegpatterns.xml or {}
local xmlpatterns=lpegpatterns.xml
local function xmlgsub(t,old,new)
- local dt=t.dt
- if dt then
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="string" then
- dt[k]=gsub(v,old,new)
- else
- xmlgsub(v,old,new)
- end
- end
+ local dt=t.dt
+ if dt then
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="string" then
+ dt[k]=gsub(v,old,new)
+ else
+ xmlgsub(v,old,new)
+ end
end
+ end
end
function xml.stripleadingspaces(dk,d,k)
- if d and k then
- local dkm=d[k-1]
- if dkm and type(dkm)=="string" then
- local s=match(dkm,"\n(%s+)")
- xmlgsub(dk,"\n"..rep(" ",#s),"\n")
- end
+ if d and k then
+ local dkm=d[k-1]
+ if dkm and type(dkm)=="string" then
+ local s=match(dkm,"\n(%s+)")
+ xmlgsub(dk,"\n"..rep(" ",#s),"\n")
end
+ end
end
local normal=(1-S("<&>"))^0
local special=P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"
@@ -14776,17 +18343,17 @@ local cleansed=Cs(((P("<")*(1-P(">"))^0*P(">"))/""+1)^0)
xmlpatterns.escaped=escaped
xmlpatterns.unescaped=unescaped
xmlpatterns.cleansed=cleansed
-function xml.escaped (str) return lpegmatch(escaped,str) end
+function xml.escaped (str) return lpegmatch(escaped,str) end
function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str) end
+function xml.cleansed (str) return lpegmatch(cleansed,str) end
function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
- local n=#e.dt
- if not check or n==0 or (n==1 and e.dt[1]=="") then
- e.dt={ str }
- end
+ local e=xml.first(root,pattern)
+ if e then
+ local n=#e.dt
+ if not check or n==0 or (n==1 and e.dt[1]=="") then
+ e.dt={ str }
end
+ end
end
@@ -14796,17 +18363,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
--- original size: 30650, stripped down to: 21793
+-- original size: 30771, stripped down to: 19680
if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
+local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
+local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
local report_xml=logs.reporter("xml")
local xml=xml
local xmlcopy,xmlname=xml.copy,xml.name
@@ -14819,308 +18386,313 @@ local utfbyte=utf.byte
local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
local striplinepatterns=utilities.strings.striplinepatterns
local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
+ report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
end
local function withelements(e,handle,depth)
- if e and handle then
- local edt=e.dt
- if edt then
- depth=depth or 0
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- handle(e,depth)
- withelements(e,handle,depth+1)
- end
- end
+ if e and handle then
+ local edt=e.dt
+ if edt then
+ depth=depth or 0
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ handle(e,depth)
+ withelements(e,handle,depth+1)
end
+ end
end
+ end
end
xml.withelements=withelements
function xml.withelement(e,n,handle)
- if e and n~=0 and handle then
- local edt=e.dt
- if edt then
- if n>0 then
- for i=1,#edt do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==1 then
- handle(ei)
- return
- else
- n=n-1
- end
- end
- end
- elseif n<0 then
- for i=#edt,1,-1 do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==-1 then
- handle(ei)
- return
- else
- n=n+1
- end
- end
- end
+ if e and n~=0 and handle then
+ local edt=e.dt
+ if edt then
+ if n>0 then
+ for i=1,#edt do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==1 then
+ handle(ei)
+ return
+ else
+ n=n-1
end
+ end
end
- end
-end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- if handle then
- if reverse then
- for c=#collected,1,-1 do
- handle(collected[c])
- end
+ elseif n<0 then
+ for i=#edt,1,-1 do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==-1 then
+ handle(ei)
+ return
else
- for c=1,#collected do
- handle(collected[c])
- end
+ n=n+1
end
+ end
end
- return collected
+ end
end
+ end
end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
+function xml.each(root,pattern,handle,reverse)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ if handle then
+ if reverse then
+ for c=#collected,1,-1 do
+ handle(collected[c])
+ end
+ else
for c=1,#collected do
- handle(collected[c].at)
+ handle(collected[c])
end
+ end
end
return collected
+ end
+end
+function xml.processattributes(root,pattern,handle)
+ local collected=xmlapplylpath(root,pattern)
+ if collected and handle then
+ for c=1,#collected do
+ handle(collected[c].at)
+ end
+ end
+ return collected
end
function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
+ return xmlapplylpath(root,pattern)
end
function xml.collecttexts(root,pattern,flatten)
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
- local xmltostring=xml.tostring
- for c=1,#collected do
- collected[c]=xmltostring(collected[c].dt)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected and flatten then
+ local xmltostring=xml.tostring
+ for c=1,#collected do
+ collected[c]=xmltostring(collected[c].dt)
end
- return collected or {}
+ end
+ return collected or {}
end
function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- local t,n={},0
- for c=1,#collected do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace then
- t[n]=tg
- elseif ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ local t={}
+ local n=0
+ for c=1,#collected do
+ local e=collected[c]
+ local ns=e.ns
+ local tg=e.tg
+ n=n+1
+ if nonamespace then
+ t[n]=tg
+ elseif ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
+ end
end
+ return t
+ end
end
local no_root={ no_root=true }
local function redo_ni(d)
- for k=1,#d do
- local dk=d[k]
- if type(dk)=="table" then
- dk.ni=k
- end
+ for k=1,#d do
+ local dk=d[k]
+ if type(dk)=="table" then
+ dk.ni=k
end
+ end
end
xml.reindex=redo_ni
local function xmltoelement(whatever,root)
- if not whatever then
- return nil
- end
- local element
- if type(whatever)=="string" then
- element=xmlinheritedconvert(whatever,root)
- else
- element=whatever
- end
- if element.error then
- return whatever
- end
- if element then
- end
- return element
+ if not whatever then
+ return nil
+ end
+ local element
+ if type(whatever)=="string" then
+ element=xmlinheritedconvert(whatever,root)
+ else
+ element=whatever
+ end
+ if element.error then
+ return whatever
+ end
+ if element then
+ end
+ return element
end
xml.toelement=xmltoelement
local function copiedelement(element,newparent)
- if type(element)=="string" then
- return element
- else
- element=xmlcopy(element).dt
- if newparent and type(element)=="table" then
- element.__p__=newparent
- end
- return element
+ if type(element)=="string" then
+ return element
+ else
+ element=xmlcopy(element).dt
+ if newparent and type(element)=="table" then
+ element.__p__=newparent
end
+ return element
+ end
end
function xml.delete(root,pattern)
- if not pattern or pattern=="" then
- local p=root.__p__
+ if not pattern or pattern=="" then
+ local p=root.__p__
+ if p then
+ if trace_manipulations then
+ report('deleting',"--",c,root)
+ end
+ local d=p.dt
+ remove(d,root.ni)
+ redo_ni(d)
+ end
+ else
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
if p then
- if trace_manipulations then
- report('deleting',"--",c,root)
- end
- local d=p.dt
- remove(d,root.ni)
- redo_ni(d)
- end
- else
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('deleting',pattern,c,e)
- end
- local d=p.dt
- local ni=e.ni
- if ni<=#d then
- if false then
- p.dt[ni]=""
- else
- remove(d,ni)
- redo_ni(d)
- end
- else
- end
- end
+ if trace_manipulations then
+ report('deleting',pattern,c,e)
+ end
+ local d=p.dt
+ local ni=e.ni
+ if ni<=#d then
+ if false then
+ p.dt[ni]=""
+ else
+ remove(d,ni)
+ redo_ni(d)
end
+ else
+ end
end
+ end
end
+ end
end
function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('replacing',pattern,c,e)
- end
- local d=p.dt
- local n=e.ni
- local t=copiedelement(element,p)
- if type(t)=="table" then
- d[n]=t[1]
- for i=2,#t do
- n=n+1
- insert(d,n,t[i])
- end
- else
- d[n]=t
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
+ if p then
+ if trace_manipulations then
+ report('replacing',pattern,c,e)
+ end
+ local d=p.dt
+ local n=e.ni
+ local t=copiedelement(element,p)
+ if type(t)=="table" then
+ d[n]=t[1]
+ for i=2,#t do
+ n=n+1
+ insert(d,n,t[i])
+ end
+ else
+ d[n]=t
end
+ redo_ni(d)
+ end
end
+ end
end
local function wrap(e,wrapper)
- local t={
- rn=e.rn,
- tg=e.tg,
- ns=e.ns,
- at=e.at,
- dt=e.dt,
- __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
+ local t={
+ rn=e.rn,
+ tg=e.tg,
+ ns=e.ns,
+ at=e.at,
+ dt=e.dt,
+ __p__=e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn=wrapper.rn or e.rn or ""
+ e.tg=wrapper.tg or e.tg or ""
+ e.ns=wrapper.ns or e.ns or ""
+ e.at=fastcopy(wrapper.at)
+ e.dt={ t }
end
function xml.wrap(root,pattern,whatever)
- if whatever then
- local wrapper=xmltoelement(whatever,root)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if trace_manipulations then
- report('wrapping',pattern,c,e)
- end
- wrap(e,wrapper)
- end
+ if whatever then
+ local wrapper=xmltoelement(whatever,root)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
end
- else
- wrap(root,xmltoelement(pattern))
+ wrap(e,wrapper)
+ end
end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
end
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 edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
- if edt then
- local be,af
- local cp=copiedelement(element,e)
- if prepend then
- be,af=cp,edt
- else
- be,af=edt,cp
- end
- local bn=#be
- for i=1,#af do
- bn=bn+1
- be[bn]=af[i]
- end
- if rri then
- r.dt[rri].dt=be
- else
- d[k].dt=be
- end
- redo_ni(d)
- end
+ 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=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
+ local cp=copiedelement(element,e)
+ if prepend then
+ be,af=cp,edt
+ else
+ be,af=edt,cp
+ end
+ local bn=#be
+ for i=1,#af do
+ bn=bn+1
+ be[bn]=af[i]
+ end
+ if rri then
+ r.dt[rri].dt=be
+ else
+ d[k].dt=be
+ end
+ redo_ni(d)
end
- if not collected then
- elseif collected.tg then
- inject_e(collected)
- else
- for c=1,#collected do
- inject_e(collected[c])
- end
+ end
+ if not collected then
+ elseif collected.tg then
+ inject_e(collected)
+ else
+ for c=1,#collected do
+ inject_e(collected[c])
end
+ end
end
local function insert_element(root,pattern,whatever,before)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
- local r=e.__p__
- local d,k=r.dt,e.ni
- if not before then
- k=k+1
- end
- insert(d,k,copiedelement(element,r))
- redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
- insert_e(collected)
- else
- for c=1,#collected do
- insert_e(collected[c])
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function insert_e(e)
+ local r=e.__p__
+ local d=r.dt
+ local k=e.ni
+ if not before then
+ k=k+1
+ end
+ insert(d,k,copiedelement(element,r))
+ redo_ni(d)
+ end
+ if not collected then
+ elseif collected.tg then
+ insert_e(collected)
+ else
+ for c=1,#collected do
+ insert_e(collected[c])
end
+ end
end
xml.insert_element=insert_element
xml.insertafter=insert_element
@@ -15128,124 +18700,124 @@ xml.insertbefore=function(r,p,e) insert_element(r,p,e,true) end
xml.injectafter=inject_element
xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
- if not level then
- level=1
- end
- for c=1,#collected do
- local ek=collected[c]
- local name=nil
- local ekdt=ek.dt
- if ekdt then
- local ekat=ek.at
- local ekrt=ek.__p__
- if ekrt then
- local epdt=ekrt.dt
- if not attribute or attribute=="" then
- name=(type(ekdt)=="table" and ekdt[1]) or ekdt
- end
- if not name then
- for a in gmatch(attribute or "href","([^|]+)") do
- name=ekat[a]
- if name then
- break
- end
- end
- end
- local data=nil
- if name and name~="" then
- local d,n=loaddata(name)
- data=d or ""
- name=n or name
- if trace_inclusions then
- report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
- end
- end
- if not data or data=="" then
- epdt[ek.ni]=""
- elseif ekat["parse"]=="text" then
- epdt[ek.ni]=xml.escaped(data)
- else
+ pattern=pattern or 'include'
+ loaddata=loaddata or io.loaddata
+ local collected=xmlapplylpath(xmldata,pattern)
+ if collected then
+ if not level then
+ level=1
+ end
+ for c=1,#collected do
+ local ek=collected[c]
+ local name=nil
+ local ekdt=ek.dt
+ if ekdt then
+ local ekat=ek.at
+ local ekrt=ek.__p__
+ if ekrt then
+ local epdt=ekrt.dt
+ if not attribute or attribute=="" then
+ name=(type(ekdt)=="table" and ekdt[1]) or ekdt
+ end
+ if not name then
+ for a in gmatch(attribute or "href","([^|]+)") do
+ name=ekat[a]
+ if name then
+ break
+ end
+ end
+ end
+ local data=nil
+ if name and name~="" then
+ local d,n=loaddata(name)
+ data=d or ""
+ name=n or name
+ if trace_inclusions then
+ report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
+ end
+ end
+ if not data or data=="" then
+ epdt[ek.ni]=""
+ elseif ekat["parse"]=="text" then
+ epdt[ek.ni]=xml.escaped(data)
+ else
local settings=xmldata.settings
local savedresource=settings.currentresource
settings.currentresource=name
- local xi=xmlinheritedconvert(data,xmldata)
- if not xi then
- epdt[ek.ni]=""
- else
- if recursive then
- include(xi,pattern,attribute,recursive,loaddata,level+1)
- end
- local child=xml.body(xi)
- child.__p__=ekrt
- child.__f__=name
+ local xi=xmlinheritedconvert(data,xmldata)
+ if not xi then
+ epdt[ek.ni]=""
+ else
+ if recursive then
+ include(xi,pattern,attribute,recursive,loaddata,level+1)
+ end
+ local child=xml.body(xi)
+ child.__p__=ekrt
+ child.__f__=name
child.cf=name
- epdt[ek.ni]=child
- local settings=xmldata.settings
- local inclusions=settings and settings.inclusions
- if inclusions then
- inclusions[#inclusions+1]=name
- elseif settings then
- settings.inclusions={ name }
- else
- settings={ inclusions={ name } }
- xmldata.settings=settings
- end
- if child.er then
- local badinclusions=settings.badinclusions
- if badinclusions then
- badinclusions[#badinclusions+1]=name
- else
- settings.badinclusions={ name }
- end
- end
- end
-settings.currentresource=savedresource
- end
+ epdt[ek.ni]=child
+ local settings=xmldata.settings
+ local inclusions=settings and settings.inclusions
+ if inclusions then
+ inclusions[#inclusions+1]=name
+ elseif settings then
+ settings.inclusions={ name }
+ else
+ settings={ inclusions={ name } }
+ xmldata.settings=settings
+ end
+ if child.er then
+ local badinclusions=settings.badinclusions
+ if badinclusions then
+ badinclusions[#badinclusions+1]=name
+ else
+ settings.badinclusions={ name }
end
+ end
end
+settings.currentresource=savedresource
+ end
end
+ end
end
+ end
end
xml.include=include
function xml.inclusion(e,default)
- while e do
- local f=e.__f__
- if f then
- return f
- else
- e=e.__p__
- end
+ while e do
+ local f=e.__f__
+ if f then
+ return f
+ else
+ e=e.__p__
end
- return default
+ end
+ return default
end
local function getinclusions(key,e,sorted)
- while e do
- local settings=e.settings
- if settings then
- local inclusions=settings[key]
- if inclusions then
- inclusions=table.unique(inclusions)
- if sorted then
- table.sort(inclusions)
- end
- return inclusions
- else
- e=e.__p__
- end
- else
- e=e.__p__
- end
+ while e do
+ local settings=e.settings
+ if settings then
+ local inclusions=settings[key]
+ if inclusions then
+ inclusions=table.unique(inclusions)
+ if sorted then
+ table.sort(inclusions)
+ end
+ return inclusions
+ else
+ e=e.__p__
+ end
+ else
+ e=e.__p__
end
+ end
end
function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
+ return getinclusions("inclusions",e,sorted)
end
function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
+ return getinclusions("badinclusions",e,sorted)
end
local b_collapser=lpegpatterns.b_collapser
local m_collapser=lpegpatterns.m_collapser
@@ -15254,194 +18826,194 @@ local b_stripper=lpegpatterns.b_stripper
local m_stripper=lpegpatterns.m_stripper
local e_stripper=lpegpatterns.e_stripper
local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
- local n=#edt
- if n==0 then
- return e
- elseif anywhere then
- local t={}
- local m=0
- for e=1,n do
- local str=edt[e]
- if type(str)~="string" then
- m=m+1
- t[m]=str
- elseif str~="" then
- if nolines then
- str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
- else
- str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
- end
- if str~="" then
- m=m+1
- t[m]=str
- end
- end
- end
- e.dt=t
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==0 then
+ return e
+ elseif anywhere then
+ local t={}
+ local m=0
+ for e=1,n do
+ local str=edt[e]
+ if type(str)~="string" then
+ m=m+1
+ t[m]=str
+ elseif str~="" then
+ if nolines then
+ str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
+ else
+ str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
+ end
+ if str~="" then
+ m=m+1
+ t[m]=str
+ end
+ end
+ end
+ e.dt=t
+ else
+ local str=edt[1]
+ if type(str)=="string" then
+ if str~="" then
+ str=lpegmatch(nolines and b_collapser or b_stripper,str)
+ end
+ if str=="" then
+ remove(edt,1)
+ n=n-1
else
- local str=edt[1]
- if type(str)=="string" then
- if str~="" then
- str=lpegmatch(nolines and b_collapser or b_stripper,str)
- end
- if str=="" then
- remove(edt,1)
- n=n-1
- else
- edt[1]=str
- end
- end
- if n>0 then
- str=edt[n]
- if type(str)=="string" then
- if str=="" then
- remove(edt)
- else
- str=lpegmatch(nolines and e_collapser or e_stripper,str)
- if str=="" then
- remove(edt)
- else
- edt[n]=str
- end
- end
- end
+ edt[1]=str
+ end
+ end
+ if n>0 then
+ str=edt[n]
+ if type(str)=="string" then
+ if str=="" then
+ remove(edt)
+ else
+ str=lpegmatch(nolines and e_collapser or e_stripper,str)
+ if str=="" then
+ remove(edt)
+ else
+ edt[n]=str
end
+ end
end
+ end
end
- return e
+ end
+ return e
end
xml.stripelement=stripelement
function xml.strip(root,pattern,nolines,anywhere)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for i=1,#collected do
- stripelement(collected[i],nolines,anywhere)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for i=1,#collected do
+ stripelement(collected[i],nolines,anywhere)
end
+ end
end
local function renamespace(root,oldspace,newspace)
- local ndt=#root.dt
- for i=1,ndt or 0 do
- local e=root[i]
- if type(e)=="table" then
- if e.ns==oldspace then
- e.ns=newspace
- if e.rn then
- e.rn=newspace
- end
- end
- local edt=e.dt
- if edt then
- renamespace(edt,oldspace,newspace)
- end
+ local ndt=#root.dt
+ for i=1,ndt or 0 do
+ local e=root[i]
+ if type(e)=="table" then
+ if e.ns==oldspace then
+ e.ns=newspace
+ if e.rn then
+ e.rn=newspace
end
+ end
+ local edt=e.dt
+ if edt then
+ renamespace(edt,oldspace,newspace)
+ end
end
+ end
end
xml.renamespace=renamespace
function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].tg=newtg
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].tg=newtg
end
+ end
end
function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].ns=newns
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].ns=newns
end
+ end
end
function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if (not e.rn or e.rn=="") and e.ns=="" then
- e.rn=newns
- end
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if (not e.rn or e.rn=="") and e.ns=="" then
+ e.rn=newns
+ end
end
+ end
end
function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- e.tg,e.ns,e.rn=newtg,newns,newrn
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ e.tg,e.ns,e.rn=newtg,newns,newrn
end
+ end
end
function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
- local first=dt[1]
- if first.tg=="@cd@" then
- e.dt=first.dt
- end
- else
+ local dt=e.dt
+ if #dt==1 then
+ local first=dt[1]
+ if first.tg=="@cd@" then
+ e.dt=first.dt
end
+ else
+ end
end
function xml.texttocdata(e)
- local dt=e.dt
- local s=xml.tostring(dt)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(dt)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
function xml.elementtocdata(e)
- local dt=e.dt
- local s=xml.tostring(e)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(e)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" }
local entities=characters and characters.entities or nil
local builtinentities=xml.builtinentities
function xml.addentitiesdoctype(root,option)
- if not entities then
- require("char-ent")
- entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
- local list={}
- local hexify=option=="hexadecimal"
- for k,v in table.sortedhash(root.statistics.entities.names) do
- if not builtinentities[k] then
- local e=entities[k]
- if not e then
- e=format("[%s]",k)
- elseif hexify then
- e=format("&#%05X;",utfbyte(k))
- end
- list[#list+1]=format(" <!ENTITY %s %q >",k,e)
- end
- end
- local dt=root.dt
- local n=dt[1].tg=="@pi@" and 2 or 1
- if #list>0 then
- insert(dt,n,{ "\n" })
- insert(dt,n,{
- tg="@dt@",
- dt={ format("Something [\n%s\n] ",concat(list)) },
- ns="",
- special=true,
- })
- insert(dt,n,{ "\n\n" })
- else
- end
+ if not entities then
+ require("char-ent")
+ entities=characters.entities
+ end
+ if entities and root and root.tg=="@rt@" and root.statistics then
+ local list={}
+ local hexify=option=="hexadecimal"
+ for k,v in table.sortedhash(root.statistics.entities.names) do
+ if not builtinentities[k] then
+ local e=entities[k]
+ if not e then
+ e=format("[%s]",k)
+ elseif hexify then
+ e=format("&#%05X;",utfbyte(k))
+ end
+ list[#list+1]=format(" <!ENTITY %s %q >",k,e)
+ end
end
+ local dt=root.dt
+ local n=dt[1].tg=="@pi@" and 2 or 1
+ if #list>0 then
+ insert(dt,n,{ "\n" })
+ insert(dt,n,{
+ tg="@dt@",
+ dt={ format("Something [\n%s\n] ",concat(list)) },
+ ns="",
+ special=true,
+ })
+ insert(dt,n,{ "\n\n" })
+ else
+ end
+ end
end
xml.all=xml.each
xml.insert=xml.insertafter
@@ -15451,239 +19023,241 @@ xml.before=xml.insertbefore
xml.process=xml.each
xml.obsolete=xml.obsolete or {}
local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace obsolete.replace_element=xml.replace
-xml.each_element=xml.each obsolete.each_element=xml.each
-xml.process_elements=xml.process obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
+xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
+xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
+xml.delete_element=xml.delete obsolete.delete_element=xml.delete
+xml.replace_element=xml.replace obsolete.replace_element=xml.replace
+xml.each_element=xml.each obsolete.each_element=xml.each
+xml.process_elements=xml.process obsolete.process_elements=xml.process
+xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
+xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
+xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
+xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
+xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
+xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
+xml.inject_element=xml.inject obsolete.inject_element=xml.inject
+xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
+xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
+xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
function xml.cdata(e)
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
end
- return ""
+ end
+ return ""
end
function xml.finalizers.xml.cdata(collected)
- if collected then
- local e=collected[1]
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
+ if collected then
+ local e=collected[1]
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
+ end
end
- return ""
+ end
+ return ""
end
function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.setcomment(e,str,n)
- e.dt={ {
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.setcdata(e,str)
- e.dt={ {
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local d=e.dt
- if d==x then
- report_xml("warning: xml.separate changes root")
- x=d
- end
- local t,n={ "\n" },1
- local i,nd=1,#d
- while i<=nd do
- while i<=nd do
- local di=d[i]
- if type(di)=="string" then
- if di=="\n" or find(di,"^%s+$") then
- i=i+1
- else
- d[i]=strip(di)
- break
- end
- else
- break
- end
- end
- if i>nd then
- break
- end
- t[n+1]="\n"
- t[n+2]=d[i]
- t[n+3]="\n"
- n=n+3
- i=i+1
+ local collected=xmlapplylpath(x,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local d=e.dt
+ if d==x then
+ report_xml("warning: xml.separate changes root")
+ x=d
+ end
+ local t={ "\n" }
+ local n=1
+ local i=1
+ local nd=#d
+ while i<=nd do
+ while i<=nd do
+ local di=d[i]
+ if type(di)=="string" then
+ if di=="\n" or find(di,"^%s+$") then
+ i=i+1
+ else
+ d[i]=strip(di)
+ break
end
- t[n+1]="\n"
- setmetatable(t,getmetatable(d))
- e.dt=t
+ else
+ break
+ end
+ end
+ if i>nd then
+ break
end
+ t[n+1]="\n"
+ t[n+2]=d[i]
+ t[n+3]="\n"
+ n=n+3
+ i=i+1
+ end
+ t[n+1]="\n"
+ setmetatable(t,getmetatable(d))
+ e.dt=t
end
- return x
+ end
+ return x
end
local helpers=xml.helpers or {}
xml.helpers=helpers
local function normal(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)=="string" and str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)=="string" and str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
local function recurse(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)~="string" then
- recurse(str,action)
- elseif str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)~="string" then
+ recurse(str,action)
+ elseif str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
function helpers.recursetext(collected,action,recursive)
- if recursive then
- for i=1,#collected do
- recurse(collected[i],action)
- end
- else
- for i=1,#collected do
- normal(collected[i],action)
- end
+ if recursive then
+ for i=1,#collected do
+ recurse(collected[i],action)
end
+ else
+ for i=1,#collected do
+ normal(collected[i],action)
+ end
+ end
end
local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
+ ["@rt@"]="root",
+ ["@pi@"]="instruction",
+ ["@cm@"]="comment",
+ ["@dt@"]="declaration",
+ ["@cd@"]="cdata",
}
local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
- [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
- _namespace=ns~="" and ns or nil,
- _tag=not x.special and tg or nil,
- _type=specials[tg] or "_element",
- }
- if at then
- for k,v in next,at do
- node[k]=v
- end
- end
- local n=0
- for i=1,#dt do
- local di=dt[i]
- if type(di)=="table" then
- if flat and di.special then
- else
- di=convert(di,strip,flat)
- if di then
- n=n+1
- node[n]=di
- end
- end
- elseif strip then
- di=lpegmatch(strip,di)
- if di~="" then
- n=n+1
- node[n]=di
- end
- else
- n=n+1
- node[n]=di
+ local ns=x.ns
+ local tg=x.tg
+ local at=x.at
+ local dt=x.dt
+ local node=flat and {
+ [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
+ } or {
+ _namespace=ns~="" and ns or nil,
+ _tag=not x.special and tg or nil,
+ _type=specials[tg] or "_element",
+ }
+ if at then
+ for k,v in next,at do
+ node[k]=v
+ end
+ end
+ local n=0
+ for i=1,#dt do
+ local di=dt[i]
+ if type(di)=="table" then
+ if flat and di.special then
+ else
+ di=convert(di,strip,flat)
+ if di then
+ n=n+1
+ node[n]=di
end
+ end
+ elseif strip then
+ di=lpegmatch(strip,di)
+ if di~="" then
+ n=n+1
+ node[n]=di
+ end
+ else
+ n=n+1
+ node[n]=di
end
- if next(node) then
- return node
- end
+ end
+ if next(node) then
+ return node
+ end
end
function xml.totable(x,strip,flat)
- if type(x)=="table" then
- if strip then
- strip=striplinepatterns[strip]
- end
- return convert(x,strip,flat)
+ if type(x)=="table" then
+ if strip then
+ strip=striplinepatterns[strip]
end
+ return convert(x,strip,flat)
+ end
end
function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
- return
- end
- if type(name)=="table" then
- attributes=name
- name=namespace
- namespace=""
- elseif type(name)~="string" then
- attributes={}
- name=namespace
- namespace=""
- end
- if type(attributes)~="table" then
- attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
+ if type(e)~="table" or not e.tg then
+ return
+ end
+ if type(name)=="table" then
+ attributes=name
+ name=namespace
+ namespace=""
+ elseif type(name)~="string" then
+ attributes={}
+ name=namespace
+ namespace=""
+ end
+ if type(attributes)~="table" then
+ attributes={}
+ end
+ e.ns=namespace
+ e.rn=namespace
+ e.tg=name
+ e.at=attributes
end
@@ -15693,14 +19267,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 11096, stripped down to: 8243
+-- original size: 11096, stripped down to: 7702
if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber,next=tonumber,next
local concat=table.concat
@@ -15712,241 +19286,241 @@ local xmltostring=xml.tostring
local xmlserialize=xml.serialize
local xmlcollected=xml.collected
local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg
+local reparsedentity=xml.reparsedentitylpeg
local unescapedentity=xml.unescapedentitylpeg
local parsedentity=reparsedentity
local function first(collected)
- return collected and collected[1]
+ return collected and collected[1]
end
local function last(collected)
- return collected and collected[#collected]
+ return collected and collected[#collected]
end
local function all(collected)
- return collected
+ return collected
end
local reverse=table.reversed
local function attribute(collected,name)
- if collected and #collected>0 then
- local at=collected[1].at
- return at and at[name]
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ return at and at[name]
+ end
end
local function att(id,name)
- local at=id.at
- return at and at[name]
+ local at=id.at
+ return at and at[name]
end
local function count(collected)
- return collected and #collected or 0
+ return collected and #collected or 0
end
local function position(collected,n)
- if not collected then
- return 0
- end
- local nc=#collected
- if nc==0 then
- return 0
- end
- n=tonumber(n) or 0
- if n<0 then
- return collected[nc+n+1]
- elseif n>0 then
- return collected[n]
- else
- return collected[1].mi or 0
- end
+ if not collected then
+ return 0
+ end
+ local nc=#collected
+ if nc==0 then
+ return 0
+ end
+ n=tonumber(n) or 0
+ if n<0 then
+ return collected[nc+n+1]
+ elseif n>0 then
+ return collected[n]
+ else
+ return collected[1].mi or 0
+ end
end
local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0
+ return collected and #collected>0 and collected[1].mi or 0
end
local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0
+ return collected and #collected>0 and collected[1].ni or 0
end
local function attributes(collected,arguments)
- if collected and #collected>0 then
- local at=collected[1].at
- if arguments then
- return at[arguments]
- elseif next(at) then
- return at
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ if arguments then
+ return at[arguments]
+ elseif next(at) then
+ return at
end
+ end
end
local function chainattribute(collected,arguments)
- if collected and #collected>0 then
- local e=collected[1]
- while e do
- local at=e.at
- if at then
- local a=at[arguments]
- if a then
- return a
- end
- else
- break
- end
- e=e.__p__
+ if collected and #collected>0 then
+ local e=collected[1]
+ while e do
+ local at=e.at
+ if at then
+ local a=at[arguments]
+ if a then
+ return a
end
+ else
+ break
+ end
+ e=e.__p__
end
- return ""
+ end
+ return ""
end
local function raw(collected)
- if collected and #collected>0 then
- local e=collected[1] or collected
- return e and xmltostring(e) or ""
- else
- return ""
- end
+ if collected and #collected>0 then
+ local e=collected[1] or collected
+ return e and xmltostring(e) or ""
+ else
+ return ""
+ end
end
local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
- result={}
- return result
- end,
- finalize=function()
- return concat(result)
- end,
- handle=function(...)
- result[#result+1]=concat {... }
- end,
- escape=false,
+ name="string",
+ initialize=function()
+ result={}
+ return result
+ end,
+ finalize=function()
+ return concat(result)
+ end,
+ handle=function(...)
+ result[#result+1]=concat {... }
+ end,
+ escape=false,
}
local function xmltotext(root)
- local dt=root.dt
- if not dt then
- return ""
- end
- local nt=#dt
- if nt==0 then
- return ""
- elseif nt==1 and type(dt[1])=="string" then
- return dt[1]
- else
- return xmlserialize(root,xmltexthandler) or ""
- end
+ local dt=root.dt
+ if not dt then
+ return ""
+ end
+ local nt=#dt
+ if nt==0 then
+ return ""
+ elseif nt==1 and type(dt[1])=="string" then
+ return dt[1]
+ else
+ return xmlserialize(root,xmltexthandler) or ""
+ end
end
function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
+ return root and xmlserialize(root,xmltexthandler) or ""
end
local function text(collected)
- if collected then
- local e=collected[1] or collected
- return e and xmltotext(e) or ""
- else
- return ""
- end
+ if collected then
+ local e=collected[1] or collected
+ return e and xmltotext(e) or ""
+ else
+ return ""
+ end
end
local function texts(collected)
- if not collected then
- return {}
- end
- local nc=#collected
- if nc==0 then
- return {}
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- if e and e.dt then
- n=n+1
- t[n]=e.dt
- end
- end
- return t
+ if not collected then
+ return {}
+ end
+ local nc=#collected
+ if nc==0 then
+ return {}
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ if e and e.dt then
+ n=n+1
+ t[n]=e.dt
+ end
+ end
+ return t
end
local function tag(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- return c and c.tg
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ return c and c.tg
end
local function name(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
- return c.tg
- else
- return c.ns..":"..c.tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ if not c then
+ elseif c.ns=="" then
+ return c.tg
+ else
+ return c.ns..":"..c.tg
+ end
end
local function tags(collected,nonamespace)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace or ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace or ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
end
- return t
+ end
+ return t
end
local function empty(collected,spacesonly)
- if not collected then
- return true
- end
- local nc=#collected
- if nc==0 then
- return true
- end
- for c=1,nc do
- local e=collected[c]
- if e then
- local edt=e.dt
- if edt then
- local n=#edt
- if n==1 then
- local edk=edt[1]
- local typ=type(edk)
- if typ=="table" then
- return false
- elseif edk~="" then
- return false
- elseif spacesonly and not find(edk,"%S") then
- return false
- end
- elseif n>1 then
- return false
- end
- end
+ if not collected then
+ return true
+ end
+ local nc=#collected
+ if nc==0 then
+ return true
+ end
+ for c=1,nc do
+ local e=collected[c]
+ if e then
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==1 then
+ local edk=edt[1]
+ local typ=type(edk)
+ if typ=="table" then
+ return false
+ elseif edk~="" then
+ return false
+ elseif spacesonly and not find(edk,"%S") then
+ return false
+ end
+ elseif n>1 then
+ return false
end
+ end
end
- return true
+ end
+ return true
end
finalizers.first=first
finalizers.last=last
@@ -15969,124 +19543,124 @@ finalizers.name=name
finalizers.tags=tags
finalizers.empty=empty
function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
+ return first(xmlfilter(id,pattern))
end
function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
+ return last(xmlfilter(id,pattern))
end
function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
+ return count(xmlfilter(id,pattern))
end
function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
+ return attribute(xmlfilter(id,pattern),a,default)
end
function xml.raw(id,pattern)
- if pattern then
- return raw(xmlfilter(id,pattern))
- else
- return raw(id)
- end
+ if pattern then
+ return raw(xmlfilter(id,pattern))
+ else
+ return raw(id)
+ end
end
function xml.text(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
- return xmltotext(id) or ""
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ return collected and #collected>0 and xmltotext(collected[1]) or ""
+ elseif id then
+ return xmltotext(id) or ""
+ else
+ return ""
+ end
end
function xml.pure(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- if collected and #collected>0 then
- parsedentity=unescapedentity
- local s=collected and #collected>0 and xmltotext(collected[1]) or ""
- parsedentity=reparsedentity
- return s
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ if collected and #collected>0 then
+ parsedentity=unescapedentity
+ local s=collected and #collected>0 and xmltotext(collected[1]) or ""
+ parsedentity=reparsedentity
+ return s
else
- parsedentity=unescapedentity
- local s=xmltotext(id) or ""
- parsedentity=reparsedentity
- return s
+ return ""
end
+ else
+ parsedentity=unescapedentity
+ local s=xmltotext(id) or ""
+ parsedentity=reparsedentity
+ return s
+ end
end
xml.content=text
function xml.position(id,pattern,n)
- return position(xmlfilter(id,pattern),n)
+ return position(xmlfilter(id,pattern),n)
end
function xml.match(id,pattern)
- return match(xmlfilter(id,pattern))
+ return match(xmlfilter(id,pattern))
end
function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
+ return empty(xmlfilter(id,pattern),spacesonly)
end
xml.all=xml.filter
xml.index=xml.position
xml.found=xml.filter
local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
- t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
+ local t={}
+ for e in xmlcollected(x[1] or x,"/*") do
+ t[e.tg]=xmltostring(e.dt) or ""
+ end
+ return next(t) and t or nil
end
xml.table=totable
finalizers.table=totable
local function textonly(e,t)
- if e then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- textonly(e,t)
- else
- t[#t+1]=e
- end
- end
+ if e then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ textonly(e,t)
+ else
+ t[#t+1]=e
end
+ end
end
- return t
+ end
+ return t
end
function xml.textonly(e)
- return concat(textonly(e,{}))
+ return concat(textonly(e,{}))
end
function finalizers.lowerall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=lower(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[lower(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=lower(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[lower(k)]=v
end
+ e.at=t
+ end
end
+ end
end
function finalizers.upperall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=upper(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[upper(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=upper(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[upper(k)]=v
end
+ e.at=t
+ end
end
+ end
end
@@ -16096,14 +19670,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
--- original size: 6407, stripped down to: 4965
+-- original size: 6407, stripped down to: 4640
if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.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 trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local formatters=string.formatters
local reporters=logs.reporters
@@ -16112,152 +19686,152 @@ local xmlcollected=xml.collected
local xmltext=xml.text
local xmlfirst=xml.first
local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
- return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
- local categoryname=category.at.name or ""
- if wantedcategories==true or wantedcategories[categoryname] then
- if nofcategories>1 then
- report("%s options:",categoryname)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for flag in xmlcollected(subcategory,"/flag") do
- local name=flag.at.name
- local value=flag.at.value
- local short=xmltext(xmlfirst(flag,"/short"))
- if value then
- report("--%-20s %s",formatters["%s=%s"](name,value),short)
- else
- report("--%-20s %s",name,short)
- end
- end
- report()
- end
- end
- end
- for category in xmlcollected(root,"/application/examples/category") do
- local title=xmltext(xmlfirst(category,"/title"))
- if title and title~="" then
- report()
- report(title)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for example in xmlcollected(subcategory,"/example") do
- local command=xmltext(xmlfirst(example,"/command"))
- local comment=xmltext(xmlfirst(example,"/comment"))
- report(command)
- end
- report()
- end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
- local comment=xmltext(comment)
+ local root=xml.convert(specification.helpinfo or "")
+ if not root then
+ return
+ end
+ local xs=xml.gethandlers("string")
+ xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
+ xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
+ local wantedcategories=select("#",...)==0 and true or table.tohash {... }
+ local nofcategories=xml.count(root,"/application/flags/category")
+ local report=specification.report
+ for category in xmlcollected(root,"/application/flags/category") do
+ local categoryname=category.at.name or ""
+ if wantedcategories==true or wantedcategories[categoryname] then
+ if nofcategories>1 then
+ report("%s options:",categoryname)
report()
- report(comment)
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for flag in xmlcollected(subcategory,"/flag") do
+ local name=flag.at.name
+ local value=flag.at.value
+ local short=xmltext(xmlfirst(flag,"/short"))
+ if value then
+ report("--%-20s %s",formatters["%s=%s"](name,value),short)
+ else
+ report("--%-20s %s",name,short)
+ end
+ end
report()
+ end
+ end
+ end
+ for category in xmlcollected(root,"/application/examples/category") do
+ local title=xmltext(xmlfirst(category,"/title"))
+ if title and title~="" then
+ report()
+ report(title)
+ report()
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for example in xmlcollected(subcategory,"/example") do
+ local command=xmltext(xmlfirst(example,"/command"))
+ local comment=xmltext(xmlfirst(example,"/comment"))
+ report(command)
+ end
+ report()
end
+ end
+ for comment in xmlcollected(root,"/application/comments/comment") do
+ local comment=xmltext(comment)
+ report()
+ report(comment)
+ report()
+ end
end
local reporthelp=reporters.help
local exporthelp=reporters.export
local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
- return false
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="table" then
+ return false
+ end
+ if type(helpinfo)~="string" then
+ helpinfo="Warning: no helpinfo found."
+ t.helpinfo=helpinfo
+ return false
+ end
+ if string.find(helpinfo,".xml$") then
+ local ownscript=environment.ownscript
+ local helpdata=false
+ if ownscript then
+ local helpfile=file.join(file.pathpart(ownscript),helpinfo)
+ helpdata=io.loaddata(helpfile)
+ if helpdata=="" then
+ helpdata=false
+ end
end
- if type(helpinfo)~="string" then
- helpinfo="Warning: no helpinfo found."
- t.helpinfo=helpinfo
- return false
+ if not helpdata then
+ local helpfile=resolvers.findfile(helpinfo,"tex")
+ helpdata=helpfile and io.loaddata(helpfile)
end
- if string.find(helpinfo,".xml$") then
- local ownscript=environment.ownscript
- local helpdata=false
- if ownscript then
- local helpfile=file.join(file.pathpart(ownscript),helpinfo)
- helpdata=io.loaddata(helpfile)
- if helpdata=="" then
- helpdata=false
- end
- end
- if not helpdata then
- local helpfile=resolvers.findfile(helpinfo,"tex")
- helpdata=helpfile and io.loaddata(helpfile)
- end
- if helpdata and helpdata~="" then
- helpinfo=helpdata
- else
- helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
- end
+ if helpdata and helpdata~="" then
+ helpinfo=helpdata
+ else
+ helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
+ end
+ t.helpinfo=helpinfo
+ return string.find(t.helpinfo,"^<%?xml") and true or false
end
function reporters.help(t,...)
- if xmlfound(t) then
- showhelp(t,...)
- else
- reporthelp(t,...)
- end
+ if xmlfound(t) then
+ showhelp(t,...)
+ else
+ reporthelp(t,...)
+ end
end
function reporters.export(t,methods,filename)
- if not xmlfound(t) then
- return exporthelp(t)
- end
- if not methods or methods=="" then
- methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
- filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
- return exporthelp(t)
- end
- if methods=="all" then
- methods=table.keys(exporters)
- elseif type(methods)=="string" then
- methods=utilities.parsers.settings_to_array(methods)
- else
- return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
- filename=false
- elseif file.pathpart(filename)=="" then
- t.report("export file %a will not be saved on the current path (safeguard)",filename)
- return
- end
- for i=1,#methods do
- local method=methods[i]
- local exporter=exporters[method]
- if exporter then
- local result=exporter(t,method)
- if result and result~="" then
- if filename then
- local fullname=file.replacesuffix(filename,method)
- t.report("saving export in %a",fullname)
- dir.mkdirs(file.pathpart(fullname))
- io.savedata(fullname,result)
- else
- reporters.lines(t,result)
- end
- else
- t.report("no output from exporter %a",method)
- end
+ if not xmlfound(t) then
+ return exporthelp(t)
+ end
+ if not methods or methods=="" then
+ methods=environment.arguments["exporthelp"]
+ end
+ if not filename or filename=="" then
+ filename=environment.files[1]
+ end
+ dofile(resolvers.findfile("trac-exp.lua","tex"))
+ local exporters=logs.exporters
+ if not exporters or not methods then
+ return exporthelp(t)
+ end
+ if methods=="all" then
+ methods=table.keys(exporters)
+ elseif type(methods)=="string" then
+ methods=utilities.parsers.settings_to_array(methods)
+ else
+ return exporthelp(t)
+ end
+ if type(filename)~="string" or filename=="" then
+ filename=false
+ elseif file.pathpart(filename)=="" then
+ t.report("export file %a will not be saved on the current path (safeguard)",filename)
+ return
+ end
+ for i=1,#methods do
+ local method=methods[i]
+ local exporter=exporters[method]
+ if exporter then
+ local result=exporter(t,method)
+ if result and result~="" then
+ if filename then
+ local fullname=file.replacesuffix(filename,method)
+ t.report("saving export in %a",fullname)
+ dir.mkdirs(file.pathpart(fullname))
+ io.savedata(fullname,result)
else
- t.report("unknown exporter %a",method)
+ reporters.lines(t,result)
end
+ else
+ t.report("no output from exporter %a",method)
+ end
+ else
+ t.report("unknown exporter %a",method)
end
+ end
end
@@ -16267,149 +19841,149 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11099, stripped down to: 7516
+-- original size: 11099, stripped down to: 7152
if not modules then modules={} end modules ['data-ini']={
- 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,getmetatable,rawset=next,type,getmetatable,rawset
local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
local report_initialization=logs.reporter("resolvers","initialization")
resolvers=resolvers or {}
local resolvers=resolvers
texconfig.kpse_init=false
texconfig.shell_escape='t'
if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
+ local default_texmfcnf=kpse.default_texmfcnf()
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
+ default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
+ environment.default_texmfcnf=default_texmfcnf
end
kpse={ original=kpse }
setmetatable(kpse,{
- __index=function(kp,name)
- report_initialization("fatal error: kpse library is accessed (key: %s)",name)
- os.exit()
- end
+ __index=function(kp,name)
+ report_initialization("fatal error: kpse library is accessed (key: %s)",name)
+ os.exit()
+ end
} )
do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
- ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
- ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
+ local osfontdir=osgetenv("OSFONTDIR")
+ if osfontdir and osfontdir~="" then
+ elseif osname=="windows" then
+ ossetenv("OSFONTDIR","c:/windows/fonts//")
+ elseif osname=="macosx" then
+ ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+ end
end
do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
- homedir=char(127)
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir)
- ossetenv("USERPROFILE",homedir)
- environment.homedir=homedir
+ local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
+ if not homedir or homedir=="" then
+ homedir=char(127)
+ end
+ homedir=file.collapsepath(homedir)
+ ossetenv("HOME",homedir)
+ ossetenv("USERPROFILE",homedir)
+ environment.homedir=homedir
end
do
- local args=environment.originalarguments or arg
- if not environment.ownmain then
- environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
- ownpath=args[-1] or arg[-1]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- if not ownpath or ownpath=="" then
- ownpath=args[-0] or arg[-0]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- end
- local binary=ownbin
- if not ownpath or ownpath=="" then
- ownpath=ownpath and filedirname(binary)
- end
- if not ownpath or ownpath=="" then
- if os.binsuffix~="" then
- binary=file.replacesuffix(binary,os.binsuffix)
- end
- local path=osgetenv("PATH")
- if path then
- for p in gmatch(path,"[^"..io.pathseparator.."]+") do
- local b=filejoin(p,binary)
- if lfs.isfile(b) then
- local olddir=lfs.currentdir()
- if lfs.chdir(p) then
- local pp=lfs.currentdir()
- if trace_locating and p~=pp then
- report_initialization("following symlink %a to %a",p,pp)
- end
- ownpath=pp
- lfs.chdir(olddir)
- else
- if trace_locating then
- report_initialization("unable to check path %a",p)
- end
- ownpath=p
- end
- break
- end
- end
+ local args=environment.originalarguments or arg
+ if not environment.ownmain then
+ environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
+ end
+ local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
+ local ownpath=environment.ownpath or os.selfdir
+ ownbin=file.collapsepath(ownbin)
+ ownpath=file.collapsepath(ownpath)
+ if not ownpath or ownpath=="" or ownpath=="unset" then
+ ownpath=args[-1] or arg[-1]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ if not ownpath or ownpath=="" then
+ ownpath=args[-0] or arg[-0]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ end
+ local binary=ownbin
+ if not ownpath or ownpath=="" then
+ ownpath=ownpath and filedirname(binary)
+ end
+ if not ownpath or ownpath=="" then
+ if os.binsuffix~="" then
+ binary=file.replacesuffix(binary,os.binsuffix)
+ end
+ local path=osgetenv("PATH")
+ if path then
+ for p in gmatch(path,"[^"..io.pathseparator.."]+") do
+ local b=filejoin(p,binary)
+ if lfs.isfile(b) then
+ local olddir=lfs.currentdir()
+ if lfs.chdir(p) then
+ local pp=lfs.currentdir()
+ if trace_locating and p~=pp then
+ report_initialization("following symlink %a to %a",p,pp)
+ end
+ ownpath=pp
+ lfs.chdir(olddir)
+ else
+ if trace_locating then
+ report_initialization("unable to check path %a",p)
+ end
+ ownpath=p
end
+ break
+ end
end
- if not ownpath or ownpath=="" then
- ownpath="."
- report_initialization("forcing fallback to ownpath %a",ownpath)
- elseif trace_locating then
- report_initialization("using ownpath %a",ownpath)
- end
+ end
end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
+ if not ownpath or ownpath=="" then
+ ownpath="."
+ report_initialization("forcing fallback to ownpath %a",ownpath)
+ elseif trace_locating then
+ report_initialization("using ownpath %a",ownpath)
+ end
+ end
+ environment.ownbin=ownbin
+ environment.ownpath=ownpath
end
resolvers.ownpath=environment.ownpath
function resolvers.getownpath()
- return environment.ownpath
+ return environment.ownpath
end
do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
- ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
- ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
- ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
- report_initialization("error: unable to locate ownpath")
- os.exit()
- end
-end
-local texos=environment.texos or osgetenv("TEXOS")
+ local ownpath=environment.ownpath or dir.current()
+ if ownpath then
+ ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
+ ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
+ ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
+ else
+ report_initialization("error: unable to locate ownpath")
+ os.exit()
+ end
+end
+local texos=environment.texos or osgetenv("TEXOS")
local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
if not texos or texos=="" then
- texos=file.basename(texmfos)
+ texos=file.basename(texmfos)
end
ossetenv('TEXMFOS',texmfos)
-ossetenv('TEXOS',texos)
-ossetenv('SELFAUTOSYSTEM',os.platform)
+ossetenv('TEXOS',texos)
+ossetenv('SELFAUTOSYSTEM',os.platform)
environment.texos=texos
environment.texmfos=texmfos
local texroot=environment.texroot or osgetenv("TEXROOT")
if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
+ texroot=osgetenv('SELFAUTOPARENT')
+ ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
local prefixes=utilities.storage.allocate()
@@ -16418,30 +19992,30 @@ local resolved={}
local abstract={}
local dynamic={}
function resolvers.resetresolve(str)
- resolved,abstract={},{}
+ resolved,abstract={},{}
end
function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
- for i=1,#all do
- all[i]=all[i]..":"
- end
+ local all=table.sortedkeys(prefixes)
+ if separator then
+ for i=1,#all do
+ all[i]=all[i]..":"
end
- return all
+ end
+ return all
end
local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
- return action(target)
- else
- return method..":"..target
- end
+ local action=prefixes[method]
+ if action then
+ return action(target)
+ else
+ return method..":"..target
+ end
end
function resolvers.unresolve(str)
- return abstract[str] or str
+ return abstract[str] or str
end
function resolvers.setdynamic(str)
- dynamic[str]=true
+ dynamic[str]=true
end
local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
local prefix=C(R("az")^2)*P(":")
@@ -16450,65 +20024,65 @@ local notarget=(#S(";,")+P(-1))*Cc("")
local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
local p_simple=prefix*P(-1)
local function resolve(str)
- if type(str)=="table" then
- local res={}
- for i=1,#str do
- res[i]=resolve(str[i])
- end
- return res
- end
- local res=resolved[str]
- if res then
- return res
+ if type(str)=="table" then
+ local res={}
+ for i=1,#str do
+ res[i]=resolve(str[i])
end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
- local res=action(res)
- if not dynamic[simple] then
- resolved[simple]=res
- abstract[res]=simple
- end
- return res
+ return res
+ end
+ local res=resolved[str]
+ if res then
+ return res
+ end
+ local simple=lpegmatch(p_simple,str)
+ local action=prefixes[simple]
+ if action then
+ local res=action(res)
+ if not dynamic[simple] then
+ resolved[simple]=res
+ abstract[res]=simple
end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
return res
+ end
+ res=lpegmatch(p_resolve,str)
+ resolved[str]=res
+ abstract[res]=str
+ return res
end
resolvers.resolve=resolve
if type(osuname)=="function" then
- for k,v in next,osuname() do
- if not prefixes[k] then
- prefixes[k]=function() return v end
- end
+ for k,v in next,osuname() do
+ if not prefixes[k] then
+ prefixes[k]=function() return v end
end
+ end
end
if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
- local colon=P(":")
- for k,v in table.sortedpairs(prefixes) do
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
- return lpegmatch(pattern,str)
+ local pattern
+ local function makepattern(t,k,v)
+ if t then
+ rawset(t,k,v)
+ end
+ local colon=P(":")
+ for k,v in table.sortedpairs(prefixes) do
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
end
+ pattern=Cs((p*colon+colon/";"+P(1))^0)
+ end
+ makepattern()
+ table.setmetatablenewindex(prefixes,makepattern)
+ function resolvers.repath(str)
+ return lpegmatch(pattern,str)
+ end
else
- function resolvers.repath(str)
- return str
- end
+ function resolvers.repath(str)
+ return str
+ end
end
@@ -16518,14 +20092,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-exp"] = package.loaded["data-exp"] or true
--- original size: 18105, stripped down to: 11207
+-- original size: 18105, stripped down to: 10389
if not modules then modules={} end modules ['data-exp']={
- 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 format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
local concat,sort=table.concat,table.sort
@@ -16535,21 +20109,21 @@ local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S
local type,next=type,next
local isdir=lfs.isdir
local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
local report_expansions=logs.reporter("resolvers","expansions")
local report_globbing=logs.reporter("resolvers","globbing")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do
- for sa in gmatch(a,"[^,]+") do
- n=n+1;t[n]=sa..sb
- end
+ local t,n={},0
+ for sb in gmatch(b,"[^,]+") do
+ for sa in gmatch(a,"[^,]+") do
+ n=n+1;t[n]=sa..sb
end
- return concat(t,",")
+ end
+ return concat(t,",")
end
local comma=P(",")
local nocomma=(1-comma)^1
@@ -16559,7 +20133,7 @@ local after=Cs((Carg(1)*nocomma+docomma)^0)
local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
local function f_first (a,b) return lpegmatch(after,b,1,a) end
local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both (a,b) return lpegmatch(both,b,1,a) end
+local function f_both (a,b) return lpegmatch(both,b,1,a) end
local left=P("{")
local right=P("}")
local var=P((1-S("{}" ))^0)
@@ -16572,141 +20146,141 @@ local l_rest=Cs((left*var*(left/"")*var*(right/"")*var*right+other )^0 )
local stripper_1=lpeg.stripper ("{}@")
local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
local function splitpathexpr(str,newlist,validate)
- if trace_expansions then
- report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
+ if trace_expansions then
+ report_expansions("expanding variable %a",str)
+ end
+ local t,ok,done=newlist or {},false,false
+ local n=#t
+ str=lpegmatch(replacer_1,str)
+ repeat
+ local old=str
repeat
- local old=str
- repeat
- local old=str
- str=lpegmatch(l_first,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_second,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_both,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_rest,str)
- until old==str
- until old==str
- str=lpegmatch(stripper_1,str)
- if validate then
- for s in gmatch(str,"[^,]+") do
- s=validate(s)
- if s then
- n=n+1
- t[n]=s
- end
- end
- else
- for s in gmatch(str,"[^,]+") do
- n=n+1
- t[n]=s
- end
+ local old=str
+ str=lpegmatch(l_first,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_second,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_both,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_rest,str)
+ until old==str
+ until old==str
+ str=lpegmatch(stripper_1,str)
+ if validate then
+ for s in gmatch(str,"[^,]+") do
+ s=validate(s)
+ if s then
+ n=n+1
+ t[n]=s
+ end
end
- if trace_expansions then
- for k=1,#t do
- report_expansions("% 4i: %s",k,t[k])
- end
+ else
+ for s in gmatch(str,"[^,]+") do
+ n=n+1
+ t[n]=s
end
- return t
+ end
+ if trace_expansions then
+ for k=1,#t do
+ report_expansions("% 4i: %s",k,t[k])
+ end
+ end
+ return t
end
local function validate(s)
- s=collapsepath(s)
- return s~="" and not find(s,"^!*unset/*$") and s
+ s=collapsepath(s)
+ return s~="" and not find(s,"^!*unset/*$") and s
end
resolvers.validatedpath=validate
function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
- splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
+ local newlist={}
+ for k=1,#pathlist do
+ splitpathexpr(pathlist[k],newlist,validate)
+ end
+ return newlist
end
local usedhomedir=nil
-local donegation=(P("!")/"" )^0
+local donegation=(P("!")/"" )^0
local doslashes=(P("\\")/"/"+1)^0
local function expandedhome()
- if not usedhomedir then
- usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
- if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
- if trace_expansions then
- report_expansions("no home dir set, ignoring dependent path using current path")
- end
- usedhomedir="."
- end
+ if not usedhomedir then
+ usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
+ if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
+ if trace_expansions then
+ report_expansions("no home dir set, ignoring dependent path using current path")
+ end
+ usedhomedir="."
end
- return usedhomedir
+ end
+ return usedhomedir
end
local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
local cleanup=Cs(donegation*dohome*doslashes)
resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
+ return str and lpegmatch(cleanup,str) or ""
end
local expandhome=P("~")/"$HOME"
local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1 )^0
+local dostring=(expandhome+1 )^0
local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
+ lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
)
function resolvers.checkedvariable(str)
- return type(str)=="string" and lpegmatch(stripper,str) or str
+ return type(str)=="string" and lpegmatch(stripper,str) or str
end
local cache={}
local splitter=lpeg.tsplitat(";")
local backslashswapper=lpeg.replacer("\\","/")
local function splitconfigurationpath(str)
- if str then
- local found=cache[str]
- if not found then
- if str=="" then
- found={}
- else
- local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
- found={}
- local noffound=0
- for i=1,#split do
- local s=split[i]
- if not find(s,"^{*unset}*") then
- noffound=noffound+1
- found[noffound]=s
- end
- end
- if trace_expansions then
- report_expansions("splitting path specification %a",str)
- for k=1,noffound do
- report_expansions("% 4i: %s",k,found[k])
- end
- end
- cache[str]=found
- end
+ if str then
+ local found=cache[str]
+ if not found then
+ if str=="" then
+ found={}
+ else
+ local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
+ found={}
+ local noffound=0
+ for i=1,#split do
+ local s=split[i]
+ if not find(s,"^{*unset}*") then
+ noffound=noffound+1
+ found[noffound]=s
+ end
end
- return found
+ if trace_expansions then
+ report_expansions("splitting path specification %a",str)
+ for k=1,noffound do
+ report_expansions("% 4i: %s",k,found[k])
+ end
+ end
+ cache[str]=found
+ end
end
+ return found
+ end
end
resolvers.splitconfigurationpath=splitconfigurationpath
function resolvers.splitpath(str)
- if type(str)=='table' then
- return str
- else
- return splitconfigurationpath(str)
- end
+ if type(str)=='table' then
+ return str
+ else
+ return splitconfigurationpath(str)
+ end
end
function resolvers.joinpath(str)
- if type(str)=='table' then
- return joinpath(str)
- else
- return str
- end
+ if type(str)=='table' then
+ return joinpath(str)
+ else
+ return str
+ end
end
local attributes,directory=lfs.attributes,lfs.dir
local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
@@ -16719,201 +20293,201 @@ local fullcache={}
local nofsharedscans=0
local addcasecraptoo=true
local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name in directory(full) do
- if not lpegmatch(pattern,name) then
- local mode=attributes(full..name,"mode")
- if mode=="file" then
- n=n+1
- noffiles=noffiles+1
- filelist[noffiles]=name
- elseif mode=="directory" then
- m=m+1
- nofdirs=nofdirs+1
- if path~="" then
- dirlist[nofdirs]=path.."/"..name
- else
- dirlist[nofdirs]=name
- end
- end
+ local full=path=="" and spec or (spec..path..'/')
+ local dirlist={}
+ local nofdirs=0
+ local pattern=tolerant and lessweird or weird
+ local filelist={}
+ local noffiles=0
+ for name in directory(full) do
+ if not lpegmatch(pattern,name) then
+ local mode=attributes(full..name,"mode")
+ if mode=="file" then
+ n=n+1
+ noffiles=noffiles+1
+ filelist[noffiles]=name
+ elseif mode=="directory" then
+ m=m+1
+ nofdirs=nofdirs+1
+ if path~="" then
+ dirlist[nofdirs]=path.."/"..name
+ else
+ dirlist[nofdirs]=name
end
+ end
end
- if noffiles>0 then
- sort(filelist)
- for i=1,noffiles do
- local name=filelist[i]
- local lower=lower(name)
- local paths=files[lower]
- if paths then
- if onlyone then
- else
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- if addcasecraptoo then
- local paths=files[name]
- if not paths then
- files[name]=path
- elseif type(paths)=="string" then
- files[name]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- end
- if type(paths)=="string" then
- files[lower]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- else
- files[lower]=path
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- end
+ end
+ if noffiles>0 then
+ sort(filelist)
+ for i=1,noffiles do
+ local name=filelist[i]
+ local lower=lower(name)
+ local paths=files[lower]
+ if paths then
+ if onlyone then
+ else
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
+ if addcasecraptoo then
+ local paths=files[name]
+ if not paths then
+ files[name]=path
+ elseif type(paths)=="string" then
+ files[name]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
+ end
+ if type(paths)=="string" then
+ files[lower]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
- end
- if nofdirs>0 then
- sort(dirlist)
- for i=1,nofdirs do
- files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
+ else
+ files[lower]=path
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
end
+ end
+ end
+ end
+ if nofdirs>0 then
+ sort(dirlist)
+ for i=1,nofdirs do
+ files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
+ end
+ scancache[sub(full,1,-2)]=files
+ return files,remap,n,m,r
end
function resolvers.scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
- local content=fullcache[realpath]
- if content then
- if trace_locating then
- report_expansions("using cached scan of path %a, branch %a",path,branch or path)
- end
- nofsharedscans=nofsharedscans+1
- return content
- end
- end
- statistics.starttiming(timer)
+ local realpath=resolveprefix(path)
+ if usecache then
+ local content=fullcache[realpath]
+ if content then
+ if trace_locating then
+ report_expansions("using cached scan of path %a, branch %a",path,branch or path)
+ end
+ nofsharedscans=nofsharedscans+1
+ return content
+ end
+ end
+ statistics.starttiming(timer)
+ if trace_locating then
+ report_expansions("scanning path %a, branch %a",path,branch or path)
+ end
+ local content
+ if isdir(realpath) then
+ local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
+ content={
+ metadata={
+ path=path,
+ files=n,
+ directories=m,
+ remappings=r,
+ },
+ files=files,
+ remap=remap,
+ }
if trace_locating then
- report_expansions("scanning path %a, branch %a",path,branch or path)
+ report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
end
- local content
- if isdir(realpath) then
- local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
- content={
- metadata={
- path=path,
- files=n,
- directories=m,
- remappings=r,
- },
- files=files,
- remap=remap,
- }
- if trace_locating then
- report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
- end
- else
- content={
- metadata={
- path=path,
- files=0,
- directories=0,
- remappings=0,
- },
- files={},
- remap={},
- }
- if trace_locating then
- report_expansions("invalid path %a",realpath)
- end
- end
- if usecache then
- scanned[#scanned+1]=realpath
- fullcache[realpath]=content
+ else
+ content={
+ metadata={
+ path=path,
+ files=0,
+ directories=0,
+ remappings=0,
+ },
+ files={},
+ remap={},
+ }
+ if trace_locating then
+ report_expansions("invalid path %a",realpath)
end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
+ end
+ if usecache then
+ scanned[#scanned+1]=realpath
+ fullcache[realpath]=content
+ end
+ nofscans=nofscans+1
+ statistics.stoptiming(timer)
+ return content
end
function resolvers.simplescanfiles(path,branch,usecache)
- return resolvers.scanfiles(path,branch,usecache,true,true)
+ return resolvers.scanfiles(path,branch,usecache,true,true)
end
function resolvers.scandata()
- table.sort(scanned)
- return {
- n=nofscans,
- shared=nofsharedscans,
- time=statistics.elapsedtime(timer),
- paths=scanned,
- }
+ table.sort(scanned)
+ return {
+ n=nofscans,
+ shared=nofsharedscans,
+ time=statistics.elapsedtime(timer),
+ paths=scanned,
+ }
end
function resolvers.get_from_content(content,path,name)
- if not content then
- return
- end
- local files=content.files
- if not files then
- return
- end
- local remap=content.remap
- if not remap then
- return
- end
- if name then
- local used=lower(name)
- return path,remap[used] or used
- else
- local name=path
- local used=lower(name)
- local path=files[used]
- if path then
- return path,remap[used] or used
- end
- end
+ if not content then
+ return
+ end
+ local files=content.files
+ if not files then
+ return
+ end
+ local remap=content.remap
+ if not remap then
+ return
+ end
+ if name then
+ local used=lower(name)
+ return path,remap[used] or used
+ else
+ local name=path
+ local used=lower(name)
+ local path=files[used]
+ if path then
+ return path,remap[used] or used
+ end
+ end
end
local nothing=function() end
function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
- local pattern=lower(pattern)
- local files=content.files
- local remap=content.remap
- if files and remap then
- local f=sortedkeys(files)
- local n=#f
- local i=0
- local function iterator()
- while i<n do
- i=i+1
- local k=f[i]
- if find(k,pattern) then
- return files[k],remap and remap[k] or k
- end
- end
- end
- return iterator
+ if content and type(pattern)=="string" then
+ local pattern=lower(pattern)
+ local files=content.files
+ local remap=content.remap
+ if files and remap then
+ local f=sortedkeys(files)
+ local n=#f
+ local i=0
+ local function iterator()
+ while i<n do
+ i=i+1
+ local k=f[i]
+ if find(k,pattern) then
+ return files[k],remap and remap[k] or k
+ end
end
+ end
+ return iterator
end
- return nothing
+ end
+ return nothing
end
@@ -16923,14 +20497,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9360, stripped down to: 6903
+-- original size: 9360, stripped down to: 6312
if not modules then modules={} end modules ['data-env']={
- 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 lower,gsub=string.lower,string.gsub
local next=next
@@ -16950,255 +20524,255 @@ resolvers.suffixmap=suffixmap
resolvers.usertypes=usertypes
local luasuffixes=utilities.lua.suffixes
local relations=allocate {
- core={
- ofm={
- names={ "ofm","omega font metric","omega font metrics" },
- variable='OFMFONTS',
- suffixes={ 'ofm','tfm' },
- },
- ovf={
- names={ "ovf","omega virtual font","omega virtual fonts" },
- variable='OVFFONTS',
- suffixes={ 'ovf','vf' },
- },
- tfm={
- names={ "tfm","tex font metric","tex font metrics" },
- variable='TFMFONTS',
- suffixes={ 'tfm' },
- },
- vf={
- names={ "vf","virtual font","virtual fonts" },
- variable='VFFONTS',
- suffixes={ 'vf' },
- },
- otf={
- names={ "otf","opentype","opentype font","opentype fonts"},
- variable='OPENTYPEFONTS',
- suffixes={ 'otf' },
- },
- ttf={
- names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
- variable='TTFONTS',
- suffixes={ 'ttf','ttc','dfont' },
- },
- afm={
- names={ "afm","adobe font metric","adobe font metrics" },
- variable="AFMFONTS",
- suffixes={ "afm" },
- },
- pfb={
- names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
- variable='T1FONTS',
- suffixes={ 'pfb','pfa' },
- },
- fea={
- names={ "fea","font feature","font features","font feature file","font feature files" },
- variable='FONTFEATURES',
- suffixes={ 'fea' },
- },
- cid={
- names={ "cid","cid map","cid maps","cid file","cid files" },
- variable='FONTCIDMAPS',
- suffixes={ 'cid','cidmap' },
- },
- fmt={
- names={ "fmt","format","tex format" },
- variable='TEXFORMATS',
- suffixes={ 'fmt' },
- },
- mem={
- names={ 'mem',"metapost format" },
- variable='MPMEMS',
- suffixes={ 'mem' },
- },
- mp={
- names={ "mp" },
- variable='MPINPUTS',
- suffixes={ 'mp','mpvi','mpiv','mpii' },
- usertype=true,
- },
- tex={
- names={ "tex" },
- variable='TEXINPUTS',
- suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
- usertype=true,
- },
- icc={
- names={ "icc","icc profile","icc profiles" },
- variable='ICCPROFILES',
- suffixes={ 'icc' },
- },
- texmfscripts={
- names={ "texmfscript","texmfscripts","script","scripts" },
- variable='TEXMFSCRIPTS',
- suffixes={ 'lua','rb','pl','py' },
- },
- lua={
- names={ "lua" },
- variable='LUAINPUTS',
- suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
- usertype=true,
- },
- lib={
- names={ "lib" },
- variable='CLUAINPUTS',
- suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
- },
- bib={
- names={ 'bib' },
- variable='BIBINPUTS',
- suffixes={ 'bib' },
- usertype=true,
- },
- bst={
- names={ 'bst' },
- variable='BSTINPUTS',
- suffixes={ 'bst' },
- usertype=true,
- },
- fontconfig={
- names={ 'fontconfig','fontconfig file','fontconfig files' },
- variable='FONTCONFIG_PATH',
- },
- pk={
- names={ "pk" },
- variable='PKFONTS',
- suffixes={ 'pk' },
- },
+ core={
+ ofm={
+ names={ "ofm","omega font metric","omega font metrics" },
+ variable='OFMFONTS',
+ suffixes={ 'ofm','tfm' },
+ },
+ ovf={
+ names={ "ovf","omega virtual font","omega virtual fonts" },
+ variable='OVFFONTS',
+ suffixes={ 'ovf','vf' },
+ },
+ tfm={
+ names={ "tfm","tex font metric","tex font metrics" },
+ variable='TFMFONTS',
+ suffixes={ 'tfm' },
+ },
+ vf={
+ names={ "vf","virtual font","virtual fonts" },
+ variable='VFFONTS',
+ suffixes={ 'vf' },
+ },
+ otf={
+ names={ "otf","opentype","opentype font","opentype fonts"},
+ variable='OPENTYPEFONTS',
+ suffixes={ 'otf' },
+ },
+ ttf={
+ names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
+ variable='TTFONTS',
+ suffixes={ 'ttf','ttc','dfont' },
+ },
+ afm={
+ names={ "afm","adobe font metric","adobe font metrics" },
+ variable="AFMFONTS",
+ suffixes={ "afm" },
+ },
+ pfb={
+ names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
+ variable='T1FONTS',
+ suffixes={ 'pfb','pfa' },
+ },
+ fea={
+ names={ "fea","font feature","font features","font feature file","font feature files" },
+ variable='FONTFEATURES',
+ suffixes={ 'fea' },
+ },
+ cid={
+ names={ "cid","cid map","cid maps","cid file","cid files" },
+ variable='FONTCIDMAPS',
+ suffixes={ 'cid','cidmap' },
+ },
+ fmt={
+ names={ "fmt","format","tex format" },
+ variable='TEXFORMATS',
+ suffixes={ 'fmt' },
+ },
+ mem={
+ names={ 'mem',"metapost format" },
+ variable='MPMEMS',
+ suffixes={ 'mem' },
+ },
+ mp={
+ names={ "mp" },
+ variable='MPINPUTS',
+ suffixes={ 'mp','mpvi','mpiv','mpii' },
+ usertype=true,
+ },
+ tex={
+ names={ "tex" },
+ variable='TEXINPUTS',
+ suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
+ usertype=true,
+ },
+ icc={
+ names={ "icc","icc profile","icc profiles" },
+ variable='ICCPROFILES',
+ suffixes={ 'icc' },
+ },
+ texmfscripts={
+ names={ "texmfscript","texmfscripts","script","scripts" },
+ variable='TEXMFSCRIPTS',
+ suffixes={ 'lua','rb','pl','py' },
+ },
+ lua={
+ names={ "lua" },
+ variable='LUAINPUTS',
+ suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
+ usertype=true,
},
- obsolete={
- enc={
- names={ "enc","enc files","enc file","encoding files","encoding file" },
- variable='ENCFONTS',
- suffixes={ 'enc' },
- },
- map={
- names={ "map","map files","map file" },
- variable='TEXFONTMAPS',
- suffixes={ 'map' },
- },
- lig={
- names={ "lig files","lig file","ligature file","ligature files" },
- variable='LIGFONTS',
- suffixes={ 'lig' },
- },
- opl={
- names={ "opl" },
- variable='OPLFONTS',
- suffixes={ 'opl' },
- },
- ovp={
- names={ "ovp" },
- variable='OVPFONTS',
- suffixes={ 'ovp' },
- },
+ lib={
+ names={ "lib" },
+ variable='CLUAINPUTS',
+ suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
},
- kpse={
- base={
- names={ 'base',"metafont format" },
- variable='MFBASES',
- suffixes={ 'base','bas' },
- },
- cmap={
- names={ 'cmap','cmap files','cmap file' },
- variable='CMAPFONTS',
- suffixes={ 'cmap' },
- },
- cnf={
- names={ 'cnf' },
- suffixes={ 'cnf' },
- },
- web={
- names={ 'web' },
- suffixes={ 'web','ch' }
- },
- cweb={
- names={ 'cweb' },
- suffixes={ 'w','web','ch' },
- },
- gf={
- names={ 'gf' },
- suffixes={ '<resolution>gf' },
- },
- mf={
- names={ 'mf' },
- variable='MFINPUTS',
- suffixes={ 'mf' },
- },
- mft={
- names={ 'mft' },
- suffixes={ 'mft' },
- },
- pk={
- names={ 'pk' },
- suffixes={ '<resolution>pk' },
- },
+ bib={
+ names={ 'bib' },
+ variable='BIBINPUTS',
+ suffixes={ 'bib' },
+ usertype=true,
},
+ bst={
+ names={ 'bst' },
+ variable='BSTINPUTS',
+ suffixes={ 'bst' },
+ usertype=true,
+ },
+ fontconfig={
+ names={ 'fontconfig','fontconfig file','fontconfig files' },
+ variable='FONTCONFIG_PATH',
+ },
+ pk={
+ names={ "pk" },
+ variable='PKFONTS',
+ suffixes={ 'pk' },
+ },
+ },
+ obsolete={
+ enc={
+ names={ "enc","enc files","enc file","encoding files","encoding file" },
+ variable='ENCFONTS',
+ suffixes={ 'enc' },
+ },
+ map={
+ names={ "map","map files","map file" },
+ variable='TEXFONTMAPS',
+ suffixes={ 'map' },
+ },
+ lig={
+ names={ "lig files","lig file","ligature file","ligature files" },
+ variable='LIGFONTS',
+ suffixes={ 'lig' },
+ },
+ opl={
+ names={ "opl" },
+ variable='OPLFONTS',
+ suffixes={ 'opl' },
+ },
+ ovp={
+ names={ "ovp" },
+ variable='OVPFONTS',
+ suffixes={ 'ovp' },
+ },
+ },
+ kpse={
+ base={
+ names={ 'base',"metafont format" },
+ variable='MFBASES',
+ suffixes={ 'base','bas' },
+ },
+ cmap={
+ names={ 'cmap','cmap files','cmap file' },
+ variable='CMAPFONTS',
+ suffixes={ 'cmap' },
+ },
+ cnf={
+ names={ 'cnf' },
+ suffixes={ 'cnf' },
+ },
+ web={
+ names={ 'web' },
+ suffixes={ 'web','ch' }
+ },
+ cweb={
+ names={ 'cweb' },
+ suffixes={ 'w','web','ch' },
+ },
+ gf={
+ names={ 'gf' },
+ suffixes={ '<resolution>gf' },
+ },
+ mf={
+ names={ 'mf' },
+ variable='MFINPUTS',
+ suffixes={ 'mf' },
+ },
+ mft={
+ names={ 'mft' },
+ suffixes={ 'mft' },
+ },
+ pk={
+ names={ 'pk' },
+ suffixes={ '<resolution>pk' },
+ },
+ },
}
resolvers.relations=relations
function resolvers.updaterelations()
- for category,categories in next,relations do
- for name,relation in next,categories do
- local rn=relation.names
- local rv=relation.variable
- if rn and rv then
- local rs=relation.suffixes
- local ru=relation.usertype
- for i=1,#rn do
- local rni=lower(gsub(rn[i]," ",""))
- formats[rni]=rv
- if rs then
- suffixes[rni]=rs
- for i=1,#rs do
- local rsi=rs[i]
- suffixmap[rsi]=rni
- end
- end
- end
- if ru then
- usertypes[name]=true
- end
+ for category,categories in next,relations do
+ for name,relation in next,categories do
+ local rn=relation.names
+ local rv=relation.variable
+ if rn and rv then
+ local rs=relation.suffixes
+ local ru=relation.usertype
+ for i=1,#rn do
+ local rni=lower(gsub(rn[i]," ",""))
+ formats[rni]=rv
+ if rs then
+ suffixes[rni]=rs
+ for i=1,#rs do
+ local rsi=rs[i]
+ suffixmap[rsi]=rni
end
+ end
+ end
+ if ru then
+ usertypes[name]=true
end
+ end
end
+ end
end
resolvers.updaterelations()
local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
+ return k and rawget(t,lower(gsub(k," ",""))) or nil
end
setmetatableindex(formats,simplified)
setmetatableindex(suffixes,simplified)
setmetatableindex(suffixmap,simplified)
function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
+ local s=suffixes[str]
+ return s and s[1] or ""
end
function resolvers.suffixofformat(str)
- return suffixes[str] or {}
+ return suffixes[str] or {}
end
for name,format in next,formats do
- dangerous[name]=true
+ dangerous[name]=true
end
dangerous.tex=nil
function resolvers.formatofvariable(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.formatofsuffix(str)
- return suffixmap[suffixonly(str)] or 'tex'
+ return suffixmap[suffixonly(str)] or 'tex'
end
function resolvers.variableofformat(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
- return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
- return formats[v]
- end
- return ''
+ local v=formats[str]
+ if v then
+ return v
+ end
+ v=suffixmap[suffixonly(str)]
+ if v then
+ return formats[v]
+ end
+ return ''
end
@@ -17208,14 +20782,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16116, stripped down to: 11459
+-- original size: 16116, stripped down to: 10782
if not modules then modules={} end modules ['data-tmp']={
- 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,concat=string.format,string.lower,string.gsub,table.concat
local concat=table.concat
@@ -17223,19 +20797,19 @@ local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
local next,type=next,type
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
local report_resolvers=logs.reporter("resolvers","caching")
local resolvers=resolvers
local cleanpath=resolvers.cleanpath
-local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
-local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
+local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
+local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
local compile=utilities.lua.compile
function utilities.lua.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip end
- return compile(luafile,lucfile,cleanup,strip)
+ if cleanup==nil then cleanup=directive_cleanup end
+ if strip==nil then strip=directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
end
caches=caches or {}
local caches=caches
@@ -17250,324 +20824,324 @@ caches.relocate=false
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local writable,readables,usedreadables=nil,{},{}
local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- cachepath=file.collapsepath(cachepath)
- local valid=isdir(cachepath)
- if valid then
- if is_readable(cachepath) then
- readables[#readables+1]=cachepath
- if not writable and is_writable(cachepath) then
- writable=cachepath
- end
- end
- elseif not writable and caches.force then
- local cacheparent=file.dirname(cachepath)
- if is_writable(cacheparent) and true then
- if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
- mkdirs(cachepath)
- if isdir(cachepath) and is_writable(cachepath) then
- report_caches("path %a created",cachepath)
- writable=cachepath
- readables[#readables+1]=cachepath
- end
- end
- end
- end
+ local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ cachepath=file.collapsepath(cachepath)
+ local valid=isdir(cachepath)
+ if valid then
+ if is_readable(cachepath) then
+ readables[#readables+1]=cachepath
+ if not writable and is_writable(cachepath) then
+ writable=cachepath
end
- end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- cachepath=resolvers.expansion(cachepath)
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- local valid=isdir(cachepath)
- if valid and is_readable(cachepath) then
- if not writable and is_writable(cachepath) then
- readables[#readables+1]=cachepath
- writable=cachepath
- break
- end
- end
+ end
+ elseif not writable and caches.force then
+ local cacheparent=file.dirname(cachepath)
+ if is_writable(cacheparent) and true then
+ if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
+ mkdirs(cachepath)
+ if isdir(cachepath) and is_writable(cachepath) then
+ report_caches("path %a created",cachepath)
+ writable=cachepath
+ readables[#readables+1]=cachepath
+ end
end
+ end
end
+ end
end
- if not writable then
- report_caches("fatal error: there is no valid writable cache path defined")
- os.exit()
- elseif #readables==0 then
- report_caches("fatal error: there is no valid readable cache path defined")
- os.exit()
- end
- writable=dir.expandname(resolvers.cleanpath(writable))
- local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
- if tree then
- caches.tree=tree
- writable=mkdirs(writable,base,more,tree)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more,tree)
- end
- else
- writable=mkdirs(writable,base,more)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more)
+ end
+ local texmfcaches=caches.defaults
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ cachepath=resolvers.expansion(cachepath)
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ local valid=isdir(cachepath)
+ if valid and is_readable(cachepath) then
+ if not writable and is_writable(cachepath) then
+ readables[#readables+1]=cachepath
+ writable=cachepath
+ break
+ end
end
+ end
end
- if trace_cache then
- for i=1,#readables do
- report_caches("using readable path %a (order %s)",readables[i],i)
- end
- report_caches("using writable path %a",writable)
+ end
+ if not writable then
+ report_caches("fatal error: there is no valid writable cache path defined")
+ os.exit()
+ elseif #readables==0 then
+ report_caches("fatal error: there is no valid readable cache path defined")
+ os.exit()
+ end
+ writable=dir.expandname(resolvers.cleanpath(writable))
+ local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
+ if tree then
+ caches.tree=tree
+ writable=mkdirs(writable,base,more,tree)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more,tree)
end
- identify=function()
- return writable,readables
+ else
+ writable=mkdirs(writable,base,more)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more)
end
+ end
+ if trace_cache then
+ for i=1,#readables do
+ report_caches("using readable path %a (order %s)",readables[i],i)
+ end
+ report_caches("using writable path %a",writable)
+ end
+ identify=function()
return writable,readables
+ end
+ return writable,readables
end
function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
- local result={}
- local done={}
- for i=1,#readables do
- local readable=readables[i]
- if readable==writable then
- done[readable]=true
- result[#result+1]=formatters["readable+writable: %a"](readable)
- elseif usedreadables[i] then
- done[readable]=true
- result[#result+1]=formatters["readable: %a"](readable)
- end
- end
- if not done[writable] then
- result[#result+1]=formatters["writable: %a"](writable)
- end
- return concat(result,separator or " | ")
- else
- return writable or "?"
+ local writable,readables=identify()
+ if #readables>1 then
+ local result={}
+ local done={}
+ for i=1,#readables do
+ local readable=readables[i]
+ if readable==writable then
+ done[readable]=true
+ result[#result+1]=formatters["readable+writable: %a"](readable)
+ elseif usedreadables[i] then
+ done[readable]=true
+ result[#result+1]=formatters["readable: %a"](readable)
+ end
end
+ if not done[writable] then
+ result[#result+1]=formatters["writable: %a"](writable)
+ end
+ return concat(result,separator or " | ")
+ else
+ return writable or "?"
+ end
end
function caches.configfiles()
- return concat(resolvers.configurationfiles(),";")
+ return concat(resolvers.configurationfiles(),";")
end
function caches.hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5.hex(tree)
- if trace_cache or trace_locating then
- report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
+ tree=gsub(tree,"[\\/]+$","")
+ tree=lower(tree)
+ local hash=md5.hex(tree)
+ if trace_cache or trace_locating then
+ report_caches("hashing tree %a, hash %a",tree,hash)
+ end
+ return hash
end
function caches.treehash()
- local tree=caches.configfiles()
- if not tree or tree=="" then
- return false
- else
- return caches.hashed(tree)
- end
+ local tree=caches.configfiles()
+ if not tree or tree=="" then
+ return false
+ else
+ return caches.hashed(tree)
+ end
end
local r_cache,w_cache={},{}
local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done={}
- for i=1,#readables do
- done[i]=file.join(readables[i],...)
- end
- else
- done=readables
- end
- r_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=r_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done={}
+ for i=1,#readables do
+ done[i]=file.join(readables[i],...)
+ end
+ else
+ done=readables
end
- return done
+ r_cache[hash]=done
+ end
+ return done
end
local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done=mkdirs(writable,...)
- else
- done=writable
- end
- w_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=w_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done=mkdirs(writable,...)
+ else
+ done=writable
end
- return done
+ w_cache[hash]=done
+ end
+ return done
end
caches.getreadablepaths=getreadablepaths
caches.getwritablepath=getwritablepath
function caches.getfirstreadablefile(filename,...)
- local fullname,path=caches.setfirstwritablefile(filename,...)
+ local fullname,path=caches.setfirstwritablefile(filename,...)
+ if is_readable(fullname) then
+ return fullname,path
+ end
+ local rd=getreadablepaths(...)
+ for i=1,#rd do
+ local path=rd[i]
+ local fullname=file.join(path,filename)
if is_readable(fullname) then
- return fullname,path
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
- local path=rd[i]
- local fullname=file.join(path,filename)
- if is_readable(fullname) then
- usedreadables[i]=true
- return fullname,path
- end
+ usedreadables[i]=true
+ return fullname,path
end
- return fullname,path
+ end
+ return fullname,path
end
function caches.setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=file.join(wr,filename)
- return fullname,wr
+ local wr=getwritablepath(...)
+ local fullname=file.join(wr,filename)
+ return fullname,wr
end
function caches.define(category,subcategory)
- return function()
- return getwritablepath(category,subcategory)
- end
+ return function()
+ return getwritablepath(category,subcategory)
+ end
end
function caches.setluanames(path,name)
- return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
+ return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
end
function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
- readables={ readables }
+ if type(readables)=="string" then
+ readables={ readables }
+ end
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local tmaname,tmcname=caches.setluanames(path,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader and isfile(tmaname) then
+ local tmacrap,tmcname=caches.setluanames(writable,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ utilities.lua.compile(tmaname,tmcname)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader then
+ loader=loadfile(tmaname)
+ end
end
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local tmaname,tmcname=caches.setluanames(path,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader and isfile(tmaname) then
- local tmacrap,tmcname=caches.setluanames(writable,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- utilities.lua.compile(tmaname,tmcname)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader then
- loader=loadfile(tmaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
end
- return false
+ end
+ return false
end
function caches.is_writable(filepath,filename)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- return is_writable(tmaname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ return is_writable(tmaname)
end
local saveoptions={ compact=true }
function caches.savedata(filepath,filename,data,raw)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- data.cache_uuid=os.uuid()
- if caches.direct then
- file.savedata(tmaname,table.serialize(data,true,saveoptions))
- else
- table.tofile(tmaname,data,true,saveoptions)
- end
- utilities.lua.compile(tmaname,tmcname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ data.cache_uuid=os.uuid()
+ if caches.direct then
+ file.savedata(tmaname,table.serialize(data,true,saveoptions))
+ else
+ table.tofile(tmaname,data,true,saveoptions)
+ end
+ utilities.lua.compile(tmaname,tmcname)
end
local content_state={}
function caches.contentstate()
- return content_state or {}
+ return content_state or {}
end
function caches.loadcontent(cachename,dataname,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
- if blob then
- local data=blob()
- if data and data.content then
- if data.type==dataname then
- if data.version==resolvers.cacheversion then
- content_state[#content_state+1]=data.uuid
- if trace_locating then
- report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
- end
- return data.content
- else
- report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
- end
- else
- report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
+ if blob then
+ local data=blob()
+ if data and data.content then
+ if data.type==dataname then
+ if data.version==resolvers.cacheversion then
+ content_state[#content_state+1]=data.uuid
+ if trace_locating then
+ report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
+ end
+ return data.content
+ else
+ report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
end
+ else
+ report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
+ end
elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
end
+ elseif trace_locating then
+ report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ end
end
function caches.collapsecontent(content)
- for k,v in next,content do
- if type(v)=="table" and #v==1 then
- content[k]=v[1]
- end
+ for k,v in next,content do
+ if type(v)=="table" and #v==1 then
+ content[k]=v[1]
end
+ end
end
function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local luaname=addsuffix(filename,luasuffixes.lua)
+ local lucname=addsuffix(filename,luasuffixes.luc)
+ if trace_locating then
+ report_resolvers("preparing %a for %a",dataname,cachename)
+ end
+ local data={
+ type=dataname,
+ root=cachename,
+ version=resolvers.cacheversion,
+ date=os.date("%Y-%m-%d"),
+ time=os.date("%H:%M:%S"),
+ content=content,
+ uuid=os.uuid(),
+ }
+ local ok=io.savedata(luaname,table.serialize(data,true))
+ if ok then
if trace_locating then
- report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
- type=dataname,
- root=cachename,
- version=resolvers.cacheversion,
- date=os.date("%Y-%m-%d"),
- time=os.date("%H:%M:%S"),
- content=content,
- uuid=os.uuid(),
- }
- local ok=io.savedata(luaname,table.serialize(data,true))
- if ok then
- if trace_locating then
- report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
- end
- if utilities.lua.compile(luaname,lucname) then
- if trace_locating then
- report_resolvers("%a compiled to %a",dataname,lucname)
- end
- return true
- else
- if trace_locating then
- report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
- end
- os.remove(lucname)
- end
- elseif trace_locating then
- report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
+ end
+ if utilities.lua.compile(luaname,lucname) then
+ if trace_locating then
+ report_resolvers("%a compiled to %a",dataname,lucname)
+ end
+ return true
+ else
+ if trace_locating then
+ report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
+ end
+ os.remove(lucname)
end
+ elseif trace_locating then
+ report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ end
end
@@ -17577,14 +21151,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-met"] = package.loaded["data-met"] or true
--- original size: 5310, stripped down to: 3980
+-- original size: 5310, stripped down to: 3784
if not modules then modules={} end modules ['data-met']={
- 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 find,format=string.find,string.format
local sequenced=table.sequenced
@@ -17598,86 +21172,86 @@ local allocate=utilities.storage.allocate
local resolvers=resolvers
local registered={}
local function splitmethod(filename)
- if not filename then
- return { scheme="unknown",original=filename }
- end
- if type(filename)=="table" then
- return filename
- end
- filename=file.collapsepath(filename,".")
- if not find(filename,"://",1,true) then
- return { scheme="file",path=filename,original=filename,filename=filename }
- end
- local specification=url.hashed(filename)
- if not specification.scheme or specification.scheme=="" then
- return { scheme="file",path=filename,original=filename,filename=filename }
- else
- return specification
- end
+ if not filename then
+ return { scheme="unknown",original=filename }
+ end
+ if type(filename)=="table" then
+ return filename
+ end
+ filename=file.collapsepath(filename,".")
+ if not find(filename,"://",1,true) then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ end
+ local specification=url.hashed(filename)
+ if not specification.scheme or specification.scheme=="" then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ else
+ return specification
+ end
end
resolvers.splitmethod=splitmethod
local function methodhandler(what,first,...)
- local method=registered[what]
- if method then
- local how,namespace=method.how,method.namespace
- if how=="uri" or how=="url" then
- local specification=splitmethod(first)
- local scheme=specification.scheme
- local resolver=namespace and namespace[scheme]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
- end
- return resolver(specification,...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
- end
- return resolver(specification,...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
- end
- end
- elseif how=="tag" then
- local resolver=namespace and namespace[first]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,first)
- end
- return resolver(...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
- end
- return resolver(...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
- end
- end
+ local method=registered[what]
+ if method then
+ local how,namespace=method.how,method.namespace
+ if how=="uri" or how=="url" then
+ local specification=splitmethod(first)
+ local scheme=specification.scheme
+ local resolver=namespace and namespace[scheme]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+ end
+ return resolver(specification,...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
+ end
+ return resolver(specification,...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
end
- else
- report_methods("resolving, invalid method %a")
+ end
+ elseif how=="tag" then
+ local resolver=namespace and namespace[first]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,first)
+ end
+ return resolver(...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
+ end
+ return resolver(...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
+ end
+ end
end
+ else
+ report_methods("resolving, invalid method %a")
+ end
end
resolvers.methodhandler=methodhandler
function resolvers.registermethod(name,namespace,how)
- registered[name]={ how=how or "tag",namespace=namespace }
- namespace["byscheme"]=function(scheme,filename,...)
- if scheme=="file" then
- return methodhandler(name,filename,...)
- else
- return methodhandler(name,addurlscheme(filename,scheme),...)
- end
+ registered[name]={ how=how or "tag",namespace=namespace }
+ namespace["byscheme"]=function(scheme,filename,...)
+ if scheme=="file" then
+ return methodhandler(name,filename,...)
+ else
+ return methodhandler(name,addurlscheme(filename,scheme),...)
end
+ end
end
-local concatinators=allocate { notfound=file.join }
-local locators=allocate { notfound=function() end }
-local hashers=allocate { notfound=function() end }
-local generators=allocate { notfound=function() end }
+local concatinators=allocate { notfound=file.join }
+local locators=allocate { notfound=function() end }
+local hashers=allocate { notfound=function() end }
+local generators=allocate { notfound=function() end }
resolvers.concatinators=concatinators
resolvers.locators=locators
resolvers.hashers=hashers
@@ -17695,17 +21269,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-res"] = package.loaded["data-res"] or true
--- original size: 68263, stripped down to: 47789
+-- original size: 68195, stripped down to: 43680
if not modules then modules={} end modules ['data-res']={
- 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 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
local P,S,R,C,Cc,Cs,Ct,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Carg
@@ -17727,11 +21301,11 @@ local isfile=lfs.isfile
local isdir=lfs.isdir
local setmetatableindex=table.setmetatableindex
local luasuffixes=utilities.lua.suffixes
-local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
+local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
+local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
local report_resolving=logs.reporter("resolvers","resolving")
local resolvers=resolvers
local expandedpathfromlist=resolvers.expandedpathfromlist
@@ -17752,15 +21326,15 @@ resolvers.luacnfname="texmfcnf.lua"
resolvers.luacnffallback="contextcnf.lua"
resolvers.luacnfstate="unknown"
if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
+ resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
else
- resolvers.luacnfspec=concat ({
- "home:texmf/web2c",
- "selfautoparent:/texmf-local/web2c",
- "selfautoparent:/texmf-context/web2c",
- "selfautoparent:/texmf-dist/web2c",
- "selfautoparent:/texmf/web2c",
- },";")
+ resolvers.luacnfspec=concat ({
+ "home:texmf/web2c",
+ "selfautoparent:/texmf-local/web2c",
+ "selfautoparent:/texmf-context/web2c",
+ "selfautoparent:/texmf-dist/web2c",
+ "selfautoparent:/texmf/web2c",
+ },";")
end
local unset_variable="unset"
local formats=resolvers.formats
@@ -17771,24 +21345,24 @@ local suffixmap=resolvers.suffixmap
resolvers.defaultsuffixes={ "tex" }
local instance=nil
function resolvers.setenv(key,value,raw)
- if instance then
- instance.environment[key]=value
- ossetenv(key,raw and value or resolveprefix(value))
- end
+ if instance then
+ instance.environment[key]=value
+ ossetenv(key,raw and value or resolveprefix(value))
+ end
end
local function getenv(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
- return value
- else
- local e=osgetenv(key)
- return e~=nil and e~="" and checkedvariable(e) or ""
- end
+ local value=rawget(instance.environment,key)
+ if value and value~="" then
+ return value
+ else
+ local e=osgetenv(key)
+ return e~=nil and e~="" and checkedvariable(e) or ""
+ end
end
resolvers.getenv=getenv
resolvers.env=getenv
local function resolvevariable(k)
- return instance.expansions[k]
+ return instance.expansions[k]
end
local dollarstripper=lpeg.stripper("$")
local inhibitstripper=P("!")^0*Cs(P(1)^0)
@@ -17802,1506 +21376,1506 @@ local somevariable=R("az","AZ","09","__","--")^1/resolvevariable
local variable=(P("$")/"")*(somevariable+(P("{")/"")*somevariable*(P("}")/""))
local variableresolver=Cs((variable+P(1))^0)
local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
+ return lpegmatch(variableexpander,var) or var
end
function resolvers.reset()
- if trace_locating then
- report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
- environment=environment,
- variables=variables,
- expansions=expansions,
- order=order,
- files={},
- setups={},
- found={},
- foundintrees={},
- hashes={},
- hashed={},
- pathlists=false,
- specification={},
- lists={},
- data={},
- fakepaths={},
- remember=true,
- diskcache=true,
- renewcache=false,
- renewtree=false,
- loaderror=false,
- savelists=true,
- pattern=nil,
- force_suffixes=true,
- pathstack={},
- }
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v=order[i][k]
- if v~=nil then
- t[k]=v
- return v
- end
- end
- if v==nil then
- v=""
- end
- t[k]=v
- return v
- end)
- setmetatableindex(environment,function(t,k)
- local v=osgetenv(k)
- if v==nil then
- v=variables[k]
- end
- if v~=nil then
- v=checkedvariable(v) or ""
- end
- v=resolvers.repath(v)
- t[k]=v
- return v
- end)
- setmetatableindex(expansions,function(t,k)
- local v=environment[k]
- if type(v)=="string" then
- v=lpegmatch(variableresolver,v)
- v=lpegmatch(variablecleaner,v)
- end
+ if trace_locating then
+ report_resolving("creating instance")
+ end
+ local environment={}
+ local variables={}
+ local expansions={}
+ local order={}
+ instance={
+ environment=environment,
+ variables=variables,
+ expansions=expansions,
+ order=order,
+ files={},
+ setups={},
+ found={},
+ foundintrees={},
+ hashes={},
+ hashed={},
+ pathlists=false,
+ specification={},
+ lists={},
+ data={},
+ fakepaths={},
+ remember=true,
+ diskcache=true,
+ renewcache=false,
+ renewtree=false,
+ loaderror=false,
+ savelists=true,
+ pattern=nil,
+ force_suffixes=true,
+ pathstack={},
+ }
+ setmetatableindex(variables,function(t,k)
+ local v
+ for i=1,#order do
+ v=order[i][k]
+ if v~=nil then
t[k]=v
return v
- end)
+ end
+ end
+ if v==nil then
+ v=""
+ end
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(environment,function(t,k)
+ local v=osgetenv(k)
+ if v==nil then
+ v=variables[k]
+ end
+ if v~=nil then
+ v=checkedvariable(v) or ""
+ end
+ v=resolvers.repath(v)
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(expansions,function(t,k)
+ local v=environment[k]
+ if type(v)=="string" then
+ v=lpegmatch(variableresolver,v)
+ v=lpegmatch(variablecleaner,v)
+ end
+ t[k]=v
+ return v
+ end)
end
function resolvers.initialized()
- return instance~=nil
+ return instance~=nil
end
local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
+ instance.lists={}
+ instance.pathlists=false
+ instance.found={}
end
local function reset_caches()
- instance.lists={}
- instance.pathlists=false
+ instance.lists={}
+ instance.pathlists=false
end
local slash=P("/")
local pathexpressionpattern=Cs (
- Cc("^")*(
- Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+ Cc("^")*(
+ Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$")
+ )^1*Cc("$")
)
local cache={}
local function makepathexpression(str)
- if str=="." then
- return "^%./$"
- else
- local c=cache[str]
- if not c then
- c=lpegmatch(pathexpressionpattern,str)
- cache[str]=c
- end
- return c
+ if str=="." then
+ return "^%./$"
+ else
+ local c=cache[str]
+ if not c then
+ c=lpegmatch(pathexpressionpattern,str)
+ cache[str]=c
end
+ return c
+ end
end
local function reportcriticalvariables(cnfspec)
- if trace_locating then
- for i=1,#resolvers.criticalvars do
- local k=resolvers.criticalvars[i]
- local v=resolvers.getenv(k) or "unknown"
- report_resolving("variable %a set to %a",k,v)
- end
- report_resolving()
- if cnfspec then
- report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
- end
- report_resolving()
+ if trace_locating then
+ for i=1,#resolvers.criticalvars do
+ local k=resolvers.criticalvars[i]
+ local v=resolvers.getenv(k) or "unknown"
+ report_resolving("variable %a set to %a",k,v)
+ end
+ report_resolving()
+ if cnfspec then
+ report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
end
- reportcriticalvariables=function() end
+ report_resolving()
+ end
+ reportcriticalvariables=function() end
end
local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
- local cnfspec=getenv("TEXMFCNF")
- if cnfspec=="" then
- cnfspec=resolvers.luacnfspec
- resolvers.luacnfstate="default"
- else
- resolvers.luacnfstate="environment"
- end
- reportcriticalvariables(cnfspec)
- local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
- local function locatecnf(luacnfname,kind)
- for i=1,#cnfpaths do
- local filepath=cnfpaths[i]
- local filename=collapsepath(filejoin(filepath,luacnfname))
- local realname=resolveprefix(filename)
- if trace_locating then
- local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
- local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
- report_resolving("looking for %s %a on %s path %a from specification %a",
- kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
- end
- if isfile(realname) then
- specification[#specification+1]=filename
- if trace_locating then
- report_resolving("found %s configuration file %a",kind,realname)
- end
- end
- end
- end
- locatecnf(resolvers.luacnfname,"regular")
- if #specification==0 then
- locatecnf(resolvers.luacnffallback,"fallback")
- end
+ local specification=instance.specification
+ if #specification==0 then
+ local cnfspec=getenv("TEXMFCNF")
+ if cnfspec=="" then
+ cnfspec=resolvers.luacnfspec
+ resolvers.luacnfstate="default"
+ else
+ resolvers.luacnfstate="environment"
+ end
+ reportcriticalvariables(cnfspec)
+ local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
+ local function locatecnf(luacnfname,kind)
+ for i=1,#cnfpaths do
+ local filepath=cnfpaths[i]
+ local filename=collapsepath(filejoin(filepath,luacnfname))
+ local realname=resolveprefix(filename)
if trace_locating then
- report_resolving()
+ local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
+ local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
+ report_resolving("looking for %s %a on %s path %a from specification %a",
+ kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+ end
+ if isfile(realname) then
+ specification[#specification+1]=filename
+ if trace_locating then
+ report_resolving("found %s configuration file %a",kind,realname)
+ end
end
- elseif trace_locating then
- report_resolving("configuration files already identified")
+ end
+ end
+ locatecnf(resolvers.luacnfname,"regular")
+ if #specification==0 then
+ locatecnf(resolvers.luacnffallback,"fallback")
+ end
+ if trace_locating then
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("configuration files already identified")
+ end
end
local function load_configuration_files()
- local specification=instance.specification
- if #specification>0 then
- local luacnfname=resolvers.luacnfname
- for i=1,#specification do
- local filename=specification[i]
- local pathname=filedirname(filename)
- local filename=filejoin(pathname,luacnfname)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local setups=instance.setups
- local data=blob()
- local parent=data and data.parent
- if parent then
- local filename=filejoin(pathname,parent)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local parentdata=blob()
- if parentdata then
- report_resolving("loading configuration file %a",filename)
- data=table.merged(parentdata,data)
- end
- end
- end
- data=data and data.content
- if data then
- if trace_locating then
- report_resolving("loading configuration file %a",filename)
- report_resolving()
- end
- local variables=data.variables or {}
- local warning=false
- for k,v in next,data do
- local variant=type(v)
- if variant=="table" then
- initializesetter(filename,k,v)
- elseif variables[k]==nil then
- if trace_locating and not warning then
- report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
- k,resolveprefix(filename))
- warning=true
- end
- variables[k]=v
- end
- end
- setups[pathname]=variables
- if resolvers.luacnfstate=="default" then
- local cnfspec=variables["TEXMFCNF"]
- if cnfspec then
- if trace_locating then
- report_resolving("reloading configuration due to TEXMF redefinition")
- end
- resolvers.setenv("TEXMFCNF",cnfspec)
- instance.specification={}
- identify_configuration_files()
- load_configuration_files()
- resolvers.luacnfstate="configuration"
- break
- end
- end
- else
- if trace_locating then
- report_resolving("skipping configuration file %a (no content)",filename)
- end
- setups[pathname]={}
- instance.loaderror=true
- end
- elseif trace_locating then
- report_resolving("skipping configuration file %a (no valid format)",filename)
+ local specification=instance.specification
+ if #specification>0 then
+ local luacnfname=resolvers.luacnfname
+ for i=1,#specification do
+ local filename=specification[i]
+ local pathname=filedirname(filename)
+ local filename=filejoin(pathname,luacnfname)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local setups=instance.setups
+ local data=blob()
+ local parent=data and data.parent
+ if parent then
+ local filename=filejoin(pathname,parent)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local parentdata=blob()
+ if parentdata then
+ report_resolving("loading configuration file %a",filename)
+ data=table.merged(parentdata,data)
end
- instance.order[#instance.order+1]=instance.setups[pathname]
- if instance.loaderror then
- break
+ end
+ end
+ data=data and data.content
+ if data then
+ if trace_locating then
+ report_resolving("loading configuration file %a",filename)
+ report_resolving()
+ end
+ local variables=data.variables or {}
+ local warning=false
+ for k,v in next,data do
+ local variant=type(v)
+ if variant=="table" then
+ initializesetter(filename,k,v)
+ elseif variables[k]==nil then
+ if trace_locating and not warning then
+ report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
+ k,resolveprefix(filename))
+ warning=true
+ end
+ variables[k]=v
+ end
+ end
+ setups[pathname]=variables
+ if resolvers.luacnfstate=="default" then
+ local cnfspec=variables["TEXMFCNF"]
+ if cnfspec then
+ if trace_locating then
+ report_resolving("reloading configuration due to TEXMF redefinition")
+ end
+ resolvers.setenv("TEXMFCNF",cnfspec)
+ instance.specification={}
+ identify_configuration_files()
+ load_configuration_files()
+ resolvers.luacnfstate="configuration"
+ break
end
+ end
+ else
+ if trace_locating then
+ report_resolving("skipping configuration file %a (no content)",filename)
+ end
+ setups[pathname]={}
+ instance.loaderror=true
end
- elseif trace_locating then
- report_resolving("warning: no lua configuration files found")
+ elseif trace_locating then
+ report_resolving("skipping configuration file %a (no valid format)",filename)
+ end
+ instance.order[#instance.order+1]=instance.setups[pathname]
+ if instance.loaderror then
+ break
+ end
end
+ elseif trace_locating then
+ report_resolving("warning: no lua configuration files found")
+ end
end
function resolvers.configurationfiles()
- return instance.specification or {}
+ return instance.specification or {}
end
local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- resolvers.hashers.byscheme(hash.type,hash.name)
- if instance.loaderror then break end
- end
+ instance.loaderror=false
+ instance.files={}
+ if not instance.renewcache then
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ resolvers.hashers.byscheme(hash.type,hash.name)
+ if instance.loaderror then break end
end
+ end
end
local function locate_file_databases()
- local texmfpaths=resolvers.expandedpathlist("TEXMF")
- if #texmfpaths>0 then
- for i=1,#texmfpaths do
- local path=collapsepath(texmfpaths[i])
- path=gsub(path,"/+$","")
- local stripped=lpegmatch(inhibitstripper,path)
- if stripped~="" then
- local runtime=stripped==path
- path=cleanpath(path)
- local spec=resolvers.splitmethod(stripped)
- if runtime and (spec.noscheme or spec.scheme=="file") then
- stripped="tree:///"..stripped
- elseif spec.scheme=="cache" or spec.scheme=="file" then
- stripped=spec.path
- end
- if trace_locating then
- if runtime then
- report_resolving("locating list of %a (runtime) (%s)",path,stripped)
- else
- report_resolving("locating list of %a (cached)",path)
- end
- end
- methodhandler('locators',stripped)
- end
+ local texmfpaths=resolvers.expandedpathlist("TEXMF")
+ if #texmfpaths>0 then
+ for i=1,#texmfpaths do
+ local path=collapsepath(texmfpaths[i])
+ path=gsub(path,"/+$","")
+ local stripped=lpegmatch(inhibitstripper,path)
+ if stripped~="" then
+ local runtime=stripped==path
+ path=cleanpath(path)
+ local spec=resolvers.splitmethod(stripped)
+ if runtime and (spec.noscheme or spec.scheme=="file") then
+ stripped="tree:///"..stripped
+ elseif spec.scheme=="cache" or spec.scheme=="file" then
+ stripped=spec.path
end
if trace_locating then
- report_resolving()
+ if runtime then
+ report_resolving("locating list of %a (runtime) (%s)",path,stripped)
+ else
+ report_resolving("locating list of %a (cached)",path)
+ end
end
- elseif trace_locating then
- report_resolving("no texmf paths are defined (using TEXMF)")
- end
-end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- methodhandler('generators',hash.name)
+ methodhandler('locators',stripped)
+ end
end
if trace_locating then
- report_resolving()
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("no texmf paths are defined (using TEXMF)")
+ end
+end
+local function generate_file_databases()
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ methodhandler('generators',hash.name)
+ end
+ if trace_locating then
+ report_resolving()
+ end
end
local function save_file_databases()
- for i=1,#instance.hashes do
- local hash=instance.hashes[i]
- local cachename=hash.name
- if hash.cache then
- local content=instance.files[cachename]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",cachename)
- end
- caches.savecontent(cachename,"files",content)
- elseif trace_locating then
- report_resolving("not saving runtime tree %a",cachename)
- end
+ for i=1,#instance.hashes do
+ local hash=instance.hashes[i]
+ local cachename=hash.name
+ if hash.cache then
+ local content=instance.files[cachename]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",cachename)
+ end
+ caches.savecontent(cachename,"files",content)
+ elseif trace_locating then
+ report_resolving("not saving runtime tree %a",cachename)
end
+ end
end
function resolvers.renew(hashname)
- if hashname and hashname~="" then
- local expanded=resolvers.expansion(hashname) or ""
- if expanded~="" then
- if trace_locating then
- report_resolving("identifying tree %a from %a",expanded,hashname)
- end
- hashname=expanded
- else
- if trace_locating then
- report_resolving("identifying tree %a",hashname)
- end
- end
- local realpath=resolveprefix(hashname)
- if isdir(realpath) then
- if trace_locating then
- report_resolving("using path %a",realpath)
- end
- methodhandler('generators',hashname)
- local content=instance.files[hashname]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",hashname)
- end
- caches.savecontent(hashname,"files",content)
- else
- report_resolving("invalid path %a",realpath)
- end
+ if hashname and hashname~="" then
+ local expanded=resolvers.expansion(hashname) or ""
+ if expanded~="" then
+ if trace_locating then
+ report_resolving("identifying tree %a from %a",expanded,hashname)
+ end
+ hashname=expanded
+ else
+ if trace_locating then
+ report_resolving("identifying tree %a",hashname)
+ end
end
+ local realpath=resolveprefix(hashname)
+ if isdir(realpath) then
+ if trace_locating then
+ report_resolving("using path %a",realpath)
+ end
+ methodhandler('generators',hashname)
+ local content=instance.files[hashname]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",hashname)
+ end
+ caches.savecontent(hashname,"files",content)
+ else
+ report_resolving("invalid path %a",realpath)
+ end
+ end
end
local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
- load_file_databases()
- if instance.loaderror then
- generate_file_databases()
- save_file_databases()
- end
- else
- generate_file_databases()
- if instance.renewcache then
- save_file_databases()
- end
+ locate_file_databases()
+ if instance.diskcache and not instance.renewcache then
+ load_file_databases()
+ if instance.loaderror then
+ generate_file_databases()
+ save_file_databases()
+ end
+ else
+ generate_file_databases()
+ if instance.renewcache then
+ save_file_databases()
end
+ end
end
function resolvers.appendhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a appended",name)
- end
- insert(instance.hashes,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a appended",name)
end
+ insert(instance.hashes,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.prependhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a prepended",name)
- end
- insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a prepended",name)
end
+ insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.extendtexmfvariable(specification)
- local t=resolvers.splitpath(getenv("TEXMF"))
- insert(t,1,specification)
- local newspec=concat(t,",")
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"]=newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"]=newspec
- else
- end
- reset_hashes()
+ local t=resolvers.splitpath(getenv("TEXMF"))
+ insert(t,1,specification)
+ local newspec=concat(t,",")
+ if instance.environment["TEXMF"] then
+ instance.environment["TEXMF"]=newspec
+ elseif instance.variables["TEXMF"] then
+ instance.variables["TEXMF"]=newspec
+ else
+ end
+ reset_hashes()
end
function resolvers.splitexpansions()
- local ie=instance.expansions
- for k,v in next,ie do
- local t,tn,h,p={},0,{},splitconfigurationpath(v)
- for kk=1,#p do
- local vv=p[kk]
- if vv~="" and not h[vv] then
- tn=tn+1
- t[tn]=vv
- h[vv]=true
- end
- end
- if #t>1 then
- ie[k]=t
- else
- ie[k]=t[1]
- end
+ local ie=instance.expansions
+ for k,v in next,ie do
+ local t,tn,h,p={},0,{},splitconfigurationpath(v)
+ for kk=1,#p do
+ local vv=p[kk]
+ if vv~="" and not h[vv] then
+ tn=tn+1
+ t[tn]=vv
+ h[vv]=true
+ end
end
+ if #t>1 then
+ ie[k]=t
+ else
+ ie[k]=t[1]
+ end
+ end
end
function resolvers.datastate()
- return caches.contentstate()
+ return caches.contentstate()
end
function resolvers.variable(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.variables[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.variables[name]
+ return result~=nil and result or ""
end
function resolvers.expansion(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.expansions[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.expansions[name]
+ return result~=nil and result or ""
end
function resolvers.unexpandedpathlist(str)
- local pth=resolvers.variable(str)
- local lst=resolvers.splitpath(pth)
- return expandedpathfromlist(lst)
+ local pth=resolvers.variable(str)
+ local lst=resolvers.splitpath(pth)
+ return expandedpathfromlist(lst)
end
function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+ return joinpath(resolvers.unexpandedpathlist(str))
end
function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
- lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
- lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
- report_resolving("pushing path %a",lastpath)
- end
+ local pathstack=instance.pathstack
+ local lastpath=pathstack[#pathstack]
+ local pluspath=filedirname(name)
+ if lastpath then
+ lastpath=collapsepath(filejoin(lastpath,pluspath))
+ else
+ lastpath=collapsepath(pluspath)
+ end
+ insert(pathstack,lastpath)
+ if trace_paths then
+ report_resolving("pushing path %a",lastpath)
+ end
end
function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
- report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
+ local pathstack=instance.pathstack
+ if trace_paths and #pathstack>0 then
+ report_resolving("popping path %a",pathstack[#pathstack])
+ end
+ remove(pathstack)
end
function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
+ local pathstack=instance.pathstack
+ local currentpath=pathstack[#pathstack]
+ return currentpath~="" and currentpath or nil
end
local done={}
function resolvers.resetextrapaths()
- local ep=instance.extra_paths
- if not ep then
- done={}
- instance.extra_paths={}
- elseif #ep>0 then
- done={}
- reset_caches()
- end
+ local ep=instance.extra_paths
+ if not ep then
+ done={}
+ instance.extra_paths={}
+ elseif #ep>0 then
+ done={}
+ reset_caches()
+ end
end
function resolvers.getextrapaths()
- return instance.extra_paths or {}
+ return instance.extra_paths or {}
end
function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
- if not paths or path=="" then
- return
- elseif done[paths] then
- return
- end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local ep=instance.extra_paths or {}
- local oldn=#ep
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
- if nofsubpaths>0 then
- for i=1,nofpaths do
- local p=paths[i]
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=p.."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- else
- for i=1,nofpaths do
- local p=paths[i]
- if not done[p] then
- newn=newn+1
- ep[newn]=cleanpath(p)
- done[p]=true
- end
- end
+ if not subpaths or subpaths=="" then
+ if not paths or path=="" then
+ return
+ elseif done[paths] then
+ return
+ end
+ end
+ local paths=settings_to_array(paths)
+ local subpaths=settings_to_array(subpaths)
+ local ep=instance.extra_paths or {}
+ local oldn=#ep
+ local newn=oldn
+ local nofpaths=#paths
+ local nofsubpaths=#subpaths
+ if nofpaths>0 then
+ if nofsubpaths>0 then
+ for i=1,nofpaths do
+ local p=paths[i]
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=p.."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
end
- elseif nofsubpaths>0 then
- for i=1,oldn do
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=ep[i].."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
+ end
+ else
+ for i=1,nofpaths do
+ local p=paths[i]
+ if not done[p] then
+ newn=newn+1
+ ep[newn]=cleanpath(p)
+ done[p]=true
end
+ end
end
- if newn>0 then
- instance.extra_paths=ep
- end
- if newn~=oldn then
- reset_caches()
+ elseif nofsubpaths>0 then
+ for i=1,oldn do
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=ep[i].."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
+ end
end
+ end
+ if newn>0 then
+ instance.extra_paths=ep
+ end
+ if newn~=oldn then
+ reset_caches()
+ end
end
function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- if instance.extra_stack then
- insert(instance.extra_stack,1,paths)
- else
- instance.extra_stack={ paths }
- end
- reset_caches()
+ local paths=settings_to_array(path)
+ if instance.extra_stack then
+ insert(instance.extra_stack,1,paths)
+ else
+ instance.extra_stack={ paths }
+ end
+ reset_caches()
end
function resolvers.popextrapath()
- if instance.extra_stack then
- reset_caches()
- return remove(instance.extra_stack,1)
- end
+ if instance.extra_stack then
+ reset_caches()
+ return remove(instance.extra_stack,1)
+ end
end
local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
- for k=1,#p do
- local v=p[k]
- if not done[v] then
- done[v]=true
- newn=newn+1
- new[newn]=v
- end
- end
+ local done={}
+ local new={}
+ local newn=0
+ local function add(p)
+ for k=1,#p do
+ local v=p[k]
+ if not done[v] then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ end
end
- for k=1,#list do
- local v=list[k]
- if done[v] then
- elseif find(v,"^[%.%/]$") then
- done[v]=true
- newn=newn+1
- new[newn]=v
- else
- break
- end
+ end
+ for k=1,#list do
+ local v=list[k]
+ if done[v] then
+ elseif find(v,"^[%.%/]$") then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ else
+ break
+ end
+ end
+ if extra_too then
+ local es=instance.extra_stack
+ if es and #es>0 then
+ for k=1,#es do
+ add(es[k])
+ end
end
- if extra_too then
- local es=instance.extra_stack
- if es and #es>0 then
- for k=1,#es do
- add(es[k])
- end
- end
- local ep=instance.extra_paths
- if ep and #ep>0 then
- add(ep)
- end
+ local ep=instance.extra_paths
+ if ep and #ep>0 then
+ add(ep)
end
- add(list)
- return new
+ end
+ add(list)
+ return new
end
function resolvers.cleanpathlist(str)
- local t=resolvers.expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i]=collapsepath(cleanpath(t[i]))
- end
+ local t=resolvers.expandedpathlist(str)
+ if t then
+ for i=1,#t do
+ t[i]=collapsepath(cleanpath(t[i]))
end
- return t
+ end
+ return t
end
function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
+ return joinpath(resolvers.expandedpathlist(str))
end
function resolvers.expandedpathlist(str,extra_too)
- if not str then
- return {}
- elseif instance.savelists then
- str=lpegmatch(dollarstripper,str)
- local lists=instance.lists
- local lst=lists[str]
- if not lst then
- local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
- lst=expandedpathfromlist(l)
- lists[str]=lst
- end
- return lst
- else
- local lst=resolvers.splitpath(resolvers.expansion(str))
- return made_list(instance,expandedpathfromlist(lst),extra_too)
+ if not str then
+ return {}
+ elseif instance.savelists then
+ str=lpegmatch(dollarstripper,str)
+ local lists=instance.lists
+ local lst=lists[str]
+ if not lst then
+ local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+ lst=expandedpathfromlist(l)
+ lists[str]=lst
end
+ return lst
+ else
+ local lst=resolvers.splitpath(resolvers.expansion(str))
+ return made_list(instance,expandedpathfromlist(lst),extra_too)
+ end
end
function resolvers.expandedpathlistfromvariable(str)
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp~="" and tmp or str)
+ str=lpegmatch(dollarstripper,str)
+ local tmp=resolvers.variableofformatorsuffix(str)
+ return resolvers.expandedpathlist(tmp~="" and tmp or str)
end
function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+ return joinpath(resolvers.expandedpathlistfromvariable(str))
end
function resolvers.cleanedpathlist(v)
- local t=resolvers.expandedpathlist(v)
- for i=1,#t do
- t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
- end
- return t
+ local t=resolvers.expandedpathlist(v)
+ for i=1,#t do
+ t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
+ end
+ return t
end
function resolvers.expandbraces(str)
- local pth=expandedpathfromlist(resolvers.splitpath(str))
- return joinpath(pth)
+ local pth=expandedpathfromlist(resolvers.splitpath(str))
+ return joinpath(pth)
end
function resolvers.registerfilehash(name,content,someerror)
- if content then
- instance.files[name]=content
- else
- instance.files[name]={}
- if somerror==true then
- instance.loaderror=someerror
- end
+ if content then
+ instance.files[name]=content
+ else
+ instance.files[name]={}
+ if somerror==true then
+ instance.loaderror=someerror
end
+ end
end
function resolvers.getfilehashes()
- return instance and instance.files or {}
+ return instance and instance.files or {}
end
function resolvers.gethashes()
- return instance and instance.hashes or {}
+ return instance and instance.hashes or {}
end
function resolvers.renewcache()
- if instance then
- instance.renewcache=true
- end
+ if instance then
+ instance.renewcache=true
+ end
end
local function isreadable(name)
- local readable=isfile(name)
- if trace_detail then
- if readable then
- report_resolving("file %a is readable",name)
- else
- report_resolving("file %a is not readable",name)
- end
+ local readable=isfile(name)
+ if trace_detail then
+ if readable then
+ report_resolving("file %a is readable",name)
+ else
+ report_resolving("file %a is not readable",name)
end
- return readable
+ end
+ return readable
end
local function collect_files(names)
- local filelist={}
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
- if not pathname or find(path,pathname) then
- local variant=hash.type
- local search=filejoin(root,path,name)
- local result=methodhandler('concatinators',variant,root,path,name)
- if trace_detail then
- report_resolving("match: variant %a, search %a, result %a",variant,search,result)
- end
- noffiles=noffiles+1
- filelist[noffiles]={ variant,search,result }
- end
+ local filelist={}
+ local noffiles=0
+ local function check(hash,root,pathname,path,basename,name)
+ if not pathname or find(path,pathname) then
+ local variant=hash.type
+ local search=filejoin(root,path,name)
+ local result=methodhandler('concatinators',variant,root,path,name)
+ if trace_detail then
+ report_resolving("match: variant %a, search %a, result %a",variant,search,result)
+ end
+ noffiles=noffiles+1
+ filelist[noffiles]={ variant,search,result }
end
- for k=1,#names do
- local filename=names[k]
+ end
+ for k=1,#names do
+ local filename=names[k]
+ if trace_detail then
+ report_resolving("checking name %a",filename)
+ end
+ local basename=filebasename(filename)
+ local pathname=filedirname(filename)
+ if pathname=="" or find(pathname,"^%.") then
+ pathname=false
+ else
+ pathname=gsub(pathname,"%*",".*")
+ pathname="/"..pathname.."$"
+ end
+ local hashes=instance.hashes
+ for h=1,#hashes do
+ local hash=hashes[h]
+ local hashname=hash.name
+ local content=hashname and instance.files[hashname]
+ if content then
if trace_detail then
- report_resolving("checking name %a",filename)
+ report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
end
- local basename=filebasename(filename)
- local pathname=filedirname(filename)
- if pathname=="" or find(pathname,"^%.") then
- pathname=false
- else
- pathname=gsub(pathname,"%*",".*")
- pathname="/"..pathname.."$"
- end
- local hashes=instance.hashes
- for h=1,#hashes do
- local hash=hashes[h]
- local hashname=hash.name
- local content=hashname and instance.files[hashname]
- if content then
- if trace_detail then
- report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
- end
- local path,name=lookup(content,basename)
- if path then
- local metadata=content.metadata
- local realroot=metadata and metadata.path or hashname
- if type(path)=="string" then
- check(hash,realroot,pathname,path,basename,name)
- else
- for i=1,#path do
- check(hash,realroot,pathname,path[i],basename,name)
- end
- end
- end
- elseif trace_locating then
- report_resolving("no match in %a (%s)",hashname,basename)
+ local path,name=lookup(content,basename)
+ if path then
+ local metadata=content.metadata
+ local realroot=metadata and metadata.path or hashname
+ if type(path)=="string" then
+ check(hash,realroot,pathname,path,basename,name)
+ else
+ for i=1,#path do
+ check(hash,realroot,pathname,path[i],basename,name)
end
+ end
end
+ elseif trace_locating then
+ report_resolving("no match in %a (%s)",hashname,basename)
+ end
end
- return noffiles>0 and filelist or nil
+ end
+ return noffiles>0 and filelist or nil
end
local fit={}
function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
- local collapsed=collapsepath(foundname,true)
- local t={
- filename=filename,
- format=format~="" and format or nil,
- filetype=filetype~="" and filetype or nil,
- usedmethod=usedmethod,
- foundname=foundname,
- fullname=collapsed,
- }
- fit[foundname]=t
- foundintrees[#foundintrees+1]=t
- end
+ local foundintrees=instance.foundintrees
+ if usedmethod=="direct" and filename==foundname and fit[foundname] then
+ else
+ local collapsed=collapsepath(foundname,true)
+ local t={
+ filename=filename,
+ format=format~="" and format or nil,
+ filetype=filetype~="" and filetype or nil,
+ usedmethod=usedmethod,
+ foundname=foundname,
+ fullname=collapsed,
+ }
+ fit[foundname]=t
+ foundintrees[#foundintrees+1]=t
+ end
end
function resolvers.foundintrees()
- return instance.foundintrees or {}
+ return instance.foundintrees or {}
end
function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
+ local f=fit[fullname]
+ return f and f.usedmethod=="database"
end
local function can_be_dir(name)
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
- if isdir(name) then
- fakepaths[name]=1
- else
- fakepaths[name]=2
- end
+ local fakepaths=instance.fakepaths
+ if not fakepaths[name] then
+ if isdir(name) then
+ fakepaths[name]=1
+ else
+ fakepaths[name]=2
end
- return fakepaths[name]==1
+ end
+ return fakepaths[name]==1
end
local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
- if filesuffix=="" or not suffixmap[filesuffix] then
- local defaultsuffixes=resolvers.defaultsuffixes
- local formatofsuffix=resolvers.formatofsuffix
- for i=1,#defaultsuffixes do
- local forcedname=filename..'.'..defaultsuffixes[i]
- wantedfiles[#wantedfiles+1]=forcedname
- filetype=formatofsuffix(forcedname)
- if trace_locating then
- report_resolving("forcing filetype %a",filetype)
- end
- end
- else
- filetype=resolvers.formatofsuffix(filename)
- if trace_locating then
- report_resolving("using suffix based filetype %a",filetype)
- end
+ local filetype=''
+ local filesuffix=suffixonly(filename)
+ local wantedfiles={}
+ wantedfiles[#wantedfiles+1]=filename
+ if askedformat=="" then
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local defaultsuffixes=resolvers.defaultsuffixes
+ local formatofsuffix=resolvers.formatofsuffix
+ for i=1,#defaultsuffixes do
+ local forcedname=filename..'.'..defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1]=forcedname
+ filetype=formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolving("forcing filetype %a",filetype)
end
+ end
else
- if filesuffix=="" or not suffixmap[filesuffix] then
- local format_suffixes=suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
- end
- end
- end
- filetype=askedformat
- if trace_locating then
- report_resolving("using given filetype %a",filetype)
+ filetype=resolvers.formatofsuffix(filename)
+ if trace_locating then
+ report_resolving("using suffix based filetype %a",filetype)
+ end
+ end
+ else
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local format_suffixes=suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
end
+ end
end
- return filetype,wantedfiles
+ filetype=askedformat
+ if trace_locating then
+ report_resolving("using given filetype %a",filetype)
+ end
+ end
+ return filetype,wantedfiles
end
local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
- if trace_detail then
- report_resolving("file %a found directly",filename)
- end
- return "direct",{ filename }
+ if not dangerous[askedformat] and isreadable(filename) then
+ if trace_detail then
+ report_resolving("file %a found directly",filename)
end
+ return "direct",{ filename }
+ end
end
local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
- if trace_locating then
- report_resolving("checking wildcard %a",filename)
- end
- local result=resolvers.findwildcardfiles(filename)
- if result then
- return "wildcard",result
- end
- end
-end
-local function find_qualified(filename,allresults,askedformat,alsostripped)
- if not is_qualified_path(filename) then
- return
- end
+ if find(filename,'*',1,true) then
if trace_locating then
- report_resolving("checking qualified name %a",filename)
+ report_resolving("checking wildcard %a",filename)
end
- if isreadable(filename) then
- if trace_detail then
- report_resolving("qualified file %a found",filename)
- end
- return "qualified",{ filename }
+ local result=resolvers.findwildcardfiles(filename)
+ if result then
+ return "wildcard",result
end
+ end
+end
+local function find_qualified(filename,allresults,askedformat,alsostripped)
+ if not is_qualified_path(filename) then
+ return
+ end
+ if trace_locating then
+ report_resolving("checking qualified name %a",filename)
+ end
+ if isreadable(filename) then
if trace_detail then
- report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then
- local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s=format_suffixes[i]
- forcedname=filename.."."..s
- if isreadable(forcedname) then
- if trace_locating then
- report_resolving("no suffix, forcing format filetype %a",s)
- end
- return "qualified",{ forcedname }
- end
- end
+ report_resolving("qualified file %a found",filename)
+ end
+ return "qualified",{ filename }
+ end
+ if trace_detail then
+ report_resolving("locating qualified file %a",filename)
+ end
+ local forcedname,suffix="",suffixonly(filename)
+ if suffix=="" then
+ local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s=format_suffixes[i]
+ forcedname=filename.."."..s
+ if isreadable(forcedname) then
+ if trace_locating then
+ report_resolving("no suffix, forcing format filetype %a",s)
+ end
+ return "qualified",{ forcedname }
end
+ end
end
- if alsostripped and suffix and suffix~="" then
- local basename=filebasename(filename)
- local pattern=lpegmatch(preparetreepattern,filename)
- local savedformat=askedformat
- local format=savedformat or ""
- if format=="" then
- askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if alsostripped and suffix and suffix~="" then
+ local basename=filebasename(filename)
+ local pattern=lpegmatch(preparetreepattern,filename)
+ local savedformat=askedformat
+ local format=savedformat or ""
+ if format=="" then
+ askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if not format then
+ askedformat="othertextfiles"
+ end
+ if basename~=filename then
+ local resolved=collect_instance_files(basename,askedformat,allresults)
+ if #resolved==0 then
+ local lowered=lower(basename)
+ if filename~=lowered then
+ resolved=collect_instance_files(lowered,askedformat,allresults)
end
- if not format then
- askedformat="othertextfiles"
+ end
+ resolvers.format=savedformat
+ if #resolved>0 then
+ local result={}
+ for r=1,#resolved do
+ local rr=resolved[r]
+ if find(rr,pattern) then
+ result[#result+1]=rr
+ end
end
- if basename~=filename then
- local resolved=collect_instance_files(basename,askedformat,allresults)
- if #resolved==0 then
- local lowered=lower(basename)
- if filename~=lowered then
- resolved=collect_instance_files(lowered,askedformat,allresults)
- end
- end
- resolvers.format=savedformat
- if #resolved>0 then
- local result={}
- for r=1,#resolved do
- local rr=resolved[r]
- if find(rr,pattern) then
- result[#result+1]=rr
- end
- end
- if #result>0 then
- return "qualified",result
- end
- end
+ if #result>0 then
+ return "qualified",result
end
+ end
end
+ end
end
local function check_subpath(fname)
- if isreadable(fname) then
- if trace_detail then
- report_resolving("found %a by deep scanning",fname)
- end
- return fname
+ if isreadable(fname) then
+ if trace_detail then
+ report_resolving("found %a by deep scanning",fname)
end
+ return fname
+ end
end
local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
- local entry={}
- if pathlist and #pathlist>0 then
- for k=1,#pathlist do
- local path=pathlist[k]
- local prescanned=find(path,'^!!')
- local resursive=find(path,'//$')
- local pathname=lpegmatch(inhibitstripper,path)
- local expression=makepathexpression(pathname)
- local barename=gsub(pathname,"/+$","")
- barename=resolveprefix(barename)
- local scheme=url.hasscheme(barename)
- local schemename=gsub(barename,"%.%*$",'')
- entry[k]={
- path=path,
- pathname=pathname,
- prescanned=prescanned,
- recursive=recursive,
- expression=expression,
- barename=barename,
- scheme=scheme,
- schemename=schemename,
- }
- end
- entry.typespec=typespec
- list[filetype]=entry
- else
- list[filetype]=false
- end
- return entry
+ local typespec=resolvers.variableofformat(filetype)
+ local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
+ local entry={}
+ if pathlist and #pathlist>0 then
+ for k=1,#pathlist do
+ local path=pathlist[k]
+ local prescanned=find(path,'^!!')
+ local resursive=find(path,'//$')
+ local pathname=lpegmatch(inhibitstripper,path)
+ local expression=makepathexpression(pathname)
+ local barename=gsub(pathname,"/+$","")
+ barename=resolveprefix(barename)
+ local scheme=url.hasscheme(barename)
+ local schemename=gsub(barename,"%.%*$",'')
+ entry[k]={
+ path=path,
+ pathname=pathname,
+ prescanned=prescanned,
+ recursive=recursive,
+ expression=expression,
+ barename=barename,
+ scheme=scheme,
+ schemename=schemename,
+ }
+ end
+ entry.typespec=typespec
+ list[filetype]=entry
+ else
+ list[filetype]=false
+ end
+ return entry
end
local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
- pathlists=setmetatableindex({},makepathlist)
- instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
- local method="intree"
- local filelist=collect_files(wantedfiles)
- local dirlist={}
- local result={}
- if filelist then
- for i=1,#filelist do
- dirlist[i]=filedirname(filelist[i][3]).."/"
+ local pathlists=instance.pathlists
+ if not pathlists then
+ pathlists=setmetatableindex({},makepathlist)
+ instance.pathlists=pathlists
+ end
+ local pathlist=pathlists[filetype]
+ if pathlist then
+ local method="intree"
+ local filelist=collect_files(wantedfiles)
+ local dirlist={}
+ local result={}
+ if filelist then
+ for i=1,#filelist do
+ dirlist[i]=filedirname(filelist[i][3]).."/"
+ end
+ end
+ if trace_detail then
+ report_resolving("checking filename %a in tree",filename)
+ end
+ for k=1,#pathlist do
+ local entry=pathlist[k]
+ local path=entry.path
+ local pathname=entry.pathname
+ local done=false
+ if filelist then
+ local expression=entry.expression
+ if trace_detail then
+ report_resolving("using pattern %a for path %a",expression,pathname)
+ end
+ for k=1,#filelist do
+ local fl=filelist[k]
+ local f=fl[2]
+ local d=dirlist[k]
+ if find(d,expression) or find(resolveprefix(d),expression) then
+ result[#result+1]=resolveprefix(fl[3])
+ done=true
+ if allresults then
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
+ end
+ else
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
+ end
+ break
end
+ elseif trace_detail then
+ report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ end
end
- if trace_detail then
- report_resolving("checking filename %a in tree",filename)
- end
- for k=1,#pathlist do
- local entry=pathlist[k]
- local path=entry.path
- local pathname=entry.pathname
- local done=false
- if filelist then
- local expression=entry.expression
+ end
+ if done then
+ method="database"
+ else
+ method="filesystem"
+ local scheme=entry.scheme
+ if not scheme or scheme=="file" then
+ local pname=entry.schemename
+ if not find(pname,"*",1,true) then
+ if can_be_dir(pname) then
+ if not done and not entry.prescanned then
if trace_detail then
- report_resolving("using pattern %a for path %a",expression,pathname)
- end
- for k=1,#filelist do
- local fl=filelist[k]
- local f=fl[2]
- local d=dirlist[k]
- if find(d,expression) or find(resolveprefix(d),expression) then
- result[#result+1]=resolveprefix(fl[3])
- done=true
- if allresults then
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
- end
- else
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
- end
- break
- end
- elseif trace_detail then
- report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ report_resolving("quick root scan for %a",pname)
+ end
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local fname=check_subpath(filejoin(pname,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
- end
- end
- if done then
- method="database"
- else
- method="filesystem"
- local scheme=entry.scheme
- if not scheme or scheme=="file" then
- local pname=entry.schemename
- if not find(pname,"*",1,true) then
- if can_be_dir(pname) then
- if not done and not entry.prescanned then
- if trace_detail then
- report_resolving("quick root scan for %a",pname)
- end
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local fname=check_subpath(filejoin(pname,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- if not done and entry.recursive then
- if trace_detail then
- report_resolving("scanning filesystem for %a",pname)
- end
- local files=resolvers.simplescanfiles(pname,false,true)
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local subpath=files[w]
- if not subpath or subpath=="" then
- elseif type(subpath)=="string" then
- local fname=check_subpath(filejoin(pname,subpath,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- else
- for i=1,#subpath do
- local sp=subpath[i]
- if sp=="" then
- else
- local fname=check_subpath(filejoin(pname,sp,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- end
- end
- end
+ end
+ end
+ if not done and entry.recursive then
+ if trace_detail then
+ report_resolving("scanning filesystem for %a",pname)
+ end
+ local files=resolvers.simplescanfiles(pname,false,true)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local subpath=files[w]
+ if not subpath or subpath=="" then
+ elseif type(subpath)=="string" then
+ local fname=check_subpath(filejoin(pname,subpath,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
+ end
else
- end
- else
- for k=1,#wantedfiles do
- local pname=entry.barename
- local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
- if fname then
+ for i=1,#subpath do
+ local sp=subpath[i]
+ if sp=="" then
+ else
+ local fname=check_subpath(filejoin(pname,sp,w))
+ if fname then
result[#result+1]=fname
done=true
if not allresults then
- break
+ break
end
+ end
end
+ end
+ if done and not allresults then
+ break
+ end
end
+ end
end
+ end
end
- if done and not allresults then
+ else
+ end
+ else
+ for k=1,#wantedfiles do
+ local pname=entry.barename
+ local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
break
+ end
end
+ end
end
- if #result>0 then
- return method,result
- end
+ end
+ if done and not allresults then
+ break
+ end
+ end
+ if #result>0 then
+ return method,result
end
+ end
end
local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_detail then
- report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
- local fname=wantedfiles[k]
- if fname and isreadable(fname) then
- filename=fname
- result[#result+1]=filejoin('.',fname)
- if not allresults then
- break
- end
- end
- end
- if #result>0 then
- return "onpath",result
+ if trace_detail then
+ report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
+ end
+ local result={}
+ for k=1,#wantedfiles do
+ local fname=wantedfiles[k]
+ if fname and isreadable(fname) then
+ filename=fname
+ result[#result+1]=filejoin('.',fname)
+ if not allresults then
+ break
+ end
end
+ end
+ if #result>0 then
+ return "onpath",result
+ end
end
local function find_otherwise(filename,filetype,wantedfiles,allresults)
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
- return "otherwise",{ resolveprefix(fl[3]) }
- end
+ local filelist=collect_files(wantedfiles)
+ local fl=filelist and filelist[1]
+ if fl then
+ return "otherwise",{ resolveprefix(fl[3]) }
+ end
end
collect_instance_files=function(filename,askedformat,allresults)
- if not filename or filename=="" then
- return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/")
- if allresults then
- local filetype,wantedfiles=find_analyze(filename,askedformat)
- local results={
- { find_direct (filename,true) },
- { find_wildcard (filename,true) },
- { find_qualified(filename,true,askedformat) },
- { find_intree (filename,filetype,wantedfiles,true) },
- { find_onpath (filename,filetype,wantedfiles,true) },
- { find_otherwise(filename,filetype,wantedfiles,true) },
- }
- local result,status,done={},{},{}
- for k,r in next,results do
- local method,list=r[1],r[2]
- if method and list then
- for i=1,#list do
- local c=collapsepath(list[i])
- if not done[c] then
- result[#result+1]=c
- done[c]=true
- end
- status[#status+1]=formatters["%-10s: %s"](method,c)
- end
- end
- end
- if trace_detail then
- report_resolving("lookup status: %s",table.serialize(status,filename))
+ if not filename or filename=="" then
+ return {}
+ end
+ askedformat=askedformat or ""
+ filename=collapsepath(filename,".")
+ filename=gsub(filename,"^%./",getcurrentdir().."/")
+ if allresults then
+ local filetype,wantedfiles=find_analyze(filename,askedformat)
+ local results={
+ { find_direct (filename,true) },
+ { find_wildcard (filename,true) },
+ { find_qualified(filename,true,askedformat) },
+ { find_intree (filename,filetype,wantedfiles,true) },
+ { find_onpath (filename,filetype,wantedfiles,true) },
+ { find_otherwise(filename,filetype,wantedfiles,true) },
+ }
+ local result,status,done={},{},{}
+ for k,r in next,results do
+ local method,list=r[1],r[2]
+ if method and list then
+ for i=1,#list do
+ local c=collapsepath(list[i])
+ if not done[c] then
+ result[#result+1]=c
+ done[c]=true
+ end
+ status[#status+1]=formatters["%-10s: %s"](method,c)
end
- return result,status
- else
- local method,result,stamp,filetype,wantedfiles
- if instance.remember then
- if askedformat=="" then
- stamp=formatters["%s::%s"](suffixonly(filename),filename)
- else
- stamp=formatters["%s::%s"](askedformat,filename)
- end
- result=stamp and instance.found[stamp]
- if result then
- if trace_locating then
- report_resolving("remembered file %a",filename)
- end
- return result
- end
+ end
+ end
+ if trace_detail then
+ report_resolving("lookup status: %s",table.serialize(status,filename))
+ end
+ return result,status
+ else
+ local method,result,stamp,filetype,wantedfiles
+ if instance.remember then
+ if askedformat=="" then
+ stamp=formatters["%s::%s"](suffixonly(filename),filename)
+ else
+ stamp=formatters["%s::%s"](askedformat,filename)
+ end
+ result=stamp and instance.found[stamp]
+ if result then
+ if trace_locating then
+ report_resolving("remembered file %a",filename)
end
- method,result=find_direct(filename)
+ return result
+ end
+ end
+ method,result=find_direct(filename)
+ if not result then
+ method,result=find_wildcard(filename)
+ if not result then
+ method,result=find_qualified(filename,false,askedformat)
if not result then
- method,result=find_wildcard(filename)
- if not result then
- method,result=find_qualified(filename,false,askedformat)
- if not result then
- filetype,wantedfiles=find_analyze(filename,askedformat)
- method,result=find_intree(filename,filetype,wantedfiles)
- if not result then
- method,result=find_onpath(filename,filetype,wantedfiles)
- if resolve_otherwise and not result then
- method,result=find_otherwise(filename,filetype,wantedfiles)
- end
- end
- end
- end
- end
- if result and #result>0 then
- local foundname=collapsepath(result[1])
- resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
- result={ foundname }
- else
- result={}
- end
- if stamp then
- if trace_locating then
- report_resolving("remembering file %a using hash %a",filename,stamp)
+ filetype,wantedfiles=find_analyze(filename,askedformat)
+ method,result=find_intree(filename,filetype,wantedfiles)
+ if not result then
+ method,result=find_onpath(filename,filetype,wantedfiles)
+ if resolve_otherwise and not result then
+ method,result=find_otherwise(filename,filetype,wantedfiles)
end
- instance.found[stamp]=result
+ end
end
- return result
+ end
+ end
+ if result and #result>0 then
+ local foundname=collapsepath(result[1])
+ resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
+ result={ foundname }
+ else
+ result={}
end
+ if stamp then
+ if trace_locating then
+ report_resolving("remembering file %a using hash %a",filename,stamp)
+ end
+ instance.found[stamp]=result
+ end
+ return result
+ end
end
local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
- return {}
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
- local lowered=lower(filename)
- if filename~=lowered then
- result,status=collect_instance_files(lowered,filetype or "",allresults)
- end
+ if not filename or filename=="" then
+ return {}
+ end
+ local result,status=collect_instance_files(filename,filetype or "",allresults)
+ if not result or #result==0 then
+ local lowered=lower(filename)
+ if filename~=lowered then
+ result,status=collect_instance_files(lowered,filetype or "",allresults)
end
- return result or {},status
+ end
+ return result or {},status
end
function resolvers.findfiles(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,true)
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,true)
+ end
end
function resolvers.findfile(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,false)[1] or ""
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,false)[1] or ""
+ end
end
function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
+ return filedirname(findfiles(filename,filetype,false)[1] or "")
end
local function findgivenfiles(filename,allresults)
- local base=filebasename(filename)
- local result={}
- local hashes=instance.hashes
- local function okay(hash,path,name)
- local found=methodhandler('concatinators',hash.type,hash.name,path,name)
- if found and found~="" then
- result[#result+1]=resolveprefix(found)
- return not allresults
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local content=instance.files[hash.name]
- if content then
- local path,name=lookup(content,base)
- if not path then
- elseif type(path)=="string" then
- if okay(hash,path,name) then
- return result
- end
- else
- for i=1,#path do
- if okay(hash,path[i],name) then
- return result
- end
- end
- end
+ local base=filebasename(filename)
+ local result={}
+ local hashes=instance.hashes
+ local function okay(hash,path,name)
+ local found=methodhandler('concatinators',hash.type,hash.name,path,name)
+ if found and found~="" then
+ result[#result+1]=resolveprefix(found)
+ return not allresults
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local content=instance.files[hash.name]
+ if content then
+ local path,name=lookup(content,base)
+ if not path then
+ elseif type(path)=="string" then
+ if okay(hash,path,name) then
+ return result
+ end
+ else
+ for i=1,#path do
+ if okay(hash,path[i],name) then
+ return result
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
+ return findgivenfiles(filename,true)
end
function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
+ return findgivenfiles(filename,false)[1] or ""
end
local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
+ (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
)
function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
+ return lpegmatch(makewildcard,pattern) or pattern
end
local function findwildcardfiles(filename,allresults,result)
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- local files=instance.files
- if find(name,"*",1,true) then
- local hashes=instance.hashes
- local function okay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
+ local result=result or {}
+ local base=filebasename(filename)
+ local dirn=filedirname(filename)
+ local path=lower(lpegmatch(makewildcard,dirn) or dirn)
+ local name=lower(lpegmatch(makewildcard,base) or base)
+ local files=instance.files
+ if find(name,"*",1,true) then
+ local hashes=instance.hashes
+ local function okay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- for found,base in filtered(files[hashname],name) do
- if type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ for found,base in filtered(files[hashname],name) do
+ if type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
end
- end
- else
- local function okayokay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
+ end
end
+ end
end
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- local found,base=lookup(content,base)
- if not found then
- elseif type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
+ end
+ end
+ else
+ local function okayokay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
+ end
+ end
+ end
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ local found,base=lookup(content,base)
+ if not found then
+ elseif type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
+ end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
end
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
+ return findwildcardfiles(filename,true,result)
end
function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
+ return findwildcardfiles(filename,false)[1] or ""
end
function resolvers.automount()
end
function resolvers.starttiming()
- statistics.starttiming(instance)
+ statistics.starttiming(instance)
end
function resolvers.stoptiming()
- statistics.stoptiming(instance)
+ statistics.stoptiming(instance)
end
function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
- load_databases()
- resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
+ resolvers.starttiming()
+ identify_configuration_files()
+ load_configuration_files()
+ if option~="nofiles" then
+ load_databases()
+ resolvers.automount()
+ end
+ resolvers.stoptiming()
+ local files=instance.files
+ return files and next(files) and true
end
function resolvers.loadtime()
- return statistics.elapsedtime(instance)
+ return statistics.elapsedtime(instance)
end
local function report(str)
- if trace_locating then
- report_resolving(str)
- else
- print(str)
- end
+ if trace_locating then
+ report_resolving(str)
+ else
+ print(str)
+ end
end
function resolvers.dowithfilesandreport(command,files,...)
- if files and #files>0 then
- if trace_locating then
- report('')
- end
- if type(files)=="string" then
- files={ files }
- end
- for f=1,#files do
- local file=files[f]
- local result=command(file,...)
- if type(result)=='string' then
- report(result)
- else
- for i=1,#result do
- report(result[i])
- end
- end
+ if files and #files>0 then
+ if trace_locating then
+ report('')
+ end
+ if type(files)=="string" then
+ files={ files }
+ end
+ for f=1,#files do
+ local file=files[f]
+ local result=command(file,...)
+ if type(result)=='string' then
+ report(result)
+ else
+ for i=1,#result do
+ report(result[i])
end
+ end
end
+ end
end
-function resolvers.showpath(str)
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+function resolvers.showpath(str)
+ return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
end
function resolvers.registerfile(files,name,path)
- if files[name] then
- if type(files[name])=='string' then
- files[name]={ files[name],path }
- else
- files[name]=path
- end
+ if files[name] then
+ if type(files[name])=='string' then
+ files[name]={ files[name],path }
else
- files[name]=path
+ files[name]=path
end
+ else
+ files[name]=path
+ end
end
function resolvers.dowithpath(name,func)
- local pathlist=resolvers.expandedpathlist(name)
- for i=1,#pathlist do
- func("^"..cleanpath(pathlist[i]))
- end
+ local pathlist=resolvers.expandedpathlist(name)
+ for i=1,#pathlist do
+ func("^"..cleanpath(pathlist[i]))
+ end
end
function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
+ func(expandedvariable(name))
end
function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(name)
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
- fmtname=resolvers.findfile(fullname)
- fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
- local barename=removesuffix(fmtname)
- local luaname=addsuffix(barename,luasuffixes.lua)
- local lucname=addsuffix(barename,luasuffixes.luc)
- local luiname=addsuffix(barename,luasuffixes.lui)
- if isfile(luiname) then
- return barename,luiname
- elseif isfile(lucname) then
- return barename,lucname
- elseif isfile(luaname) then
- return barename,luaname
- end
- end
- return nil,nil
+ local engine=environment.ownmain or "luatex"
+ local barename=removesuffix(name)
+ local fullname=addsuffix(barename,"fmt")
+ local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
+ if fmtname=="" then
+ fmtname=resolvers.findfile(fullname)
+ fmtname=cleanpath(fmtname)
+ end
+ if fmtname~="" then
+ local barename=removesuffix(fmtname)
+ local luaname=addsuffix(barename,luasuffixes.lua)
+ local lucname=addsuffix(barename,luasuffixes.luc)
+ local luiname=addsuffix(barename,luasuffixes.lui)
+ if isfile(luiname) then
+ return barename,luiname
+ elseif isfile(lucname) then
+ return barename,lucname
+ elseif isfile(luaname) then
+ return barename,luaname
+ end
+ end
+ return nil,nil
end
function resolvers.booleanvariable(str,default)
- local b=resolvers.expansion(str)
- if b=="" then
- return default
- else
- b=toboolean(b)
- return (b==nil and default) or b
- end
+ local b=resolvers.expansion(str)
+ if b=="" then
+ return default
+ else
+ b=toboolean(b)
+ return (b==nil and default) or b
+ end
end
function resolvers.dowithfilesintree(pattern,handle,before,after)
- local hashes=instance.hashes
- for i=1,#hashes do
- local hash=hashes[i]
- local blobtype=hash.type
- local blobpath=hash.name
- if blobtype and blobpath then
- local total=0
- local checked=0
- local done=0
- if before then
- before(blobtype,blobpath,pattern)
- end
- for path,name in filtered(instance.files[blobpath],pattern) do
- if type(path)=="string" then
- checked=checked+1
- if handle(blobtype,blobpath,path,name) then
- done=done+1
- end
- else
- checked=checked+#path
- for i=1,#path do
- if handle(blobtype,blobpath,path[i],name) then
- done=done+1
- end
- end
- end
- end
- if after then
- after(blobtype,blobpath,pattern,total,checked,done)
+ local hashes=instance.hashes
+ for i=1,#hashes do
+ local hash=hashes[i]
+ local blobtype=hash.type
+ local blobpath=hash.name
+ if blobtype and blobpath then
+ local total=0
+ local checked=0
+ local done=0
+ if before then
+ before(blobtype,blobpath,pattern)
+ end
+ for path,name in filtered(instance.files[blobpath],pattern) do
+ if type(path)=="string" then
+ checked=checked+1
+ if handle(blobtype,blobpath,path,name) then
+ done=done+1
+ end
+ else
+ checked=checked+#path
+ for i=1,#path do
+ if handle(blobtype,blobpath,path[i],name) then
+ done=done+1
end
+ end
end
+ end
+ if after then
+ after(blobtype,blobpath,pattern,checked,done)
+ end
end
+ end
end
local obsolete=resolvers.obsolete or {}
resolvers.obsolete=obsolete
-resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
-resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
+resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
+resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
function resolvers.knownvariables(pattern)
- if instance then
- local environment=instance.environment
- local variables=instance.variables
- local expansions=instance.expansions
- local order=instance.order
- local pattern=upper(pattern or "")
- local result={}
- for i=1,#order do
- for key in next,order[i] do
- if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
- result[key]={
- environment=rawget(environment,key),
- variable=key,
- expansion=expansions[key],
- resolved=resolveprefix(expansions[key]),
- }
- end
- end
+ if instance then
+ local environment=instance.environment
+ local variables=instance.variables
+ local expansions=instance.expansions
+ local order=instance.order
+ local pattern=upper(pattern or "")
+ local result={}
+ for i=1,#order do
+ for key in next,order[i] do
+ if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
+ result[key]={
+ environment=rawget(environment,key),
+ variable=key,
+ expansion=expansions[key],
+ resolved=resolveprefix(expansions[key]),
+ }
end
- return result
- else
- return {}
+ end
end
+ return result
+ else
+ return {}
+ end
end
@@ -19311,14 +22885,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-pre"] = package.loaded["data-pre"] or true
--- original size: 4090, stripped down to: 3059
+-- original size: 4854, stripped down to: 2889
if not modules then modules={} end modules ['data-pre']={
- 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 resolvers=resolvers
local prefixes=resolvers.prefixes
@@ -19331,64 +22905,64 @@ local dirname=file.dirname
local joinpath=file.join
local isfile=lfs.isfile
prefixes.environment=function(str)
- return cleanpath(expansion(str))
+ return cleanpath(expansion(str))
end
local function relative(str,n)
- if not isfile(str) then
- local pstr="./"..str
+ if not isfile(str) then
+ local pstr="./"..str
+ if isfile(pstr) then
+ str=pstr
+ else
+ local p="../"
+ for i=1,n or 2 do
+ local pstr=p..str
if isfile(pstr) then
- str=pstr
+ str=pstr
+ break
else
- local p="../"
- for i=1,n or 2 do
- local pstr=p..str
- if isfile(pstr) then
- str=pstr
- break
- else
- p=p.."../"
- end
- end
+ p=p.."../"
end
+ end
end
- return cleanpath(str)
+ end
+ return cleanpath(str)
end
local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(fullname~="" and fullname or str)
end
prefixes.relative=relative
prefixes.locate=locate
prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
- fullname=locate(str)
- end
- return fullname
+ local fullname=relative(str)
+ if not isfile(fullname) then
+ fullname=locate(str)
+ end
+ return fullname
end
prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(basename((fullname~="" and fullname) or str))
end
prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(dirname((fullname~="" and fullname) or str))
end
prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOLOC')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOPARENT')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTODIR')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('HOME')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.env=prefixes.environment
prefixes.rel=prefixes.relative
@@ -19398,24 +22972,24 @@ prefixes.full=prefixes.locate
prefixes.file=prefixes.filename
prefixes.path=prefixes.pathname
local function toppath()
- local inputstack=resolvers.inputstack
- if not inputstack then
- return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
- return "."
- else
- return pathname
- end
+ local inputstack=resolvers.inputstack
+ if not inputstack then
+ return "."
+ end
+ local pathname=dirname(inputstack[#inputstack] or "")
+ if pathname=="" then
+ return "."
+ else
+ return pathname
+ end
end
local function jobpath()
- local path=resolvers.stackpath()
- if not path or path=="" then
- return "."
- else
- return path
- end
+ local path=resolvers.stackpath()
+ if not path or path=="" then
+ return "."
+ else
+ return path
+ end
end
resolvers.toppath=toppath
resolvers.jobpath=jobpath
@@ -19423,8 +22997,6 @@ prefixes.toppath=function(str) return cleanpath(joinpath(toppath(),str)) end
prefixes.jobpath=function(str) return cleanpath(joinpath(jobpath(),str)) end
resolvers.setdynamic("toppath")
resolvers.setdynamic("jobpath")
-prefixes.jobfile=prefixes.jobpath
-resolvers.setdynamic("jobfile")
end -- of closure
@@ -19433,14 +23005,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-inp"] = package.loaded["data-inp"] or true
--- original size: 910, stripped down to: 823
+-- original size: 910, stripped down to: 818
if not modules then modules={} end modules ['data-inp']={
- 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 allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -19463,14 +23035,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-out"] = package.loaded["data-out"] or true
--- original size: 530, stripped down to: 475
+-- original size: 530, stripped down to: 470
if not modules then modules={} end modules ['data-out']={
- 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 allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -19486,16 +23058,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-fil"] = package.loaded["data-fil"] or true
--- original size: 3863, stripped down to: 3310
+-- original size: 3863, stripped down to: 3170
if not modules then modules={} end modules ['data-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 trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_files=logs.reporter("resolvers","files")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -19503,88 +23075,88 @@ local finders,openers,loaders,savers=resolvers.finders,resolvers.openers,resolve
local locators,hashers,generators,concatinators=resolvers.locators,resolvers.hashers,resolvers.generators,resolvers.concatinators
local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
function locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename)
- if realname and realname~='' and lfs.isdir(realname) then
- if trace_locating then
- report_files("file locator %a found as %a",filename,realname)
- end
- resolvers.appendhash('file',filename,true)
- elseif trace_locating then
- report_files("file locator %a not found",filename)
+ local filename=specification.filename
+ local realname=resolveprefix(filename)
+ if realname and realname~='' and lfs.isdir(realname) then
+ if trace_locating then
+ report_files("file locator %a found as %a",filename,realname)
end
+ resolvers.appendhash('file',filename,true)
+ elseif trace_locating then
+ report_files("file locator %a not found",filename)
+ end
end
function hashers.file(specification)
- local pathname=specification.filename
- local content=caches.loadcontent(pathname,'files')
- resolvers.registerfilehash(pathname,content,content==nil)
+ local pathname=specification.filename
+ local content=caches.loadcontent(pathname,'files')
+ resolvers.registerfilehash(pathname,content,content==nil)
end
function generators.file(specification)
- local pathname=specification.filename
- local content=resolvers.scanfiles(pathname,false,true)
- resolvers.registerfilehash(pathname,content,true)
+ local pathname=specification.filename
+ local content=resolvers.scanfiles(pathname,false,true)
+ resolvers.registerfilehash(pathname,content,true)
end
concatinators.file=file.join
function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=resolvers.findfile(filename,filetype)
- if foundname and foundname~="" then
- if trace_locating then
- report_files("file finder: %a found",filename)
- end
- return foundname
- else
- if trace_locating then
- report_files("file finder: %a not found",filename)
- end
- return finders.notfound()
+ local filename=specification.filename
+ local foundname=resolvers.findfile(filename,filetype)
+ if foundname and foundname~="" then
+ if trace_locating then
+ report_files("file finder: %a found",filename)
+ end
+ return foundname
+ else
+ if trace_locating then
+ report_files("file finder: %a not found",filename)
end
+ return finders.notfound()
+ end
end
function openers.helpers.textopener(tag,filename,f)
- return {
- reader=function() return f:read () end,
- close=function() logs.show_close(filename) return f:close() end,
- }
+ return {
+ reader=function() return f:read () end,
+ close=function() logs.show_close(filename) return f:close() end,
+ }
end
function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"r")
- if f then
- if trace_locating then
- report_files("file opener: %a opened",filename)
- end
- return openers.helpers.textopener("file",filename,f)
- end
- end
- if trace_locating then
- report_files("file opener: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"r")
+ if f then
+ if trace_locating then
+ report_files("file opener: %a opened",filename)
+ end
+ return openers.helpers.textopener("file",filename,f)
end
- return openers.notfound()
+ end
+ if trace_locating then
+ report_files("file opener: %a not found",filename)
+ end
+ return openers.notfound()
end
function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"rb")
- if f then
- logs.show_load(filename)
- if trace_locating then
- report_files("file loader: %a loaded",filename)
- end
- local s=f:read("*a")
- if checkgarbage then
- checkgarbage(#s)
- end
- f:close()
- if s then
- return true,s,#s
- end
- end
- end
- if trace_locating then
- report_files("file loader: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"rb")
+ if f then
+ logs.show_load(filename)
+ if trace_locating then
+ report_files("file loader: %a loaded",filename)
+ end
+ local s=f:read("*a")
+ if checkgarbage then
+ checkgarbage(#s)
+ end
+ f:close()
+ if s then
+ return true,s,#s
+ end
end
- return loaders.notfound()
+ end
+ if trace_locating then
+ report_files("file loader: %a not found",filename)
+ end
+ return loaders.notfound()
end
@@ -19594,116 +23166,116 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-con"] = package.loaded["data-con"] or true
--- original size: 5029, stripped down to: 3607
+-- original size: 5029, stripped down to: 3432
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
- return stored
+ 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
+ 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
+ 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
- return data
+ 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
@@ -19713,97 +23285,101 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-use"] = package.loaded["data-use"] or true
--- original size: 4272, stripped down to: 3289
+-- original size: 4434, stripped down to: 3180
if not modules then modules={} end modules ['data-use']={
- 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 format,lower,gsub,find=string.format,string.lower,string.gsub,string.find
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_mounts=logs.reporter("resolvers","mounts")
local resolvers=resolvers
resolvers.automounted=resolvers.automounted or {}
function resolvers.automount(usecache)
- local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
- if (not mountpaths or #mountpaths==0) and usecache then
- mountpaths=caches.getreadablepaths("mount")
- end
- if mountpaths and #mountpaths>0 then
- resolvers.starttiming()
- for k=1,#mountpaths do
- local root=mountpaths[k]
- local f=io.open(root.."/url.tmi")
- if f then
- for line in f:lines() do
- if line then
- if find(line,"^[%%#%-]") then
- elseif find(line,"^zip://") then
- if trace_locating then
- report_mounts("mounting %a",line)
- end
- table.insert(resolvers.automounted,line)
- resolvers.usezipfile(line)
- end
- end
- end
- f:close()
+ local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
+ if (not mountpaths or #mountpaths==0) and usecache then
+ mountpaths=caches.getreadablepaths("mount")
+ end
+ if mountpaths and #mountpaths>0 then
+ resolvers.starttiming()
+ for k=1,#mountpaths do
+ local root=mountpaths[k]
+ local f=io.open(root.."/url.tmi")
+ if f then
+ for line in f:lines() do
+ if line then
+ if find(line,"^[%%#%-]") then
+ elseif find(line,"^zip://") then
+ if trace_locating then
+ report_mounts("mounting %a",line)
+ end
+ table.insert(resolvers.automounted,line)
+ resolvers.usezipfile(line)
end
+ end
end
- resolvers.stoptiming()
+ f:close()
+ end
end
+ resolvers.stoptiming()
+ end
end
statistics.register("used config file",function() return caches.configfiles() end)
statistics.register("used cache path",function() return caches.usedpaths() end)
function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner)
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
- local luvname=file.replacesuffix(texname,"luv")
- local luvdata={
- enginebanner=enginebanner,
- formatbanner=formatbanner,
- sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
- sourcefile=sourcefile,
- luaversion=LUAVERSION,
- }
- io.savedata(luvname,table.serialize(luvdata,true))
- lua.registerfinalizer(function()
- logs.report("format banner","%s",banner)
- logs.newline()
- end)
- end
+ local enginebanner=status.banner
+ if formatbanner and enginebanner and sourcefile then
+ local luvname=file.replacesuffix(texname,"luv")
+ local luvdata={
+ enginebanner=enginebanner,
+ formatbanner=formatbanner,
+ sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
+ sourcefile=sourcefile,
+ luaversion=LUAVERSION,
+ }
+ io.savedata(luvname,table.serialize(luvdata,true))
+ lua.registerfinalizer(function()
+ 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
end
function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
- local luvname=file.replacesuffix(texname,"luv")
- if lfs.isfile(luvname) then
- local luv=dofile(luvname)
- if luv and luv.sourcefile then
- local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
- local luvbanner=luv.enginebanner or "?"
- if luvbanner~=enginebanner then
- return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
- end
- local luvhash=luv.sourcehash or "?"
- if luvhash~=sourcehash then
- return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
- end
- local luvluaversion=luv.luaversion or 0
- if luvluaversion~=LUAVERSION then
- return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
- end
- else
- return "invalid status file"
- end
- else
- return "missing status file"
- end
+ local enginebanner=status.banner
+ if enginebanner and texname then
+ local luvname=file.replacesuffix(texname,"luv")
+ if lfs.isfile(luvname) then
+ local luv=dofile(luvname)
+ if luv and luv.sourcefile then
+ local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
+ local luvbanner=luv.enginebanner or "?"
+ if luvbanner~=enginebanner then
+ return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+ end
+ local luvhash=luv.sourcehash or "?"
+ if luvhash~=sourcehash then
+ return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
+ end
+ local luvluaversion=luv.luaversion or 0
+ if luvluaversion~=LUAVERSION then
+ return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
+ end
+ else
+ return "invalid status file"
+ end
+ else
+ return "missing status file"
end
- return true
+ end
+ return true
end
@@ -19813,233 +23389,233 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-zip"] = package.loaded["data-zip"] or true
--- original size: 8716, stripped down to: 6795
+-- original size: 8700, stripped down to: 6313
if not modules then modules={} end modules ['data-zip']={
- 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 format,find,match=string.format,string.find,string.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_zip=logs.reporter("resolvers","zip")
local resolvers=resolvers
zip=zip or {}
local zip=zip
-zip.archives=zip.archives or {}
-local archives=zip.archives
-zip.registeredfiles=zip.registeredfiles or {}
-local registeredfiles=zip.registeredfiles
+local archives=zip.archives or {}
+zip.archives=archives
+local registeredfiles=zip.registeredfiles or {}
+zip.registeredfiles=registeredfiles
local function validzip(str)
- if not find(str,"^zip://") then
- return "zip:///"..str
- else
- return str
- end
+ if not find(str,"^zip://") then
+ return "zip:///"..str
+ else
+ return str
+ end
end
function zip.openarchive(name)
- if not name or name=="" then
- return nil
- else
- local arch=archives[name]
- if not arch then
- local full=resolvers.findfile(name) or ""
- arch=full~="" and zip.open(full) or false
- archives[name]=arch
- end
- return arch
+ if not name or name=="" then
+ return nil
+ else
+ local arch=archives[name]
+ if not arch then
+ local full=resolvers.findfile(name) or ""
+ arch=full~="" and zip.open(full) or false
+ archives[name]=arch
end
+ return arch
+ end
end
function zip.closearchive(name)
- if not name or (name=="" and archives[name]) then
- zip.close(archives[name])
- archives[name]=nil
- end
+ if not name or (name=="" and archives[name]) then
+ zip.close(archives[name])
+ archives[name]=nil
+ end
end
function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and zip.openarchive(archive)
- if trace_locating then
- if zipfile then
- report_zip("locator: archive %a found",archive)
- else
- report_zip("locator: archive %a not found",archive)
- end
+ local archive=specification.filename
+ local zipfile=archive and archive~="" and zip.openarchive(archive)
+ if trace_locating then
+ if zipfile then
+ report_zip("locator: archive %a found",archive)
+ else
+ report_zip("locator: archive %a not found",archive)
end
+ end
end
function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
- report_zip("loading file %a",archive)
- end
- resolvers.usezipfile(specification.original)
+ local archive=specification.filename
+ if trace_locating then
+ report_zip("loading file %a",archive)
+ end
+ resolvers.usezipfile(specification.original)
end
function resolvers.concatinators.zip(zipfile,path,name)
- if not path or path=="" then
- return format('%s?name=%s',zipfile,name)
- else
- return format('%s?name=%s/%s',zipfile,path,name)
- end
+ if not path or path=="" then
+ return format('%s?name=%s',zipfile,name)
+ else
+ return format('%s?name=%s/%s',zipfile,path,name)
+ end
end
function resolvers.finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("finder: archive %a found",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- dfile=zfile:close()
- if trace_locating then
- report_zip("finder: file %a found",queryname)
- end
- return specification.original
- elseif trace_locating then
- report_zip("finder: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("finder: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("finder: archive %a found",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ dfile:close()
+ if trace_locating then
+ report_zip("finder: file %a found",queryname)
+ end
+ return specification.original
+ elseif trace_locating then
+ report_zip("finder: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("finder: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("finder: %a not found",original)
- end
- return resolvers.finders.notfound()
+ end
+ if trace_locating then
+ report_zip("finder: %a not found",original)
+ end
+ return resolvers.finders.notfound()
end
function resolvers.openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("opener; archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- if trace_locating then
- report_zip("opener: file %a found",queryname)
- end
- return resolvers.openers.helpers.textopener('zip',original,dfile)
- elseif trace_locating then
- report_zip("opener: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("opener: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("opener; archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ if trace_locating then
+ report_zip("opener: file %a found",queryname)
+ end
+ return resolvers.openers.helpers.textopener('zip',original,dfile)
+ elseif trace_locating then
+ report_zip("opener: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("opener: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("opener: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("opener: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("loader: archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- logs.show_load(original)
- if trace_locating then
- report_zip("loader; file %a loaded",original)
- end
- local s=dfile:read("*all")
- dfile:close()
- return true,s,#s
- elseif trace_locating then
- report_zip("loader: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("loader; unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("loader: archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ logs.show_load(original)
+ if trace_locating then
+ report_zip("loader; file %a loaded",original)
+ end
+ local s=dfile:read("*all")
+ dfile:close()
+ return true,s,#s
+ elseif trace_locating then
+ report_zip("loader: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("loader; unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("loader: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("loader: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.usezipfile(archive)
- local specification=resolvers.splitmethod(archive)
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
- local z=zip.openarchive(archive)
- if z then
- local tree=url.query(specification.query).tree or ""
- if trace_locating then
- report_zip("registering: archive %a",archive)
- end
- resolvers.starttiming()
- resolvers.prependhash('zip',archive)
- resolvers.extendtexmfvariable(archive)
- registeredfiles[archive]=z
- resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
- resolvers.stoptiming()
- elseif trace_locating then
- report_zip("registering: unknown archive %a",archive)
- end
+ local specification=resolvers.splitmethod(archive)
+ local archive=specification.filename
+ if archive and not registeredfiles[archive] then
+ local z=zip.openarchive(archive)
+ if z then
+ local tree=url.query(specification.query).tree or ""
+ if trace_locating then
+ report_zip("registering: archive %a",archive)
+ end
+ resolvers.starttiming()
+ resolvers.prependhash('zip',archive)
+ resolvers.extendtexmfvariable(archive)
+ registeredfiles[archive]=z
+ resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
+ resolvers.stoptiming()
elseif trace_locating then
- report_zip("registering: archive %a not found",archive)
+ report_zip("registering: unknown archive %a",archive)
end
+ elseif trace_locating then
+ report_zip("registering: archive %a not found",archive)
+ end
end
function resolvers.registerzipfile(z,tree)
- local names={}
- local files={}
- local remap={}
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- local register=resolvers.registerfile
- if trace_locating then
- report_zip("registering: using filter %a",filter)
- end
- for i in z:files() do
- local filename=i.filename
- local path,name=match(filename,filter)
- if not path then
- n=n+1
- register(names,filename,"")
- local usedname=lower(filename)
- files[usedname]=""
- if usedname~=filename then
- remap[usedname]=filename
- end
- elseif name and name~="" then
- n=n+1
- register(names,name,path)
- local usedname=lower(name)
- files[usedname]=path
- if usedname~=name then
- remap[usedname]=name
- end
- else
- end
+ local names={}
+ local files={}
+ local remap={}
+ local n=0
+ local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
+ local register=resolvers.registerfile
+ if trace_locating then
+ report_zip("registering: using filter %a",filter)
+ end
+ for i in z:files() do
+ local filename=i.filename
+ local path,name=match(filename,filter)
+ if not path then
+ n=n+1
+ register(names,filename,"")
+ local usedname=lower(filename)
+ files[usedname]=""
+ if usedname~=filename then
+ remap[usedname]=filename
+ end
+ elseif name and name~="" then
+ n=n+1
+ register(names,name,path)
+ local usedname=lower(name)
+ files[usedname]=path
+ if usedname~=name then
+ remap[usedname]=name
+ end
+ else
end
- report_zip("registering: %s files registered",n)
- return {
- files=files,
- remap=remap,
- }
+ end
+ report_zip("registering: %s files registered",n)
+ return {
+ files=files,
+ remap=remap,
+ }
end
@@ -20049,20 +23625,20 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tre"] = package.loaded["data-tre"] or true
--- original size: 8479, stripped down to: 5580
+-- original size: 8478, stripped down to: 5223
if not modules then modules={} end modules ['data-tre']={
- 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 find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file .join
+local basename,dirname,joinname=file.basename,file.dirname,file .join
local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_trees=logs.reporter("resolvers","trees")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -20071,165 +23647,167 @@ local lookup=resolvers.get_from_content
local collectors={}
local found={}
function resolvers.finders.tree(specification)
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
- if spec~="" then
- local path=dirname(spec)
- local name=basename(spec)
- if path=="" then
- path="."
- end
- local names=collectors[path]
- if not names then
- local pattern=find(path,"/%*+$") and path or (path.."/*")
- names=globdir(pattern)
- collectors[path]=names
- end
- local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
- for i=1,#names do
- local fullname=names[i]
- if find(fullname,pattern) then
- found[spec]=fullname
- return fullname
- end
- end
- local pattern=lower(pattern)
- for i=1,#names do
- local fullname=lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
- found[spec]=fullname
- return fullname
- else
- break
- end
- end
- end
+ local spec=specification.filename
+ local okay=found[spec]
+ if okay==nil then
+ if spec~="" then
+ local path=dirname(spec)
+ local name=basename(spec)
+ if path=="" then
+ path="."
+ end
+ local names=collectors[path]
+ if not names then
+ local pattern=find(path,"/%*+$") and path or (path.."/*")
+ names=globdir(pattern)
+ collectors[path]=names
+ end
+ local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
+ for i=1,#names do
+ local fullname=names[i]
+ if find(fullname,pattern) then
+ found[spec]=fullname
+ return fullname
+ end
+ end
+ local pattern=lower(pattern)
+ for i=1,#names do
+ local fullname=lower(names[i])
+ if find(fullname,pattern) then
+ if isfile(fullname) then
+ found[spec]=fullname
+ return fullname
+ else
+ break
+ end
end
- okay=notfound()
- found[spec]=okay
+ end
end
- return okay
+ okay=notfound()
+ found[spec]=okay
+ end
+ return okay
end
function resolvers.locators.tree(specification)
- local name=specification.filename
- local realname=resolveprefix(name)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
- end
- resolvers.appendhash('tree',name,false)
- elseif trace_locating then
- report_trees("locator %a not found",name)
+ local name=specification.filename
+ local realname=resolveprefix(name)
+ if realname and realname~='' and isdir(realname) then
+ if trace_locating then
+ report_trees("locator %a found",realname)
end
+ resolvers.appendhash('tree',name,false)
+ elseif trace_locating then
+ report_trees("locator %a not found",name)
+ end
end
function resolvers.hashers.tree(specification)
- local name=specification.filename
- report_trees("analyzing %a",name)
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+ local name=specification.filename
+ if trace_locating then
+ report_trees("analyzing %a",name)
+ end
+ resolvers.methodhandler("hashers",name)
+ resolvers.generators.file(specification)
end
local collectors={}
local splitter=lpeg.splitat("/**/")
local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=caches.loadcontent(dataname,"files",dataname)
- if not content then
- content=resolvers.scanfiles(rootname,nil,nil,false,true)
- caches.savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
+ local rootname=lpegmatch(stripper,k)
+ local dataname=joinname(rootname,"dirlist")
+ local content=caches.loadcontent(dataname,"files",dataname)
+ if not content then
+ content=resolvers.scanfiles(rootname,nil,nil,false,true)
+ caches.savecontent(dataname,"files",content,dataname)
+ end
+ t[k]=content
+ return content
end)
local function checked(root,p,n)
- if p then
- if type(p)=="table" then
- for i=1,#p do
- local fullname=joinname(root,p[i],n)
- if isfile(fullname) then
- return fullname
- end
- end
- else
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
+ if p then
+ if type(p)=="table" then
+ for i=1,#p do
+ local fullname=joinname(root,p[i],n)
+ if isfile(fullname) then
+ return fullname
end
+ end
+ else
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- return notfound()
+ end
+ return notfound()
end
local function resolve(specification)
- local filename=specification.filename
- if filename~="" then
- local root,rest=lpegmatch(splitter,filename)
- if root and rest then
- local path,name=dirname(rest),basename(rest)
- if name~=rest then
- local content=collectors[root]
- local p,n=lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern=".*/"..path.."$"
- local istable=type(p)=="table"
- if istable then
- for i=1,#p do
- local pi=p[i]
- if pi==path or find(pi,pattern) then
- local fullname=joinname(root,pi,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- elseif p==path or find(p,pattern) then
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- local queries=specification.queries
- if queries and queries.option=="fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
+ local filename=specification.filename
+ if filename~="" then
+ local root,rest=lpegmatch(splitter,filename)
+ if root and rest then
+ local path,name=dirname(rest),basename(rest)
+ if name~=rest then
+ local content=collectors[root]
+ local p,n=lookup(content,name)
+ if not p then
+ return notfound()
+ end
+ local pattern=".*/"..path.."$"
+ local istable=type(p)=="table"
+ if istable then
+ for i=1,#p do
+ local pi=p[i]
+ if pi==path or find(pi,pattern) then
+ local fullname=joinname(root,pi,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
+ end
+ elseif p==path or find(p,pattern) then
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- local path,name=dirname(filename),basename(filename)
- local root=lpegmatch(stripper,path)
- local content=collectors[path]
- local p,n=lookup(content,name)
- if p then
- return checked(root,p,n)
+ local queries=specification.queries
+ if queries and queries.option=="fileonly" then
+ return checked(root,p,n)
+ else
+ return notfound()
end
+ end
end
- return notfound()
+ local path,name=dirname(filename),basename(filename)
+ local root=lpegmatch(stripper,path)
+ local content=collectors[path]
+ local p,n=lookup(content,name)
+ if p then
+ return checked(root,p,n)
+ end
+ end
+ return notfound()
end
-resolvers.finders .dirlist=resolve
-resolvers.locators .dirlist=resolvers.locators .tree
-resolvers.hashers .dirlist=resolvers.hashers .tree
+resolvers.finders .dirlist=resolve
+resolvers.locators .dirlist=resolvers.locators .tree
+resolvers.hashers .dirlist=resolvers.hashers .tree
resolvers.generators.dirlist=resolvers.generators.file
-resolvers.openers .dirlist=resolvers.openers .file
-resolvers.loaders .dirlist=resolvers.loaders .file
+resolvers.openers .dirlist=resolvers.openers .file
+resolvers.loaders .dirlist=resolvers.loaders .file
function resolvers.finders.dirfile(specification)
- local queries=specification.queries
- if queries then
- queries.option="fileonly"
- else
- specification.queries={ option="fileonly" }
- end
- return resolve(specification)
-end
-resolvers.locators .dirfile=resolvers.locators .dirlist
-resolvers.hashers .dirfile=resolvers.hashers .dirlist
+ local queries=specification.queries
+ if queries then
+ queries.option="fileonly"
+ else
+ specification.queries={ option="fileonly" }
+ end
+ return resolve(specification)
+end
+resolvers.locators .dirfile=resolvers.locators .dirlist
+resolvers.hashers .dirfile=resolvers.hashers .dirlist
resolvers.generators.dirfile=resolvers.generators.dirlist
-resolvers.openers .dirfile=resolvers.openers .dirlist
-resolvers.loaders .dirfile=resolvers.loaders .dirlist
+resolvers.openers .dirfile=resolvers.openers .dirlist
+resolvers.loaders .dirfile=resolvers.loaders .dirlist
end -- of closure
@@ -20238,19 +23816,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-sch"] = package.loaded["data-sch"] or true
--- original size: 6753, stripped down to: 5511
+-- original size: 6753, stripped down to: 5268
if not modules then modules={} end modules ['data-sch']={
- 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 load,tonumber=load,tonumber
local gsub,concat,format=string.gsub,table.concat,string.format
local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
+local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
local report_schemes=logs.reporter("resolvers","schemes")
local http=require("socket.http")
local ltn12=require("ltn12")
@@ -20263,27 +23841,27 @@ schemes.cleaners=cleaners
local threshold=24*60*60
directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
function cleaners.none(specification)
- return specification.original
+ return specification.original
end
function cleaners.strip(specification)
- local path,name=file.splitbase(specification.original)
- if path=="" then
- return (gsub(name,"[^%a%d%.]+","-"))
- else
- return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
+ local path,name=file.splitbase(specification.original)
+ if path=="" then
+ return (gsub(name,"[^%a%d%.]+","-"))
+ else
+ return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
+ end
end
function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
+ return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
end
local cleaner=cleaners.strip
directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
+ local hash=cleaner(specification)
+ if trace_schemes then
+ report_schemes("hashing %a to %a",specification.original,hash)
+ end
+ return hash
end
local cached={}
local loaded={}
@@ -20291,139 +23869,139 @@ local reused={}
local thresholds={}
local handlers={}
local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template="--silent --insecure --create-dirs --output %cachename% %original%",
- checkers={
- cachename="cache",
- original="url",
- }
+ name="curl resolver",
+ method="execute",
+ program="curl",
+ template="--silent --insecure --create-dirs --output %cachename% %original%",
+ checkers={
+ cachename="cache",
+ original="url",
+ }
}
local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
- cached[original]=cachename
- local handler=handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
- end
- logs.flush()
- runner {
- original=original,
- cachename=cachename,
- }
- end
- end
- if io.exists(cachename) then
- cached[original]=cachename
- if trace_schemes then
- report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
- end
- else
- cached[original]=""
- if trace_schemes then
- report_schemes("using missing %a, protocol %a",original,scheme)
- end
+ local original=specification.original
+ local scheme=specification.scheme
+ local cleanname=schemes.cleanname(specification)
+ local cachename=caches.setfirstwritablefile(cleanname,"schemes")
+ if not cached[original] then
+ statistics.starttiming(schemes)
+ if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
+ cached[original]=cachename
+ local handler=handlers[scheme]
+ if handler then
+ if trace_schemes then
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
end
- loaded[scheme]=loaded[scheme]+1
- statistics.stoptiming(schemes)
- else
+ logs.flush()
+ handler(specification,cachename)
+ else
if trace_schemes then
- report_schemes("reusing %a, protocol %a",original,scheme)
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
end
- reused[scheme]=reused[scheme]+1
+ logs.flush()
+ runner {
+ original=original,
+ cachename=cachename,
+ }
+ end
+ end
+ if io.exists(cachename) then
+ cached[original]=cachename
+ if trace_schemes then
+ report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
+ end
+ else
+ cached[original]=""
+ if trace_schemes then
+ report_schemes("using missing %a, protocol %a",original,scheme)
+ end
end
- return cached[original]
+ loaded[scheme]=loaded[scheme]+1
+ statistics.stoptiming(schemes)
+ else
+ if trace_schemes then
+ report_schemes("reusing %a, protocol %a",original,scheme)
+ end
+ reused[scheme]=reused[scheme]+1
+ end
+ return cached[original]
end
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",fetch(specification),filetype)
end
local opener=openers.file
local loader=loaders.file
local function install(scheme,handler,newthreshold)
- handlers [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders [scheme]=finder
- openers [scheme]=opener
- loaders [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
+ handlers [scheme]=handler
+ loaded [scheme]=0
+ reused [scheme]=0
+ finders [scheme]=finder
+ openers [scheme]=opener
+ loaders [scheme]=loader
+ thresholds[scheme]=newthreshold or threshold
end
schemes.install=install
local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local f=io.open(tempname,"wb")
- local status,message=http.request {
- url=specification.original,
- sink=ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
+ local tempname=cachename..".tmp"
+ local f=io.open(tempname,"wb")
+ local status,message=http.request {
+ url=specification.original,
+ sink=ltn12.sink.file(f)
+ }
+ if not status then
+ os.remove(tempname)
+ else
+ os.remove(cachename)
+ os.rename(tempname,cachename)
+ end
+ return cachename
end
install('http',http_handler)
install('https')
install('ftp')
statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in table.sortedhash(loaded) do
- if v>0 then
- nl=nl+1
- l[nl]=k..":"..v
- end
- end
- for k,v in table.sortedhash(reused) do
- if v>0 then
- nr=nr+1
- r[nr]=k..":"..v
- end
- end
- local n=nl+nr
- if n>0 then
- l=nl>0 and concat(l) or "none"
- r=nr>0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes),n,threshold,l,r)
- else
- return nil
- end
+ local l,r,nl,nr={},{},0,0
+ for k,v in table.sortedhash(loaded) do
+ if v>0 then
+ nl=nl+1
+ l[nl]=k..":"..v
+ end
+ end
+ for k,v in table.sortedhash(reused) do
+ if v>0 then
+ nr=nr+1
+ r[nr]=k..":"..v
+ end
+ end
+ local n=nl+nr
+ if n>0 then
+ l=nl>0 and concat(l) or "none"
+ r=nr>0 and concat(r) or "none"
+ return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
+ statistics.elapsedtime(schemes),n,threshold,l,r)
+ else
+ return nil
+ end
end)
local httprequest=http.request
local toquery=url.toquery
local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
- url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply
+ local q=data and toquery(data)
+ if q then
+ url=url.."?"..q
+ end
+ local reply=httprequest(url)
+ return reply
end
schemes.fetchstring=fetchstring
function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
- local s=load("return "..reply)
- if s then
- return s()
- end
+ local reply=fetchstring(url,data)
+ if reply then
+ local s=load("return "..reply)
+ if s then
+ return s()
end
+ end
end
@@ -20433,14 +24011,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lua"] = package.loaded["data-lua"] or true
--- original size: 4207, stripped down to: 3137
+-- original size: 4207, stripped down to: 3041
if not modules then modules={} end modules ['data-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 package,lpeg=package,lpeg
local gsub=string.gsub
@@ -20459,20 +24037,20 @@ helpers.report=logs.reporter("resolvers","libraries")
trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
trackers.register("resolvers.locating",function(v) helpers.trace=v end)
helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
+ "already loaded",
+ "preload table",
+ "lua variable format",
+ "lib variable format",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
}
local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
function helpers.cleanpath(path)
- return resolveprefix(lpegmatch(pattern,path))
+ return resolveprefix(lpegmatch(pattern,path))
end
local loadedaslib=helpers.loadedaslib
local registerpath=helpers.registerpath
@@ -20480,56 +24058,56 @@ local lualibfile=helpers.lualibfile
local luaformatpaths
local libformatpaths
local function getluaformatpaths()
- if not luaformatpaths then
- luaformatpaths={}
- for i=1,#luaformats do
- registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
- end
+ if not luaformatpaths then
+ luaformatpaths={}
+ for i=1,#luaformats do
+ registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
end
- return luaformatpaths
+ end
+ return luaformatpaths
end
local function getlibformatpaths()
- if not libformatpaths then
- libformatpaths={}
- for i=1,#libformats do
- registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
- end
+ if not libformatpaths then
+ libformatpaths={}
+ for i=1,#libformats do
+ registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
end
- return libformatpaths
+ end
+ return libformatpaths
end
local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do
- local format=suffixes[i]
- local resolved=resolvers.findfile(name,format) or ""
- if trace then
- report("%s format, identifying %a using format %a",what,name,format)
- end
- if resolved~="" then
- if trace then
- report("%s format, %a found on %a",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ local report=helpers.report
+ for i=1,#suffixes do
+ local format=suffixes[i]
+ local resolved=resolvers.findfile(name,format) or ""
+ if trace then
+ report("%s format, identifying %a using format %a",what,name,format)
+ end
+ if resolved~="" then
+ if trace then
+ report("%s format, %a found on %a",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbyformat=loadedbyformat
methods["lua variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
end
methods["lib variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
end
resolvers.loadlualib=require
@@ -20540,64 +24118,64 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-aux"] = package.loaded["data-aux"] or true
--- original size: 2438, stripped down to: 2003
+-- original size: 2452, stripped down to: 1877
if not modules then modules={} end modules ['data-aux']={
- 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 find=string.find
local type,next=type,next
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local resolvers=resolvers
local report_scripts=logs.reporter("resolvers","scripts")
function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- newname=file.addsuffix(newname,"lua")
- local oldscript=resolvers.cleanpath(oldname)
+ local scriptpath="context/lua"
+ newname=file.addsuffix(newname,"lua")
+ local oldscript=resolvers.cleanpath(oldname)
+ if trace_locating then
+ report_scripts("to be replaced old script %a",oldscript)
+ end
+ local newscripts=resolvers.findfiles(newname) or {}
+ if #newscripts==0 then
if trace_locating then
- report_scripts("to be replaced old script %a",oldscript)
+ report_scripts("unable to locate new script")
end
- local newscripts=resolvers.findfiles(newname) or {}
- if #newscripts==0 then
+ else
+ for i=1,#newscripts do
+ local newscript=resolvers.cleanpath(newscripts[i])
+ if trace_locating then
+ report_scripts("checking new script %a",newscript)
+ end
+ if oldscript==newscript then
if trace_locating then
- report_scripts("unable to locate new script")
+ report_scripts("old and new script are the same")
end
- else
- for i=1,#newscripts do
- local newscript=resolvers.cleanpath(newscripts[i])
- if trace_locating then
- report_scripts("checking new script %a",newscript)
- end
- if oldscript==newscript then
- if trace_locating then
- report_scripts("old and new script are the same")
- end
- elseif not find(newscript,scriptpath,1,true) then
- if trace_locating then
- report_scripts("new script should come from %a",scriptpath)
- end
- elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
- if trace_locating then
- report_scripts("invalid new script name")
- end
- else
- local newdata=io.loaddata(newscript)
- if newdata then
- if trace_locating then
- report_scripts("old script content replaced by new content")
- end
- io.savedata(oldscript,newdata)
- break
- elseif trace_locating then
- report_scripts("unable to load new script")
- end
- end
+ elseif not find(newscript,scriptpath,1,true) then
+ if trace_locating then
+ report_scripts("new script should come from %a",scriptpath)
end
+ elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+ if trace_locating then
+ report_scripts("invalid new script name")
+ end
+ else
+ local newdata=io.loaddata(newscript)
+ if newdata then
+ if trace_locating then
+ report_scripts("old script content replaced by new content: %s",oldscript)
+ end
+ io.savedata(oldscript,newdata)
+ break
+ elseif trace_locating then
+ report_scripts("unable to load new script")
+ end
+ end
end
+ end
end
@@ -20607,53 +24185,53 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
--- original size: 2601, stripped down to: 1627
+-- original size: 2601, stripped down to: 1549
if not modules then modules={} end modules ['data-tmf']={
- 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 resolvers=resolvers
local report_tds=logs.reporter("resolvers","tds")
function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
- local getenv,setenv=resolvers.getenv,resolvers.setenv
- local texos="texmf-"..os.platform
- local oldroot=environment.texroot
- local newroot=file.collapsepath(tree)
- local newtree=file.join(newroot,texos)
- local newpath=file.join(newtree,"bin")
- if not lfs.isdir(newtree) then
- report_tds("no %a under tree %a",texos,tree)
- os.exit()
- end
- if not lfs.isdir(newpath) then
- report_tds("no '%s/bin' under tree %a",texos,tree)
- os.exit()
- end
- local texmfos=newtree
- environment.texroot=newroot
- environment.texos=texos
- environment.texmfos=texmfos
- if resolve then
- resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
- end
- setenv('SELFAUTOPARENT',newroot)
- setenv('SELFAUTODIR',newtree)
- setenv('SELFAUTOLOC',newpath)
- setenv('TEXROOT',newroot)
- setenv('TEXOS',texos)
- setenv('TEXMFOS',texmfos)
- setenv('TEXMFCNF',resolvers.luacnfspec,true)
- setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
- report_tds("changing from root %a to %a",oldroot,newroot)
- report_tds("prepending %a to PATH",newpath)
- report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
- report_tds()
- end
+ if type(tree)=="string" and tree~="" then
+ local getenv,setenv=resolvers.getenv,resolvers.setenv
+ local texos="texmf-"..os.platform
+ local oldroot=environment.texroot
+ local newroot=file.collapsepath(tree)
+ local newtree=file.join(newroot,texos)
+ local newpath=file.join(newtree,"bin")
+ if not lfs.isdir(newtree) then
+ report_tds("no %a under tree %a",texos,tree)
+ os.exit()
+ end
+ if not lfs.isdir(newpath) then
+ report_tds("no '%s/bin' under tree %a",texos,tree)
+ os.exit()
+ end
+ local texmfos=newtree
+ environment.texroot=newroot
+ environment.texos=texos
+ environment.texmfos=texmfos
+ if resolve then
+ resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
+ end
+ setenv('SELFAUTOPARENT',newroot)
+ setenv('SELFAUTODIR',newtree)
+ setenv('SELFAUTOLOC',newpath)
+ setenv('TEXROOT',newroot)
+ setenv('TEXOS',texos)
+ setenv('TEXMFOS',texmfos)
+ setenv('TEXMFCNF',resolvers.luacnfspec,true)
+ setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
+ report_tds("changing from root %a to %a",oldroot,newroot)
+ report_tds("prepending %a to PATH",newpath)
+ report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
+ report_tds()
+ end
end
@@ -20663,14 +24241,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lst"] = package.loaded["data-lst"] or true
--- original size: 1823, stripped down to: 1591
+-- original size: 1823, stripped down to: 1542
if not modules then modules={} end modules ['data-lst']={
- 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=type
local concat,sortedhash=table.concat,table.sortedhash
@@ -20681,37 +24259,37 @@ local resolveprefix=resolvers.resolve
local report_lists=logs.reporter("resolvers","lists")
local report_resolved=logs.reporter("system","resolved")
local function tabstr(str)
- if type(str)=='table' then
- return concat(str," | ")
- else
- return str
- end
+ if type(str)=='table' then
+ return concat(str," | ")
+ else
+ return str
+ end
end
function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
- report_lists(key)
- report_lists(" env: %s",tabstr(value.environment or "unset"))
- report_lists(" var: %s",tabstr(value.variable or "unset"))
- report_lists(" exp: %s",tabstr(value.expansion or "unset"))
- report_lists(" res: %s",tabstr(value.resolved or "unset"))
- end
+ local result=resolvers.knownvariables(pattern)
+ for key,value in sortedhash(result) do
+ report_lists(key)
+ report_lists(" env: %s",tabstr(value.environment or "unset"))
+ report_lists(" var: %s",tabstr(value.variable or "unset"))
+ report_lists(" exp: %s",tabstr(value.expansion or "unset"))
+ report_lists(" res: %s",tabstr(value.resolved or "unset"))
+ end
end
function listers.configurations()
- local configurations=resolvers.configurationfiles()
- for i=1,#configurations do
- report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
- for i=1,#list do
- local li=resolveprefix(list[i])
- if lfs.isdir(li) then
- report_resolved("path - %s",li)
- else
- report_resolved("path + %s",li)
- end
+ local configurations=resolvers.configurationfiles()
+ for i=1,#configurations do
+ report_resolved("file : %s",resolveprefix(configurations[i]))
+ end
+ report_resolved("")
+ local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+ for i=1,#list do
+ local li=resolveprefix(list[i])
+ if lfs.isdir(li) then
+ report_resolved("path - %s",li)
+ else
+ report_resolved("path + %s",li)
end
+ end
end
@@ -20721,14 +24299,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 14943, stripped down to: 8305
+-- original size: 16094, stripped down to: 8443
if not modules then modules={} end modules ['util-lib']={
- 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=type
local next=next
@@ -20748,256 +24326,291 @@ local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
local done=false
local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
- end
- found_library=required
- else
- if trace then
- report("qualified name %a not found",required)
- end
- end
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ local required_full=gsub(required,"%.","/")
+ local required_path=pathpart(required_full)
+ local required_base=nameonly(required_full)
+ if qualifiedpath(required) then
+ if isfile(addsuffix(required,os.libsuffix)) then
+ if trace then
+ report("qualified name %a found",required)
+ end
+ found_library=required
else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine="luatex"
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ if trace then
+ report("qualified name %a not found",required)
+ end
+ end
+ else
+ local required_name=required_base.."."..os.libsuffix
+ local version=type(version)=="string" and version~="" and version or false
+ local engine="luatex"
+ if trace and not done then
+ local list=expandpaths("lib")
+ for i=1,#list do
+ report("tds path %i: %s",i,list[i])
+ end
+ end
+ local function found(locate,asked_library,how,...)
+ if trace then
+ report("checking %s: %a",how,asked_library)
+ end
+ return locate(asked_library,...)
+ end
+ local function check(locate,...)
+ local found=nil
+ if version then
+ local asked_library=joinfile(required_path,version,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
- end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
+ found=locate(asked_library,...)
+ end
+ if not found or found=="" then
+ local asked_library=joinfile(required_path,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
+ found=locate(asked_library,...)
+ end
+ return found and found~="" and found or false
+ end
+ local function attempt(checkpattern)
+ if trace then
+ report("checking tds lib paths strictly")
+ end
+ local found=findfile and check(findfile,"lib")
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
+ end
+ if trace then
+ report("checking tds lib paths with wildcard")
+ end
+ local asked_library=joinfile(required_path,".*",required_name)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
+ end
+ local list=findfiles(asked_library,"lib",true)
+ if list and #list>0 then
+ sort(list)
+ local found=list[#list]
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
- end
- found_library=attempt()
- end
- else
- found_library=attempt()
+ end
+ if trace then
+ report("checking lib paths")
+ end
+ package.extralibpath(environment.ownpath)
+ local paths=package.libpaths()
+ local pattern="/[^/]+%."..os.libsuffix.."$"
+ for i=1,#paths do
+ required_path=gsub(paths[i],pattern,"")
+ local found=check(lfs.isfound)
+ if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
+ return found
end
+ end
+ return false
end
- if not found_library then
+ if engine then
+ if trace then
+ report("attemp 1, engine %a",engine)
+ end
+ found_library=attempt("/"..engine.."/")
+ if not found_library then
if trace then
- report("not found: %a",required)
+ report("attemp 2, no engine",asked_library)
end
- library=false
+ found_library=attempt()
+ end
else
- if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
- end
+ found_library=attempt()
end
+ end
+ if not found_library then
if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
+ report("not found: %a",required)
end
- return library
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local result,message=action(found_library,required_base)
+ if result then
+ library=result
+ else
+ library=false
+ report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
+ end
+ end
+ if trace then
+ if not library then
+ report("unknown library: %a",required)
+ else
+ report("stored library: %a",required)
+ end
+ end
+ return library or nil
end
do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
- else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
- end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ local loadlib=package.loadlib
+ local pushdir=dir.push
+ local popdir=dir.pop
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ pushdir(pathpart(name))
+ local opener="luaopen_"..base
+ if trace_swiglib then
+ report_swiglib("opening: %a with %a",name,opener)
+ end
+ local library,message=loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
+ else
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
end
+ popdir()
return library
+ end)
+ loadedlibs[required]=library or false
end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
- end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
+ else
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
+ if trace_swiglib then
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
+ else
+ fullname="swiglib."..name
+ end
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
- end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
- end
- return library
+ return library
+ end
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
+ end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- 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
- l=library
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ local loaded={}
+ local function locateindeed(name)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l==nil 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
+ loaded[name]=l
+ elseif trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- elseif version=="system" then
- return locateindeed(name)
- else
- return locate(name,version,trace_ffilib,report_ffilib,locateindeed)
+ 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
- function ffi.load(name)
- local library=ffilib(name)
+ return { required }
+ end
+ function ffilib(name,version)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l~=nil then
+ if trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
+ end
+ return l
+ 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
+ return library
end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
+ end
+ else
+ for i=1,#list do
+ local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
+ if type(library)=="userdata" then
+ return library
end
- return savedffiload(name)
+ end
end
+ end
+ function ffi.load(name)
+ 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
+ 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
@@ -21007,13 +24620,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
--- original size: 5703, stripped down to: 2507
+-- original size: 5703, stripped down to: 2321
if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gmatch,match=string.gmatch,string.match
local type=type
@@ -21026,81 +24639,81 @@ local hash=states.hash
states.tag=states.tag or ""
states.filename=states.filename or ""
function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
- "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
+ tag=tag or states.tag
+ filename=file.addsuffix(filename or states.filename,'lus')
+ io.savedata(filename,
+ "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
+ )
end
function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
+ states.filename=filename
+ states.tag=tag or "whatever"
+ states.filename=file.addsuffix(states.filename,'lus')
+ data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
end
local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
- if type(d)=="table" then
- local dkey,hkey=key,key
- local pre,post=match(key,"(.+)%.([^%.]+)$")
- if pre and post then
- for k in gmatch(pre,"[^%.]+") do
- local dk=d[k]
- if not dk then
- dk={}
- d[k]=dk
- elseif type(dk)=="string" then
- break
- end
- d=dk
- end
- dkey,hkey=post,key
- end
- if value==nil then
- value=default
- elseif value==false then
- elseif persistent then
- value=value or d[dkey] or default
- else
- value=value or default
- end
- d[dkey],h[hkey]=value,value
- elseif type(d)=="string" then
- data[tag],hash[tag]=value,value
+ local d,h=data[tag],hash[tag]
+ if d then
+ if type(d)=="table" then
+ local dkey,hkey=key,key
+ local pre,post=match(key,"(.+)%.([^%.]+)$")
+ if pre and post then
+ for k in gmatch(pre,"[^%.]+") do
+ local dk=d[k]
+ if not dk then
+ dk={}
+ d[k]=dk
+ elseif type(dk)=="string" then
+ break
+ end
+ d=dk
end
+ dkey,hkey=post,key
+ end
+ if value==nil then
+ value=default
+ elseif value==false then
+ elseif persistent then
+ value=value or d[dkey] or default
+ else
+ value=value or default
+ end
+ d[dkey],h[hkey]=value,value
+ elseif type(d)=="string" then
+ data[tag],hash[tag]=value,value
end
+ end
end
local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
- return h[key]
- else
- local d=data[tag]
- if d then
- for k in gmatch(key,"[^%.]+") do
- local dk=d[k]
- if dk~=nil then
- d=dk
- else
- return default
- end
- end
- if d==false then
- return false
- else
- return d or default
- end
+ local h=hash[tag]
+ if h and h[key] then
+ return h[key]
+ else
+ local d=data[tag]
+ if d then
+ for k in gmatch(key,"[^%.]+") do
+ local dk=d[k]
+ if dk~=nil then
+ d=dk
+ else
+ return default
end
+ end
+ if d==false then
+ return false
+ else
+ return d or default
+ end
end
+ end
end
states.set_by_tag=set_by_tag
states.get_by_tag=get_by_tag
function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
+ set_by_tag(states.tag,key,value,default,persistent)
end
function states.get(key,default)
- return get_by_tag(states.tag,key,default)
+ return get_by_tag(states.tag,key,default)
end
@@ -21110,14 +24723,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
--- original size: 9268, stripped down to: 7401
+-- original size: 9418, stripped down to: 7087
if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- 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 mtxrun",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format=string.format
local concat=table.concat
@@ -21125,229 +24738,232 @@ local quoted=string.quoted
local luasuffixes=utilities.lua.suffixes
local report_format=logs.reporter("resolvers","formats")
local function primaryflags()
- local arguments=environment.arguments
- local flags={}
- if arguments.silent then
- flags[#flags+1]="--interaction=batchmode"
- end
- if arguments.jit then
- flags[#flags+1]="--jiton"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local flags={}
+ if arguments.silent then
+ flags[#flags+1]="--interaction=batchmode"
+ end
+ return concat(flags," ")
end
local function secondaryflags()
- local arguments=environment.arguments
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
- flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
- flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
- flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
- flags[#flags+1]="--c:errors"
- end
- if arguments.jit then
- flags[#flags+1]="--c:jiton"
- end
- if arguments.ansi then
- flags[#flags+1]="--c:ansi"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local trackers=arguments.trackers
+ local directives=arguments.directives
+ local flags={}
+ if trackers and trackers~="" then
+ flags[#flags+1]="--c:trackers="..quoted(trackers)
+ end
+ if directives and directives~="" then
+ flags[#flags+1]="--c:directives="..quoted(directives)
+ end
+ if arguments.silent then
+ flags[#flags+1]="--c:silent"
+ end
+ if arguments.errors then
+ flags[#flags+1]="--c:errors"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--c:jiton"
+ end
+ 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
local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
local checkers={
- primaryflags="string",
- secondaryflags="string",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
+ primaryflags="string",
+ secondaryflags="string",
+ luafile="readable",
+ texfile="readable",
+ redirect="string",
+ dump="string",
}
local runners={
- luatex=sandbox.registerrunner {
- name="make luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="make luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="make luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="make luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.make_format(name,arguments)
- local engine=environment.ownmain or "luatex"
- local silent=environment.arguments.silent
- local errors=environment.arguments.errors
- local olddir=dir.current()
- local path=caches.getwritablepath("formats",engine) or ""
- if path~="" then
- lfs.chdir(path)
- end
- report_format("using format path %a",dir.current())
- local texsourcename=file.addsuffix(name,"mkiv")
- local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(name,"tex")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- report_format("no tex source file with name %a (mkiv or tex)",name)
- lfs.chdir(olddir)
- return
- else
- report_format("using tex source file %a",fulltexsourcename)
- end
- local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
- local specificationname=file.replacesuffix(fulltexsourcename,"lus")
- local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- if fullspecificationname=="" then
- specificationname=file.join(texsourcepath,"context.lus")
- fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- end
- if fullspecificationname=="" then
- report_format("unknown stub specification %a",specificationname)
- lfs.chdir(olddir)
- return
- end
- local specificationpath=file.dirname(fullspecificationname)
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
- usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
- elseif type(usedlualibs)=="table" then
- report_format("using stub specification %a",fullspecificationname)
- local texbasename=file.basename(name)
- local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
- local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
- report_format("creating initialization file %a",luastubname)
- utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
- if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
- report_format("using compiled initialization file %a",lucstubname)
- usedluastub=lucstubname
- else
- report_format("using uncompiled initialization file %a",luastubname)
- usedluastub=luastubname
- end
- else
- report_format("invalid stub specification %a",fullspecificationname)
- lfs.chdir(olddir)
- return
- end
- local specification={
- primaryflags=primaryflags(),
- secondaryflags=secondaryflags(),
- luafile=quoted(usedluastub),
- texfile=quoted(fulltexsourcename),
- dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
- elseif silent then
- statistics.starttiming()
- specification.redirect="> temp.log"
- local result=runner(specification)
- local runtime=statistics.stoptiming()
- if result~=0 then
- print(format("%s silent make > fatal error when making format %q",engine,name))
- else
- print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
- end
- os.remove("temp.log")
- else
- runner(specification)
- end
- local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
- local mp=dir.glob(pattern)
- if mp then
- for i=1,#mp do
- local name=mp[i]
- report_format("removing related mplib format %a",file.basename(name))
- os.remove(name)
- end
- end
+ local engine=environment.ownmain or "luatex"
+ local silent=environment.arguments.silent
+ local errors=environment.arguments.errors
+ local olddir=dir.current()
+ local path=caches.getwritablepath("formats",engine) or ""
+ if path~="" then
+ lfs.chdir(path)
+ end
+ report_format("using format path %a",dir.current())
+ local texsourcename=file.addsuffix(name,"mkiv")
+ local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ if fulltexsourcename=="" then
+ texsourcename=file.addsuffix(name,"tex")
+ fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ end
+ if fulltexsourcename=="" then
+ report_format("no tex source file with name %a (mkiv or tex)",name)
+ lfs.chdir(olddir)
+ return
+ else
+ report_format("using tex source file %a",fulltexsourcename)
+ end
+ local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
+ local specificationname=file.replacesuffix(fulltexsourcename,"lus")
+ local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ if fullspecificationname=="" then
+ specificationname=file.join(texsourcepath,"context.lus")
+ fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ end
+ if fullspecificationname=="" then
+ report_format("unknown stub specification %a",specificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specificationpath=file.dirname(fullspecificationname)
+ local usedluastub=nil
+ local usedlualibs=dofile(fullspecificationname)
+ if type(usedlualibs)=="string" then
+ usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
+ elseif type(usedlualibs)=="table" then
+ report_format("using stub specification %a",fullspecificationname)
+ local texbasename=file.basename(name)
+ local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
+ local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
+ report_format("creating initialization file %a",luastubname)
+ utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
+ report_format("using compiled initialization file %a",lucstubname)
+ usedluastub=lucstubname
+ else
+ report_format("using uncompiled initialization file %a",luastubname)
+ usedluastub=luastubname
+ end
+ else
+ report_format("invalid stub specification %a",fullspecificationname)
lfs.chdir(olddir)
+ return
+ end
+ local specification={
+ primaryflags=primaryflags(),
+ secondaryflags=secondaryflags(),
+ luafile=quoted(usedluastub),
+ texfile=quoted(fulltexsourcename),
+ dump=os.platform=="unix" and "\\\\dump" or "\\dump",
+ }
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
+ elseif silent then
+ statistics.starttiming()
+ specification.redirect="> temp.log"
+ local result=runner(specification)
+ local runtime=statistics.stoptiming()
+ if result~=0 then
+ print(format("%s silent make > fatal error when making format %q",engine,name))
+ else
+ print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
+ end
+ os.remove("temp.log")
+ else
+ runner(specification)
+ end
+ local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
+ local mp=dir.glob(pattern)
+ if mp then
+ for i=1,#mp do
+ local name=mp[i]
+ report_format("removing related mplib format %a",file.basename(name))
+ os.remove(name)
+ end
+ end
+ lfs.chdir(olddir)
end
local template=[[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
local checkers={
- flags="string",
- more="string",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
+ flags="string",
+ more="string",
+ fmtfile="readable",
+ luafile="readable",
+ texfile="readable",
}
local runners={
- luatex=sandbox.registerrunner {
- name="run luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="run luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="run luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="run luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.run_format(name,data,more)
- if name and name~="" then
- local engine=environment.ownmain or "luatex"
- local barename=file.removesuffix(name)
- local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
- if fmtname=="" then
- fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
- end
- fmtname=resolvers.cleanpath(fmtname)
- if fmtname=="" then
- report_format("no format with name %a",name)
+ if name and name~="" then
+ local engine=environment.ownmain or "luatex"
+ local barename=file.removesuffix(name)
+ local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
+ if fmtname=="" then
+ fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
+ end
+ fmtname=resolvers.cleanpath(fmtname)
+ if fmtname=="" then
+ report_format("no format with name %a",name)
+ else
+ local barename=file.removesuffix(name)
+ local luaname=file.addsuffix(barename,"luc")
+ if not lfs.isfile(luaname) then
+ luaname=file.addsuffix(barename,"lua")
+ end
+ if not lfs.isfile(luaname) then
+ report_format("using format name %a",fmtname)
+ report_format("no luc/lua file with name %a",barename)
+ else
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be run, no runner available for engine %a",name,engine)
else
- local barename=file.removesuffix(name)
- local luaname=file.addsuffix(barename,"luc")
- if not lfs.isfile(luaname) then
- luaname=file.addsuffix(barename,"lua")
- end
- if not lfs.isfile(luaname) then
- report_format("using format name %a",fmtname)
- report_format("no luc/lua file with name %a",barename)
- else
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be run, no runner available for engine %a",name,engine)
- else
- runner {
- flags=primaryflags(),
- fmtfile=quoted(barename),
- luafile=quoted(luaname),
- texfile=quoted(data),
- more=more,
- }
- end
- end
+ runner {
+ flags=primaryflags(),
+ fmtfile=quoted(barename),
+ luafile=quoted(luaname),
+ texfile=quoted(data),
+ more=more,
+ }
end
+ end
end
+ end
end
end -- of closure
--- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
+-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 877962
--- stripped bytes : 317771
+-- original bytes : 994864
+-- stripped bytes : 395007
-- end library merge
@@ -21370,6 +24986,7 @@ local owntree = environment and environment.ownpath or ownpath
local ownlibs = { -- order can be made better
+ 'l-bit32.lua',
'l-lua.lua',
'l-macro.lua',
'l-sandbox.lua',
@@ -21385,6 +25002,7 @@ local ownlibs = { -- order can be made better
'l-file.lua',
'l-gzip.lua',
'l-md5.lua',
+ 'l-sha.lua',
'l-url.lua',
'l-dir.lua',
'l-boolean.lua',
@@ -21399,6 +25017,19 @@ local ownlibs = { -- order can be made better
'util-prs.lua',
'util-fmt.lua',
+ 'util-soc-imp-reset.lua',
+ 'util-soc-imp-socket.lua',
+ 'util-soc-imp-copas.lua',
+ 'util-soc-imp-ltn12.lua',
+ -- 'util-soc-imp-mbox.lua',
+ 'util-soc-imp-mime.lua',
+ 'util-soc-imp-url.lua',
+ 'util-soc-imp-headers.lua',
+ 'util-soc-imp-tp.lua',
+ 'util-soc-imp-http.lua',
+ 'util-soc-imp-ftp.lua',
+ 'util-soc-imp-smtp.lua',
+
'trac-set.lua',
'trac-log.lua',
'trac-inf.lua', -- was before trac-set
@@ -21601,9 +25232,7 @@ local helpinfo = [[
<flag name="locate"><short>locate given filename in database (default) or system (<ref name="first"/> <ref name="all"/> <ref name="detail"/>)</short></flag>
</subcategory>
<subcategory>
- <flag name="autotree"><short>use texmf tree cf. env texmfstart_tree or texmfstarttree</short></flag>
<flag name="tree" value="pathtotree"><short>use given texmf tree (default file: setuptex.tmf)</short></flag>
- <flag name="environment" value="name"><short>use given (tmf) environment file</short></flag>
<flag name="path" value="runpath"><short>go to given path before execution</short></flag>
<flag name="ifchanged" value="filename"><short>only execute when given file has changed (md checksum)</short></flag>
<flag name="iftouched" value="old,new"><short>only execute when given file has changed (time stamp)</short></flag>
@@ -21623,7 +25252,7 @@ local helpinfo = [[
</subcategory>
<subcategory>
<flag name="edit"><short>launch editor with found file</short></flag>
- <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>)</short></flag>
+ <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>,<ref name="list"/>)</short></flag>
</subcategory>
<subcategory>
<flag name="timedrun"><short>run a script and time its run</short></flag>
@@ -22022,9 +25651,9 @@ function resolvers.launch(str)
end
function runners.launch_file(filename)
- trackers.enable("resolvers.locating")
local allresults = environment.arguments["all"]
- local pattern = environment.arguments["pattern"]
+ local pattern = environment.arguments["pattern"]
+ local listonly = environment.arguments["list"]
if not pattern or pattern == "" then
pattern = filename
end
@@ -22039,14 +25668,32 @@ function runners.launch_file(filename)
t = resolvers.findfiles("*/" .. pattern .. "*",nil,allresults)
end
if t and #t > 0 then
- if allresults then
- for _, v in pairs(t) do
- report("launching %s", v)
- resolvers.launch(v)
+ for i=1,#t do
+ local name = t[i]
+ if listonly then
+ report("% 3i: %-30s %s",i,file.basename(name),file.dirname(name))
+ else
+ report("launching: %s",name)
+ resolvers.launch(name)
+ if not allresults then
+ break
+ end
+ end
+ end
+ if listonly then
+ io.write("\n")
+ io.write("\n[select number]\n\n>> ")
+ local answer = tonumber(io.read())
+ if answer then
+ io.write("\n")
+ local name = t[answer]
+ if name then
+ report("launching: %s",name)
+ resolvers.launch(name)
+ else
+ report("invalid number")
+ end
end
- else
- report("launching %s", t[1])
- resolvers.launch(t[1])
end
else
report("no match for %s", pattern)
@@ -22166,12 +25813,9 @@ function runners.execute_ctx_script(filename,...)
dofile(fullname)
local savename = environment.arguments['save']
if savename then
- local save_list = runners.save_list
- if save_list and next(save_list) then
- if type(savename) ~= "string" then savename = file.basename(fullname) end
- savename = file.replacesuffix(savename,"cfg")
- runners.save_script_session(savename,save_list)
- end
+ if type(savename) ~= "string" then savename = file.basename(fullname) end
+ savename = file.replacesuffix(savename,"cfg")
+ runners.save_script_session(savename,save_list)
end
return true
end
@@ -22188,22 +25832,22 @@ function runners.execute_ctx_script(filename,...)
local scriptbase = match(scriptname,".*mtx%-([^%-]-)%.lua")
if scriptbase then
local data = io.loaddata(scriptname)
-local application = match(data,"local application.-=.-(%{.-%})")
-if application then
- application = loadstring("return " .. application)
- if application then
- application = application()
- local banner = application.banner
- if banner then
- local description, version = match(banner,"^(.-) ([%d.]+)$")
- if description then
- valid[#valid+1] = { scriptbase, version, description }
- else
- valid[#valid+1] = { scriptbase, "", banner }
- end
- end
- end
-end
+ local application = match(data,"local application.-=.-(%{.-%})")
+ if application then
+ application = loadstring("return " .. application)
+ if application then
+ application = application()
+ local banner = application.banner
+ if banner then
+ local description, version = match(banner,"^(.-) ([%d.]+)$")
+ if description then
+ valid[#valid+1] = { scriptbase, version, description }
+ else
+ valid[#valid+1] = { scriptbase, "", banner }
+ end
+ end
+ end
+ end
end
end
if #valid > 0 then
@@ -22243,7 +25887,7 @@ function runners.timedrun(filename) -- just for me
end
function runners.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
function runners.associate(filename)
diff --git a/scripts/context/stubs/win64/metatex.exe b/scripts/context/stubs/win64/metatex.exe
deleted file mode 100644
index 93290a6e0..000000000
--- a/scripts/context/stubs/win64/metatex.exe
+++ /dev/null
Binary files differ
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index 0f4767d91..569a7f2e1 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -1,16 +1,5 @@
#!/usr/bin/env texlua
--- for k, v in next, _G.string do
--- local tv = type(v)
--- if tv == "table" then
--- for kk, vv in next, v do
--- print(k,kk,vv)
--- end
--- else
--- print(tv,k,v)
--- end
--- end
-
if not modules then modules = { } end modules ['mtxrun'] = {
version = 1.001,
comment = "runner, lua replacement for texmfstart.rb",
@@ -20,25 +9,43 @@ if not modules then modules = { } end modules ['mtxrun'] = {
}
-- one can make a stub:
+
+-- mtxrun :
--
-- #!/bin/sh
-- env LUATEXDIR=/....../texmf/scripts/context/lua luatex --luaonly mtxrun.lua "$@"
+-- mtxrun.cmd :
+--
+-- @luatex --luaonly %~d0%~p0mtxrun.lua %*
+
-- filename : mtxrun.lua
-- comment : companion to context.tex
-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
-- copyright: PRAGMA ADE / ConTeXt Development Team
-- license : see context related readme files
--- This script is based on texmfstart.rb but does not use kpsewhich to
--- locate files. Although kpse is a library it never came to opening up
--- its interface to other programs (esp scripting languages) and so we
--- do it ourselves. The lua variant evolved out of an experimental ruby
--- one. Interesting is that using a scripting language instead of c does
--- not have a speed penalty. Actually the lua variant is more efficient,
--- especially when multiple calls to kpsewhich are involved. The lua
+-- This script is based on texmfstart.rb but does not use kpsewhich to locate files.
+-- Although kpse is a library it never came to opening up its interface to other
+-- programs (esp scripting languages) and so we do it ourselves. The lua variant
+-- evolved out of an experimental ruby one. Interesting is that using a scripting
+-- language instead of c does not have a speed penalty. Actually the lua variant is
+-- more efficient, especially when multiple calls to kpsewhich are involved. The lua
-- library also gives way more control.
+-- When libraries used here are updates you can run
+--
+-- mtxrun --selfmerge
+--
+-- to update the embedded code. After that you might need to run
+--
+-- mtxrun --selfupdate
+--
+-- to copy the new script (from scripts/context/lua) to location where
+-- binaries are expected. If you want to remove the embedded code you can run
+--
+-- mtxxun --selfclean
+
-- to be done / considered
--
-- support for --exec or make it default
@@ -54,16 +61,147 @@ if not modules then modules = { } end modules ['mtxrun'] = {
do -- create closure to overcome 200 locals limit
+package.loaded["l-bit32"] = package.loaded["l-bit32"] or true
+
+-- original size: 3607, stripped down to: 3009
+
+if not modules then modules={} end modules ['l-bit32']={
+ version=1.001,
+ license="the same as regular Lua",
+ source="bitwise.lua, v 1.24 2014/12/26 17:20:53 roberto",
+ comment="drop-in for bit32, adapted a bit by Hans Hagen",
+}
+if bit32 then
+elseif utf8 then
+ load ([[
+local select = select -- instead of: arg = { ... }
+bit32 = {
+ bnot = function (a)
+ return ~a & 0xFFFFFFFF
+ end,
+ band = function (x, y, z, ...)
+ if not z then
+ return ((x or -1) & (y or -1)) & 0xFFFFFFFF
+ else
+ local res = x & y & z
+ for i=1,select("#",...) do
+ res = res & select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ bor = function (x, y, z, ...)
+ if not z then
+ return ((x or 0) | (y or 0)) & 0xFFFFFFFF
+ else
+ local res = x | y | z
+ for i=1,select("#",...) do
+ res = res | select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ bxor = function (x, y, z, ...)
+ if not z then
+ return ((x or 0) ~ (y or 0)) & 0xFFFFFFFF
+ else
+ local res = x ~ y ~ z
+ for i=1,select("#",...) do
+ res = res ~ select(i,...)
+ end
+ return res & 0xFFFFFFFF
+ end
+ end,
+ btest = function (x, y, z, ...)
+ if not z then
+ return (((x or -1) & (y or -1)) & 0xFFFFFFFF) ~= 0
+ else
+ local res = x & y & z
+ for i=1,select("#",...) do
+ res = res & select(i,...)
+ end
+ return (res & 0xFFFFFFFF) ~= 0
+ end
+ end,
+ lshift = function (a, b)
+ return ((a & 0xFFFFFFFF) << b) & 0xFFFFFFFF
+ end,
+ rshift = function (a, b)
+ return ((a & 0xFFFFFFFF) >> b) & 0xFFFFFFFF
+ end,
+ arshift = function (a, b)
+ a = a & 0xFFFFFFFF
+ if b <= 0 or (a & 0x80000000) == 0 then
+ return (a >> b) & 0xFFFFFFFF
+ else
+ return ((a >> b) | ~(0xFFFFFFFF >> b)) & 0xFFFFFFFF
+ end
+ end,
+ lrotate = function (a ,b)
+ b = b & 31
+ a = a & 0xFFFFFFFF
+ a = (a << b) | (a >> (32 - b))
+ return a & 0xFFFFFFFF
+ end,
+ rrotate = function (a, b)
+ b = -b & 31
+ a = a & 0xFFFFFFFF
+ a = (a << b) | (a >> (32 - b))
+ return a & 0xFFFFFFFF
+ end,
+ extract = function (a, f, w)
+ return (a >> f) & ~(-1 << (w or 1))
+ end,
+ replace = function (a, v, f, w)
+ local mask = ~(-1 << (w or 1))
+ return ((a & ~(mask << f)) | ((v & mask) << f)) & 0xFFFFFFFF
+ end,
+}
+ ]] ) ()
+elseif bit then
+ load ([[
+local band, bnot, rshift, lshift = bit.band, bit.bnot, bit.rshift, bit.lshift
+bit32 = {
+ arshift = bit.arshift,
+ band = band,
+ bnot = bnot,
+ bor = bit.bor,
+ bxor = bit.bxor,
+ btest = function(...)
+ return band(...) ~= 0
+ end,
+ extract = function(a,f,w)
+ return band(rshift(a,f),2^(w or 1)-1)
+ end,
+ lrotate = bit.rol,
+ lshift = lshift,
+ replace = function(a,v,f,w)
+ local mask = 2^(w or 1)-1
+ return band(a,bnot(lshift(mask,f)))+lshift(band(v,mask),f)
+ end,
+ rrotate = bit.ror,
+ rshift = rshift,
+}
+ ]] ) ()
+else
+ xpcall(function() local _,t=require("bit32") if t then bit32=t end return end,function() end)
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
package.loaded["l-lua"] = package.loaded["l-lua"] or true
--- original size: 6230, stripped down to: 3662
+-- original size: 6281, stripped down to: 2863
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+).*$")
@@ -71,122 +209,111 @@ 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
+ ffi.number=tonumber
end
-if not bit32 then
- bit32=require("l-bit32")
+if LUAVERSION>5.3 then
+ collectgarbage("generational")
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
end -- of closure
@@ -195,25 +322,27 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-macro"] = package.loaded["l-macro"] or true
--- original size: 8260, stripped down to: 5213
+-- original size: 10131, stripped down to: 5991
if not modules then modules={} end modules ['l-macros']={
- 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 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)
@@ -230,172 +359,214 @@ local definitions={}
local resolve
local subparser
local report_lua=function(...)
- if logs and logs.reporter then
- report_lua=logs.reporter("system","lua")
- report_lua(...)
- else
- print(format(...))
- end
-end
-resolve=C(C(name)*arguments^-1)/function(raw,s,a)
- local d=definitions[s]
- if d then
- if a then
- local n=#a
- local p=patterns[s][n]
- if p then
- local d=d[n]
- for i=1,n do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return lpegmatch(p,d,1,a) or d
- else
- return raw
- end
- else
- return d[0] or raw
- end
- elseif a then
- for i=1,#a do
- a[i]=lpegmatch(subparser,a[i]) or a[i]
- end
- return s.."("..concat(a,",")..")"
- else
- return raw
- end
-end
-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 n=0
+ if logs and logs.reporter then
+ report_lua=logs.reporter("system","lua")
+ report_lua(...)
+ else
+ print(format(...))
+ end
+end
+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
- n=#a
- local pattern=P(false)
+ local n=#a
+ local p=patterns[s][n]
+ if p then
+ local d=d[n]
for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- p[n]=pattern
+ return lpegmatch(p,d,1,a) or d
+ else
+ return raw
+ end
+ else
+ return d[0] or raw
end
- local d=definitions[k]
- if not d then
- d={ [0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
+ elseif a then
+ for i=1,#a do
+ a[i]=lpegmatch(subparser,a[i]) or a[i]
end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+ return s.."("..concat(a,",")..")"
+ else
+ return raw
+ end
end
-local register=(C(name)*spaces^0*(arguments+Cc(false))*spaces^0*C(body))/function(k,a,v)
- local n=0
- if a then
- n=#a
- local pattern=P(false)
- for i=1,n do
- pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
- end
- pattern=Cs((pattern+P(1))^1)
- local p=patterns[k]
- if not p then
- p={ [0]=false,false,false,false,false,false,false,false,false }
- patterns[k]=p
- end
- p[n]=pattern
- end
- local d=definitions[k]
- if not d then
- d={ [0]=false,false,false,false,false,false,false,false,false }
- definitions[k]=d
- end
- d[n]=lpegmatch(subparser,v) or v
- return ""
+subparser=Cs((resolve+P(1))^1)
+local enddefine=P("#enddefine")/""
+local beginregister=(C(name)*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v)
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ 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=(Cs(name)*(arguments+Cc(false))*spaces^0*Cs(body))/function(k,a,v)
+ local n=0
+ if a then
+ n=#a
+ local pattern=P(false)
+ for i=1,n do
+ pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end
+ end
+ pattern=Cs((pattern+P(1))^1)
+ local p=patterns[k]
+ if not p then
+ p={ [0]=false,false,false,false,false,false,false,false,false }
+ patterns[k]=p
+ end
+ p[n]=pattern
+ end
+ local d=definitions[k]
+ if not d then
+ 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 unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a)
- local n=0
- if a then
- n=#a
- local p=patterns[k]
- if p then
- p[n]=false
- end
- end
- local d=definitions[k]
- if d then
- d[n]=false
+ local n=0
+ if a then
+ n=#a
+ local p=patterns[k]
+ if p then
+ p[n]=false
end
- return ""
+ end
+ local d=definitions[k]
+ if d then
+ d[n]=false
+ end
+ return ""
end
local begindefine=(P("begindefine")*spaces^0/"")*beginregister
-local define=(P("define" )*spaces^0/"")*register
-local undefine=(P("undefine" )*spaces^0/"")*unregister
+local define=(P("define" )*spaces^0/"")*register
+local undefine=(P("undefine" )*spaces^0/"")*unregister
local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 )
function macros.reset()
- definitions={}
- patterns={}
+ definitions={}
+ patterns={}
+end
+function macros.showdefinitions()
+ 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
+ return lpegmatch(parser,str) or str
end
function macros.resolving()
- return next(patterns)
-end
-local function loaded(name,trace,detail)
- local f=io.open(name,"rb")
- if not f then
- return false,format("file '%s' not found",name)
- end
- local c=f:read("*a")
- if not c then
- return false,format("file '%s' is invalid",name)
- end
+ 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 n=lpegmatch(parser,c)
- if trace then
- if #n~=#c then
- report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
- if detail then
- report_lua()
- report_lua(n)
- report_lua()
- end
- elseif detail then
- report_lua("no macros expanded in '%s'",name)
- end
+ local f=loadfile(name)
+ os.remove(name)
+ return f
+ end
+end
+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
- if #name>30 then
- n="--[["..sub(name,-30).."]] "..n
- else
- n="--[["..name.."]] "..n
+ end
+ return load(data,name)
+end
+local function loaded(name,trace,detail)
+ local f=io.open(name,"rb")
+ if not f then
+ return false,format("file '%s' not found",name)
+ end
+ local c=f:read("*a")
+ if not c then
+ return false,format("file '%s' is invalid",name)
+ end
+ f:close()
+ local n=lpegmatch(parser,c)
+ if trace then
+ if #n~=#c then
+ report_lua("macros expanded in '%s' (%i => %i bytes)",name,#c,#n)
+ if detail then
+ report_lua()
+ report_lua(n)
+ report_lua()
+ end
+ elseif detail then
+ report_lua("no macros expanded in '%s'",name)
end
- return load(n)
+ end
+ return reload(lfs and lfs.currentdir(),name,n)
end
macros.loaded=loaded
function required(name,trace)
- local filename=file.addsuffix(name,"lua")
- local fullname=resolvers and resolvers.find_file(filename) or filename
- if not fullname or fullname=="" then
- return false
- end
- local codeblob=package.loaded[fullname]
- if codeblob then
- return codeblob
- end
- local code,message=loaded(fullname,macros,trace,trace)
- if type(code)=="function" then
- code=code()
- else
- report_lua("error when loading '%s'",fullname)
- return false,message
- end
- if code==nil then
- code=false
- end
- package.loaded[fullname]=code
- return code
+ local filename=file.addsuffix(name,"lua")
+ local fullname=resolvers and resolvers.find_file(filename) or filename
+ if not fullname or fullname=="" then
+ return false
+ end
+ local codeblob=package.loaded[fullname]
+ if codeblob then
+ return codeblob
+ end
+ local code,message=loaded(fullname,macros,trace,trace)
+ if type(code)=="function" then
+ code=code()
+ else
+ report_lua("error when loading '%s'",fullname)
+ return false,message
+ end
+ if code==nil then
+ code=false
+ end
+ package.loaded[fullname]=code
+ return code
end
macros.required=required
@@ -406,14 +577,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
--- original size: 9678, stripped down to: 6688
+-- original size: 9747, stripped down to: 6313
if not modules then modules={} end modules ['l-sandbox']={
- 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 global=_G
local next=next
@@ -439,231 +610,234 @@ local trace=false
local logger=false
local blocked={}
local function report(...)
- tprint("sandbox ! "..format(...))
+ tprint("sandbox ! "..format(...))
end
sandbox.report=report
function sandbox.setreporter(r)
- report=r
- sandbox.report=r
+ report=r
+ sandbox.report=r
end
function sandbox.settrace(v)
- trace=v
+ trace=v
end
function sandbox.setlogger(l)
- logger=type(l)=="function" and l or false
+ logger=type(l)=="function" and l or false
end
local function register(func,overload,comment)
- if type(func)=="function" then
- if type(overload)=="string" then
- comment=overload
- overload=nil
- end
- local function f(...)
- if sandboxed then
- local overload=overloads[f]
- if overload then
- if logger then
- local result={ overload(func,...) }
- logger {
- comment=comments[f] or tostring(f),
- arguments={... },
- result=result[1] and true or false,
- }
- return unpack(result)
- else
- return overload(func,...)
- end
- else
- end
- else
- return func(...)
- end
- end
- if comment then
- comments[f]=comment
- if trace then
- report("registering function: %s",comment)
- end
+ if type(func)=="function" then
+ if type(overload)=="string" then
+ comment=overload
+ overload=nil
+ end
+ local function f(...)
+ if sandboxed then
+ local overload=overloads[f]
+ if overload then
+ if logger then
+ local result={ overload(func,...) }
+ logger {
+ comment=comments[f] or tostring(f),
+ arguments={... },
+ result=result[1] and true or false,
+ }
+ return unpack(result)
+ else
+ return overload(func,...)
+ end
+ else
end
- overloads[f]=overload or false
- originals[f]=func
- return f
+ else
+ return func(...)
+ end
end
+ if comment then
+ comments[f]=comment
+ if trace then
+ report("registering function: %s",comment)
+ end
+ end
+ overloads[f]=overload or false
+ originals[f]=func
+ return f
+ end
end
local function redefine(func,comment)
- if type(func)=="function" then
- skiploads[func]=comment or comments[func] or "unknown"
- if overloads[func]==false then
- overloads[func]=nil
- end
+ if type(func)=="function" then
+ skiploads[func]=comment or comments[func] or "unknown"
+ if overloads[func]==false then
+ overloads[func]=nil
end
+ end
end
sandbox.register=register
sandbox.redefine=redefine
function sandbox.original(func)
- return originals and originals[func] or func
+ return originals and originals[func] or func
end
function sandbox.overload(func,overload,comment)
- comment=comment or comments[func] or "?"
- if type(func)~="function" then
- if trace then
- report("overloading unknown function: %s",comment)
- end
- elseif type(overload)~="function" then
- if trace then
- report("overloading function with bad overload: %s",comment)
- end
- elseif overloads[func]==nil then
- if trace then
- report("function is not registered: %s",comment)
- end
- elseif skiploads[func] then
- if trace then
- report("function is not skipped: %s",comment)
- end
- else
- if trace then
- report("overloading function: %s",comment)
- end
- overloads[func]=overload
+ comment=comment or comments[func] or "?"
+ if type(func)~="function" then
+ if trace then
+ report("overloading unknown function: %s",comment)
+ end
+ elseif type(overload)~="function" then
+ if trace then
+ report("overloading function with bad overload: %s",comment)
+ end
+ elseif overloads[func]==nil then
+ if trace then
+ report("function is not registered: %s",comment)
+ end
+ elseif skiploads[func] then
+ if trace then
+ report("function is not skipped: %s",comment)
end
- return func
+ else
+ if trace then
+ report("overloading function: %s",comment)
+ end
+ overloads[func]=overload
+ end
+ return func
end
local function whatever(specification,what,target)
- if type(specification)~="table" then
- report("%s needs a specification",what)
- elseif type(specification.category)~="string" or type(specification.action)~="function" then
- report("%s needs a category and action",what)
- elseif not sandboxed then
- target[#target+1]=specification
- elseif trace then
- report("already enabled, discarding %s",what)
- end
+ if type(specification)~="table" then
+ report("%s needs a specification",what)
+ elseif type(specification.category)~="string" or type(specification.action)~="function" then
+ report("%s needs a category and action",what)
+ elseif not sandboxed then
+ target[#target+1]=specification
+ elseif trace then
+ report("already enabled, discarding %s",what)
+ end
end
function sandbox.initializer(specification)
- whatever(specification,"initializer",initializers)
+ whatever(specification,"initializer",initializers)
end
function sandbox.finalizer(specification)
- whatever(specification,"finalizer",finalizers)
+ whatever(specification,"finalizer",finalizers)
end
function require(name)
- local n=gsub(name,"^.*[\\/]","")
- local n=gsub(n,"[%.].*$","")
- local b=blocked[n]
- if b==false then
- return nil
- elseif b then
- if trace then
- report("using blocked: %s",n)
- end
- return b
- else
- if trace then
- report("requiring: %s",name)
- end
- return requiem(name)
+ local n=gsub(name,"^.*[\\/]","")
+ local n=gsub(n,"[%.].*$","")
+ local b=blocked[n]
+ if b==false then
+ return nil
+ elseif b then
+ if trace then
+ report("using blocked: %s",n)
end
-end
-function blockrequire(name,lib)
+ return b
+ else
if trace then
- report("preventing reload of: %s",name)
+ report("requiring: %s",name)
end
- blocked[name]=lib or _G[name] or false
+ return requiem(name)
+ end
+end
+function blockrequire(name,lib)
+ if trace then
+ report("preventing reload of: %s",name)
+ end
+ blocked[name]=lib or _G[name] or false
end
function sandbox.enable()
- if not sandboxed then
- for i=1,#initializers do
- initializers[i].action()
- end
- for i=1,#finalizers do
- finalizers[i].action()
- end
- local nnot=0
- local nyes=0
- local cnot={}
- local cyes={}
- local skip={}
- for k,v in next,overloads do
- local c=comments[k]
- if v then
- if c then
- cyes[#cyes+1]=c
- else
- nyes=nyes+1
- end
- else
- if c then
- cnot[#cnot+1]=c
- else
- nnot=nnot+1
- end
- end
- end
- for k,v in next,skiploads do
- skip[#skip+1]=v
- end
- if #cyes>0 then
- sort(cyes)
- report("overloaded known: %s",concat(cyes," | "))
- end
- if nyes>0 then
- report("overloaded unknown: %s",nyes)
- end
- if #cnot>0 then
- sort(cnot)
- report("not overloaded known: %s",concat(cnot," | "))
- end
- if nnot>0 then
- report("not overloaded unknown: %s",nnot)
+ if not sandboxed then
+ debug={
+ traceback=debug.traceback,
+ }
+ for i=1,#initializers do
+ initializers[i].action()
+ end
+ for i=1,#finalizers do
+ finalizers[i].action()
+ end
+ local nnot=0
+ local nyes=0
+ local cnot={}
+ local cyes={}
+ local skip={}
+ for k,v in next,overloads do
+ local c=comments[k]
+ if v then
+ if c then
+ cyes[#cyes+1]=c
+ else
+ nyes=nyes+1
end
- if #skip>0 then
- sort(skip)
- report("not overloaded redefined: %s",concat(skip," | "))
+ else
+ if c then
+ cnot[#cnot+1]=c
+ else
+ nnot=nnot+1
end
- initializers=nil
- finalizers=nil
- originals=nil
- sandboxed=true
+ end
+ end
+ for k,v in next,skiploads do
+ skip[#skip+1]=v
+ end
+ if #cyes>0 then
+ sort(cyes)
+ report("overloaded known: %s",concat(cyes," | "))
+ end
+ if nyes>0 then
+ report("overloaded unknown: %s",nyes)
end
+ if #cnot>0 then
+ sort(cnot)
+ report("not overloaded known: %s",concat(cnot," | "))
+ end
+ if nnot>0 then
+ report("not overloaded unknown: %s",nnot)
+ end
+ if #skip>0 then
+ sort(skip)
+ report("not overloaded redefined: %s",concat(skip," | "))
+ end
+ initializers=nil
+ finalizers=nil
+ originals=nil
+ sandboxed=true
+ end
end
blockrequire("lfs",lfs)
blockrequire("io",io)
blockrequire("os",os)
blockrequire("ffi",ffi)
local function supported(library)
- local l=_G[library]
- return l
+ local l=_G[library]
+ return l
end
loadfile=register(loadfile,"loadfile")
if supported("io") then
- io.open=register(io.open,"io.open")
- io.popen=register(io.popen,"io.popen")
- io.lines=register(io.lines,"io.lines")
- io.output=register(io.output,"io.output")
- io.input=register(io.input,"io.input")
+ io.open=register(io.open,"io.open")
+ io.popen=register(io.popen,"io.popen")
+ io.lines=register(io.lines,"io.lines")
+ io.output=register(io.output,"io.output")
+ io.input=register(io.input,"io.input")
end
if supported("os") then
- os.execute=register(os.execute,"os.execute")
- os.spawn=register(os.spawn,"os.spawn")
- os.exec=register(os.exec,"os.exec")
- os.rename=register(os.rename,"os.rename")
- os.remove=register(os.remove,"os.remove")
+ os.execute=register(os.execute,"os.execute")
+ os.spawn=register(os.spawn,"os.spawn")
+ os.exec=register(os.exec,"os.exec")
+ os.rename=register(os.rename,"os.rename")
+ os.remove=register(os.remove,"os.remove")
end
if supported("lfs") then
- lfs.chdir=register(lfs.chdir,"lfs.chdir")
- lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
- lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
- lfs.isfile=register(lfs.isfile,"lfs.isfile")
- lfs.isdir=register(lfs.isdir,"lfs.isdir")
- lfs.attributes=register(lfs.attributes,"lfs.attributes")
- lfs.dir=register(lfs.dir,"lfs.dir")
- lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
- lfs.touch=register(lfs.touch,"lfs.touch")
- lfs.link=register(lfs.link,"lfs.link")
- lfs.setmode=register(lfs.setmode,"lfs.setmode")
- lfs.readlink=register(lfs.readlink,"lfs.readlink")
- lfs.shortname=register(lfs.shortname,"lfs.shortname")
- lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
+ lfs.chdir=register(lfs.chdir,"lfs.chdir")
+ lfs.mkdir=register(lfs.mkdir,"lfs.mkdir")
+ lfs.rmdir=register(lfs.rmdir,"lfs.rmdir")
+ lfs.isfile=register(lfs.isfile,"lfs.isfile")
+ lfs.isdir=register(lfs.isdir,"lfs.isdir")
+ lfs.attributes=register(lfs.attributes,"lfs.attributes")
+ lfs.dir=register(lfs.dir,"lfs.dir")
+ lfs.lock_dir=register(lfs.lock_dir,"lfs.lock_dir")
+ lfs.touch=register(lfs.touch,"lfs.touch")
+ lfs.link=register(lfs.link,"lfs.link")
+ lfs.setmode=register(lfs.setmode,"lfs.setmode")
+ lfs.readlink=register(lfs.readlink,"lfs.readlink")
+ lfs.shortname=register(lfs.shortname,"lfs.shortname")
+ lfs.symlinkattributes=register(lfs.symlinkattributes,"lfs.symlinkattributes")
end
@@ -673,14 +847,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-package"] = package.loaded["l-package"] or true
--- original size: 11562, stripped down to: 8625
+-- original size: 11605, stripped down to: 8299
if not modules then modules={} end modules ['l-package']={
- 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=type
local gsub,format,find=string.gsub,string.format,string.find
@@ -688,40 +862,40 @@ local insert,remove=table.insert,table.remove
local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match
local package=package
local searchers=package.searchers or package.loaders
-local filejoin=file and file.join or function(path,name) return path.."/"..name end
-local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
-local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
+local filejoin=file and file.join or function(path,name) return path.."/"..name end
+local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end
+local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end
local function cleanpath(path)
- return path
+ return path
end
local pattern=Cs((((1-S("\\/"))^0*(S("\\/")^1/"/"))^0*(P(".")^1/"/"+P(1))^1)*-1)
local function lualibfile(name)
- return lpegmatch(pattern,name) or name
+ return lpegmatch(pattern,name) or name
end
local offset=luarocks and 1 or 0
local helpers=package.helpers or {
- cleanpath=cleanpath,
- lualibfile=lualibfile,
- trace=false,
- report=function(...) print(format(...)) end,
- builtin={
- ["preload table"]=searchers[1+offset],
- ["path specification"]=searchers[2+offset],
- ["cpath specification"]=searchers[3+offset],
- ["all in one fallback"]=searchers[4+offset],
- },
- methods={},
- sequence={
- "already loaded",
- "preload table",
- "qualified path",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
- }
+ cleanpath=cleanpath,
+ lualibfile=lualibfile,
+ trace=false,
+ report=function(...) print(format(...)) end,
+ builtin={
+ ["preload table"]=searchers[1+offset],
+ ["path specification"]=searchers[2+offset],
+ ["cpath specification"]=searchers[3+offset],
+ ["all in one fallback"]=searchers[4+offset],
+ },
+ methods={},
+ sequence={
+ "already loaded",
+ "preload table",
+ "qualified path",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
}
package.helpers=helpers
local methods=helpers.methods
@@ -737,253 +911,256 @@ local nofextralib=-1
local nofpathlua=-1
local nofpathlib=-1
local function listpaths(what,paths)
- local nofpaths=#paths
- if nofpaths>0 then
- for i=1,nofpaths do
- helpers.report("using %s path %i: %s",what,i,paths[i])
- end
- else
- helpers.report("no %s paths defined",what)
+ local nofpaths=#paths
+ if nofpaths>0 then
+ for i=1,nofpaths do
+ helpers.report("using %s path %i: %s",what,i,paths[i])
end
- return nofpaths
+ else
+ helpers.report("no %s paths defined",what)
+ end
+ return nofpaths
end
local function getextraluapaths()
- if helpers.trace and #extraluapaths~=nofextralua then
- nofextralua=listpaths("extra lua",extraluapaths)
- end
- return extraluapaths
+ if helpers.trace and #extraluapaths~=nofextralua then
+ nofextralua=listpaths("extra lua",extraluapaths)
+ end
+ return extraluapaths
end
local function getextralibpaths()
- if helpers.trace and #extralibpaths~=nofextralib then
- nofextralib=listpaths("extra lib",extralibpaths)
- end
- return extralibpaths
+ if helpers.trace and #extralibpaths~=nofextralib then
+ nofextralib=listpaths("extra lib",extralibpaths)
+ end
+ return extralibpaths
end
local function getluapaths()
- local luapath=package.path or ""
- if oldluapath~=luapath then
- luapaths=file.splitpath(luapath,";")
- oldluapath=luapath
- nofpathlua=-1
- end
- if helpers.trace and #luapaths~=nofpathlua then
- nofpathlua=listpaths("builtin lua",luapaths)
- end
- return luapaths
+ local luapath=package.path or ""
+ if oldluapath~=luapath then
+ luapaths=file.splitpath(luapath,";")
+ oldluapath=luapath
+ nofpathlua=-1
+ end
+ if helpers.trace and #luapaths~=nofpathlua then
+ nofpathlua=listpaths("builtin lua",luapaths)
+ end
+ return luapaths
end
local function getlibpaths()
- local libpath=package.cpath or ""
- if oldlibpath~=libpath then
- libpaths=file.splitpath(libpath,";")
- oldlibpath=libpath
- nofpathlib=-1
- end
- if helpers.trace and #libpaths~=nofpathlib then
- nofpathlib=listpaths("builtin lib",libpaths)
- end
- return libpaths
+ local libpath=package.cpath or ""
+ if oldlibpath~=libpath then
+ libpaths=file.splitpath(libpath,";")
+ oldlibpath=libpath
+ nofpathlib=-1
+ end
+ if helpers.trace and #libpaths~=nofpathlib then
+ nofpathlib=listpaths("builtin lib",libpaths)
+ end
+ return libpaths
end
package.luapaths=getluapaths
package.libpaths=getlibpaths
package.extraluapaths=getextraluapaths
package.extralibpaths=getextralibpaths
local hashes={
- lua={},
- lib={},
+ lua={},
+ lib={},
}
local function registerpath(tag,what,target,...)
- local pathlist={... }
- local cleanpath=helpers.cleanpath
- local trace=helpers.trace
- local report=helpers.report
- local hash=hashes[what]
- local function add(path)
- local path=cleanpath(path)
- if not hash[path] then
- target[#target+1]=path
- hash[path]=true
- if trace then
- report("registered %s path %s: %s",tag,#target,path)
- end
- else
- if trace then
- report("duplicate %s path: %s",tag,path)
- end
- end
+ local pathlist={... }
+ local cleanpath=helpers.cleanpath
+ local trace=helpers.trace
+ local report=helpers.report
+ local hash=hashes[what]
+ local function add(path)
+ local path=cleanpath(path)
+ if not hash[path] then
+ target[#target+1]=path
+ hash[path]=true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
end
- for p=1,#pathlist do
- local path=pathlist[p]
- if type(path)=="table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
+ end
+ for p=1,#pathlist do
+ local path=pathlist[p]
+ if type(path)=="table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
end
+ end
end
local function pushpath(tag,what,target,path)
- local path=helpers.cleanpath(path)
- insert(target,1,path)
- if helpers.trace then
- helpers.report("pushing %s path in front: %s",tag,path)
- end
+ local path=helpers.cleanpath(path)
+ insert(target,1,path)
+ if helpers.trace then
+ helpers.report("pushing %s path in front: %s",tag,path)
+ end
end
local function poppath(tag,what,target)
- local path=remove(target,1)
- if helpers.trace then
- if path then
- helpers.report("popping %s path from front: %s",tag,path)
- else
- helpers.report("no %s path to pop",tag)
- end
+ local path=remove(target,1)
+ if helpers.trace then
+ if path then
+ helpers.report("popping %s path from front: %s",tag,path)
+ else
+ helpers.report("no %s path to pop",tag)
end
+ end
end
helpers.registerpath=registerpath
function package.extraluapath(...)
- registerpath("extra lua","lua",extraluapaths,...)
+ registerpath("extra lua","lua",extraluapaths,...)
end
function package.pushluapath(path)
- pushpath("extra lua","lua",extraluapaths,path)
+ pushpath("extra lua","lua",extraluapaths,path)
end
function package.popluapath()
- poppath("extra lua","lua",extraluapaths)
+ poppath("extra lua","lua",extraluapaths)
end
function package.extralibpath(...)
- registerpath("extra lib","lib",extralibpaths,...)
+ registerpath("extra lib","lib",extralibpaths,...)
end
function package.pushlibpath(path)
- pushpath("extra lib","lib",extralibpaths,path)
+ pushpath("extra lib","lib",extralibpaths,path)
end
function package.poplibpath()
- poppath("extra lib","lua",extralibpaths)
+ poppath("extra lib","lua",extralibpaths)
end
local function loadedaslib(resolved,rawname)
- local base=gsub(rawname,"%.","_")
- local init="luaopen_"..gsub(base,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
+ local base=gsub(rawname,"%.","_")
+ local init="luaopen_"..gsub(base,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
end
helpers.loadedaslib=loadedaslib
local function loadedbypath(name,rawname,paths,islib,what)
- local trace=helpers.trace
- for p=1,#paths do
- local path=paths[p]
- local resolved=filejoin(path,name)
- if trace then
- helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
- end
- if isreadable(resolved) then
- if trace then
- helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ for p=1,#paths do
+ local path=paths[p]
+ local resolved=filejoin(path,name)
+ if trace then
+ helpers.report("%s path, identifying '%s' on '%s'",what,name,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ helpers.report("%s path, '%s' found on '%s'",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbypath=loadedbypath
local function loadedbyname(name,rawname)
- if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
- local trace=helpers.trace
- if trace then
- helpers.report("qualified name, identifying '%s'",what,name)
- end
- if isreadable(name) then
- if trace then
- helpers.report("qualified name, '%s' found",what,name)
- end
- return loadfile(name)
- end
+ if find(name,"^/") or find(name,"^[a-zA-Z]:/") then
+ local trace=helpers.trace
+ if trace then
+ helpers.report("qualified name, identifying '%s'",what,name)
+ end
+ if isreadable(name) then
+ if trace then
+ helpers.report("qualified name, '%s' found",what,name)
+ end
+ return loadfile(name)
end
+ end
end
helpers.loadedbyname=loadedbyname
methods["already loaded"]=function(name)
- return package.loaded[name]
+ return package.loaded[name]
end
methods["preload table"]=function(name)
- return builtin["preload table"](name)
+ return builtin["preload table"](name)
end
methods["qualified path"]=function(name)
- return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
+ return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
end
methods["lua extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
+ return loadedbypath(addsuffix(lualibfile(name),"lua"),name,getextraluapaths(),false,"lua")
end
methods["lib extra list"]=function(name)
- return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
+ return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
end
methods["path specification"]=function(name)
- getluapaths()
- return builtin["path specification"](name)
+ getluapaths()
+ return builtin["path specification"](name)
end
methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
+ getlibpaths()
+ return builtin["cpath specification"](name)
end
methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+ return builtin["all in one fallback"](name)
end
methods["not loaded"]=function(name)
- if helpers.trace then
- helpers.report("unable to locate '%s'",name or "?")
- end
- return nil
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name or "?")
+ end
+ return nil
end
local level=0
local used={}
helpers.traceused=false
function helpers.loaded(name)
- local sequence=helpers.sequence
- level=level+1
- for i=1,#sequence do
- local method=sequence[i]
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
- end
- local result,rest=methods[method](name)
- if type(result)=="function" then
- if helpers.trace then
- helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
- end
- if helpers.traceused then
- used[#used+1]={ level=level,name=name }
- end
- level=level-1
- return result,rest
- end
+ local sequence=helpers.sequence
+ level=level+1
+ for i=1,#sequence do
+ local method=sequence[i]
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name)
end
- level=level-1
- return nil
+ local result,rest=methods[method](name)
+ if type(result)=="function" then
+ if helpers.trace then
+ helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name)
+ end
+ if helpers.traceused then
+ used[#used+1]={ level=level,name=name }
+ end
+ level=level-1
+ return result,rest
+ end
+ end
+ level=level-1
+ return nil
end
function helpers.showused()
- local n=#used
- if n>0 then
- helpers.report("%s libraries loaded:",n)
- helpers.report()
- for i=1,n do
- local u=used[i]
- helpers.report("%i %a",u.level,u.name)
- end
- helpers.report()
- end
+ local n=#used
+ if n>0 then
+ helpers.report("%s libraries loaded:",n)
+ helpers.report()
+ for i=1,n do
+ local u=used[i]
+ helpers.report("%i %a",u.level,u.name)
+ end
+ helpers.report()
+ end
end
function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading, name '%s', %s",name,"done")
- else
- helpers.report("unloading, name '%s', %s",name,"not loaded")
- end
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading, name '%s', %s",name,"done")
+ else
+ helpers.report("unloading, name '%s', %s",name,"not loaded")
end
- package.loaded[name]=nil
+ end
+ package.loaded[name]=nil
end
table.insert(searchers,1,helpers.loaded)
+if context then
+ package.path=""
+end
end -- of closure
@@ -992,14 +1169,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38582, stripped down to: 20518
+-- original size: 38434, stripped down to: 19310
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
@@ -1010,7 +1187,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
@@ -1033,7 +1210,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('"')
@@ -1042,9 +1219,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")
@@ -1076,7 +1253,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
@@ -1085,15 +1262,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
@@ -1150,7 +1327,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
@@ -1160,76 +1337,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("")
@@ -1239,505 +1424,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
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
+ 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
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ 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
+ 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
- pattern=(1-pattern)^0*pattern
+ for i=1,#lst do
+ pattern=pattern+P(lst[i])
+ end
end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- end
- else
- return pattern
+ 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
+ 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
- return p
+ 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
+ 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
- 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
+ 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
- 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
+ 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
- return (insensitive and make2 or make1)(tree)
+ 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
+ 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
@@ -1756,32 +1899,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
@@ -1791,14 +1949,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-function"] = package.loaded["l-function"] or true
--- original size: 361, stripped down to: 322
+-- original size: 361, stripped down to: 317
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
@@ -1810,14 +1968,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-string"] = package.loaded["l-string"] or true
--- original size: 6461, stripped down to: 3341
+-- original size: 6461, stripped down to: 3255
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
@@ -1825,25 +1983,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
@@ -1851,81 +2009,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
@@ -1935,166 +2093,172 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 40197, stripped down to: 23561
+-- original size: 41298, stripped down to: 21498
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 a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
end
- return tostring(a)<tostring(b)
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
+ end
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt={}
+ local category=0
+ local s=0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- 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)=="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
@@ -2102,907 +2266,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 n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ 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 n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ if not t then
+ t={}
+ end
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp={}
+ local ntmp=0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
+ end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
+ if not tables then
+ tables={}
+ end
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh={}
+ local h=0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- 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
+ 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
- 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 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"))
- else
- handle(format("%s{",depth))
- end
+ 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
- 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
- end
- if last>0 then
- first=1
- 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
- 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
+ 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
- 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
+ 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 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
+ elseif k=="__p__" then
+ if false then
+ handle(format("%s __p__=nil,",depth))
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 {")
+ 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(name.."={")
+ handle(format("%s [%q]=%q,",depth,k,v))
end
- elseif tname=="number" then
- if hexify then
- handle(format("[0x%X]={",name))
+ 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
- handle("["..name.."]={")
+ do_serialize(v,k,depth,level+1)
end
- elseif tname=="boolean" then
- if name then
- handle("return {")
+ 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("{")
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
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
+ 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
+ handle(format("%s [%q]=load(%q),",depth,k,f))
+ end
+ end
end
- if next(root)~=nil then
- do_serialize(root,name,"",0)
+ 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
- handle("}")
+ end
+ if level>0 then
+ handle(format("%s},",depth))
+ end
end
-function table.serialize(root,name,specification)
- local t,n={},0
- local function flush(s)
- n=n+1
- t[n]=s
+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
+ 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
+ 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
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- serialize(flush,root,name,specification)
- return concat(t,"\n")
+ end
+ handle("}")
+end
+function table.serialize(root,name,specification)
+ 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)
+ 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
- f:close()
- io.flush()
+ 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
+ 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
- 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
+ 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
+ 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
- return f
+ 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
- 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
+ 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 ""
+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
- local n=#t
- local s={}
- if n>0 then
- for i=1,n do
- s[i]=tostring(t[i])
+ 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 n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ 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 n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
- else
- return nothing
+ end
+ return kv,s
+ else
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
@@ -3012,14 +3213,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11823, stripped down to: 6945
+-- original size: 11823, stripped down to: 6325
if not modules then modules={} end modules ['l-io']={
- 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 io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -3027,334 +3228,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 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
- f:close()
- flush()
+ if data then
+ g:write(data)
+ end
+ 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
+ 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
+ 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
+ [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
@@ -3364,14 +3565,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-number"] = package.loaded["l-number"] or true
--- original size: 5645, stripped down to: 2253
+-- original size: 5720, stripped down to: 2176
if not modules then modules={} end modules ['l-number']={
- 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 tostring,tonumber=tostring,tonumber
local format,floor,match,rep=string.format,math.floor,string.match,string.rep
@@ -3381,99 +3582,107 @@ local floor=math.floor
number=number or {}
local number=number
if bit32 then
- local bextract=bit32.extract
- local t={
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- "0","0","0","0","0","0","0","0",
- }
- function number.tobitstring(b,m)
- local n=32
- for i=0,31 do
- local v=bextract(b,i)
- local k=32-i
- if v==1 then
- n=k
- t[k]="1"
- else
- t[k]="0"
- end
- end
- if m then
- m=33-m*8
- if m<1 then
- m=1
- end
- return concat(t,"",m)
- elseif n<8 then
- return concat(t)
- elseif n<16 then
- return concat(t,"",9)
- elseif n<24 then
- return concat(t,"",17)
- else
- return concat(t,"",25)
- end
+ local bextract=bit32.extract
+ local t={
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ "0","0","0","0","0","0","0","0",
+ }
+ 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=w-i
+ if v==1 then
+ n=k
+ t[k]="1"
+ else
+ t[k]="0"
+ end
+ end
+ 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,"",1,m)
+ elseif n<8 then
+ return concat(t)
+ elseif n<16 then
+ return concat(t,"",9)
+ elseif n<24 then
+ return concat(t,"",17)
+ else
+ return concat(t,"",25)
end
+ end
else
- function number.tobitstring(n,m)
- if n>0 then
- local t={}
- while n>0 do
- insert(t,1,n%2>0 and 1 or 0)
- n=floor(n/2)
- end
- local nn=8-#t%8
- if nn>0 and nn<8 then
- for i=1,nn do
- insert(t,1,0)
- end
- end
- if m then
- m=m*8-#t
- if m>0 then
- insert(t,1,rep("0",m))
- end
- end
- return concat(t)
- elseif m then
- rep("00000000",m)
- else
- return "00000000"
+ function number.tobitstring(n,m)
+ if n>0 then
+ local t={}
+ while n>0 do
+ insert(t,1,n%2>0 and 1 or 0)
+ n=floor(n/2)
+ end
+ local nn=8-#t%8
+ if nn>0 and nn<8 then
+ for i=1,nn do
+ insert(t,1,0)
+ end
+ end
+ if m then
+ m=m*8-#t
+ if m>0 then
+ insert(t,1,rep("0",m))
end
+ end
+ return concat(t)
+ elseif m then
+ rep("00000000",m)
+ else
+ return "00000000"
end
+ end
end
function number.valid(str,default)
- return tonumber(str) or default or nil
+ return tonumber(str) or default or nil
end
function number.toevenhex(n)
- local s=format("%X",n)
- if #s%2==0 then
- return s
- else
- return "0"..s
- end
+ local s=format("%X",n)
+ if #s%2==0 then
+ return s
+ else
+ return "0"..s
+ end
end
function number.bytetodecimal(b)
- local d=floor(b*100/255+0.5)
- if d>100 then
- return 100
- elseif d<-100 then
- return -100
- else
- return d
- end
+ local d=floor(b*100/255+0.5)
+ if d>100 then
+ return 100
+ elseif d<-100 then
+ return -100
+ else
+ return d
+ end
end
function number.decimaltobyte(d)
- local b=floor(d*255/100+0.5)
- if b>255 then
- return 255
- elseif b<-255 then
- return -255
- else
- return b
- end
+ local b=floor(d*255/100+0.5)
+ if b>255 then
+ return 255
+ elseif b<-255 then
+ return -255
+ else
+ return b
+ end
+end
+function number.idiv(i,d)
+ return floor(i/d)
end
@@ -3483,14 +3692,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-set"] = package.loaded["l-set"] or true
--- original size: 1923, stripped down to: 1133
+-- original size: 1923, stripped down to: 1044
if not modules then modules={} end modules ['l-set']={
- 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"
}
set=set or {}
local nums={}
@@ -3499,54 +3708,54 @@ local concat=table.concat
local next,type=next,type
set.create=table.tohash
function set.tonumber(t)
- if next(t) then
- local s=""
- for k,v in next,t do
- if v then
- s=s.." "..k
- end
- end
- local n=nums[s]
- if not n then
- n=#tabs+1
- tabs[n]=t
- nums[s]=n
- end
- return n
- else
- return 0
+ if next(t) then
+ local s=""
+ for k,v in next,t do
+ if v then
+ s=s.." "..k
+ end
end
+ local n=nums[s]
+ if not n then
+ n=#tabs+1
+ tabs[n]=t
+ nums[s]=n
+ end
+ return n
+ else
+ return 0
+ end
end
function set.totable(n)
- if n==0 then
- return {}
- else
- return tabs[n] or {}
- end
+ if n==0 then
+ return {}
+ else
+ return tabs[n] or {}
+ end
end
function set.tolist(n)
- if n==0 or not tabs[n] then
- return ""
- else
- local t,n={},0
- for k,v in next,tabs[n] do
- if v then
- n=n+1
- t[n]=k
- end
- end
- return concat(t," ")
+ if n==0 or not tabs[n] then
+ return ""
+ else
+ local t,n={},0
+ for k,v in next,tabs[n] do
+ if v then
+ n=n+1
+ t[n]=k
+ end
end
+ return concat(t," ")
+ end
end
function set.contains(n,s)
- if type(n)=="table" then
- return n[s]
- elseif n==0 then
- return false
- else
- local t=tabs[n]
- return t and t[s]
- end
+ if type(n)=="table" then
+ return n[s]
+ elseif n==0 then
+ return false
+ else
+ local t=tabs[n]
+ return t and t[s]
+ end
end
@@ -3556,14 +3765,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-os"] = package.loaded["l-os"] or true
--- original size: 16268, stripped down to: 9246
+-- original size: 19347, stripped down to: 10258
if not modules then modules={} end modules ['l-os']={
- 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 os=os
local date,time=os.date,os.time
@@ -3571,357 +3780,434 @@ local find,format,gsub,upper,gmatch=string.find,string.format,string.gsub,string
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
-math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
-randomseed(math.initialseed)
-if not os.__getenv__ then
- os.__getenv__=os.getenv
- os.__setenv__=os.setenv
- if os.env then
- local osgetenv=os.getenv
- local ossetenv=os.setenv
- local osenv=os.env local _=osenv.PATH
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- if type(v)=="table" then
- v=concat(v,";")
- end
- ossetenv(K,v)
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
- end
+do
+ local selfdir=os.selfdir
+ if selfdir=="" then
+ selfdir=nil
+ end
+ if not selfdir then
+ if arg then
+ for i=1,#arg do
+ local a=arg[i]
+ if find(a,"^%-%-[c:]*texmfbinpath=") then
+ selfdir=gsub(a,"^.-=","")
+ break
end
- else
- local ossetenv=os.setenv
- local osgetenv=os.getenv
- local osenv={}
- function os.setenv(k,v)
- if v==nil then
- v=""
- end
- local K=upper(k)
- osenv[K]=v
- end
- function os.getenv(k)
- local K=upper(k)
- local v=osenv[K] or osgetenv(K) or osgetenv(k)
- if v=="" then
- return nil
- else
- return v
+ 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
+ local attributes=lfs.attributes
+ isfile=function(name)
+ local a=attributes(name,"mode")
+ return a=="file" or a=="link" or nil
+ end
+ else
+ local open=io.open
+ isfile=function(name)
+ local f=open(name)
+ if f then
+ f:close()
+ return true
end
+ end
end
- local function __index(t,k)
- return os.getenv(k)
- end
- local function __newindex(t,k,v)
- os.setenv(k,v)
+ for p in gmatch(path,patt) do
+ if isfile(p.."/"..name) then
+ selfdir=p
+ break
+ end
end
- os.env={}
- setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
+ os.selfdir=selfdir or "."
+ end
+end
+math.initialseed=tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
+randomseed(math.initialseed)
+if not os.__getenv__ then
+ os.__getenv__=os.getenv
+ os.__setenv__=os.setenv
+ if os.env then
+ local osgetenv=os.getenv
+ local ossetenv=os.setenv
+ local osenv=os.env local _=osenv.PATH
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ if type(v)=="table" then
+ v=concat(v,";")
+ end
+ ossetenv(K,v)
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osenv[k] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ else
+ local ossetenv=os.setenv
+ local osgetenv=os.getenv
+ local osenv={}
+ function os.setenv(k,v)
+ if v==nil then
+ v=""
+ end
+ local K=upper(k)
+ osenv[K]=v
+ end
+ function os.getenv(k)
+ local K=upper(k)
+ local v=osenv[K] or osgetenv(K) or osgetenv(k)
+ if v=="" then
+ return nil
+ else
+ return v
+ end
+ end
+ local function __index(t,k)
+ return os.getenv(k)
+ end
+ local function __newindex(t,k,v)
+ os.setenv(k,v)
+ end
+ os.env={}
+ setmetatable(os.env,{ __index=__index,__newindex=__newindex } )
+ end
end
local execute=os.execute
local iopopen=io.popen
local function resultof(command)
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- else
- return ""
- end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ else
+ return ""
+ end
end
os.resultof=resultof
function os.pipeto(command)
- return iopopen(command,"w")
+ return iopopen(command,"w")
end
if not io.fileseparator then
- if find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
- else
- io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
- end
+ if find(os.getenv("PATH"),";",1,true) then
+ io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "windows"
+ else
+ io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix"
+ end
end
os.type=os.type or (io.pathseparator==";" and "windows") or "unix"
-os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
+os.name=os.name or (os.type=="windows" and "mswin" ) or "linux"
if os.type=="windows" then
- os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='dll','exe',{ 'exe','cmd','bat' }
else
- os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
+ os.libsuffix,os.binsuffix,os.binsuffixes='so','',{ '' }
end
local launchers={
- windows="start %s",
- macosx="open %s",
- unix="$BROWSER %s &> /dev/null &",
+ windows="start %s",
+ macosx="open %s",
+ unix="xdg-open %s &> /dev/null &",
}
function os.launch(str)
- execute(format(launchers[os.name] or launchers.unix,str))
+ execute(format(launchers[os.name] or launchers.unix,str))
end
if not os.times then
- function os.times()
- return {
- utime=os.gettimeofday(),
- stime=0,
- cutime=0,
- cstime=0,
- }
- end
+ function os.times()
+ return {
+ utime=os.gettimeofday(),
+ stime=0,
+ cutime=0,
+ cstime=0,
+ }
+ end
end
local gettimeofday=os.gettimeofday or os.clock
os.gettimeofday=gettimeofday
local startuptime=gettimeofday()
function os.runtime()
- return gettimeofday()-startuptime
+ return gettimeofday()-startuptime
end
local resolvers=os.resolvers or {}
os.resolvers=resolvers
setmetatable(os,{ __index=function(t,k)
- local r=resolvers[k]
- return r and r(t,k) or nil
+ local r=resolvers[k]
+ return r and r(t,k) or nil
end })
local name,platform=os.name or "linux",os.getenv("MTX_PLATFORM") or ""
if platform~="" then
- os.platform=platform
+ os.platform=platform
elseif os.type=="windows" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("PROCESSOR_ARCHITECTURE") or ""
- if find(architecture,"AMD64",1,true) then
- platform="win64"
- else
- platform="mswin"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("PROCESSOR_ARCHITECTURE") or ""
+ local platform=""
+ if find(architecture,"AMD64",1,true) then
+ platform="win64"
+ else
+ platform="mswin"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="linux" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- if find(architecture,"x86_64",1,true) then
- platform="linux-64"
- elseif find(architecture,"ppc",1,true) then
- platform="linux-ppc"
- else
- platform="linux"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ 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
+ 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=musl and "linuxmusl" or "linux"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="macosx" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("echo $HOSTTYPE") or ""
- if architecture=="" then
- platform="osx-intel"
- elseif find(architecture,"i386",1,true) then
- platform="osx-intel"
- elseif find(architecture,"x86_64",1,true) then
- platform="osx-64"
- else
- platform="osx-ppc"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local architecture=resultof("echo $HOSTTYPE") or ""
+ local platform=""
+ if architecture=="" then
+ platform="osx-intel"
+ elseif find(architecture,"i386",1,true) then
+ platform="osx-intel"
+ elseif find(architecture,"x86_64",1,true) then
+ platform="osx-64"
+ else
+ platform="osx-ppc"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="sunos" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("uname -m") or ""
- if find(architecture,"sparc",1,true) then
- platform="solaris-sparc"
- else
- platform="solaris-intel"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"sparc",1,true) then
+ platform="solaris-sparc"
+ else
+ platform="solaris-intel"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="freebsd" then
- function resolvers.platform(t,k)
- local platform,architecture="",resultof("uname -m") or ""
- if find(architecture,"amd64",1,true) then
- platform="freebsd-amd64"
- else
- platform="freebsd"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"amd64",1,true) then
+ platform="freebsd-amd64"
+ else
+ platform="freebsd"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
elseif name=="kfreebsd" then
- function resolvers.platform(t,k)
- local platform,architecture="",os.getenv("HOSTTYPE") or resultof("uname -m") or ""
- if find(architecture,"x86_64",1,true) then
- platform="kfreebsd-amd64"
- else
- platform="kfreebsd-i386"
- end
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
+ function resolvers.platform(t,k)
+ local architecture=os.getenv("HOSTTYPE") or resultof("uname -m") or ""
+ local platform=""
+ if find(architecture,"x86_64",1,true) then
+ platform="kfreebsd-amd64"
+ else
+ platform="kfreebsd-i386"
end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
else
- function resolvers.platform(t,k)
- local platform="linux"
- os.setenv("MTX_PLATFORM",platform)
- os.platform=platform
- return platform
- end
+ function resolvers.platform(t,k)
+ local platform="linux"
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform=platform
+ return platform
+ end
end
os.newline=name=="windows" and "\013\010" or "\010"
function resolvers.bits(t,k)
- local bits=find(os.platform,"64",1,true) and 64 or 32
- os.bits=bits
- return bits
+ local bits=find(os.platform,"64",1,true) and 64 or 32
+ os.bits=bits
+ return bits
end
local t={ 8,9,"a","b" }
function os.uuid()
- return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
- random(0xFFFF),random(0xFFFF),
- random(0x0FFF),
- t[ceil(random(4))] or 8,random(0x0FFF),
- random(0xFFFF),
- random(0xFFFF),random(0xFFFF),random(0xFFFF)
- )
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
end
local d
function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
- if delta then
- if d>0 then
- return format("+%02i:00",d)
- else
- return format("-%02i:00",-d)
- end
+ d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ if delta then
+ if d>0 then
+ return format("+%02i:00",d)
else
- return 1
+ return format("-%02i:00",-d)
end
+ else
+ return 1
+ end
end
local timeformat=format("%%s%s",os.timezone(true))
local dateformat="!%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.fulltime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=format(timeformat,date(dateformat))
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=format(timeformat,date(dateformat))
+ end
+ return lastdate
end
local dateformat="%Y-%m-%d %H:%M:%S"
local lasttime=nil
local lastdate=nil
function os.localtime(t,default)
- t=t and tonumber(t) or 0
- if t>0 then
- elseif default then
- return default
- else
- t=time()
- end
- if t~=lasttime then
- lasttime=t
- lastdate=date(dateformat,t)
- end
- return lastdate
+ t=t and tonumber(t) or 0
+ if t>0 then
+ elseif default then
+ return default
+ else
+ t=time()
+ end
+ if t~=lasttime then
+ lasttime=t
+ lastdate=date(dateformat,t)
+ end
+ return lastdate
end
function os.converttime(t,default)
- local t=tonumber(t)
- if t and t>0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
+ local t=tonumber(t)
+ if t and t>0 then
+ return date(dateformat,t)
+ else
+ return default or "-"
+ end
end
local memory={}
local function which(filename)
- local fullname=memory[filename]
- if fullname==nil then
- local suffix=file.suffix(filename)
- local suffixes=suffix=="" and os.binsuffixes or { suffix }
- for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
- local df=file.join(directory,filename)
- for i=1,#suffixes do
- local dfs=file.addsuffix(df,suffixes[i])
- if io.exists(dfs) then
- fullname=dfs
- break
- end
- end
- end
- if not fullname then
- fullname=false
+ local fullname=memory[filename]
+ if fullname==nil then
+ local suffix=file.suffix(filename)
+ local suffixes=suffix=="" and os.binsuffixes or { suffix }
+ for directory in gmatch(os.getenv("PATH"),"[^"..io.pathseparator.."]+") do
+ local df=file.join(directory,filename)
+ for i=1,#suffixes do
+ local dfs=file.addsuffix(df,suffixes[i])
+ if io.exists(dfs) then
+ fullname=dfs
+ break
end
- memory[filename]=fullname
+ end
end
- return fullname
+ if not fullname then
+ fullname=false
+ end
+ memory[filename]=fullname
+ end
+ return fullname
end
os.which=which
os.where=which
function os.today()
- return date("!*t")
+ return date("!*t")
end
function os.now()
- return date("!%Y-%m-%d %H:%M:%S")
+ return date("!%Y-%m-%d %H:%M:%S")
end
if not os.sleep then
- local socket=socket
- function os.sleep(n)
- if not socket then
- socket=require("socket")
- end
- socket.sleep(n)
+ local socket=socket
+ function os.sleep(n)
+ if not socket then
+ socket=require("socket")
end
+ socket.sleep(n)
+ end
end
local function isleapyear(year)
- return (year%4==0) and (year%100~=0 or year%400==0)
+ return (year%4==0) and (year%100~=0 or year%400==0)
end
os.isleapyear=isleapyear
local days={ 31,28,31,30,31,30,31,31,30,31,30,31 }
local function nofdays(year,month)
- if not month then
- return isleapyear(year) and 365 or 364
- else
- return month==2 and isleapyear(year) and 29 or days[month]
- end
+ if not month then
+ return isleapyear(year) and 365 or 364
+ else
+ return month==2 and isleapyear(year) and 29 or days[month]
+ end
end
os.nofdays=nofdays
function os.weekday(day,month,year)
- return date("%w",time { year=year,month=month,day=day })+1
+ return date("%w",time { year=year,month=month,day=day })+1
end
function os.validdate(year,month,day)
- if month<1 then
- month=1
- elseif month>12 then
- month=12
- end
- if day<1 then
- day=1
- else
- local max=nofdays(year,month)
- if day>max then
- day=max
- end
- end
- return year,month,day
+ if month<1 then
+ month=1
+ elseif month>12 then
+ month=12
+ end
+ if day<1 then
+ day=1
+ else
+ local max=nofdays(year,month)
+ if day>max then
+ day=max
+ end
+ 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
@@ -3931,19 +4217,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-file"] = package.loaded["l-file"] or true
--- original size: 21616, stripped down to: 10359
+-- original size: 21804, stripped down to: 9980
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
@@ -3951,24 +4237,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(".")
@@ -3982,27 +4266,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
@@ -4011,7 +4295,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)
@@ -4027,142 +4311,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)
- else
- return "",str
- end
+ 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 {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ 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
+ 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)
@@ -4172,30 +4456,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)
- 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
- else
- return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
- end
+ 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
+ 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
+ else
+ return lpegmatch(deslasher,concat({ one,two,three,... },"/"))
+ end
end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
@@ -4205,56 +4489,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
+ n=n-1
end
- 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)
@@ -4262,26 +4546,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("://")
@@ -4290,40 +4574,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
+ 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
- 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
+ if l<0 then
+ return false
end
- return true
+ end
+ return true
+end
+local symlinkattributes=lfs.symlinkattributes
+function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
end
@@ -4333,51 +4621,51 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-gzip"] = package.loaded["l-gzip"] or true
--- original size: 1211, stripped down to: 1002
+-- original size: 1211, stripped down to: 951
if not modules then modules={} end modules ['l-gzip']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not gzip then
- return
+ return
end
local suffix,suffixes=file.suffix,file.suffixes
function gzip.load(filename)
- local f=io.open(filename,"rb")
- if not f then
- elseif suffix(filename)=="gz" then
- f:close()
- local g=gzip.open(filename,"rb")
- if g then
- local str=g:read("*all")
- g:close()
- return str
- end
- else
- local str=f:read("*all")
- f:close()
- return str
- end
+ local f=io.open(filename,"rb")
+ if not f then
+ elseif suffix(filename)=="gz" then
+ f:close()
+ local g=gzip.open(filename,"rb")
+ if g then
+ local str=g:read("*all")
+ g:close()
+ return str
+ end
+ else
+ local str=f:read("*all")
+ f:close()
+ return str
+ end
end
function gzip.save(filename,data)
- if suffix(filename)~="gz" then
- filename=filename..".gz"
- end
- local f=io.open(filename,"wb")
- if f then
- local s=zlib.compress(data or "",9,nil,15+16)
- f:write(s)
- f:close()
- return #s
- end
+ if suffix(filename)~="gz" then
+ filename=filename..".gz"
+ end
+ local f=io.open(filename,"wb")
+ if f then
+ local s=zlib.compress(data or "",9,nil,15+16)
+ f:write(s)
+ f:close()
+ return #s
+ end
end
function gzip.suffix(filename)
- local suffix,extra=suffixes(filename)
- local gzipped=extra=="gz"
- return suffix,gzipped
+ local suffix,extra=suffixes(filename)
+ local gzipped=extra=="gz"
+ return suffix,gzipped
end
@@ -4387,87 +4675,119 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-md5"] = package.loaded["l-md5"] or true
--- original size: 3309, stripped down to: 2314
+-- original size: 3309, stripped down to: 2218
if not modules then modules={} end modules ['l-md5']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
if not md5 then
- md5=optionalrequire("md5")
+ md5=optionalrequire("md5")
end
if not md5 then
- md5={
- sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
- sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
- }
+ md5={
+ sum=function(str) print("error: md5 is not loaded (sum ignored)") return str end,
+ sumhexa=function(str) print("error: md5 is not loaded (sumhexa ignored)") return str end,
+ }
end
local md5,file=md5,file
local gsub=string.gsub
do
- local patterns=lpeg and lpeg.patterns
- if patterns then
- local bytestoHEX=patterns.bytestoHEX
- local bytestohex=patterns.bytestohex
- local bytestodec=patterns.bytestodec
- local lpegmatch=lpeg.match
- local md5sum=md5.sum
- if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
- if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
- if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
- md5.sumhexa=md5.hex
- md5.sumHEXA=md5.HEX
- end
+ local patterns=lpeg and lpeg.patterns
+ if patterns then
+ local bytestoHEX=patterns.bytestoHEX
+ local bytestohex=patterns.bytestohex
+ local bytestodec=patterns.bytestodec
+ local lpegmatch=lpeg.match
+ local md5sum=md5.sum
+ if not md5.HEX then function md5.HEX(str) if str then return lpegmatch(bytestoHEX,md5sum(str)) end end end
+ if not md5.hex then function md5.hex(str) if str then return lpegmatch(bytestohex,md5sum(str)) end end end
+ if not md5.dec then function md5.dec(str) if str then return lpegmatch(bytestodec,md5sum(str)) end end end
+ md5.sumhexa=md5.hex
+ md5.sumHEXA=md5.HEX
+ end
end
function file.needsupdating(oldname,newname,threshold)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime=lfs.attributes(newname,"modification")
- if not newtime then
- return true
- elseif newtime>=oldtime then
- return false
- elseif oldtime-newtime<(threshold or 1) then
- return false
- else
- return true
- end
- else
- return false
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime then
+ local newtime=lfs.attributes(newname,"modification")
+ if not newtime then
+ return true
+ elseif newtime>=oldtime then
+ return false
+ elseif oldtime-newtime<(threshold or 1) then
+ return false
+ else
+ return true
+ end
+ else
+ return false
+ end
end
file.needs_updating=file.needsupdating
function file.syncmtimes(oldname,newname)
- local oldtime=lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
- end
+ local oldtime=lfs.attributes(oldname,"modification")
+ if oldtime and lfs.isfile(newname) then
+ lfs.touch(newname,oldtime,oldtime)
+ end
end
function file.checksum(name)
- if md5 then
- local data=io.loaddata(name)
- if data then
- return md5.HEX(data)
- end
+ if md5 then
+ local data=io.loaddata(name)
+ if data then
+ return md5.HEX(data)
end
- return nil
+ end
+ return nil
end
function file.loadchecksum(name)
- if md5 then
- local data=io.loaddata(name..".md5")
- return data and (gsub(data,"%s",""))
- end
- return nil
+ if md5 then
+ local data=io.loaddata(name..".md5")
+ return data and (gsub(data,"%s",""))
+ end
+ return nil
end
function file.savechecksum(name,checksum)
- if not checksum then checksum=file.checksum(name) end
- if checksum then
- io.savedata(name..".md5",checksum)
- return checksum
- end
- return nil
+ if not checksum then checksum=file.checksum(name) end
+ if checksum then
+ io.savedata(name..".md5",checksum)
+ return checksum
+ end
+ return nil
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["l-sha"] = package.loaded["l-sha"] or true
+
+-- original size: 1085, stripped down to: 969
+
+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
@@ -4477,14 +4797,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-url"] = package.loaded["l-url"] or true
--- original size: 14755, stripped down to: 7236
+-- original size: 14755, stripped down to: 6981
if not modules then modules={} end modules ['l-url']={
- 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 char,format,byte=string.char,string.format,string.byte
local concat=table.concat
@@ -4497,14 +4817,14 @@ local url=url
local unescapes={}
local escapes={}
setmetatable(unescapes,{ __index=function(t,k)
- local v=char(tonumber(k,16))
- t[k]=v
- return v
+ local v=char(tonumber(k,16))
+ t[k]=v
+ return v
end })
setmetatable(escapes,{ __index=function(t,k)
- local v=format("%%%02X",byte(k))
- t[k]=v
- return v
+ local v=format("%%%02X",byte(k))
+ t[k]=v
+ return v
end })
local colon=P(":")
local qmark=P("?")
@@ -4523,21 +4843,21 @@ local escaped=(plus/" ")+escapedchar
local noslash=P("/")/""
local plustospace=P("+")/" "
local decoder=Cs((
- plustospace+escapedchar+P("\r\n")/"\n"+P(1)
- )^0 )
+ plustospace+escapedchar+P("\r\n")/"\n"+P(1)
+ )^0 )
local encoder=Cs((
- R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
- )^0 )
+ R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar
+ )^0 )
lpegpatterns.urldecoder=decoder
lpegpatterns.urlencoder=encoder
-function url.decode (str) return str and lpegmatch(decoder,str) or str end
-function url.encode (str) return str and lpegmatch(encoder,str) or str end
+function url.decode (str) return str and lpegmatch(decoder,str) or str end
+function url.encode (str) return str and lpegmatch(encoder,str) or str end
function url.unescape(str) return str and lpegmatch(unescaper,str) or str end
local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0)
-local pathstr=Cs((escaped+(1- qmark-hash))^0)
-local querystr=Cs(((1- hash))^0)
-local fragmentstr=Cs((escaped+(1- endofstring))^0)
+local pathstr=Cs((escaped+(1- qmark-hash))^0)
+local querystr=Cs(((1- hash))^0)
+local fragmentstr=Cs((escaped+(1- endofstring))^0)
local scheme=schemestr*colon+nothing
local authority=slash*slash*authoritystr+nothing
local path=slash*pathstr+nothing
@@ -4555,19 +4875,19 @@ lpegpatterns.urlescaper=escaper
lpegpatterns.urlunescaper=unescaper
lpegpatterns.urlgetcleaner=getcleaner
function url.unescapeget(str)
- return lpegmatch(getcleaner,str)
+ return lpegmatch(getcleaner,str)
end
local function split(str)
- return (type(str)=="string" and lpegmatch(parser,str)) or str
+ return (type(str)=="string" and lpegmatch(parser,str)) or str
end
local isscheme=schemestr*colon*slash*slash
local function hasscheme(str)
- if str then
- local scheme=lpegmatch(isscheme,str)
- return scheme~="" and scheme or false
- else
- return false
- end
+ if str then
+ local scheme=lpegmatch(isscheme,str)
+ return scheme~="" and scheme or false
+ else
+ return false
+ end
end
local rootletter=R("az","AZ")+S("_-+")
local separator=P("://")
@@ -4577,161 +4897,161 @@ local barswapper=replacer("|",":")
local backslashswapper=replacer("\\","/")
local equal=P("=")
local amp=P("&")
-local key=Cs(((plustospace+escapedchar+1)-equal )^0)
+local key=Cs(((plustospace+escapedchar+1)-equal )^0)
local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0)
local splitquery=Cf (Ct("")*P { "sequence",
- sequence=V("pair")*(amp*V("pair"))^0,
- pair=Cg(key*equal*value),
+ sequence=V("pair")*(amp*V("pair"))^0,
+ pair=Cg(key*equal*value),
},rawset)
local userpart=(1-atsign-colon)^1
local serverpart=(1-colon)^1
local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil))
local function hashed(str)
- if not str or str=="" then
- return {
- scheme="invalid",
- original=str,
- }
- end
- local detailed=split(str)
- local rawscheme=""
- local rawquery=""
- local somescheme=false
- local somequery=false
- if detailed then
- rawscheme=detailed[1]
- rawquery=detailed[4]
- somescheme=rawscheme~=""
- somequery=rawquery~=""
- end
- if not somescheme and not somequery then
- return {
- scheme="file",
- authority="",
- path=str,
- query="",
- fragment="",
- original=str,
- noscheme=true,
- filename=str,
- }
- end
- local authority=detailed[2]
- local path=detailed[3]
- local filename
- local username
- local password
- local host
- local port
- if authority~="" then
- username,password,host,port=lpegmatch(splitauthority,authority)
- end
- if authority=="" then
- filename=path
- elseif path=="" then
- filename=""
- else
- filename=authority.."/"..path
- end
+ if not str or str=="" then
return {
- scheme=rawscheme,
- authority=authority,
- path=path,
- query=lpegmatch(unescaper,rawquery),
- queries=lpegmatch(splitquery,rawquery),
- fragment=detailed[5],
- original=str,
- noscheme=false,
- filename=filename,
- host=host,
- port=port,
+ scheme="invalid",
+ original=str,
}
+ end
+ local detailed=split(str)
+ local rawscheme=""
+ local rawquery=""
+ local somescheme=false
+ local somequery=false
+ if detailed then
+ rawscheme=detailed[1]
+ rawquery=detailed[4]
+ somescheme=rawscheme~=""
+ somequery=rawquery~=""
+ end
+ if not somescheme and not somequery then
+ return {
+ scheme="file",
+ authority="",
+ path=str,
+ query="",
+ fragment="",
+ original=str,
+ noscheme=true,
+ filename=str,
+ }
+ end
+ local authority=detailed[2]
+ local path=detailed[3]
+ local filename
+ local username
+ local password
+ local host
+ local port
+ if authority~="" then
+ username,password,host,port=lpegmatch(splitauthority,authority)
+ end
+ if authority=="" then
+ filename=path
+ elseif path=="" then
+ filename=""
+ else
+ filename=authority.."/"..path
+ end
+ return {
+ scheme=rawscheme,
+ authority=authority,
+ path=path,
+ query=lpegmatch(unescaper,rawquery),
+ queries=lpegmatch(splitquery,rawquery),
+ fragment=detailed[5],
+ original=str,
+ noscheme=false,
+ filename=filename,
+ host=host,
+ port=port,
+ }
end
url.split=split
url.hasscheme=hasscheme
url.hashed=hashed
function url.addscheme(str,scheme)
- if hasscheme(str) then
- return str
- elseif not scheme then
- return "file:///"..str
- else
- return scheme..":///"..str
- end
+ if hasscheme(str) then
+ return str
+ elseif not scheme then
+ return "file:///"..str
+ else
+ return scheme..":///"..str
+ end
end
function url.construct(hash)
- local result,r={},0
- local scheme=hash.scheme
- local authority=hash.authority
- local path=hash.path
- local queries=hash.queries
- local fragment=hash.fragment
- if scheme and scheme~="" then
- r=r+1;result[r]=lpegmatch(escaper,scheme)
- r=r+1;result[r]="://"
- end
- if authority and authority~="" then
- r=r+1;result[r]=lpegmatch(escaper,authority)
- end
- if path and path~="" then
- r=r+1;result[r]="/"
- r=r+1;result[r]=lpegmatch(escaper,path)
- end
- if queries then
- local done=false
- for k,v in sortedhash(queries) do
- r=r+1;result[r]=done and "&" or "?"
- r=r+1;result[r]=lpegmatch(escaper,k)
- r=r+1;result[r]="="
- r=r+1;result[r]=lpegmatch(escaper,v)
- done=true
- end
- end
- if fragment and fragment~="" then
- r=r+1;result[r]="#"
- r=r+1;result[r]=lpegmatch(escaper,fragment)
- end
- return concat(result)
+ local result,r={},0
+ local scheme=hash.scheme
+ local authority=hash.authority
+ local path=hash.path
+ local queries=hash.queries
+ local fragment=hash.fragment
+ if scheme and scheme~="" then
+ r=r+1;result[r]=lpegmatch(escaper,scheme)
+ r=r+1;result[r]="://"
+ end
+ if authority and authority~="" then
+ r=r+1;result[r]=lpegmatch(escaper,authority)
+ end
+ if path and path~="" then
+ r=r+1;result[r]="/"
+ r=r+1;result[r]=lpegmatch(escaper,path)
+ end
+ if queries then
+ local done=false
+ for k,v in sortedhash(queries) do
+ r=r+1;result[r]=done and "&" or "?"
+ r=r+1;result[r]=lpegmatch(escaper,k)
+ r=r+1;result[r]="="
+ r=r+1;result[r]=lpegmatch(escaper,v)
+ done=true
+ end
+ end
+ if fragment and fragment~="" then
+ r=r+1;result[r]="#"
+ r=r+1;result[r]=lpegmatch(escaper,fragment)
+ end
+ return concat(result)
end
local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0)
function url.filename(filename)
- local spec=hashed(filename)
- local path=spec.path
- return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
+ local spec=hashed(filename)
+ local path=spec.path
+ return (spec.scheme=="file" and path and lpegmatch(pattern,path)) or filename
end
local function escapestring(str)
- return lpegmatch(escaper,str)
+ return lpegmatch(escaper,str)
end
url.escape=escapestring
function url.query(str)
- if type(str)=="string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
+ if type(str)=="string" then
+ return lpegmatch(splitquery,str) or ""
+ else
+ return str
+ end
end
function url.toquery(data)
- local td=type(data)
- if td=="string" then
- return #str and escape(data) or nil
- elseif td=="table" then
- if next(data) then
- local t={}
- for k,v in next,data do
- t[#t+1]=format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
- end
- else
+ local td=type(data)
+ if td=="string" then
+ return #str and escape(data) or nil
+ elseif td=="table" then
+ if next(data) then
+ local t={}
+ for k,v in next,data do
+ t[#t+1]=format("%s=%s",k,escapestring(v))
+ end
+ return concat(t,"&")
end
+ else
+ end
end
local pattern=Cs(noslash^0*(1-noslash*P(-1))^0)
function url.barepath(path)
- if not path or path=="" then
- return ""
- else
- return lpegmatch(pattern,path)
- end
+ if not path or path=="" then
+ return ""
+ else
+ return lpegmatch(pattern,path)
+ end
end
@@ -4741,14 +5061,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 17703, stripped down to: 11691
+-- original size: 18002, stripped down to: 10681
if not modules then modules={} end modules ['l-dir']={
- 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,select=type,select
local find,gmatch,match,gsub,sub=string.find,string.gmatch,string.match,string.gsub,string.sub
@@ -4760,471 +5080,478 @@ local dir=dir
local lfs=lfs
local attributes=lfs.attributes
local walkdir=lfs.dir
-local isdir=lfs.isdir
+local isdir=lfs.isdir
local isfile=lfs.isfile
local currentdir=lfs.currentdir
local chdir=lfs.chdir
local mkdir=lfs.mkdir
local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true)
if onwindows then
- local tricky=S("/\\")*P(-1)
- isdir=function(name)
- if lpegmatch(tricky,name) then
- return attributes(name,"mode")=="directory"
- else
- return attributes(name.."/.","mode")=="directory"
- end
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
+ local tricky=S("/\\")*P(-1)
+ isdir=function(name)
+ if lpegmatch(tricky,name) then
+ return attributes(name,"mode")=="directory"
+ else
+ return attributes(name.."/.","mode")=="directory"
end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
else
- isdir=function(name)
- return attributes(name,"mode")=="directory"
- end
- isfile=function(name)
- return attributes(name,"mode")=="file"
- end
- lfs.isdir=isdir
- lfs.isfile=isfile
+ isdir=function(name)
+ return attributes(name,"mode")=="directory"
+ end
+ isfile=function(name)
+ return attributes(name,"mode")=="file"
+ end
+ lfs.isdir=isdir
+ lfs.isfile=isfile
end
function dir.current()
- return (gsub(currentdir(),"\\","/"))
+ return (gsub(currentdir(),"\\","/"))
end
local function glob_pattern_function(path,patt,recurse,action)
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- action(full)
- end
- elseif recurse and mode=="directory" then
- if not dirs then
- dirs={ full }
- else
- dirs[#dirs+1]=full
- end
- end
- end
- end
- if dirs then
- for i=1,#dirs do
- glob_pattern_function(dirs[i],patt,recurse,action)
- end
+ if isdir(path) then
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ for name in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ action(full)
+ end
+ elseif recurse and mode=="directory" then
+ if dirs then
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
+ end
end
+ end
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_function(dirs[i],patt,recurse,action)
+ end
end
+ end
end
local function glob_pattern_table(path,patt,recurse,result)
- if not result then
- result={}
- end
- if isdir(path) then
- local usedpath
- if path=="/" then
- usedpath="/."
- elseif not find(path,"/$") then
- usedpath=path.."/."
- path=path.."/"
- else
- usedpath=path
- end
- local dirs
- for name in walkdir(usedpath) do
- if name~="." and name~=".." then
- local full=path..name
- local mode=attributes(full,'mode')
- if mode=='file' then
- if not patt or find(full,patt) then
- result[#result+1]=full
- end
- elseif recurse and mode=="directory" then
- if not dirs then
- dirs={ full }
- else
- dirs[#dirs+1]=full
- end
- end
- end
- end
+ if not result then
+ result={}
+ end
+ local usedpath
+ if path=="/" then
+ usedpath="/."
+ elseif not find(path,"/$") then
+ usedpath=path.."/."
+ path=path.."/"
+ else
+ usedpath=path
+ end
+ local dirs
+ local nofdirs=0
+ local noffiles=#result
+ for name,a in walkdir(usedpath) do
+ if name~="." and name~=".." then
+ local full=path..name
+ local mode=attributes(full,'mode')
+ if mode=='file' then
+ if not patt or find(full,patt) then
+ noffiles=noffiles+1
+ result[noffiles]=full
+ end
+ elseif recurse and mode=="directory" then
if dirs then
- for i=1,#dirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
+ nofdirs=nofdirs+1
+ dirs[nofdirs]=full
+ else
+ nofdirs=1
+ dirs={ full }
end
+ end
end
- return result
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
+ end
+ end
+ return result
end
local function globpattern(path,patt,recurse,method)
- local kind=type(method)
- if patt and sub(patt,1,-3)==path then
- patt=false
- end
- if kind=="function" then
- return glob_pattern_function(path,patt,recurse,method)
- elseif kind=="table" then
- return glob_pattern_table(path,patt,recurse,method)
- else
- return glob_pattern_table(path,patt,recurse,{})
- end
+ local kind=type(method)
+ if patt and sub(patt,1,-3)==path then
+ patt=false
+ end
+ local okay=isdir(path)
+ if kind=="function" then
+ return okay and glob_pattern_function(path,patt,recurse,method) or {}
+ elseif kind=="table" then
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
+ else
+ return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+ end
end
dir.globpattern=globpattern
local function collectpattern(path,patt,recurse,result)
- local ok,scanner
- result=result or {}
- if path=="/" then
- ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
- else
- ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
- end
- if ok and type(scanner)=="function" then
- if not find(path,"/$") then
- path=path..'/'
- end
- for name in scanner,first do
- if name=="." then
- elseif name==".." then
- else
- local full=path..name
- local attr=attributes(full)
- local mode=attr.mode
- if mode=='file' then
- if find(full,patt) then
- result[name]=attr
- end
- elseif recurse and mode=="directory" then
- attr.list=collectpattern(full,patt,recurse)
- result[name]=attr
- end
- end
+ local ok,scanner
+ result=result or {}
+ if path=="/" then
+ ok,scanner,first=xpcall(function() return walkdir(path..".") end,function() end)
+ else
+ ok,scanner,first=xpcall(function() return walkdir(path) end,function() end)
+ end
+ if ok and type(scanner)=="function" then
+ if not find(path,"/$") then
+ path=path..'/'
+ end
+ for name in scanner,first do
+ if name=="." then
+ elseif name==".." then
+ else
+ local full=path..name
+ local attr=attributes(full)
+ local mode=attr.mode
+ if mode=='file' then
+ if find(full,patt) then
+ result[name]=attr
+ end
+ elseif recurse and mode=="directory" then
+ attr.list=collectpattern(full,patt,recurse)
+ result[name]=attr
end
+ end
end
- return result
+ end
+ return result
end
dir.collectpattern=collectpattern
local separator,pattern
if onwindows then
- local slash=S("/\\")/"/"
- pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
- }
+ local slash=S("/\\")/"/"
+ pattern={
+ [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
+ [3]=Cs(P(1)^0)
+ }
else
- pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
- }
+ pattern={
+ [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ [2]=C(((1-S("*?/"))^0*P("/"))^0),
+ [3]=C(P(1)^0)
+ }
end
local filter=Cs ((
- P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
+ P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
)^0 )
local function glob(str,t)
- if type(t)=="function" then
- if type(str)=="table" then
- for s=1,#str do
- glob(str[s],t)
- end
- elseif isfile(str) then
- t(str)
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- globpattern(start,result,recurse,t)
- end
- end
+ if type(t)=="function" then
+ if type(str)=="table" then
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ elseif isfile(str) then
+ t(str)
+ else
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ globpattern(start,result,recurse,t)
+ end
+ end
+ else
+ if type(str)=="table" then
+ local t=t or {}
+ for s=1,#str do
+ glob(str[s],t)
+ end
+ return t
+ elseif isfile(str) then
+ if t then
+ t[#t+1]=str
+ return t
+ else
+ return { str }
+ end
else
- if type(str)=="table" then
- local t=t or {}
- for s=1,#str do
- glob(str[s],t)
- end
- return t
- elseif isfile(str) then
- if t then
- t[#t+1]=str
- return t
- else
- return { str }
- end
- else
- local root,path,base=lpegmatch(pattern,str)
- if root and path and base then
- local recurse=find(base,"**",1,true)
- local start=root..path
- local result=lpegmatch(filter,start..base)
- return globpattern(start,result,recurse,t)
- else
- return {}
- end
- end
+ local root,path,base=lpegmatch(pattern,str)
+ if root and path and base then
+ local recurse=find(base,"**",1,true)
+ local start=root..path
+ local result=lpegmatch(filter,start..base)
+ return globpattern(start,result,recurse,t)
+ else
+ return {}
+ end
end
+ end
end
dir.glob=glob
local function globfiles(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if recurse then
- globfiles(path.."/"..name,recurse,func,files)
- end
- elseif mode=="file" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if recurse then
+ globfiles(path.."/"..name,recurse,func,files)
+ end
+ elseif mode=="file" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
end
+ end
end
- return files
+ end
+ return files
end
dir.globfiles=globfiles
local function globdirs(path,recurse,func,files)
- if type(func)=="string" then
- local s=func
- func=function(name) return find(name,s) end
- end
- files=files or {}
- local noffiles=#files
- for name in walkdir(path) do
- if find(name,"^%.") then
- else
- local mode=attributes(name,'mode')
- if mode=="directory" then
- if not func or func(name) then
- noffiles=noffiles+1
- files[noffiles]=path.."/"..name
- if recurse then
- globdirs(path.."/"..name,recurse,func,files)
- end
- end
- end
+ if type(func)=="string" then
+ local s=func
+ func=function(name) return find(name,s) end
+ end
+ files=files or {}
+ local noffiles=#files
+ for name in walkdir(path) do
+ if find(name,"^%.") then
+ else
+ local mode=attributes(name,'mode')
+ if mode=="directory" then
+ if not func or func(name) then
+ noffiles=noffiles+1
+ files[noffiles]=path.."/"..name
+ if recurse then
+ globdirs(path.."/"..name,recurse,func,files)
+ end
end
+ end
end
- return files
+ end
+ return files
end
dir.globdirs=globdirs
function dir.ls(pattern)
- return concat(glob(pattern),"\n")
+ return concat(glob(pattern),"\n")
end
local make_indeed=true
if onwindows then
- function dir.mkdirs(...)
- local n=select("#",...)
- local str
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s=="" then
+ elseif str=="" then
+ str=s
else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s=="" then
- elseif str=="" then
- str=s
- else
- str=str.."/"..s
- end
- end
+ str=str.."/"..s
end
- local pth=""
- local drive=false
- local first,middle,last=match(str,"^(//)(//*)(.*)$")
- if first then
+ end
+ end
+ local pth=""
+ local drive=false
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ else
+ first,last=match(str,"^(//)/*(.-)$")
+ if first then
+ middle,last=match(str,"([^/]+)/+(.-)$")
+ if middle then
+ pth="//"..middle
else
- first,last=match(str,"^(//)/*(.-)$")
- if first then
- middle,last=match(str,"([^/]+)/+(.-)$")
- if middle then
- pth="//"..middle
- else
- pth="//"..last
- last=""
- end
- else
- first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
- if first then
- pth,drive=first..middle,true
- else
- middle,last=match(str,"^(/*)(.-)$")
- if not middle then
- last=str
- end
- end
- end
+ pth="//"..last
+ last=""
end
- for s in gmatch(last,"[^/]+") do
- if pth=="" then
- pth=s
- elseif drive then
- pth,drive=pth..s,false
- else
- pth=pth.."/"..s
- end
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
+ else
+ first,middle,last=match(str,"^([a-zA-Z]:)(/*)(.-)$")
+ if first then
+ pth,drive=first..middle,true
+ else
+ middle,last=match(str,"^(/*)(.-)$")
+ if not middle then
+ last=str
+ end
end
- return pth,(isdir(pth)==true)
+ end
end
+ for s in gmatch(last,"[^/]+") do
+ if pth=="" then
+ pth=s
+ elseif drive then
+ pth,drive=pth..s,false
+ else
+ pth=pth.."/"..s
+ end
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ return pth,(isdir(pth)==true)
+ end
else
- function dir.mkdirs(...)
- local n=select("#",...)
- local str,pth
- if n==1 then
- str=select(1,...)
- if isdir(str) then
- return str,true
- end
- else
- str=""
- for i=1,n do
- local s=select(i,...)
- if s and s~="" then
- if str~="" then
- str=str.."/"..s
- else
- str=s
- end
- end
- end
+ function dir.mkdirs(...)
+ local n=select("#",...)
+ local str,pth
+ if n==1 then
+ str=select(1,...)
+ if isdir(str) then
+ return str,true
+ end
+ else
+ str=""
+ for i=1,n do
+ local s=select(i,...)
+ if s and s~="" then
+ if str~="" then
+ str=str.."/"..s
+ else
+ str=s
+ end
end
- str=gsub(str,"/+","/")
- if find(str,"^/") then
- pth="/"
- for s in gmatch(str,"[^/]+") do
- local first=(pth=="/")
- if first then
- pth=pth..s
- else
- pth=pth.."/"..s
- end
- if make_indeed and not first and not isdir(pth) then
- mkdir(pth)
- end
- end
+ end
+ end
+ str=gsub(str,"/+","/")
+ if find(str,"^/") then
+ pth="/"
+ for s in gmatch(str,"[^/]+") do
+ local first=(pth=="/")
+ if first then
+ pth=pth..s
else
- pth="."
- for s in gmatch(str,"[^/]+") do
- pth=pth.."/"..s
- if make_indeed and not isdir(pth) then
- mkdir(pth)
- end
- end
+ pth=pth.."/"..s
end
- return pth,(isdir(pth)==true)
+ if make_indeed and not first and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
+ else
+ pth="."
+ for s in gmatch(str,"[^/]+") do
+ pth=pth.."/"..s
+ if make_indeed and not isdir(pth) then
+ mkdir(pth)
+ end
+ end
end
+ return pth,(isdir(pth)==true)
+ end
end
dir.makedirs=dir.mkdirs
do
- local chdir=sandbox and sandbox.original(chdir) or chdir
- if onwindows then
- local xcurrentdir=dir.current
- function dir.expandname(str)
- local first,nothing,last=match(str,"^(//)(//*)(.*)$")
- if first then
- first=xcurrentdir().."/"
- end
- if not first then
- first,last=match(str,"^(//)/*(.*)$")
- end
- if not first then
- first,last=match(str,"^([a-zA-Z]:)(.*)$")
- if first and not find(last,"^/") then
- local d=currentdir()
- if chdir(first) then
- first=xcurrentdir()
- end
- chdir(d)
- end
- end
- if not first then
- first,last=xcurrentdir(),str
- end
- last=gsub(last,"//","/")
- last=gsub(last,"/%./","/")
- last=gsub(last,"^/*","")
- first=gsub(first,"/*$","")
- if last=="" or last=="." then
- return first
- else
- return first.."/"..last
- end
- end
- else
- function dir.expandname(str)
- if not find(str,"^/") then
- str=currentdir().."/"..str
- end
- str=gsub(str,"//","/")
- str=gsub(str,"/%./","/")
- str=gsub(str,"(.)/%.$","%1")
- return str
+ local chdir=sandbox and sandbox.original(chdir) or chdir
+ if onwindows then
+ local xcurrentdir=dir.current
+ function dir.expandname(str)
+ local first,nothing,last=match(str,"^(//)(//*)(.*)$")
+ if first then
+ first=xcurrentdir().."/"
+ end
+ if not first then
+ first,last=match(str,"^(//)/*(.*)$")
+ end
+ if not first then
+ first,last=match(str,"^([a-zA-Z]:)(.*)$")
+ if first and not find(last,"^/") then
+ local d=currentdir()
+ if chdir(first) then
+ first=xcurrentdir()
+ end
+ chdir(d)
end
+ end
+ if not first then
+ first,last=xcurrentdir(),str
+ end
+ last=gsub(last,"//","/")
+ last=gsub(last,"/%./","/")
+ last=gsub(last,"^/*","")
+ first=gsub(first,"/*$","")
+ if last=="" or last=="." then
+ return first
+ else
+ return first.."/"..last
+ end
end
+ else
+ function dir.expandname(str)
+ if not find(str,"^/") then
+ str=currentdir().."/"..str
+ end
+ str=gsub(str,"//","/")
+ str=gsub(str,"/%./","/")
+ str=gsub(str,"(.)/%.$","%1")
+ return str
+ end
+ end
end
file.expandname=dir.expandname
local stack={}
function dir.push(newdir)
- local curdir=currentdir()
- insert(stack,curdir)
- if newdir and newdir~="" then
- chdir(newdir)
- return newdir
- else
- return curdir
- end
+ local curdir=currentdir()
+ insert(stack,curdir)
+ if newdir and newdir~="" then
+ chdir(newdir)
+ return newdir
+ else
+ return curdir
+ end
end
function dir.pop()
- local d=remove(stack)
- if d then
- chdir(d)
- end
- return d
+ local d=remove(stack)
+ if d then
+ chdir(d)
+ end
+ return d
end
local function found(...)
- for i=1,select("#",...) do
- local path=select(i,...)
- local kind=type(path)
- if kind=="string" then
- if isdir(path) then
- return path
- end
- elseif kind=="table" then
- local path=found(unpack(path))
- if path then
- return path
- end
- end
+ for i=1,select("#",...) do
+ local path=select(i,...)
+ local kind=type(path)
+ if kind=="string" then
+ if isdir(path) then
+ return path
+ end
+ elseif kind=="table" then
+ local path=found(unpack(path))
+ if path then
+ return path
+ end
end
+ end
end
dir.found=found
@@ -5235,69 +5562,69 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-boolean"] = package.loaded["l-boolean"] or true
--- original size: 1850, stripped down to: 1568
+-- original size: 1850, stripped down to: 1498
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
@@ -5307,18 +5634,24 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-unicode"] = package.loaded["l-unicode"] or true
--- original size: 40036, stripped down to: 17837
+-- original size: 41047, stripped down to: 17171
if not modules then modules={} end modules ['l-unicode']={
- 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"
}
-utf=utf or (unicode and unicode.utf8) or {}
-utf.characters=utf.characters or string.utfcharacters
-utf.values=utf.values or string.utfvalues
+utf=utf or {}
+unicode=nil
+if not string.utfcharacters then
+ local gmatch=string.gmatch
+ function string.characters(str)
+ return gmatch(str,".[\128-\191]*")
+ end
+end
+utf.characters=string.utfcharacters
local type=type
local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch
local concat=table.concat
@@ -5329,345 +5662,340 @@ local tabletopattern=lpeg.utfchartabletopattern
local bytepairs=string.bytepairs
local finder=lpeg.finder
local replacer=lpeg.replacer
-local utfvalues=utf.values
-local utfgmatch=utf.gmatch
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 }
-end
if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
+ utf.char=string.utfcharacter or (utf8 and utf8.char)
+ if not utf.char then
+ local char=string.char
+ if bit32 then
+ local rshift=bit32.rshift
+ function utf.char(n)
+ if n<0x80 then
+ return char(n)
+ elseif n<0x800 then
+ return char(
+ 0xC0+rshift(n,6),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x10000 then
+ return char(
+ 0xE0+rshift(n,12),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
+ elseif n<0x200000 then
+ return char(
+ 0xF0+rshift(n,18),
+ 0x80+(rshift(n,12)%0x40),
+ 0x80+(rshift(n,6)%0x40),
+ 0x80+(n%0x40)
+ )
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
+ 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
end
+ end
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
+ utf.byte=string.utfvalue or (utf8 and utf8.codepoint)
+ if not utf.byte then
+ function utf.byte(c)
+ return lpegmatch(p_utf8byte,c)
end
+ end
end
local utfchar,utfbyte=utf.char,utf.byte
function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
+ return data and lpegmatch(p_utftype,data) or "unknown"
end
local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
+ (
+ patterns.utf8one+(
+ patterns.utf8two+patterns.utf8three+patterns.utf8four
+ )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
+ )^0
)
patterns.toentities=toentities
function utf.toentities(str)
- return lpegmatch(toentities,str)
+ 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 )
+ 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
+ return lpegmatch(pattern,s) or s
end
local validatedutf=Cs (
- (
- patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
- )^0
+ (
+ patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�"
+ )^0
)
patterns.validatedutf=validatedutf
function utf.is_valid(str)
- return type(str)=="string" and lpegmatch(validatedutf,str) or false
+ 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
+ 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
+ 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
- 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
+ end
+ local function slide_one(s,p)
+ n=n+1
+ if n==first then
+ b=p
end
- local function slide_two(s,p)
- n=n+1
- if n==first then
- b=p
- else
- return true
- end
+ if n>=last then
+ e=p-1
+ else
+ return p
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
+ 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_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(p_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
- 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)
+ end
+ if stop<0 then
+ stop=l+stop
+ if stop==0 then
+ stop=1
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)
+ 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
+ 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)
+ 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
- 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
+ if not pattern then
+ pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ end
+ return lpegmatch(pattern,str)
end
- elseif variant=="function" then
- if option=="pattern" then
- return Cs((p_utf8char/mapping+p_utf8char)^0)
+ end
+ elseif option=="pattern" then
+ return Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ else
+ local pattern=Cs((tabletopattern(mapping)/action+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
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
+ return lpegmatch(pattern,str)
end
+ end,pattern
+ end
+ elseif variant=="function" then
+ if option=="pattern" then
+ return Cs((p_utf8character/mapping+p_utf8character)^0)
else
- return function(str)
- return str or ""
+ local pattern=Cs((p_utf8character/mapping+p_utf8character)^0)
+ return function(str)
+ if not str or str=="" then
+ return ""
+ else
+ return lpegmatch(pattern,str)
end
+ end,pattern
end
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
+ else
return function(str)
- return lpegmatch(r,str)
+ return str or ""
end
+ end
+end
+function utf.replacer(t)
+ local r=replacer(t,false,false,true)
+ return function(str)
+ return lpegmatch(r,str)
+ end
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
+ 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
end
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
function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
+ return lpegmatch(utflinesplitter,str or "")
end
function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
+ if ignorewhitespace then
+ return lpegmatch(utfcharsplitter_iws,str or "")
+ else
+ return lpegmatch(utfcharsplitter_ows,str or "")
+ end
end
function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
+ return lpegmatch(utfcharsplitter_raw,str)
end
function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
+ local str=f:read(4) or ""
+ local off=lpegmatch(p_utfoffset,str)
+ if off<4 then
+ f:seek('set',off)
+ end
+ return lpegmatch(p_utftype,str)
end
local utf16_to_utf8_be,utf16_to_utf8_le
local utf32_to_utf8_be,utf32_to_utf8_le
@@ -5681,36 +6009,36 @@ local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_n
local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
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
- more=0
- return utfchar(now)
- elseif now>=0xD800 and now<=0xDBFF then
- more=now
- return ""
- else
- return utfchar(now)
- end
+ 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
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 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
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))
+ return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d))
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))
+ return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a))
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)
@@ -5721,88 +6049,88 @@ 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
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_be,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf16_to_utf8_le,s)
+ else
+ return s
+ 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
+ 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
- return t
+ end
+ return t
end
utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_be,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
+ if s and s~="" then
+ return lpegmatch(p_utf32_to_utf8_le,s)
+ else
+ return s
+ end
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
+ 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
- return t
+ end
+ return t
end
utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t
utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t
@@ -5813,189 +6141,225 @@ 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
+ 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
+ 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
+ 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
+ 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
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
+ 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
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
+ if nobom then
+ return lpegmatch(b_remap,str)
+ else
+ return char(254,255)..lpegmatch(b_remap,str)
+ end
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
+ if nobom then
+ return lpegmatch(l_remap,str)
+ else
+ return char(255,254)..lpegmatch(l_remap,str)
+ end
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
+ if littleendian then
+ return utf8_to_utf16_le(str,nobom)
+ else
+ return utf8_to_utf16_be(str,nobom)
+ end
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
+ (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 " ")
+ return lpegmatch(pattern,str,1,separator or " ")
end
function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
+ return format("U+%05X",type(s)=="number" and s or utfbyte(s))
end
function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
+ return format("0x%05X",type(s)=="number" and s or utfbyte(s))
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
-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
+ 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
end
-if not utf.characters then
- function utf.characters(str)
- return gmatch(str,".[\128-\191]*")
+do
+ local p_nany=p_utf8character/""
+ 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
- string.utfcharacters=utf.characters
+ end
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
+if not string.utfvalues then
+ local find=string.find
+ local dummy=function()
+ end
+ function string.utfvalues(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
- string.utfvalues=utf.values
+ end
end
+utf.values=string.utfvalues
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
+ 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
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 extract=bit32.extract
+ local char=string.char
+ function utf.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
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
+ 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
- return s
+ end
+ return s
+end
+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)
+ 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
+ end
+ if 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 p_utf8byte/f
+ end
+ end
end
@@ -6005,93 +6369,93 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-math"] = package.loaded["l-math"] or true
--- original size: 2555, stripped down to: 1900
+-- original size: 2555, stripped down to: 1831
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)<floor(n)
- end
+ local floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
@@ -6101,14 +6465,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-str"] = package.loaded["util-str"] or true
--- original size: 38734, stripped down to: 22142
+-- original size: 43539, stripped down to: 21641
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"
+ 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 {}
@@ -6121,624 +6485,657 @@ 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 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
if not number then number={} end
-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 ptf=1/65536
+local bpf=(7200/7227)/65536
local function points(n)
- n=tonumber(n)
- return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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)
+ return lpegmatch(pattern,str)
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
+ 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
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((
+ 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
+ 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)
+ extra,start=0,position
+ end+anything
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
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 space=spacer^0
-local nospace=space/""
+ 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-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 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,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["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
+ return str and lpegmatch(striplinepatterns[how],str) or str
+end
+function strings.collapse(str)
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return 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)..'"')
+ 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).."'")
+ 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]",
+ "[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
+ 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
+ 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))*(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==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
if sep1==true then
- return lpegmatch(splitter,s,1,".",",")
+ return lpegmatch(splitter,n,1,".",",")
elseif sep1=="." then
- return lpegmatch(splitter,s,1,sep1,sep2 or ",")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
elseif sep1=="," then
- return lpegmatch(splitter,s,1,sep1,sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ 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
- )
+ 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
+ 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 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
- 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))
+ 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
- return tostring(n)
+ 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
+ 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
+ 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 #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
%s
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,
+}
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ 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)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
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
+ 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 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
+ 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 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ 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)
+ 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
+ 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
+ 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
+ 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
+ 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)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ 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
+ 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
+ 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)
+ 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)
+ 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()
+ 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(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))
+ 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")
@@ -6750,160 +7147,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("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
-patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
+patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+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
@@ -6913,14 +7306,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 27741, stripped down to: 17085
+-- original size: 28772, stripped down to: 16111
if not modules then modules={} end modules ['util-tab']={
- 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"
}
utilities=utilities or {}
utilities.tables=utilities.tables or {}
@@ -6935,219 +7328,220 @@ local formatters=string.formatters
local utftoeight=utf.toeight
local splitter=lpeg.tsplitat(".")
function utilities.tables.definetable(target,nofirst,nolast)
- local composed,t=nil,{}
- local snippets=lpegmatch(splitter,target)
- for i=1,#snippets-(nolast and 1 or 0) do
- local name=snippets[i]
- if composed then
- composed=composed.."."..name
- t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
- else
- composed=name
- if not nofirst then
- t[#t+1]=formatters["%s = %s or { }"](composed,composed)
- end
- end
- end
+ local composed=nil
+ local t={}
+ local snippets=lpegmatch(splitter,target)
+ for i=1,#snippets-(nolast and 1 or 0) do
+ local name=snippets[i]
if composed then
- if nolast then
- composed=composed.."."..snippets[#snippets]
- end
- return concat(t,"\n"),composed
+ composed=composed.."."..name
+ t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed)
else
- return "",target
+ composed=name
+ if not nofirst then
+ t[#t+1]=formatters["%s = %s or { }"](composed,composed)
+ end
+ end
+ end
+ if composed then
+ if nolast then
+ composed=composed.."."..snippets[#snippets]
end
+ return concat(t,"\n"),composed
+ else
+ return "",target
+ end
end
function tables.definedtable(...)
- local t=_G
- for i=1,select("#",...) do
- local li=select(i,...)
- local tl=t[li]
- if not tl then
- tl={}
- t[li]=tl
- end
- t=tl
- end
- return t
+ local t=_G
+ for i=1,select("#",...) do
+ local li=select(i,...)
+ local tl=t[li]
+ if not tl then
+ tl={}
+ t[li]=tl
+ end
+ t=tl
+ end
+ return t
end
function tables.accesstable(target,root)
- local t=root or _G
- for name in gmatch(target,"([^%.]+)") do
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ for name in gmatch(target,"([^%.]+)") do
+ t=t[name]
+ if not t then
+ return
end
- return t
+ end
+ return t
end
function tables.migratetable(target,v,root)
- local t=root or _G
- local names=lpegmatch(splitter,target)
- for i=1,#names-1 do
- local name=names[i]
- t[name]=t[name] or {}
- t=t[name]
- if not t then
- return
- end
+ local t=root or _G
+ local names=lpegmatch(splitter,target)
+ for i=1,#names-1 do
+ local name=names[i]
+ t[name]=t[name] or {}
+ t=t[name]
+ if not t then
+ return
end
- t[names[#names]]=v
+ end
+ t[names[#names]]=v
end
function tables.removevalue(t,value)
- if value then
- for i=1,#t do
- if t[i]==value then
- remove(t,i)
- end
- end
+ if value then
+ for i=1,#t do
+ if t[i]==value then
+ remove(t,i)
+ end
end
+ end
end
function tables.replacevalue(t,oldvalue,newvalue)
- if oldvalue and newvalue then
- for i=1,#t do
- if t[i]==oldvalue then
- t[i]=newvalue
- end
- end
+ if oldvalue and newvalue then
+ for i=1,#t do
+ if t[i]==oldvalue then
+ t[i]=newvalue
+ end
end
+ end
end
function tables.insertbeforevalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i,extra)
+ return
end
- insert(t,1,extra)
+ end
+ insert(t,1,extra)
end
function tables.insertaftervalue(t,value,extra)
- for i=1,#t do
- if t[i]==extra then
- remove(t,i)
- end
+ for i=1,#t do
+ if t[i]==extra then
+ remove(t,i)
end
- for i=1,#t do
- if t[i]==value then
- insert(t,i+1,extra)
- return
- end
+ end
+ for i=1,#t do
+ if t[i]==value then
+ insert(t,i+1,extra)
+ return
end
- insert(t,#t+1,extra)
+ end
+ insert(t,#t+1,extra)
end
local escape=Cs(Cc('"')*((P('"')/'""'+P(1))^0)*Cc('"'))
function table.tocsv(t,specification)
- if t and #t>0 then
- local result={}
- local r={}
- specification=specification or {}
- local fields=specification.fields
- if type(fields)~="string" then
- fields=sortedkeys(t[1])
- end
- local separator=specification.separator or ","
- local noffields=#fields
- if specification.preamble==true then
- for f=1,noffields do
- r[f]=lpegmatch(escape,tostring(fields[f]))
- end
- result[1]=concat(r,separator)
- end
- for i=1,#t do
- local ti=t[i]
- for f=1,noffields do
- local field=ti[fields[f]]
- if type(field)=="string" then
- r[f]=lpegmatch(escape,field)
- else
- r[f]=tostring(field)
- end
- end
- result[i+1]=concat(r,separator)
+ if t and #t>0 then
+ local result={}
+ local r={}
+ specification=specification or {}
+ local fields=specification.fields
+ if type(fields)~="string" then
+ fields=sortedkeys(t[1])
+ end
+ local separator=specification.separator or ","
+ local noffields=#fields
+ if specification.preamble==true then
+ for f=1,noffields do
+ r[f]=lpegmatch(escape,tostring(fields[f]))
+ end
+ result[1]=concat(r,separator)
+ end
+ for i=1,#t do
+ local ti=t[i]
+ for f=1,noffields do
+ local field=ti[fields[f]]
+ if type(field)=="string" then
+ r[f]=lpegmatch(escape,field)
+ else
+ r[f]=tostring(field)
end
- return concat(result,"\n")
- else
- return ""
+ end
+ result[i+1]=concat(r,separator)
end
+ return concat(result,"\n")
+ else
+ return ""
+ end
end
local nspaces=utilities.strings.newrepeater(" ")
local function toxml(t,d,result,step)
- local r=#result
- for k,v in sortedpairs(t) do
- local s=nspaces[d]
- local tk=type(k)
- local tv=type(v)
- if tv=="table" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</entry>"](s,k)
- else
- r=r+1 result[r]=formatters["%s<%s>"](s,k)
- toxml(v,d+step,result,step)
- r=r+1 result[r]=formatters["%s</%s>"](s,k)
- end
- elseif tv=="string" then
- if tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
- end
- elseif tk=="number" then
- r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
- else
- r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
- end
+ local r=#result
+ for k,v in sortedpairs(t) do
+ local s=nspaces[d]
+ local tk=type(k)
+ local tv=type(v)
+ if tv=="table" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</entry>"](s,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>"](s,k)
+ toxml(v,d+step,result,step)
+ r=r+1 result[r]=formatters["%s</%s>"](s,k)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%!xml!</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%!xml!</%s>"](s,k,v,k)
+ end
+ elseif tk=="number" then
+ r=r+1 result[r]=formatters["%s<entry n='%s'>%S</entry>"](s,k,v,k)
+ else
+ r=r+1 result[r]=formatters["%s<%s>%S</%s>"](s,k,v,k)
end
+ end
end
function table.toxml(t,specification)
- specification=specification or {}
- local name=specification.name
- local noroot=name==false
- local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
- local indent=specification.indent or 0
- local spaces=specification.spaces or 1
- if noroot then
- toxml(t,indent,result,spaces)
- else
- toxml({ [name or "data"]=t },indent,result,spaces)
- end
- return concat(result,"\n")
+ specification=specification or {}
+ local name=specification.name
+ local noroot=name==false
+ local result=(specification.nobanner or noroot) and {} or { "<?xml version='1.0' standalone='yes' ?>" }
+ local indent=specification.indent or 0
+ local spaces=specification.spaces or 1
+ if noroot then
+ toxml(t,indent,result,spaces)
+ else
+ toxml({ [name or "data"]=t },indent,result,spaces)
+ end
+ return concat(result,"\n")
end
function tables.encapsulate(core,capsule,protect)
- if type(capsule)~="table" then
- protect=true
- capsule={}
- end
+ if type(capsule)~="table" then
+ protect=true
+ capsule={}
+ end
+ for key,value in next,core do
+ if capsule[key] then
+ print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
+ os.exit()
+ else
+ capsule[key]=value
+ end
+ end
+ if protect then
for key,value in next,core do
+ core[key]=nil
+ end
+ setmetatable(core,{
+ __index=capsule,
+ __newindex=function(t,key,value)
if capsule[key] then
- print(formatters["\ninvalid %s %a in %a"]("inheritance",key,core))
- os.exit()
+ print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
+ os.exit()
else
- capsule[key]=value
+ rawset(t,key,value)
end
- end
- if protect then
- for key,value in next,core do
- core[key]=nil
- end
- setmetatable(core,{
- __index=capsule,
- __newindex=function(t,key,value)
- if capsule[key] then
- print(formatters["\ninvalid %s %a' in %a"]("overload",key,core))
- os.exit()
- else
- rawset(t,key,value)
- end
- end
- } )
- end
+ end
+ } )
+ end
end
local f_hashed_string=formatters["[%q]=%q,"]
local f_hashed_number=formatters["[%q]=%s,"]
@@ -7161,157 +7555,157 @@ local f_ordered_string=formatters["%q,"]
local f_ordered_number=formatters["%s,"]
local f_ordered_boolean=formatters["%l,"]
function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- for i=0,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
- end
- end
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ for i=0,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
- end
- end
- else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
- end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ else
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_hashed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_hashed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_hashed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
- return r
+ end
end
- return concat(fastserialize(t,true))
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
+ end
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
- if not str or str=="" then
- return
- end
- local code=load(str)
- if not code then
- return
- end
- code=code()
- if not code then
- return
- end
- return code
+ if not str or str=="" then
+ return
+ end
+ local code=load(str)
+ if not code then
+ return
+ end
+ code=code()
+ if not code then
+ return
+ end
+ return code
end
function table.load(filename,loader)
- if filename then
- local t=(loader or io.loaddata)(filename)
- if t and t~="" then
- local t=utftoeight(t)
- t=load(t)
- if type(t)=="function" then
- t=t()
- if type(t)=="table" then
- return t
- end
- end
+ if filename then
+ local t=(loader or io.loaddata)(filename)
+ if t and t~="" then
+ local t=utftoeight(t)
+ t=load(t)
+ if type(t)=="function" then
+ t=t()
+ if type(t)=="table" then
+ return t
end
+ end
end
+ end
end
function table.save(filename,t,n,...)
- io.savedata(filename,table.serialize(t,n==nil and true or n,...))
+ io.savedata(filename,table.serialize(t,n==nil and true or n,...))
end
local f_key_value=formatters["%s=%q"]
local f_add_table=formatters[" {%t},\n"]
local f_return_table=formatters["return {\n%t}"]
local function slowdrop(t)
- local r={}
- local l={}
- for i=1,#t do
- local ti=t[i]
- local j=0
- for k,v in next,ti do
- j=j+1
- l[j]=f_key_value(k,v)
- end
- r[i]=f_add_table(l)
- end
- return f_return_table(r)
+ local r={}
+ local l={}
+ for i=1,#t do
+ local ti=t[i]
+ local j=0
+ for k,v in next,ti do
+ j=j+1
+ l[j]=f_key_value(k,v)
+ end
+ r[i]=f_add_table(l)
+ end
+ return f_return_table(r)
end
local function fastdrop(t)
- local r={ "return {\n" }
- local m=1
- for i=1,#t do
- local ti=t[i]
- m=m+1 r[m]=" {"
- for k,v in next,ti do
- m=m+1 r[m]=f_key_value(k,v)
- end
- m=m+1 r[m]="},\n"
- end
- m=m+1
- r[m]="}"
- return concat(r)
+ local r={ "return {\n" }
+ local m=1
+ for i=1,#t do
+ local ti=t[i]
+ m=m+1 r[m]=" {"
+ for k,v in next,ti do
+ m=m+1 r[m]=f_key_value(k,v)
+ end
+ m=m+1 r[m]="},\n"
+ end
+ m=m+1
+ r[m]="}"
+ return concat(r)
end
function table.drop(t,slow)
- if #t==0 then
- return "return { }"
- elseif slow==true then
- return slowdrop(t)
- else
- return fastdrop(t)
- end
+ if #t==0 then
+ return "return { }"
+ elseif slow==true then
+ return slowdrop(t)
+ else
+ return fastdrop(t)
+ end
end
local selfmapper={ __index=function(t,k) t[k]=k return k end }
-function table.twowaymapper(t)
- if not t then
- t={}
- else
- local zero=rawget(t,0)
- for i=zero and 0 or 1,#t do
- local ti=t[i]
- if ti then
- local i=tostring(i)
- t[i]=ti
- t[ti]=i
- end
- end
+function table.twowaymapper(t)
+ if not t then
+ t={}
+ else
+ local zero=rawget(t,0)
+ for i=zero and 0 or 1,#t do
+ local ti=t[i]
+ if ti then
+ local i=tostring(i)
+ t[i]=ti
+ t[ti]=i
+ end
end
- setmetatable(t,selfmapper)
- return t
+ end
+ setmetatable(t,selfmapper)
+ return t
end
local f_start_key_idx=formatters["%w{"]
local f_start_key_num=formatters["%w[%s]={"]
@@ -7349,187 +7743,223 @@ local spaces=utilities.strings.newrepeater(" ")
local original_serialize=table.serialize
local is_simple_table=table.is_simple_table
local function serialize(root,name,specification)
- if type(specification)=="table" then
- return original_serialize(root,name,specification)
- end
- local t
- local n=1
- local unknown=false
- local function do_serialize(root,name,depth,level,indexed)
- if level>0 then
- n=n+1
- if indexed then
- t[n]=f_start_key_idx(depth)
+ if type(specification)=="table" then
+ return original_serialize(root,name,specification)
+ end
+ local t
+ local n=1
+ local unknown=false
+ local function do_serialize(root,name,depth,level,indexed)
+ if level>0 then
+ n=n+1
+ if indexed then
+ t[n]=f_start_key_idx(depth)
+ else
+ local tn=type(name)
+ if tn=="number" then
+ t[n]=f_start_key_num(depth,name)
+ elseif tn=="string" then
+ t[n]=f_start_key_str(depth,name)
+ elseif tn=="boolean" then
+ t[n]=f_start_key_boo(depth,name)
+ else
+ t[n]=f_start_key_nop(depth)
+ end
+ end
+ depth=depth+1
+ end
+ if root and next(root)~=nil then
+ local first=nil
+ local last=0
+ 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
+ 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 first and tk=="number" and k<=last and k>=first then
+ if tv=="number" then
+ n=n+1 t[n]=f_val_num(depth,v)
+ elseif tv=="string" then
+ n=n+1 t[n]=f_val_str(depth,v)
+ elseif tv=="table" then
+ if next(v)==nil then
+ n=n+1 t[n]=f_val_not(depth)
else
- local tn=type(name)
- if tn=="number" then
- t[n]=f_start_key_num(depth,name)
- elseif tn=="string" then
- t[n]=f_start_key_str(depth,name)
- elseif tn=="boolean" then
- t[n]=f_start_key_boo(depth,name)
- else
- t[n]=f_start_key_nop(depth)
- end
- end
- depth=depth+1
- end
- if root and next(root)~=nil then
- local first=nil
- local last=0
- last=#root
- for k=1,last do
- if rawget(root,k)==nil then
- last=k-1
- break
- end
+ local st=is_simple_table(v)
+ if st then
+ n=n+1 t[n]=f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
end
- if last>0 then
- first=1
+ elseif tv=="boolean" then
+ n=n+1 t[n]=f_val_boo(depth,v)
+ elseif unknown then
+ n=n+1 t[n]=f_val_str(depth,tostring(v))
+ end
+ elseif tv=="number" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_num(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_num(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
+ end
+ elseif tv=="string" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
+ end
+ elseif tv=="table" then
+ if next(v)==nil then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_not(depth,k)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_not(depth,k)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_not(depth,k)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
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 first and tk=="number" and k<=last and k>=first then
- if tv=="number" then
- n=n+1 t[n]=f_val_num(depth,v)
- elseif tv=="string" then
- n=n+1 t[n]=f_val_str(depth,v)
- elseif tv=="table" then
- if next(v)==nil then
- n=n+1 t[n]=f_val_not(depth)
- else
- local st=is_simple_table(v)
- if st then
- n=n+1 t[n]=f_val_seq(depth,st)
- else
- do_serialize(v,k,depth,level+1,true)
- end
- end
- elseif tv=="boolean" then
- n=n+1 t[n]=f_val_boo(depth,v)
- elseif unknown then
- n=n+1 t[n]=f_val_str(depth,tostring(v))
- end
- elseif tv=="number" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_num(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_num(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_num(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_num(depth,tostring(k),v)
- end
- elseif tv=="string" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),v)
- end
- elseif tv=="table" then
- if next(v)==nil then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_not(depth,k)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_not(depth,k)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_not(depth,k)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_not(depth,tostring(k))
- end
- else
- local st=is_simple_table(v)
- if not st then
- do_serialize(v,k,depth,level+1)
- elseif tk=="number" then
- n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
- end
- end
- elseif tv=="boolean" then
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
- end
- else
- if tk=="number" then
- n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
- elseif tk=="string" then
- n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
- elseif tk=="boolean" then
- n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
- elseif unknown then
- n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
- end
- end
+ else
+ local st=is_simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk=="number" then
+ n=n+1 t[n]=f_key_num_value_seq(depth,k,st)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_seq(depth,k,st)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_seq(depth,k,st)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_seq(depth,tostring(k),st)
end
- end
- if level>0 then
- n=n+1 t[n]=f_stop(depth-1)
- end
- end
- local tname=type(name)
- if tname=="string" then
- if name=="return" then
- t={ f_table_return() }
- else
- t={ f_table_name(name) }
- end
- elseif tname=="number" then
- t={ f_table_entry(name) }
- elseif tname=="boolean" then
- if name then
- t={ f_table_return() }
+ end
+ elseif tv=="boolean" then
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_boo(depth,k,v)
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_boo(depth,k,v)
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_boo(depth,k,v)
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_boo(depth,tostring(k),v)
+ end
else
- t={ f_table_direct() }
+ if tk=="number" then
+ n=n+1 t[n]=f_key_num_value_str(depth,k,tostring(v))
+ elseif tk=="string" then
+ n=n+1 t[n]=f_key_str_value_str(depth,k,tostring(v))
+ elseif tk=="boolean" then
+ n=n+1 t[n]=f_key_boo_value_str(depth,k,tostring(v))
+ elseif unknown then
+ n=n+1 t[n]=f_key_str_value_str(depth,tostring(k),tostring(v))
+ end
end
+ end
+ end
+ if level>0 then
+ n=n+1 t[n]=f_stop(depth-1)
+ end
+ end
+ local tname=type(name)
+ if tname=="string" then
+ if name=="return" then
+ t={ f_table_return() }
else
- t={ f_table_name("t") }
+ t={ f_table_name(name) }
end
- if root then
- if 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
- local st=is_simple_table(root)
- if st then
- return t[1]..f_fin_seq(st)
- else
- do_serialize(root,name,1,0)
- end
- end
+ elseif tname=="number" then
+ t={ f_table_entry(name) }
+ elseif tname=="boolean" then
+ if name then
+ t={ f_table_return() }
+ else
+ t={ f_table_direct() }
+ end
+ else
+ t={ f_table_name("t") }
+ end
+ if root then
+ if 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
+ local st=is_simple_table(root)
+ if st then
+ return t[1]..f_fin_seq(st)
+ else
+ do_serialize(root,name,1,0)
+ end
end
- n=n+1
- t[n]=f_table_finish()
- return concat(t,"\n")
+ end
+ n=n+1
+ t[n]=f_table_finish()
+ return concat(t,"\n")
end
table.serialize=serialize
if setinspector then
- setinspector("table",function(v)
- if type(v)=="table" then
- print(serialize(v,"table",{ metacheck=false }))
- return true
- end
- end)
+ setinspector("table",function(v)
+ if type(v)=="table" then
+ print(serialize(v,"table",{ metacheck=false }))
+ return true
+ end
+ end)
+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
@@ -7539,15 +7969,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fil"] = package.loaded["util-fil"] or true
--- original size: 7787, stripped down to: 5858
+-- original size: 8607, stripped down to: 6727
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 {}
@@ -7555,251 +7986,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
@@ -7809,338 +8269,412 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sac"] = package.loaded["util-sac"] or true
--- original size: 8716, stripped down to: 6754
+-- original size: 11065, stripped down to: 8209
if not modules then modules={} end modules ['util-sac']={
- 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 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)
+ 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()
end
function streams.size(f)
- return f and f[3] or 0
+ return f and f[3] or 0
end
function streams.setposition(f,i)
- if f[4] then
- if i<=0 then
- f[2]=1
- else
- f[2]=i+1
- end
+ if f[4] then
+ if i<=0 then
+ f[2]=1
else
- if i<=1 then
- f[2]=1
- else
- f[2]=i
- end
+ f[2]=i+1
end
-end
-function streams.getposition(f)
- if f[4] then
- return f[2]-1
+ else
+ if i<=1 then
+ f[2]=1
else
- return f[2]
+ f[2]=i
end
+ end
+end
+function streams.getposition(f)
+ if f[4] then
+ return f[2]-1
+ else
+ return f[2]
+ end
end
function streams.look(f,n,chars)
- local b=f[2]
- local e=b+n-1
- if chars then
- return sub(f[1],b,e)
- else
- return byte(f[1],b,e)
- end
+ local b=f[2]
+ local e=b+n-1
+ if chars then
+ return sub(f[1],b,e)
+ else
+ return byte(f[1],b,e)
+ end
end
function streams.skip(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readbyte(f)
- local i=f[2]
- f[2]=i+1
- return byte(f[1],i)
+ local i=f[2]
+ f[2]=i+1
+ return byte(f[1],i)
end
function streams.readbytes(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return byte(f[1],i,j-1)
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return byte(f[1],i,j-1)
end
function streams.readbytetable(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return { byte(f[1],i,j-1) }
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return { byte(f[1],i,j-1) }
end
function streams.skipbytes(f,n)
- f[2]=f[2]+n
+ f[2]=f[2]+n
end
function streams.readchar(f)
- local i=f[2]
- f[2]=i+1
- return sub(f[1],i,i)
+ local i=f[2]
+ f[2]=i+1
+ return sub(f[1],i,i)
end
function streams.readstring(f,n)
- local i=f[2]
- local j=i+n
- f[2]=j
- return sub(f[1],i,j-1)
-end
-function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- local n=byte(f[1],i)
- if n>=0x80 then
- return n-0x100
- else
- return n
- end
+ local i=f[2]
+ local j=i+n
+ f[2]=j
+ return sub(f[1],i,j-1)
+end
+function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ local n=byte(f[1],i)
+ if n>=0x80 then
+ return n-0x100
+ else
+ return n
+ end
end
-streams.readcardinal1=streams.readbyte
+streams.readcardinal1=streams.readbyte
streams.readcardinal=streams.readcardinal1
streams.readinteger=streams.readinteger1
function streams.readcardinal2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readcardinal2LE(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- return 0x100*a+b
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ return 0x100*a+b
end
function streams.readinteger2(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readinteger2le(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x100*a+b-0x10000
- else
- return 0x100*a+b
- end
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x100*a+b-0x10000
+ else
+ return 0x100*a+b
+ end
end
function streams.readcardinal3(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readcardinal3le(f)
- local i=f[2]
- local j=i+2
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- return 0x10000*a+0x100*b+c
+ local i=f[2]
+ local j=i+2
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ return 0x10000*a+0x100*b+c
end
function streams.readinteger3(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readinteger3le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x10000*a+0x100*b+c-0x1000000
- else
- return 0x10000*a+0x100*b+c
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local c,b,a=byte(f[1],i,j)
+ if a>=0x80 then
+ return 0x10000*a+0x100*b+c-0x1000000
+ else
+ return 0x10000*a+0x100*b+c
+ end
end
function streams.readcardinal4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- return 0x1000000*a+0x10000*b+0x100*c+d
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ return 0x1000000*a+0x10000*b+0x100*c+d
end
function streams.readinteger4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ 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 streams.readinteger4le(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local d,c,b,a=byte(f[1],i,j)
- if a>=0x80 then
- return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000
- else
- return 0x1000000*a+0x10000*b+0x100*c+d
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local d,c,b,a=byte(f[1],i,j)
+ 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 streams.readfixed2(f)
+ local i=f[2]
+ local j=i+1
+ f[2]=j+1
+ local a,b=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((a-0x100).."."..b)
+ else
+ tonumber((a ).."."..b)
+ end
end
function streams.readfixed4(f)
- local i=f[2]
- local j=i+3
- f[2]=j+1
- local a,b,c,d=byte(f[1],i,j)
- if a>=0x80 then
- return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000
- else
- return (0x100*a+b )+(0x100*c+d)/0x10000
- end
+ local i=f[2]
+ local j=i+3
+ f[2]=j+1
+ local a,b,c,d=byte(f[1],i,j)
+ if a>=0x80 then
+ tonumber((0x100*a+b-0x10000).."."..(0x100*c+d))
+ else
+ tonumber((0x100*a+b ).."."..(0x100*c+d))
+ end
end
-function streams.readfixed2(f)
+if bit32 then
+ local extract=bit32.extract
+ local band=bit32.band
+ function streams.read2dot14(f)
local i=f[2]
local j=i+1
f[2]=j+1
local a,b=byte(f[1],i,j)
if a>=0x80 then
- return (a-0x100)+b/0x100
+ local n=-(0x100*a+b)
+ return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0))
else
- return (a )+b/0x100
- end
-end
-if extract then
- local extract=bit32.extract
- local band=bit32.band
- function streams.read2dot14(f)
- local i=f[2]
- local j=i+1
- f[2]=j+1
- local a,b=byte(f[1],i,j)
- 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 n=0x100*a+b
+ return (extract(n,14,2)+(band(n,0x3FFF)/16384.0))
end
+ end
end
function streams.skipshort(f,n)
- f[2]=f[2]+2*(n or 1)
+ f[2]=f[2]+2*(n or 1)
end
function streams.skiplong(f,n)
- f[2]=f[2]+4*(n or 1)
+ f[2]=f[2]+4*(n or 1)
end
if sio and sio.readcardinal2 then
- local readcardinal1=sio.readcardinal1
- local readcardinal2=sio.readcardinal2
- local readcardinal3=sio.readcardinal3
- local readcardinal4=sio.readcardinal4
- local readinteger1=sio.readinteger1
- local readinteger2=sio.readinteger2
- local readinteger3=sio.readinteger3
- local readinteger4=sio.readinteger4
- local readfixed2=sio.readfixed2
- local readfixed4=sio.readfixed4
- local read2dot14=sio.read2dot14
- local readbytes=sio.readbytes
- local readbytetable=sio.readbytetable
- function streams.readcardinal1(f)
- local i=f[2]
- f[2]=i+1
- return readcardinal1(f[1],i)
- end
- function streams.readcardinal2(f)
- local i=f[2]
- f[2]=i+2
- return readcardinal2(f[1],i)
- end
- function streams.readcardinal3(f)
- local i=f[2]
- f[2]=i+3
- return readcardinal3(f[1],i)
- end
- function streams.readcardinal4(f)
- local i=f[2]
- f[2]=i+4
- return readcardinal4(f[1],i)
- end
- function streams.readinteger1(f)
- local i=f[2]
- f[2]=i+1
- return readinteger1(f[1],i)
- end
- function streams.readinteger2(f)
- local i=f[2]
- f[2]=i+2
- return readinteger2(f[1],i)
- end
- function streams.readinteger3(f)
- local i=f[2]
- f[2]=i+3
- return readinteger3(f[1],i)
- end
- function streams.readinteger4(f)
- local i=f[2]
- f[2]=i+4
- return readinteger4(f[1],i)
- end
- function streams.read2dot4(f)
- local i=f[2]
- f[2]=i+2
- return read2dot4(f[1],i)
- end
- function streams.readbytes(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytes(f[1],i,n)
+ local readcardinal1=sio.readcardinal1
+ local readcardinal2=sio.readcardinal2
+ local readcardinal3=sio.readcardinal3
+ local readcardinal4=sio.readcardinal4
+ local readinteger1=sio.readinteger1
+ local readinteger2=sio.readinteger2
+ local readinteger3=sio.readinteger3
+ local readinteger4=sio.readinteger4
+ local readfixed2=sio.readfixed2
+ local readfixed4=sio.readfixed4
+ local read2dot14=sio.read2dot14
+ local readbytes=sio.readbytes
+ local readbytetable=sio.readbytetable
+ function streams.readcardinal1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readcardinal1(f[1],i)
+ end
+ function streams.readcardinal2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readcardinal2(f[1],i)
+ end
+ function streams.readcardinal3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readcardinal3(f[1],i)
+ end
+ function streams.readcardinal4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readcardinal4(f[1],i)
+ end
+ function streams.readinteger1(f)
+ local i=f[2]
+ f[2]=i+1
+ return readinteger1(f[1],i)
+ end
+ function streams.readinteger2(f)
+ local i=f[2]
+ f[2]=i+2
+ return readinteger2(f[1],i)
+ end
+ function streams.readinteger3(f)
+ local i=f[2]
+ f[2]=i+3
+ return readinteger3(f[1],i)
+ end
+ function streams.readinteger4(f)
+ local i=f[2]
+ f[2]=i+4
+ return readinteger4(f[1],i)
+ end
+ function streams.read2dot4(f)
+ local i=f[2]
+ f[2]=i+2
+ return read2dot4(f[1],i)
+ end
+ function streams.readbytes(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
end
- function streams.readbytetable(f,n)
- local i=f[2]
- local s=f[3]
- local p=i+n
- if p>s then
- f[2]=s+1
- else
- f[2]=p
- end
- return readbytetable(f[1],i,n)
+ return readbytes(f[1],i,n)
+ end
+ function streams.readbytetable(f,n)
+ local i=f[2]
+ local s=f[3]
+ local p=i+n
+ if p>s then
+ f[2]=s+1
+ else
+ f[2]=p
+ end
+ return readbytetable(f[1],i,n)
+ end
+ streams.readbyte=streams.readcardinal1
+ streams.readsignedbyte=streams.readinteger1
+ streams.readcardinal=streams.readcardinal1
+ 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
- streams.readbyte=streams.readcardinal1
- streams.readsignedbyte=streams.readinteger1
- streams.readcardinal=streams.readcardinal1
- streams.readinteger=streams.readinteger1
+ 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
@@ -8150,156 +8684,168 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sto"] = package.loaded["util-sto"] or true
--- original size: 6449, stripped down to: 3069
+-- original size: 6661, stripped down to: 3074
if not modules then modules={} end modules ['util-sto']={
- 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 setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type
utilities=utilities or {}
utilities.storage=utilities.storage or {}
local storage=utilities.storage
function storage.mark(t)
- if not t then
- print("\nfatal error: storage cannot be marked\n")
- os.exit()
- return
- end
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ if not t then
+ print("\nfatal error: storage cannot be marked\n")
+ os.exit()
+ return
+ end
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.allocate(t)
- t=t or {}
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m.__storage__=true
- return t
+ t=t or {}
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m.__storage__=true
+ return t
end
function storage.marked(t)
- local m=getmetatable(t)
- return m and m.__storage__
+ local m=getmetatable(t)
+ return m and m.__storage__
end
function storage.checked(t)
- if not t then
- report("\nfatal error: storage has not been allocated\n")
- os.exit()
- return
- end
- return t
+ if not t then
+ report("\nfatal error: storage has not been allocated\n")
+ os.exit()
+ return
+ end
+ return t
end
function storage.setinitializer(data,initialize)
- local m=getmetatable(data) or {}
- m.__index=function(data,k)
- m.__index=nil
- initialize()
- return data[k]
- end
- setmetatable(data,m)
+ local m=getmetatable(data) or {}
+ m.__index=function(data,k)
+ m.__index=nil
+ initialize()
+ return data[k]
+ end
+ setmetatable(data,m)
end
local keyisvalue={ __index=function(t,k)
- t[k]=k
- return k
+ t[k]=k
+ return k
end }
function storage.sparse(t)
- t=t or {}
- setmetatable(t,keyisvalue)
- return t
-end
-local function f_empty () return "" end
-local function f_self (t,k) t[k]=k return k end
-local function f_table (t,k) local v={} t[k]=v return v end
-local function f_number(t,k) t[k]=0 return 0 end
-local function f_ignore() end
+ t=t or {}
+ setmetatable(t,keyisvalue)
+ return t
+end
+local function f_empty () return "" end
+local function f_self (t,k) t[k]=k return k end
+local function f_table (t,k) local v={} t[k]=v return v end
+local function f_number(t,k) t[k]=0 return 0 end
+local function f_ignore() end
local f_index={
- ["empty"]=f_empty,
- ["self"]=f_self,
- ["table"]=f_table,
- ["number"]=f_number,
+ ["empty"]=f_empty,
+ ["self"]=f_self,
+ ["table"]=f_table,
+ ["number"]=f_number,
}
function table.setmetatableindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- else
- setmetatable(t,{ __index=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ else
+ setmetatable(t,{ __index=i })
+ end
+ return t
end
local f_index={
- ["ignore"]=f_ignore,
+ ["ignore"]=f_ignore,
}
function table.setmetatablenewindex(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__newindex=i
- else
- setmetatable(t,{ __newindex=i })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__newindex=i
+ else
+ setmetatable(t,{ __newindex=i })
+ end
+ return t
end
function table.setmetatablecall(t,f)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- if m then
- m.__call=f
- else
- setmetatable(t,{ __call=f })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ if m then
+ m.__call=f
+ else
+ setmetatable(t,{ __call=f })
+ end
+ return t
end
function table.setmetatableindices(t,f,n,c)
- if type(t)~="table" then
- f,t=t,{}
- end
- local m=getmetatable(t)
- local i=f_index[f] or f
- if m then
- m.__index=i
- m.__newindex=n
- m.__call=c
- else
- setmetatable(t,{
- __index=i,
- __newindex=n,
- __call=c,
- })
- end
- return t
+ if type(t)~="table" then
+ f,t=t,{}
+ end
+ local m=getmetatable(t)
+ local i=f_index[f] or f
+ if m then
+ m.__index=i
+ m.__newindex=n
+ m.__call=c
+ else
+ setmetatable(t,{
+ __index=i,
+ __newindex=n,
+ __call=c,
+ })
+ end
+ return t
end
function table.setmetatablekey(t,key,value)
- local m=getmetatable(t)
- if not m then
- m={}
- setmetatable(t,m)
- end
- m[key]=value
- return t
+ local m=getmetatable(t)
+ if not m then
+ m={}
+ setmetatable(t,m)
+ end
+ m[key]=value
+ return t
end
function table.getmetatablekey(t,key,value)
- local m=getmetatable(t)
- return m and m[key]
+ local m=getmetatable(t)
+ 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
@@ -8309,14 +8855,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 22956, stripped down to: 16106
+-- original size: 23460, stripped down to: 15834
if not modules then modules={} end modules ['util-prs']={
- 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 lpeg,table,string=lpeg,table,string
local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp
@@ -8338,6 +8884,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("}")
@@ -8357,8 +8904,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
+ [2]=left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -8366,311 +8913,329 @@ local nestedbrackets=P { lbracket*(nobracket+V(1))^0*rbracket }
local spaces=space^0
local argument=Cs((lbrace/"")*((nobrace+nestedbraces)^0)*(rbrace/""))
local content=(1-endofstring)^0
-lpegpatterns.nestedbraces=nestedbraces
+lpegpatterns.nestedbraces=nestedbraces
lpegpatterns.nestedparents=nestedparents
-lpegpatterns.nested=nestedbraces
+lpegpatterns.nested=nestedbraces
lpegpatterns.argument=argument
lpegpatterns.content=content
-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("")))
local hash={}
local function set(key,value)
- hash[key]=value
+ hash[key]=value
end
local pattern_a_s=(pattern_a/set)^1
local pattern_b_s=(pattern_b/set)^1
local pattern_c_s=(pattern_c/set)^1
+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
- return (pattern_c/set)^1
- elseif how=="tolerant" then
- return (pattern_b/set)^1
- else
- return (pattern_a/set)^1
- end
+ if how=="strict" then
+ return (pattern_c/set)^1
+ elseif how=="tolerant" then
+ return (pattern_b/set)^1
+ else
+ return (pattern_a/set)^1
+ end
end
function parsers.settings_to_hash(str,existing)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_a_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_a_s,str)
+ return hash
+ 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 {}
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
else
- hash=existing or {}
- lpegmatch(pattern_b_s,str)
- return hash
+ return str
end
+ else
+ hash=existing or {}
+ lpegmatch(pattern_b_s,str)
+ return hash
+ end
end
function parsers.settings_to_hash_strict(str,existing)
- if not str or str=="" then
- return nil
- elseif type(str)=="table" then
- if existing then
- for k,v in next,str do
- existing[k]=v
- end
- return exiting
- else
- return str
- end
- elseif str and str~="" then
- hash=existing or {}
- lpegmatch(pattern_c_s,str)
- return next(hash) and hash
+ if not str or str=="" then
+ return nil
+ elseif type(str)=="table" then
+ if existing then
+ for k,v in next,str do
+ existing[k]=v
+ end
+ return exiting
+ else
+ return str
end
+ elseif str and str~="" then
+ hash=existing or {}
+ lpegmatch(pattern_c_s,str)
+ return next(hash) and hash
+ end
end
local separator=comma*space^0
-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 pattern=spaces*Ct(value*(separator*value)^0)
patterns.settings_to_array=pattern
function parsers.settings_to_array(str,strict)
- if not str or str=="" then
- return {}
- elseif type(str)=="table" then
- return str
- elseif strict then
- if find(str,"{",1,true) then
- return lpegmatch(pattern,str)
- else
- return { str }
- end
- elseif find(str,",",1,true) then
- return lpegmatch(pattern,str)
+ if not str or str=="" then
+ return {}
+ elseif type(str)=="table" then
+ return str
+ elseif strict then
+ if find(str,"{",1,true) then
+ return lpegmatch(pattern,str)
else
- return { str }
+ return { str }
end
+ elseif find(str,",",1,true) then
+ return lpegmatch(pattern,str)
+ else
+ return { str }
+ end
end
function parsers.settings_to_numbers(str)
- if not str or str=="" then
- return {}
- end
- if type(str)=="table" then
- elseif find(str,",",1,true) then
- str=lpegmatch(pattern,str)
- else
- return { tonumber(str) }
- end
- for i=1,#str do
- str[i]=tonumber(str[i])
- end
- return str
-end
-local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
+ if not str or str=="" then
+ return {}
+ end
+ if type(str)=="table" then
+ elseif find(str,",",1,true) then
+ str=lpegmatch(pattern,str)
+ else
+ return { tonumber(str) }
+ end
+ for i=1,#str do
+ str[i]=tonumber(str[i])
+ end
+ return str
+end
+local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+nestedbrackets+nestedparents+(1-comma))^0)
local pattern=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_obey_fences(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache_a={}
local cache_b={}
function parsers.groupedsplitat(symbol,withaction)
- if not symbol then
- symbol=","
- end
- local pattern=(withaction and cache_b or cache_a)[symbol]
- if not pattern then
- local symbols=S(symbol)
- local separator=space^0*symbols*space^0
- local value=P(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
- pattern=spaces*withvalue*(separator*withvalue)^0
- cache_b[symbol]=pattern
- else
- pattern=spaces*Ct(value*(separator*value)^0)
- cache_a[symbol]=pattern
- end
- end
- return pattern
+ if not symbol then
+ symbol=","
+ end
+ local pattern=(withaction and cache_b or cache_a)[symbol]
+ if not pattern then
+ local symbols=S(symbol)
+ local separator=space^0*symbols*space^0
+ 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
+ pattern=spaces*withvalue*(separator*withvalue)^0
+ cache_b[symbol]=pattern
+ else
+ pattern=spaces*Ct(value*(separator*value)^0)
+ cache_a[symbol]=pattern
+ end
+ end
+ return pattern
end
local pattern_a=parsers.groupedsplitat(",",false)
local pattern_b=parsers.groupedsplitat(",",true)
function parsers.stripped_settings_to_array(str)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_a,str)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_a,str)
+ end
end
function parsers.process_stripped_settings(str,action)
- if not str or str=="" then
- return {}
- else
- return lpegmatch(pattern_b,str,1,action)
- end
+ if not str or str=="" then
+ return {}
+ else
+ return lpegmatch(pattern_b,str,1,action)
+ end
end
local function set(t,v)
- t[#t+1]=v
+ t[#t+1]=v
end
local value=P(Carg(1)*value)/set
local pattern=value*(separator*value)^0*Carg(1)
function parsers.add_settings_to_array(t,str)
- return lpegmatch(pattern,str,nil,t)
+ return lpegmatch(pattern,str,nil,t)
end
function parsers.hash_to_string(h,separator,yes,no,strict,omit)
- if h then
- local t,tn,s={},0,sortedkeys(h)
- omit=omit and tohash(omit)
- for i=1,#s do
- local key=s[i]
- if not omit or not omit[key] then
- local value=h[key]
- if type(value)=="boolean" then
- if yes and no then
- if value then
- tn=tn+1
- t[tn]=key..'='..yes
- elseif not strict then
- tn=tn+1
- t[tn]=key..'='..no
- end
- elseif value or not strict then
- tn=tn+1
- t[tn]=key..'='..tostring(value)
- end
- else
- tn=tn+1
- t[tn]=key..'='..value
- end
- end
+ if h then
+ local t={}
+ local tn=0
+ local s=sortedkeys(h)
+ omit=omit and tohash(omit)
+ for i=1,#s do
+ local key=s[i]
+ if not omit or not omit[key] then
+ local value=h[key]
+ if type(value)=="boolean" then
+ if yes and no then
+ if value then
+ tn=tn+1
+ t[tn]=key..'='..yes
+ elseif not strict then
+ tn=tn+1
+ t[tn]=key..'='..no
+ end
+ elseif value or not strict then
+ tn=tn+1
+ t[tn]=key..'='..tostring(value)
+ end
+ else
+ tn=tn+1
+ t[tn]=key..'='..value
end
- return concat(t,separator or ",")
- else
- return ""
+ end
end
+ return concat(t,separator or ",")
+ else
+ return ""
+ end
end
function parsers.array_to_string(a,separator)
- if a then
- return concat(a,separator or ",")
- else
- return ""
- end
+ if a then
+ return concat(a,separator or ",")
+ else
+ return ""
+ end
end
local pattern=Cf(Ct("")*Cg(C((1-S(", "))^1)*S(", ")^0*Cc(true))^1,rawset)
function utilities.parsers.settings_to_set(str)
- return str and lpegmatch(pattern,str) or {}
+ return str and lpegmatch(pattern,str) or {}
end
hashes.settings_to_set=table.setmetatableindex(function(t,k)
- local v=k and lpegmatch(pattern,k) or {}
- t[k]=v
- return v
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
end)
getmetatable(hashes.settings_to_set).__mode="kv"
function parsers.simple_hash_to_string(h,separator)
- local t,tn={},0
- for k,v in sortedhash(h) do
- if v then
- tn=tn+1
- t[tn]=k
- end
+ local t={}
+ local tn=0
+ for k,v in sortedhash(h) do
+ if v then
+ tn=tn+1
+ t[tn]=k
end
- return concat(t,separator or ",")
+ end
+ return concat(t,separator or ",")
end
local str=Cs(lpegpatterns.unquoted)+C((1-whitespace-equal)^1)
local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset)
local splitter=setting^1
function utilities.parsers.options_to_hash(str,target)
- return str and lpegmatch(splitter,str,1,target or {}) or {}
+ return str and lpegmatch(splitter,str,1,target or {}) or {}
end
local splitter=lpeg.tsplitat(" ")
function utilities.parsers.options_to_array(str)
- return str and lpegmatch(splitter,str) or {}
+ return str and lpegmatch(splitter,str) or {}
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1)
local pattern_a=spaces*Ct(value*(separator*value)^0)
local function repeater(n,str)
- if not n then
- return str
+ if not n then
+ return str
+ else
+ local s=lpegmatch(pattern_a,str)
+ if n==1 then
+ return unpack(s)
else
- local s=lpegmatch(pattern_a,str)
- if n==1 then
- return unpack(s)
- else
- local t,tn={},0
- for i=1,n do
- for j=1,#s do
- tn=tn+1
- t[tn]=s[j]
- end
- end
- return unpack(t)
+ local t={}
+ local tn=0
+ for i=1,n do
+ for j=1,#s do
+ tn=tn+1
+ t[tn]=s[j]
end
+ end
+ return unpack(t)
end
+ end
end
local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+(C(digit^1)/tonumber*lparent*Cs((noparent+nestedparents)^1)*rparent)/repeater+C((nestedbraces+(1-comma))^1)
local pattern_b=spaces*Ct(value*(separator*value)^0)
function parsers.settings_to_array_with_repeat(str,expand)
- if expand then
- return lpegmatch(pattern_b,str) or {}
- else
- return lpegmatch(pattern_a,str) or {}
- end
+ if expand then
+ return lpegmatch(pattern_b,str) or {}
+ else
+ return lpegmatch(pattern_a,str) or {}
+ end
end
local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace
local pattern=Ct((space+value)^0)
function parsers.arguments_to_table(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
function parsers.getparameters(self,class,parentclass,settings)
- local sc=self[class]
- if not sc then
- sc={}
- self[class]=sc
- if parentclass then
- local sp=self[parentclass]
- if not sp then
- sp={}
- self[parentclass]=sp
- end
- setmetatableindex(sc,sp)
- end
+ local sc=self[class]
+ if not sc then
+ sc={}
+ self[class]=sc
+ if parentclass then
+ local sp=self[parentclass]
+ if not sp then
+ sp={}
+ self[parentclass]=sp
+ end
+ setmetatableindex(sc,sp)
end
- parsers.settings_to_hash(settings,sc)
+ end
+ parsers.settings_to_hash(settings,sc)
end
function parsers.listitem(str)
- return gmatch(str,"[^, ]+")
+ return gmatch(str,"[^, ]+")
end
local pattern=Cs { "start",
- start=V("one")+V("two")+V("three"),
- rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
- thousand=digit*digit*digit,
- one=digit*V("rest"),
- two=digit*digit*V("rest"),
- three=V("thousand")*V("rest"),
+ start=V("one")+V("two")+V("three"),
+ rest=(Cc(",")*V("thousand"))^0*(P(".")+endofstring)*anything^0,
+ thousand=digit*digit*digit,
+ one=digit*V("rest"),
+ two=digit*digit*V("rest"),
+ three=V("thousand")*V("rest"),
}
lpegpatterns.splitthousands=pattern
function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
+ return lpegmatch(pattern,str) or str
end
local optionalwhitespace=whitespace^0
lpegpatterns.words=Ct((Cs((1-punctuation-whitespace)^1)+anything)^1)
@@ -8684,75 +9249,75 @@ local key=C((1-equal)^1)
local value=dquote*C((1-dquote-escape*dquote)^0)*dquote
local pattern=Cf(Ct("")*(Cg(key*equal*value)*separator^0)^1,rawset)^0*P(-1)
function parsers.keq_to_hash(str)
- if str and str~="" then
- return lpegmatch(pattern,str)
- else
- return {}
- end
+ if str and str~="" then
+ return lpegmatch(pattern,str)
+ else
+ return {}
+ end
end
local defaultspecification={ separator=",",quote='"' }
function parsers.csvsplitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=specification.quote
- local separator=S(separator~="" and separator or ",")
- local whatever=C((1-separator-newline)^0)
- if quotechar and quotechar~="" then
- local quotedata=nil
- for chr in gmatch(quotechar,".") do
- local quotechar=P(chr)
- local quoteword=quotechar*C((1-quotechar)^0)*quotechar
- if quotedata then
- quotedata=quotedata+quoteword
- else
- quotedata=quoteword
- end
- end
- whatever=quotedata+whatever
- end
- local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
- return function(data)
- return lpegmatch(parser,data)
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=specification.quote
+ local separator=S(separator~="" and separator or ",")
+ local whatever=C((1-separator-newline)^0)
+ if quotechar and quotechar~="" then
+ local quotedata=nil
+ for chr in gmatch(quotechar,".") do
+ local quotechar=P(chr)
+ local quoteword=quotechar*C((1-quotechar)^0)*quotechar
+ if quotedata then
+ quotedata=quotedata+quoteword
+ else
+ quotedata=quoteword
+ end
end
+ whatever=quotedata+whatever
+ end
+ local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 )
+ return function(data)
+ return lpegmatch(parser,data)
+ end
end
function parsers.rfc4180splitter(specification)
- specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
- local separator=specification.separator
- local quotechar=P(specification.quote)
- local dquotechar=quotechar*quotechar
+ specification=specification and setmetatableindex(specification,defaultspecification) or defaultspecification
+ local separator=specification.separator
+ local quotechar=P(specification.quote)
+ local dquotechar=quotechar*quotechar
/specification.quote
- local separator=S(separator~="" and separator or ",")
- local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
- local non_escaped=C((1-quotechar-newline-separator)^1)
- local field=escaped+non_escaped+Cc("")
- local record=Ct(field*(separator*field)^1)
- local headerline=record*Cp()
- local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
- local headeryes=Ct(morerecords)
- local headernop=Ct(record*morerecords)
- return function(data,getheader)
- if getheader then
- local header,position=lpegmatch(headerline,data)
- local data=lpegmatch(headeryes,data,position)
- return data,header
- else
- return lpegmatch(headernop,data)
- end
- end
+ local separator=S(separator~="" and separator or ",")
+ local escaped=quotechar*Cs((dquotechar+(1-quotechar))^0)*quotechar
+ local non_escaped=C((1-quotechar-newline-separator)^1)
+ local field=escaped+non_escaped+Cc("")
+ local record=Ct(field*(separator*field)^1)
+ local headerline=record*Cp()
+ local morerecords=(newline^(specification.strict and -1 or 1)*record)^0
+ local headeryes=Ct(morerecords)
+ local headernop=Ct(record*morerecords)
+ return function(data,getheader)
+ if getheader then
+ local header,position=lpegmatch(headerline,data)
+ local data=lpegmatch(headeryes,data,position)
+ return data,header
+ else
+ return lpegmatch(headernop,data)
+ end
+ end
end
local function ranger(first,last,n,action)
- if not first then
- elseif last==true then
- for i=first,n or first do
- action(i)
- end
- elseif last then
- for i=first,last do
- action(i)
- end
- else
- action(first)
+ if not first then
+ elseif last==true then
+ for i=first,n or first do
+ action(i)
end
+ elseif last then
+ for i=first,last do
+ action(i)
+ end
+ else
+ action(first)
+ end
end
local cardinal=lpegpatterns.cardinal/tonumber
local spacers=lpegpatterns.spacer^0
@@ -8760,89 +9325,89 @@ local endofstring=lpegpatterns.endofstring
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1
local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring
function parsers.stepper(str,n,action)
- if type(n)=="function" then
- lpegmatch(stepper,str,1,false,n or print)
- else
- lpegmatch(stepper,str,1,n,action or print)
- end
+ if type(n)=="function" then
+ lpegmatch(stepper,str,1,false,n or print)
+ else
+ lpegmatch(stepper,str,1,n,action or print)
+ end
end
local pattern_math=Cs((P("%")/"\\percent "+P("^")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
local pattern_text=Cs((P("%")/"\\percent "+(P("^")/"\\high")*Cc("{")*lpegpatterns.integer*Cc("}")+anything)^0)
patterns.unittotex=pattern
function parsers.unittotex(str,textmode)
- return lpegmatch(textmode and pattern_text or pattern_math,str)
+ return lpegmatch(textmode and pattern_text or pattern_math,str)
end
local pattern=Cs((P("^")/"<sup>"*lpegpatterns.integer*Cc("</sup>")+anything)^0)
function parsers.unittoxml(str)
- return lpegmatch(pattern,str)
+ return lpegmatch(pattern,str)
end
local cache={}
local spaces=lpegpatterns.space^0
local dummy=function() end
setmetatableindex(cache,function(t,k)
- local separator=P(k)
- local value=(1-separator)^0
- local pattern=spaces*C(value)*separator^0*Cp()
- t[k]=pattern
- return pattern
+ local separator=P(k)
+ local value=(1-separator)^0
+ local pattern=spaces*C(value)*separator^0*Cp()
+ t[k]=pattern
+ return pattern
end)
local commalistiterator=cache[","]
function utilities.parsers.iterator(str,separator)
- local n=#str
- if n==0 then
- return dummy
- else
- local pattern=separator and cache[separator] or commalistiterator
- local p=1
- return function()
- if p<=n then
- local s,e=lpegmatch(pattern,str,p)
- if e then
- p=e
- return s
- end
- end
+ local n=#str
+ if n==0 then
+ return dummy
+ else
+ local pattern=separator and cache[separator] or commalistiterator
+ local p=1
+ return function()
+ if p<=n then
+ local s,e=lpegmatch(pattern,str,p)
+ if e then
+ p=e
+ return s
end
+ end
end
+ end
end
local function initialize(t,name)
- local source=t[name]
- if source then
- local result={}
- for k,v in next,t[name] do
- result[k]=v
- end
- return result
- else
- return {}
+ local source=t[name]
+ if source then
+ local result={}
+ for k,v in next,t[name] do
+ result[k]=v
end
+ return result
+ else
+ return {}
+ end
end
local function fetch(t,name)
- return t[name] or {}
+ return t[name] or {}
end
local function process(result,more)
- for k,v in next,more do
- result[k]=v
- end
- return result
+ for k,v in next,more do
+ result[k]=v
+ end
+ return result
end
local name=C((1-S(", "))^1)
local parser=(Carg(1)*name/initialize)*(S(", ")^1*(Carg(1)*name/fetch))^0
local merge=Cf(parser,process)
function utilities.parsers.mergehashes(hash,list)
- return lpegmatch(merge,list,1,hash)
+ return lpegmatch(merge,list,1,hash)
end
function utilities.parsers.runtime(time)
- if not time then
- time=os.runtime()
- end
- local days=div(time,24*60*60)
- time=mod(time,24*60*60)
- local hours=div(time,60*60)
- time=mod(time,60*60)
- local minutes=div(time,60)
- local seconds=mod(time,60)
- return days,hours,minutes,seconds
+ if not time then
+ time=os.runtime()
+ end
+ local days=div(time,24*60*60)
+ time=mod(time,24*60*60)
+ local hours=div(time,60*60)
+ time=mod(time,60*60)
+ local minutes=div(time,60)
+ local seconds=mod(time,60)
+ return days,hours,minutes,seconds
end
local spacing=whitespace^0
local apply=P("->")
@@ -8850,11 +9415,11 @@ local method=C((1-apply)^1)
local token=lbrace*C((1-rbrace)^1)*rbrace+C(anything^1)
local pattern=spacing*(method*spacing*apply+Carg(1))*spacing*token
function utilities.parsers.splitmethod(str,default)
- if str then
- return lpegmatch(pattern,str,1,default or false)
- else
- return default or false,""
- end
+ if str then
+ return lpegmatch(pattern,str,1,default or false)
+ else
+ return default or false,""
+ end
end
@@ -8864,14 +9429,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-fmt"] = package.loaded["util-fmt"] or true
--- original size: 2274, stripped down to: 1781
+-- original size: 2541, stripped down to: 1624
if not modules then modules={} end modules ['util-fmt']={
- 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"
}
utilities=utilities or {}
utilities.formatters=utilities.formatters or {}
@@ -8882,61 +9447,2887 @@ local strip=string.strip
local lpegmatch=lpeg.match
local stripper=lpeg.patterns.stripzeros
function formatters.stripzeros(str)
- return lpegmatch(stripper,str)
+ return lpegmatch(stripper,str)
end
function formatters.formatcolumns(result,between)
- if result and #result>0 then
- between=between or " "
- local widths,numbers={},{}
- local first=result[1]
- local n=#first
- for i=1,n do
- widths[i]=0
+ if result and #result>0 then
+ between=between or " "
+ local widths,numbers={},{}
+ local first=result[1]
+ local n=#first
+ for i=1,n do
+ widths[i]=0
+ end
+ for i=1,#result do
+ local r=result[i]
+ for j=1,n do
+ local rj=r[j]
+ local tj=type(rj)
+ if tj=="number" then
+ numbers[j]=true
+ rj=tostring(rj)
+ elseif tj~="string" then
+ rj=tostring(rj)
+ r[j]=rj
+ end
+ local w=#rj
+ if w>widths[j] then
+ widths[j]=w
end
- for i=1,#result do
- local r=result[i]
- 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
- local w=#rj
- if w>widths[j] then
- widths[j]=w
- end
+ end
+ end
+ for i=1,n do
+ local w=widths[i]
+ if numbers[i] then
+ if w>80 then
+ widths[i]="%s"..between
+ else
+ widths[i]="%0"..w.."i"..between
+ end
+ else
+ if w>80 then
+ widths[i]="%s"..between
+ elseif w>0 then
+ widths[i]="%-"..w.."s"..between
+ else
+ widths[i]="%s"
+ end
+ end
+ end
+ local template=strip(concat(widths))
+ for i=1,#result do
+ local str=format(template,unpack(result[i]))
+ result[i]=strip(str)
+ end
+ end
+ return result
+end
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-reset"] = package.loaded["util-soc-imp-reset"] or true
+
+-- original size: 374, stripped down to: 282
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-socket"] = package.loaded["util-soc-imp-socket"] or true
+
+-- original size: 4870, stripped down to: 3527
+
+
+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
+ 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
+ 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
+package.loaded["socket"]=socket
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-copas"] = package.loaded["util-soc-imp-copas"] or true
+
+-- original size: 25844, stripped down to: 14821
+
+
+local socket=socket or require("socket")
+local ssl=ssl or nil
+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
+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
+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
+ 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
- for i=1,n do
- local w=widths[i]
- if numbers[i] then
- if w>80 then
- widths[i]="%s"..between
- else
- widths[i]="%0"..w.."i"..between
- end
- else
- if w>80 then
- widths[i]="%s"..between
- elseif w>0 then
- widths[i]="%-"..w.."s"..between
- else
- widths[i]="%s"
- end
+ }
+ } )
+ return set
+end
+local _sleeping={
+ times={},
+ cos={},
+ lethargy={},
+ insert=function()
+ end,
+ remove=function()
+ end,
+ push=function(self,sleeptime,co)
+ if not co then
+ return
+ end
+ if sleeptime<0 then
+ 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=
+ 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=
+ 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
- local template=strip(concat(widths))
- for i=1,#result do
- local str=format(template,unpack(result[i]))
- result[i]=strip(str)
+ end
+}
+local _servers=newset()
+local _reading=newset()
+local _writing=newset()
+local _reading_log={}
+local _writing_log={}
+local _is_timeout={
+ timeout=true,
+ wantread=true,
+ wantwrite=true,
+}
+local function isTCP(socket)
+ return not find(tostring(socket),"^udp")
+end
+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
+local function copasreceivefrom(client,size)
+ local s,err,port
+ if not size or size==0 then
+ size=UDP_DATAGRAM_MAX
+ end
+ repeat
+ 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
+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
+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)
+ 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
+local function copassendto(client,data,ip,port)
+ repeat
+ local s,err=client:sendto(data,ip,port)
+ 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
+local function copasconnect(skt,host,port)
+ skt:settimeout(0)
+ local ret,err,tried_more_than_once
+ repeat
+ ret,err=skt:connect (host,port)
+ if ret or (err~="timeout" and err~="Operation already in progress") then
+ 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
+local function copasdohandshake(skt,sslt)
+ 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
+local function copasflush(client)
+end
+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
+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,
+ 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,
+ bind=function(self,...)
+ return self.socket:bind(...)
+ end,
+ 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,
+ 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,
+}
+local _skt_mt_udp_index={
+ 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,
+ setpeername=function(self,...)
+ return self.socket:getpeername(...)
+ end,
+ setsockname=function(self,...)
+ return self.socket:setsockname(...)
+ end,
+ 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
+local function wrap(skt,sslt)
+ if getmetatable(skt)==_skt_mt_tcp or getmetatable(skt)==_skt_mt_udp then
+ return skt
+ 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
+function copas.handler(handler,sslparams)
+ return function (skt,...)
+ skt=wrap(skt)
+ if sslparams then
+ skt:dohandshake(sslparams)
+ end
+ return handler(skt,...)
+ end
+end
+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
+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
+ if skt and copas.autoclose and isTCP(skt) then
+ skt:close()
+ end
+ _errhandlers[co]=nil
+ end
+end
+local function _accept(input,handler)
+ local client=input:accept()
+ if client then
+ client:settimeout(0)
+ local co=createcoroutine(handler)
+ _doTick (co,client)
+ end
+ return client
+end
+local function _tickRead(skt)
+ _doTick(_reading:pop(skt),skt)
+end
+local function _tickWrite(skt)
+ _doTick(_writing:pop(skt),skt)
+end
+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
+function copas.addthread(handler,...)
+ local thread=createcoroutine(function(_,...) return handler(...) end)
+ _doTick(thread,nil,...)
+ return thread
+end
+local _tasks={}
+local function addtaskRead(task)
+ task.def_tick=_tickRead
+ _tasks[task]=true
+end
+local function addtaskWrite(task)
+ task.def_tick=_tickWrite
+ _tasks[task]=true
+end
+local function tasks()
+ return next,_tasks
+end
+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)
+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)
+local _sleeping_t={
+ tick=function(self,time,...)
+ _doTick(_sleeping:pop(time),...)
+ end
+}
+function copas.sleep(sleeptime)
+ yieldcoroutine((sleeptime or 0),_sleeping)
+end
+function copas.wakeup(co)
+ _sleeping:wakeup(co)
+end
+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
+ for skt,time in next,_reading_log do
+ if not r_evs[skt] and (time-now)>WATCH_DOG_TIMEOUT then
+ local n=#r_evs+1
+ _reading_log[skt]=nil
+ r_evs[n]=skt
+ r_evs[skt]=n
+ end
+ end
+ 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
+local function copasfinished()
+ return not (next(_reading) or next(_writing) or _sleeping:getnext())
+end
+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
+function copas.loop(timeout)
+ copas.running=true
+ while not copasfinished() do
+ copasstep(timeout)
+ end
+ copas.running=false
+end
+package.loaded["copas"]=copas
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-ltn12"] = package.loaded["util-soc-imp-ltn12"] or true
+
+-- original size: 8709, stripped down to: 5411
+
+
+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,
+}
+function filter.cycle(low,ctx,extra)
+ if low then
+ return function(chunk)
+ return (low(ctx,chunk,extra))
+ end
+ end
+end
+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
- return result
+ end
+end
+local function empty()
+ return nil
+end
+function source.empty()
+ return empty
+end
+local function sourceerror(err)
+ return function()
+ return nil,err
+ end
+end
+source.error=sourceerror
+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
+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
+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
+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
+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
+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
+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
+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
+local function null()
+ return 1
+end
+function sink.null()
+ return null
+end
+local function sinkerror(err)
+ return function()
+ return nil,err
+ end
+end
+sink.error=sinkerror
+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
+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
+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
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-mime"] = package.loaded["util-soc-imp-mime"] or true
+
+-- original size: 2328, stripped down to: 1874
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-url"] = package.loaded["util-soc-imp-url"] or true
+
+-- original size: 6863, stripped down to: 5269
+
+
+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)
+ 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
+ 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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-headers"] = package.loaded["util-soc-imp-headers"] or true
+
+-- original size: 5721, stripped down to: 3754
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-tp"] = package.loaded["util-soc-imp-tp"] or true
+
+-- original size: 3116, stripped down to: 2533
+
+
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-http"] = package.loaded["util-soc-imp-http"] or true
+
+-- original size: 12577, stripped down to: 9577
+
+
+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
+local http={
+ TIMEOUT=60,
+ USERAGENT=socket._VERSION,
+}
+socket.http=http
+local PORT=80
+local SCHEMES={
+ http=true,
+}
+local function receiveheaders(sock,headers)
+ if not headers then
+ headers={}
+ end
+ local line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while line~="" do
+ local name,value=skipsocket(2,find(line,"^(.-):%s*(.*)"))
+ if not (name and value) then
+ return nil,"malformed reponse headers"
+ end
+ name=lower(name)
+ line,err=sock:receive()
+ if err then
+ return nil,err
+ end
+ while find(line,"^%s") do
+ value=value..line
+ line=sock:receive()
+ if err then
+ return nil,err
+ end
+ end
+ local found=headers[name]
+ if found then
+ value=found..", "..value
+ end
+ headers[name]=value
+ end
+ return headers
+end
+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
+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
+ 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"]
+ local mode="default"
+ if encoding and encoding~="identity" then
+ mode="http-chunked"
+ elseif length then
+ mode="by-length"
+ end
+ 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
+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
+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
+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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-ftp"] = package.loaded["util-soc-imp-ftp"] or true
+
+-- original size: 10357, stripped down to: 8548
+
+
+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
+ 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
+
+
+end -- of closure
+
+do -- create closure to overcome 200 locals limit
+
+package.loaded["util-soc-imp-smtp"] = package.loaded["util-soc-imp-smtp"] or true
+
+-- original size: 7018, stripped down to: 5883
+
+
+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
end -- of closure
@@ -8945,14 +12336,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-set"] = package.loaded["trac-set"] or true
--- original size: 13044, stripped down to: 9231
+-- original size: 13340, stripped down to: 8826
if not modules then modules={} end modules ['trac-set']={
- 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=type,next,tostring,tonumber
local concat,sortedhash=table.concat,table.sortedhash
@@ -8967,305 +12358,318 @@ utilities.setters=setters
local data={}
local trace_initialize=false
function setters.initialize(filename,name,values)
- local setter=data[name]
- if setter then
- frozen=true
- local data=setter.data
- if data then
- for key,newvalue in sortedhash(values) do
- local newvalue=is_boolean(newvalue,newvalue,true)
- local functions=data[key]
- if functions then
- local oldvalue=functions.value
- if functions.frozen then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
- end
- elseif #functions>0 and not oldvalue then
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
- end
- for i=1,#functions do
- functions[i](newvalue)
- end
- functions.value=newvalue
- functions.frozen=functions.frozen or frozen
- else
- if trace_initialize then
- setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
- end
- end
- else
- functions={ default=newvalue,frozen=frozen }
- data[key]=functions
- if trace_initialize then
- setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
- end
- end
+ local setter=data[name]
+ if setter then
+ frozen=true
+ local data=setter.data
+ if data then
+ for key,newvalue in sortedhash(values) do
+ local newvalue=is_boolean(newvalue,newvalue,true)
+ local functions=data[key]
+ if functions then
+ local oldvalue=functions.value
+ if functions.frozen then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
+ end
+ elseif #functions>0 and not oldvalue then
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
+ end
+ for i=1,#functions do
+ functions[i](newvalue)
+ end
+ functions.value=newvalue
+ functions.frozen=functions.frozen or frozen
+ else
+ if trace_initialize then
+ setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
end
- return true
+ end
+ else
+ functions={ default=newvalue,frozen=frozen }
+ data[key]=functions
+ if trace_initialize then
+ setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
+ end
end
+ end
+ return true
end
+ end
end
local function set(t,what,newvalue)
- local data=t.data
- if not data.frozen then
- local done=t.done
- if type(what)=="string" then
- what=settings_to_hash(what)
- end
- if type(what)~="table" then
- return
- end
- if not done then
- done={}
- t.done=done
- end
- for w,value in sortedhash(what) do
- if value=="" then
- value=newvalue
- elseif not value then
- value=false
- else
- value=is_boolean(value,value,true)
- end
- w=topattern(w,true,true)
- for name,functions in sortedhash(data) do
- if done[name] then
- elseif find(name,w) then
- done[name]=true
- for i=1,#functions do
- functions[i](value)
- end
- functions.value=value
- end
- end
+ local data=t.data
+ if not data.frozen then
+ local done=t.done
+ if type(what)=="string" then
+ what=settings_to_hash(what)
+ end
+ if type(what)~="table" then
+ return
+ end
+ if not done then
+ done={}
+ t.done=done
+ end
+ for w,value in sortedhash(what) do
+ if value=="" then
+ value=newvalue
+ elseif not value then
+ value=false
+ else
+ value=is_boolean(value,value,true)
+ end
+ w=topattern(w,true,true)
+ for name,functions in sortedhash(data) do
+ if done[name] then
+ elseif find(name,w) then
+ done[name]=true
+ for i=1,#functions do
+ functions[i](value)
+ end
+ functions.value=value
end
+ end
end
+ end
end
local function reset(t)
- local data=t.data
- if not data.frozen then
- for name,functions in sortedthash(data) do
- for i=1,#functions do
- functions[i](false)
- end
- functions.value=false
- end
+ local data=t.data
+ if not data.frozen then
+ for name,functions in sortedthash(data) do
+ for i=1,#functions do
+ functions[i](false)
+ end
+ functions.value=false
end
+ end
end
local function enable(t,what)
- set(t,what,true)
+ set(t,what,true)
end
local function disable(t,what)
- local data=t.data
- if not what or what=="" then
- t.done={}
- reset(t)
- else
- set(t,what,false)
- end
+ local data=t.data
+ if not what or what=="" then
+ t.done={}
+ reset(t)
+ else
+ set(t,what,false)
+ end
end
function setters.register(t,what,...)
- local data=t.data
- what=lower(what)
- local functions=data[what]
- if not functions then
- functions={}
- data[what]=functions
- if trace_initialize then
- t.report("defining %a",what)
- end
- end
- local default=functions.default
- for i=1,select("#",...) do
- local fnc=select(i,...)
- local typ=type(fnc)
- if typ=="string" then
- if trace_initialize then
- t.report("coupling %a to %a",what,fnc)
- end
- local s=fnc
- fnc=function(value) set(t,s,value) end
- elseif typ~="function" then
- fnc=nil
- end
- if fnc then
- functions[#functions+1]=fnc
- local value=functions.value or default
- if value~=nil then
- fnc(value)
- functions.value=value
- end
- end
+ local data=t.data
+ what=lower(what)
+ local functions=data[what]
+ if not functions then
+ functions={}
+ data[what]=functions
+ if trace_initialize then
+ t.report("defining %a",what)
+ end
+ end
+ local default=functions.default
+ for i=1,select("#",...) do
+ local fnc=select(i,...)
+ local typ=type(fnc)
+ if typ=="string" then
+ if trace_initialize then
+ t.report("coupling %a to %a",what,fnc)
+ end
+ local s=fnc
+ fnc=function(value) set(t,s,value) end
+ elseif typ~="function" then
+ fnc=nil
+ end
+ if fnc then
+ functions[#functions+1]=fnc
+ local value=functions.value or default
+ if value~=nil then
+ fnc(value)
+ functions.value=value
+ end
end
- return false
+ end
+ return false
end
function setters.enable(t,what)
- local e=t.enable
- t.enable,t.done=enable,{}
- enable(t,what)
- t.enable,t.done=e,{}
+ local e=t.enable
+ t.enable,t.done=enable,{}
+ enable(t,what)
+ t.enable,t.done=e,{}
end
function setters.disable(t,what)
- local e=t.disable
- t.disable,t.done=disable,{}
- disable(t,what)
- t.disable,t.done=e,{}
+ local e=t.disable
+ t.disable,t.done=disable,{}
+ disable(t,what)
+ t.disable,t.done=e,{}
end
function setters.reset(t)
- t.done={}
- reset(t)
+ t.done={}
+ reset(t)
end
function setters.list(t)
- local list=table.sortedkeys(t.data)
- local user,system={},{}
- for l=1,#list do
- local what=list[l]
- if find(what,"^%*") then
- system[#system+1]=what
- else
- user[#user+1]=what
- end
+ local list=table.sortedkeys(t.data)
+ local user,system={},{}
+ for l=1,#list do
+ local what=list[l]
+ if find(what,"^%*") then
+ system[#system+1]=what
+ else
+ user[#user+1]=what
end
- return user,system
+ end
+ return user,system
end
function setters.show(t)
- local list=setters.list(t)
- t.report()
- for k=1,#list do
- local name=list[k]
- local functions=t.data[name]
- if functions then
- local value=functions.value
- local default=functions.default
- local modules=#functions
- if default==nil then
- default="unset"
- elseif type(default)=="table" then
- default=concat(default,"|")
- else
- default=tostring(default)
- end
- if value==nil then
- value="unset"
- elseif type(value)=="table" then
- value=concat(value,"|")
- else
- value=tostring(value)
- end
- t.report(name)
- t.report(" modules : %i",modules)
- t.report(" default : %s",default)
- t.report(" value : %s",value)
- t.report()
- end
+ local list=setters.list(t)
+ t.report()
+ for k=1,#list do
+ local name=list[k]
+ local functions=t.data[name]
+ if functions then
+ local value=functions.value
+ local default=functions.default
+ local modules=#functions
+ if default==nil then
+ default="unset"
+ elseif type(default)=="table" then
+ default=concat(default,"|")
+ else
+ default=tostring(default)
+ end
+ if value==nil then
+ value="unset"
+ elseif type(value)=="table" then
+ value=concat(value,"|")
+ else
+ value=tostring(value)
+ end
+ t.report(name)
+ t.report(" modules : %i",modules)
+ t.report(" default : %s",default)
+ t.report(" value : %s",value)
+ t.report()
end
+ end
end
local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show
function setters.report(setter,...)
- print(format("%-15s : %s\n",setter.name,format(...)))
+ print(format("%-15s : %s\n",setter.name,format(...)))
end
local function default(setter,name)
- local d=setter.data[name]
- return d and d.default
+ local d=setter.data[name]
+ return d and d.default
end
local function value(setter,name)
- local d=setter.data[name]
- return d and (d.value or d.default)
+ local d=setter.data[name]
+ return d and (d.value or d.default)
end
function setters.new(name)
- local setter
- setter={
- data=allocate(),
- name=name,
- report=function(...) setters.report (setter,...) end,
- enable=function(...) enable (setter,...) end,
- disable=function(...) disable (setter,...) end,
- reset=function(...) reset (setter,...) end,
- register=function(...) register(setter,...) end,
- list=function(...) list (setter,...) end,
- show=function(...) show (setter,...) end,
- default=function(...) return default (setter,...) end,
- value=function(...) return value (setter,...) end,
- }
- data[name]=setter
- return setter
+ local setter
+ setter={
+ data=allocate(),
+ name=name,
+ report=function(...) setters.report (setter,...) end,
+ enable=function(...) enable (setter,...) end,
+ disable=function(...) disable (setter,...) end,
+ reset=function(...) reset (setter,...) end,
+ register=function(...) register(setter,...) end,
+ list=function(...) list (setter,...) end,
+ show=function(...) show (setter,...) end,
+ default=function(...) return default (setter,...) end,
+ value=function(...) return value (setter,...) end,
+ }
+ data[name]=setter
+ return setter
end
trackers=setters.new("trackers")
directives=setters.new("directives")
experiments=setters.new("experiments")
-local t_enable,t_disable=trackers .enable,trackers .disable
+local t_enable,t_disable=trackers .enable,trackers .disable
local d_enable,d_disable=directives .enable,directives .disable
local e_enable,e_disable=experiments.enable,experiments.disable
-local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
-local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
+local trace_directives=false local trace_directives=false trackers.register("system.directives",function(v) trace_directives=v end)
+local trace_experiments=false local trace_experiments=false trackers.register("system.experiments",function(v) trace_experiments=v end)
function directives.enable(...)
- if trace_directives then
- directives.report("enabling: % t",{...})
- end
- d_enable(...)
+ if trace_directives then
+ directives.report("enabling: % t",{...})
+ end
+ d_enable(...)
end
function directives.disable(...)
- if trace_directives then
- directives.report("disabling: % t",{...})
- end
- d_disable(...)
+ if trace_directives then
+ directives.report("disabling: % t",{...})
+ end
+ d_disable(...)
end
function experiments.enable(...)
- if trace_experiments then
- experiments.report("enabling: % t",{...})
- end
- e_enable(...)
+ if trace_experiments then
+ experiments.report("enabling: % t",{...})
+ end
+ e_enable(...)
end
function experiments.disable(...)
- if trace_experiments then
- experiments.report("disabling: % t",{...})
- end
- e_disable(...)
+ if trace_experiments then
+ experiments.report("disabling: % t",{...})
+ end
+ e_disable(...)
end
directives.register("system.nostatistics",function(v)
- if statistics then
- statistics.enable=not v
- else
- end
+ if statistics then
+ statistics.enable=not v
+ else
+ end
end)
directives.register("system.nolibraries",function(v)
- if libraries then
- libraries=nil
- else
- end
+ if libraries then
+ libraries=nil
+ else
+ end
end)
if environment then
- local engineflags=environment.engineflags
- if engineflags then
- local list=engineflags["c:trackers"] or engineflags["trackers"]
- if type(list)=="string" then
- setters.initialize("commandline flags","trackers",settings_to_hash(list))
- end
- local list=engineflags["c:directives"] or engineflags["directives"]
- if type(list)=="string" then
- setters.initialize("commandline flags","directives",settings_to_hash(list))
- end
+ local engineflags=environment.engineflags
+ if engineflags then
+ local list=engineflags["c:trackers"] or engineflags["trackers"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","trackers",settings_to_hash(list))
end
-end
-if texconfig then
- local function set(k,v)
- v=tonumber(v)
- if v then
- texconfig[k]=v
- end
+ local list=engineflags["c:directives"] or engineflags["directives"]
+ if type(list)=="string" then
+ setters.initialize("commandline flags","directives",settings_to_hash(list))
end
- directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
- directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
- directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
- directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
- directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
- directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
- directives.register("luatex.paramsize",function(v) set("param_size",v) end)
- directives.register("luatex.savesize",function(v) set("save_size",v) end)
- directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+ end
end
+if texconfig then
+ local function set(k,v)
+ v=tonumber(v)
+ if v then
+ texconfig[k]=v
+ end
+ end
+ directives.register("luatex.expanddepth",function(v) set("expand_depth",v) end)
+ directives.register("luatex.hashextra",function(v) set("hash_extra",v) end)
+ directives.register("luatex.nestsize",function(v) set("nest_size",v) end)
+ directives.register("luatex.maxinopen",function(v) set("max_in_open",v) end)
+ directives.register("luatex.maxprintline",function(v) set("max_print_line",v) end)
+ directives.register("luatex.maxstrings",function(v) set("max_strings",v) end)
+ directives.register("luatex.paramsize",function(v) set("param_size",v) end)
+ directives.register("luatex.savesize",function(v) set("save_size",v) end)
+ directives.register("luatex.stacksize",function(v) set("stack_size",v) end)
+end
+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,
+}
end -- of closure
@@ -9274,14 +12678,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-log"] = package.loaded["trac-log"] or true
--- original size: 32922, stripped down to: 23011
+-- original size: 32608, stripped down to: 20925
if not modules then modules={} end modules ['trac-log']={
- version=1.001,
- comment="companion to trac-log.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 trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local next,type,select,print=next,type,select,print
local format,gmatch,find=string.format,string.gmatch,string.find
@@ -9292,7 +12696,7 @@ local datetime=os.date
local openfile=io.open
local runningtex=tex and (tex.jobname or tex.formatname)
local write_nl=runningtex and texio and texio.write_nl or print
-local write=runningtex and texio and texio.write or io.write
+local write=runningtex and texio and texio.write or io.write
local setmetatableindex=table.setmetatableindex
local formatters=string.formatters
local settings_to_hash=utilities.parsers.settings_to_hash
@@ -9308,404 +12712,404 @@ webpage : http://www.pragma-ade.nl / http://tex.aanhet.net
wiki : http://contextgarden.net
]]
formatters.add (
- formatters,"unichr",
- [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
+ formatters,"unichr",
+ [["U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"]]
)
formatters.add (
- formatters,"chruni",
- [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
+ formatters,"chruni",
+ [[utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"]]
)
local function ignore() end
setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end)
local report,subreport,status,settarget,setformats,settranslations
local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters,newline
if runningtex then
- if texio.setescape then
- texio.setescape(0)
- end
- if arg then
- for k,v in next,arg do
- if v=="--ansi" or v=="--c:ansi" then
- variant="ansi"
- break
- end
- end
- end
- local function useluawrites()
- local texio_write_nl=texio.write_nl
- local texio_write=texio.write
- local io_write=io.write
- write_nl=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write_nl("log",...)
- texio_write_nl("term","")
- io_write(...)
- elseif target=="log" then
- texio_write_nl("log",...)
- elseif target=="term" then
- texio_write_nl("term","")
- io_write(...)
- elseif type(target)=="number" then
- texio_write_nl(target,...)
- elseif target~="none" then
- texio_write_nl("log",target,...)
- texio_write_nl("term","")
- io_write(target,...)
- end
- end
- write=function(target,...)
- if not io_write then
- io_write=io.write
- end
- if target=="term and log" then
- texio_write("log",...)
- io_write(...)
- elseif target=="log" then
- texio_write("log",...)
- elseif target=="term" then
- io_write(...)
- elseif type(target)=="number" then
- texio_write(target,...)
- elseif target~="none" then
- texio_write("log",target,...)
- io_write(target,...)
- end
- end
- texio.write=write
- texio.write_nl=write_nl
- useluawrites=ignore
- end
- local whereto="both"
- local target=nil
- local targets=nil
- local formats=table.setmetatableindex("self")
- local translations=table.setmetatableindex("self")
- local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
- local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="log",
- log="log",
- file="log",
- console="term",
- terminal="term",
- both="term and log",
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s > %s\n"],
- report_nop=formatters["%-15s >\n"],
- direct_yes=formatters["%-15s > %s"],
- direct_nop=formatters["%-15s >"],
- subreport_yes=formatters["%-15s > %s > %s\n"],
- subreport_nop=formatters["%-15s > %s >\n"],
- subdirect_yes=formatters["%-15s > %s > %s"],
- subdirect_nop=formatters["%-15s > %s >"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- targets={
- logfile="none",
- log="none",
- file="none",
- console="term",
- terminal="term",
- both="term",
- },
- }
- }
- logs.flush=io.flush
- writer=function(...)
- write_nl(target,...)
- end
- newline=function()
- write_nl(target,"\n")
- end
- report=function(a,b,c,...)
- if c~=nil then
- write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,report_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,report_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
- end
- direct=function(a,b,c,...)
- if c~=nil then
- return direct_yes(translations[a],formatters[formats[b]](c,...))
- elseif b then
- return direct_yes(translations[a],formats[b])
- elseif a then
- return direct_nop(translations[a])
- else
- return ""
- end
- end
- subreport=function(a,s,b,c,...)
- if c~=nil then
- write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
- elseif a then
- write_nl(target,subreport_nop(translations[a],translations[s]))
- else
- write_nl(target,"\n")
- end
- end
- subdirect=function(a,s,b,c,...)
- if c~=nil then
- return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
- elseif b then
- return subdirect_yes(translations[a],translations[s],formats[b])
- elseif a then
- return subdirect_nop(translations[a],translations[s])
- else
- return ""
- end
+ if texio.setescape then
+ texio.setescape(0)
+ end
+ if arg then
+ for k,v in next,arg do
+ if v=="--ansi" or v=="--c:ansi" then
+ variant="ansi"
+ break
+ end
end
- status=function(a,b,c,...)
- if c~=nil then
- write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
- elseif b then
- write_nl(target,status_yes(translations[a],formats[b]))
- elseif a then
- write_nl(target,status_nop(translations[a]))
- else
- write_nl(target,"\n")
- end
+ end
+ local function useluawrites()
+ local texio_write_nl=texio.write_nl
+ local texio_write=texio.write
+ local io_write=io.write
+ write_nl=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write_nl("log",...)
+ texio_write_nl("term","")
+ io_write(...)
+ elseif target=="log" then
+ texio_write_nl("log",...)
+ elseif target=="term" then
+ texio_write_nl("term","")
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write_nl(target,...)
+ elseif target~="none" then
+ texio_write_nl("log",target,...)
+ texio_write_nl("term","")
+ io_write(target,...)
+ end
end
- settarget=function(askedwhereto)
- whereto=askedwhereto or whereto or "both"
- target=targets[whereto]
- if not target then
- whereto="both"
- target=targets[whereto]
- end
- if target=="term" or target=="term and log" then
- logs.flush=io.flush
- else
- logs.flush=ignore
- end
+ write=function(target,...)
+ if not io_write then
+ io_write=io.write
+ end
+ if target=="term and log" then
+ texio_write("log",...)
+ io_write(...)
+ elseif target=="log" then
+ texio_write("log",...)
+ elseif target=="term" then
+ io_write(...)
+ elseif type(target)=="number" then
+ texio_write(target,...)
+ elseif target~="none" then
+ texio_write("log",target,...)
+ io_write(target,...)
+ end
end
- local stack={}
- pushtarget=function(newtarget)
- insert(stack,target)
- settarget(newtarget)
+ texio.write=write
+ texio.write_nl=write_nl
+ useluawrites=ignore
+ end
+ local whereto="both"
+ local target=nil
+ local targets=nil
+ local formats=table.setmetatableindex("self")
+ local translations=table.setmetatableindex("self")
+ local report_yes,subreport_yes,direct_yes,subdirect_yes,status_yes
+ local report_nop,subreport_nop,direct_nop,subdirect_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="log",
+ log="log",
+ file="log",
+ console="term",
+ terminal="term",
+ both="term and log",
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s > %s\n"],
+ report_nop=formatters["%-15s >\n"],
+ direct_yes=formatters["%-15s > %s"],
+ direct_nop=formatters["%-15s >"],
+ subreport_yes=formatters["%-15s > %s > %s\n"],
+ subreport_nop=formatters["%-15s > %s >\n"],
+ subdirect_yes=formatters["%-15s > %s > %s"],
+ subdirect_nop=formatters["%-15s > %s >"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ targets={
+ logfile="none",
+ log="none",
+ file="none",
+ console="term",
+ terminal="term",
+ both="term",
+ },
+ }
+ }
+ logs.flush=io.flush
+ writer=function(...)
+ write_nl(target,...)
+ end
+ newline=function()
+ write_nl(target,"\n")
+ end
+ report=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,report_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,report_nop(translations[a]))
+ else
+ write_nl(target,"\n")
end
- poptarget=function()
- if #stack>0 then
- settarget(remove(stack))
- end
+ end
+ direct=function(a,b,c,...)
+ if c~=nil then
+ return direct_yes(translations[a],formatters[formats[b]](c,...))
+ elseif b then
+ return direct_yes(translations[a],formats[b])
+ elseif a then
+ return direct_nop(translations[a])
+ else
+ return ""
end
- setformats=function(f)
- formats=f
+ end
+ subreport=function(a,s,b,c,...)
+ if c~=nil then
+ write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,subreport_yes(translations[a],translations[s],formats[b]))
+ elseif a then
+ write_nl(target,subreport_nop(translations[a],translations[s]))
+ else
+ write_nl(target,"\n")
end
- settranslations=function(t)
- translations=t
+ end
+ subdirect=function(a,s,b,c,...)
+ if c~=nil then
+ return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...))
+ elseif b then
+ return subdirect_yes(translations[a],translations[s],formats[b])
+ elseif a then
+ return subdirect_nop(translations[a],translations[s])
+ else
+ return ""
end
- setprocessor=function(f)
- local writeline=write_nl
- write_nl=function(target,...)
- writeline(target,f(...))
- end
+ end
+ status=function(a,b,c,...)
+ if c~=nil then
+ write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...)))
+ elseif b then
+ write_nl(target,status_yes(translations[a],formats[b]))
+ elseif a then
+ write_nl(target,status_nop(translations[a]))
+ else
+ write_nl(target,"\n")
+ end
+ end
+ settarget=function(askedwhereto)
+ whereto=askedwhereto or whereto or "both"
+ target=targets[whereto]
+ if not target then
+ whereto="both"
+ target=targets[whereto]
+ end
+ if target=="term" or target=="term and log" then
+ logs.flush=io.flush
+ else
+ logs.flush=ignore
+ end
+ end
+ local stack={}
+ pushtarget=function(newtarget)
+ insert(stack,target)
+ settarget(newtarget)
+ end
+ poptarget=function()
+ if #stack>0 then
+ settarget(remove(stack))
+ end
+ end
+ setformats=function(f)
+ formats=f
+ end
+ settranslations=function(t)
+ translations=t
+ end
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(target,...)
+ writeline(target,f(...))
+ end
+ end
+ setformatters=function(specification)
+ local t=nil
+ local f=nil
+ local d=variants.default
+ if not specification then
+ elseif type(specification)=="table" then
+ t=specification.targets
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ t=v.targets
+ f=v.formats
+ variant=specification
+ end
end
- setformatters=function(specification)
- local t=nil
- local f=nil
- local d=variants.default
- if not specification then
- elseif type(specification)=="table" then
- t=specification.targets
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- t=v.targets
- f=v.formats
- variant=specification
- end
- end
- targets=t or d.targets
- target=targets[whereto] or target
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- direct_yes=f.direct_yes
- direct_nop=f.direct_nop
- subdirect_yes=f.subdirect_yes
- subdirect_nop=f.subdirect_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- if variant=="ansi" then
- useluawrites()
- end
- settarget(whereto)
- end
- setformatters(variant)
- setlogfile=ignore
- settimedlog=ignore
+ targets=t or d.targets
+ target=targets[whereto] or target
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ direct_yes=f.direct_yes
+ direct_nop=f.direct_nop
+ subdirect_yes=f.subdirect_yes
+ subdirect_nop=f.subdirect_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ if variant=="ansi" then
+ useluawrites()
+ end
+ settarget(whereto)
+ end
+ setformatters(variant)
+ setlogfile=ignore
+ settimedlog=ignore
else
- local report_yes,subreport_yes,status_yes
- local report_nop,subreport_nop,status_nop
- local variants={
- default={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- ansi={
- formats={
- report_yes=formatters["%-15s | %s"],
- report_nop=formatters["%-15s |"],
- subreport_yes=formatters["%-15s | %s | %s"],
- subreport_nop=formatters["%-15s | %s |"],
- status_yes=formatters["%-15s : %s\n"],
- status_nop=formatters["%-15s :\n"],
- },
- },
- }
- logs.flush=ignore
- writer=function(s)
- write_nl(s)
- end
- newline=function()
- write_nl("\n")
+ local report_yes,subreport_yes,status_yes
+ local report_nop,subreport_nop,status_nop
+ local variants={
+ default={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ ansi={
+ formats={
+ report_yes=formatters["%-15s | %s"],
+ report_nop=formatters["%-15s |"],
+ subreport_yes=formatters["%-15s | %s | %s"],
+ subreport_nop=formatters["%-15s | %s |"],
+ status_yes=formatters["%-15s : %s\n"],
+ status_nop=formatters["%-15s :\n"],
+ },
+ },
+ }
+ logs.flush=ignore
+ writer=function(s)
+ write_nl(s)
+ end
+ newline=function()
+ write_nl("\n")
+ end
+ report=function(a,b,c,...)
+ if c then
+ write_nl(report_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(report_yes(a,b))
+ elseif a then
+ write_nl(report_nop(a))
+ else
+ write_nl("")
end
- report=function(a,b,c,...)
- if c then
- write_nl(report_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(report_yes(a,b))
- elseif a then
- write_nl(report_nop(a))
- else
- write_nl("")
- end
+ end
+ subreport=function(a,sub,b,c,...)
+ if c then
+ write_nl(subreport_yes(a,sub,formatters[b](c,...)))
+ elseif b then
+ write_nl(subreport_yes(a,sub,b))
+ elseif a then
+ write_nl(subreport_nop(a,sub))
+ else
+ write_nl("")
end
- subreport=function(a,sub,b,c,...)
- if c then
- write_nl(subreport_yes(a,sub,formatters[b](c,...)))
- elseif b then
- write_nl(subreport_yes(a,sub,b))
- elseif a then
- write_nl(subreport_nop(a,sub))
- else
- write_nl("")
+ end
+ status=function(a,b,c,...)
+ if c then
+ write_nl(status_yes(a,formatters[b](c,...)))
+ elseif b then
+ write_nl(status_yes(a,b))
+ elseif a then
+ write_nl(status_nop(a))
+ else
+ write_nl("\n")
+ end
+ end
+ direct=ignore
+ subdirect=ignore
+ settarget=ignore
+ pushtarget=ignore
+ poptarget=ignore
+ setformats=ignore
+ settranslations=ignore
+ setprocessor=function(f)
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(f(s))
+ end
+ end
+ setformatters=function(specification)
+ local f=nil
+ local d=variants.default
+ if specification then
+ if type(specification)=="table" then
+ f=specification.formats or specification
+ else
+ local v=variants[specification]
+ if v then
+ f=v.formats
end
+ end
end
- status=function(a,b,c,...)
- if c then
- write_nl(status_yes(a,formatters[b](c,...)))
- elseif b then
- write_nl(status_yes(a,b))
- elseif a then
- write_nl(status_nop(a))
- else
- write_nl("\n")
- end
- end
- direct=ignore
- subdirect=ignore
- settarget=ignore
- pushtarget=ignore
- poptarget=ignore
- setformats=ignore
- settranslations=ignore
- setprocessor=function(f)
- local writeline=write_nl
+ if f then
+ d=d.formats
+ else
+ f=d.formats
+ d=f
+ end
+ setmetatableindex(f,d)
+ report_yes=f.report_yes
+ report_nop=f.report_nop
+ subreport_yes=f.subreport_yes
+ subreport_nop=f.subreport_nop
+ status_yes=f.status_yes
+ status_nop=f.status_nop
+ end
+ setformatters(variant)
+ setlogfile=function(name,keepopen)
+ if name and name~="" then
+ local localtime=os.localtime
+ local writeline=write_nl
+ if keepopen then
+ local f=io.open(name,"ab")
write_nl=function(s)
- writeline(f(s))
- end
- end
- setformatters=function(specification)
- local f=nil
- local d=variants.default
- if specification then
- if type(specification)=="table" then
- f=specification.formats or specification
- else
- local v=variants[specification]
- if v then
- f=v.formats
- end
- end
- end
- if f then
- d=d.formats
- else
- f=d.formats
- d=f
- end
- setmetatableindex(f,d)
- report_yes=f.report_yes
- report_nop=f.report_nop
- subreport_yes=f.subreport_yes
- subreport_nop=f.subreport_nop
- status_yes=f.status_yes
- status_nop=f.status_nop
- end
- setformatters(variant)
- setlogfile=function(name,keepopen)
- if name and name~="" then
- local localtime=os.localtime
- local writeline=write_nl
- if keepopen then
- local f=io.open(name,"ab")
- write_nl=function(s)
- writeline(s)
- f:write(localtime()," | ",s,"\n")
- end
- else
- write_nl=function(s)
- writeline(s)
- local f=io.open(name,"ab")
- f:write(localtime()," | ",s,"\n")
- f:close()
- end
- end
+ writeline(s)
+ f:write(localtime()," | ",s,"\n")
end
- setlogfile=ignore
- end
- settimedlog=function()
- local localtime=os.localtime
- local writeline=write_nl
+ else
write_nl=function(s)
- writeline(localtime().." | "..s)
+ writeline(s)
+ local f=io.open(name,"ab")
+ f:write(localtime()," | ",s,"\n")
+ f:close()
end
- settimedlog=ignore
+ end
end
+ setlogfile=ignore
+ end
+ settimedlog=function()
+ local localtime=os.localtime
+ local writeline=write_nl
+ write_nl=function(s)
+ writeline(localtime().." | "..s)
+ end
+ settimedlog=ignore
+ end
end
logs.report=report
logs.subreport=subreport
@@ -9727,198 +13131,186 @@ local data={}
local states=nil
local force=false
function logs.reporter(category,subcategory)
- local logger=data[category]
- if not logger then
- local state=states==true
- if not state and type(states)=="table" then
- for c,_ in next,states do
- if find(category,c) then
- state=true
- break
- end
- end
+ local logger=data[category]
+ if not logger then
+ local state=states==true
+ if not state and type(states)=="table" then
+ for c,_ in next,states do
+ if find(category,c) then
+ state=true
+ break
end
- logger={
- reporters={},
- state=state,
- }
- data[category]=logger
- end
- local reporter=logger.reporters[subcategory or "default"]
- if not reporter then
- if subcategory then
- reporter=function(...)
- if force or not logger.state then
- subreport(category,subcategory,...)
- end
- end
- logger.reporters[subcategory]=reporter
- else
- local tag=category
- reporter=function(...)
- if force or not logger.state then
- report(category,...)
- end
- end
- logger.reporters.default=reporter
+ end
+ end
+ logger={
+ reporters={},
+ state=state,
+ }
+ data[category]=logger
+ end
+ local reporter=logger.reporters[subcategory or "default"]
+ if not reporter then
+ if subcategory then
+ reporter=function(...)
+ if force or not logger.state then
+ subreport(category,subcategory,...)
end
+ end
+ logger.reporters[subcategory]=reporter
+ else
+ local tag=category
+ reporter=function(...)
+ if force or not logger.state then
+ report(category,...)
+ end
+ end
+ logger.reporters.default=reporter
end
- return reporter
+ end
+ return reporter
end
logs.new=logs.reporter
local ctxreport=logs.writer
function logs.setmessenger(m)
- ctxreport=m
+ ctxreport=m
end
function logs.messenger(category,subcategory)
- if subcategory then
- return function(...)
- ctxreport(subdirect(category,subcategory,...))
- end
- else
- return function(...)
- ctxreport(direct(category,...))
- end
+ if subcategory then
+ return function(...)
+ ctxreport(subdirect(category,subcategory,...))
end
+ else
+ return function(...)
+ ctxreport(direct(category,...))
+ end
+ end
end
local function setblocked(category,value)
- if category==true or category=="all" then
- category,value="*",true
- elseif category==false then
- category,value="*",false
- elseif value==nil then
- value=true
- end
- if category=="*" then
- states=value
+ if category==true or category=="all" then
+ category,value="*",true
+ elseif category==false then
+ category,value="*",false
+ elseif value==nil then
+ value=true
+ end
+ if category=="*" then
+ states=value
+ for k,v in next,data do
+ v.state=value
+ end
+ else
+ alllocked=false
+ states=settings_to_hash(category,type(states)=="table" and states or nil)
+ for c in next,states do
+ local v=data[c]
+ if v then
+ v.state=value
+ else
+ c=topattern(c,true,true)
for k,v in next,data do
+ if find(k,c) then
v.state=value
+ end
end
- else
- alllocked=false
- states=settings_to_hash(category,type(states)=="table" and states or nil)
- for c in next,states do
- local v=data[c]
- if v then
- v.state=value
- else
- c=topattern(c,true,true)
- for k,v in next,data do
- if find(k,c) then
- v.state=value
- end
- end
- end
- end
+ end
end
+ end
end
function logs.disable(category,value)
- setblocked(category,value==nil and true or value)
+ setblocked(category,value==nil and true or value)
end
function logs.enable(category)
- setblocked(category,false)
+ setblocked(category,false)
end
function logs.categories()
- return sortedkeys(data)
+ return sortedkeys(data)
end
function logs.show()
- local n,c,s,max=0,0,0,0
- for category,v in table.sortedpairs(data) do
- n=n+1
- local state=v.state
- local reporters=v.reporters
- local nc=#category
- if nc>c then
- c=nc
- end
- for subcategory,_ in next,reporters do
- local ns=#subcategory
- if ns>c then
- s=ns
- end
- local m=nc+ns
- if m>max then
- max=m
- end
- end
- local subcategories=concat(sortedkeys(reporters),", ")
- if state==true then
- state="disabled"
- elseif state==false then
- state="enabled"
- else
- state="unknown"
- end
- report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ local n,c,s,max=0,0,0,0
+ for category,v in table.sortedpairs(data) do
+ n=n+1
+ local state=v.state
+ local reporters=v.reporters
+ local nc=#category
+ if nc>c then
+ c=nc
+ end
+ for subcategory,_ in next,reporters do
+ local ns=#subcategory
+ if ns>c then
+ s=ns
+ end
+ local m=nc+ns
+ if m>max then
+ max=m
+ end
+ end
+ local subcategories=concat(sortedkeys(reporters),", ")
+ if state==true then
+ state="disabled"
+ elseif state==false then
+ state="enabled"
+ else
+ state="unknown"
end
- report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
+ report("logging","category %a, subcategories %a, state %a",category,subcategories,state)
+ end
+ report("logging","categories: %s, max category: %s, max subcategory: %s, max combined: %s",n,c,s,max)
end
local delayed_reporters={}
setmetatableindex(delayed_reporters,function(t,k)
- local v=logs.reporter(k.name)
- t[k]=v
- return v
+ local v=logs.reporter(k.name)
+ t[k]=v
+ return v
end)
function utilities.setters.report(setter,...)
- delayed_reporters[setter](...)
+ delayed_reporters[setter](...)
end
directives.register("logs.blocked",function(v)
- setblocked(v,true)
+ setblocked(v,true)
end)
directives.register("logs.target",function(v)
- settarget(v)
+ settarget(v)
end)
if tex then
- local report=logs.reporter("pages")
- local texgetcount=tex and tex.getcount
- local real,user,sub
- function logs.start_page_number()
- real=texgetcount("realpageno")
- user=texgetcount("userpageno")
- sub=texgetcount("subpageno")
- end
- local timing=false
- local starttime=nil
- local lasttime=nil
- trackers.register("pages.timing",function(v)
- starttime=os.clock()
- timing=true
- end)
- function logs.stop_page_number()
- if timing then
- local elapsed,average
- local stoptime=os.clock()
- 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)
- else
- report("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average)
- end
- 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
- end
- logs.flush()
+ local report=logs.reporter("pages")
+ local texgetcount=tex and tex.getcount
+ local real,user,sub=0,0,0
+ function logs.start_page_number()
+ real=texgetcount("realpageno")
+ user=texgetcount("userpageno")
+ sub=texgetcount("subpageno")
+ end
+ local timing=false
+ local lasttime=nil
+ trackers.register("pages.timing",function(v)
+ timing=""
+ end)
+ function logs.stop_page_number()
+ if timing then
+ local elapsed=statistics.currenttime(statistics)
+ local average,page
+ if not lasttime or real<2 then
+ average=elapsed
+ page=elapsed
+ else
+ 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
+ report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing)
+ end
+ logs.flush()
+ end
end
local nesting=0
local verbose=false
@@ -9942,222 +13334,222 @@ logs.help=ignore
local Carg,C,lpegmatch=lpeg.Carg,lpeg.C,lpeg.match
local p_newline=lpeg.patterns.newline
local linewise=(
- Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
+ Carg(1)*C((1-p_newline)^1)/function(t,s) t.report(s) end+Carg(1)*p_newline^2/function(t) t.report() end+p_newline
)^1
local function reportlines(t,str)
- if str then
- lpegmatch(linewise,str,1,t)
- end
+ if str then
+ lpegmatch(linewise,str,1,t)
+ end
end
local function reportbanner(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- t.report()
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ t.report()
+ end
end
local function reportversion(t)
- local banner=t.banner
- if banner then
- t.report(banner)
- end
+ local banner=t.banner
+ if banner then
+ t.report(banner)
+ end
end
local function reporthelp(t,...)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="string" then
- reportlines(t,helpinfo)
- elseif type(helpinfo)=="table" then
- for i=1,select("#",...) do
- reportlines(t,t.helpinfo[select(i,...)])
- if i<n then
- t.report()
- end
- end
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="string" then
+ reportlines(t,helpinfo)
+ elseif type(helpinfo)=="table" then
+ for i=1,select("#",...) do
+ reportlines(t,t.helpinfo[select(i,...)])
+ if i<n then
+ t.report()
+ end
end
+ end
end
local function reportinfo(t)
- t.report()
- reportlines(t,t.moreinfo)
+ t.report()
+ reportlines(t,t.moreinfo)
end
local function reportexport(t,method)
- report(t.helpinfo)
+ report(t.helpinfo)
end
local reporters={
- lines=reportlines,
- banner=reportbanner,
- version=reportversion,
- help=reporthelp,
- info=reportinfo,
- export=reportexport,
+ lines=reportlines,
+ banner=reportbanner,
+ version=reportversion,
+ help=reporthelp,
+ info=reportinfo,
+ export=reportexport,
}
local exporters={
}
logs.reporters=reporters
logs.exporters=exporters
function logs.application(t)
- t.name=t.name or "unknown"
- t.banner=t.banner
- t.moreinfo=moreinfo
- t.report=logs.reporter(t.name)
- t.help=function(...)
- reporters.banner(t)
- reporters.help(t,...)
- reporters.info(t)
- end
- t.export=function(...)
- reporters.export(t,...)
- end
- t.identify=function()
- reporters.banner(t)
- end
- t.version=function()
- reporters.version(t)
- end
- return t
+ t.name=t.name or "unknown"
+ t.banner=t.banner
+ t.moreinfo=moreinfo
+ t.report=logs.reporter(t.name)
+ t.help=function(...)
+ reporters.banner(t)
+ reporters.help(t,...)
+ reporters.info(t)
+ end
+ t.export=function(...)
+ reporters.export(t,...)
+ end
+ t.identify=function()
+ reporters.banner(t)
+ end
+ t.version=function()
+ reporters.version(t)
+ end
+ return t
end
local f_syslog=formatters["%s %s => %s => %s => %s\r"]
function logs.system(whereto,process,jobname,category,fmt,arg,...)
- local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
- for i=1,10 do
- local f=openfile(whereto,"a")
- if f then
- f:write(message)
- f:close()
- break
- else
- sleep(0.1)
- end
+ local message=f_syslog(datetime("%d/%m/%y %H:%m:%S"),process,jobname,category,arg==nil and fmt or format(fmt,arg,...))
+ for i=1,10 do
+ local f=openfile(whereto,"a")
+ if f then
+ f:write(message)
+ f:close()
+ break
+ else
+ sleep(0.1)
end
+ end
end
local report_system=logs.reporter("system","logs")
function logs.obsolete(old,new)
- local o=loadstring("return "..new)()
- if type(o)=="function" then
- return function(...)
- report_system("function %a is obsolete, use %a",old,new)
- loadstring(old.."="..new.." return "..old)()(...)
- end
- elseif type(o)=="table" then
- local t,m={},{}
- m.__index=function(t,k)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- return o[k]
- end
- m.__newindex=function(t,k,v)
- report_system("table %a is obsolete, use %a",old,new)
- m.__index,m.__newindex=o,o
- o[k]=v
- end
- if libraries then
- libraries.obsolete[old]=t
- end
- setmetatable(t,m)
- return t
+ local o=loadstring("return "..new)()
+ if type(o)=="function" then
+ return function(...)
+ report_system("function %a is obsolete, use %a",old,new)
+ loadstring(old.."="..new.." return "..old)()(...)
+ end
+ elseif type(o)=="table" then
+ local t,m={},{}
+ m.__index=function(t,k)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ return o[k]
+ end
+ m.__newindex=function(t,k,v)
+ report_system("table %a is obsolete, use %a",old,new)
+ m.__index,m.__newindex=o,o
+ o[k]=v
+ end
+ if libraries then
+ libraries.obsolete[old]=t
end
+ setmetatable(t,m)
+ return t
+ end
end
if utilities then
- utilities.report=report_system
+ utilities.report=report_system
end
if tex and tex.error then
- function logs.texerrormessage(...)
- tex.error(format(...),{})
- end
+ function logs.texerrormessage(...)
+ tex.error(format(...))
+ end
else
- function logs.texerrormessage(...)
- print(format(...))
- end
+ function logs.texerrormessage(...)
+ print(format(...))
+ end
end
io.stdout:setvbuf('no')
io.stderr:setvbuf('no')
if package.helpers.report then
- package.helpers.report=logs.reporter("package loader")
+ package.helpers.report=logs.reporter("package loader")
end
if tex then
- local finalactions={}
- local fatalerrors={}
- local possiblefatal={}
- local loggingerrors=false
- function logs.loggingerrors()
- return loggingerrors
- end
- directives.register("logs.errors",function(v)
- loggingerrors=v
- if type(v)=="string" then
- fatalerrors=settings_to_hash(v)
- else
- fatalerrors={}
- end
- end)
- function logs.registerfinalactions(...)
- insert(finalactions,...)
- end
- local what=nil
- local report=nil
- local state=nil
- local target=nil
- local function startlogging(t,r,w,s)
- target=t
- state=force
- force=true
- report=type(r)=="function" and r or logs.reporter(r)
- what=w
- pushtarget(target)
+ local finalactions={}
+ local fatalerrors={}
+ local possiblefatal={}
+ local loggingerrors=false
+ function logs.loggingerrors()
+ return loggingerrors
+ end
+ directives.register("logs.errors",function(v)
+ loggingerrors=v
+ if type(v)=="string" then
+ fatalerrors=settings_to_hash(v)
+ else
+ fatalerrors={}
+ end
+ end)
+ function logs.registerfinalactions(...)
+ insert(finalactions,...)
+ end
+ local what=nil
+ local report=nil
+ local state=nil
+ local target=nil
+ local function startlogging(t,r,w,s)
+ target=t
+ state=force
+ force=true
+ report=type(r)=="function" and r or logs.reporter(r)
+ what=w
+ pushtarget(target)
+ newline()
+ if s then
+ report("start %s: %s",what,s)
+ else
+ report("start %s",what)
+ end
+ if target=="logfile" then
+ newline()
+ end
+ return report
+ end
+ local function stoplogging()
+ if target=="logfile" then
+ newline()
+ end
+ report("stop %s",what)
+ if target=="logfile" then
+ newline()
+ end
+ poptarget()
+ state=oldstate
+ end
+ function logs.startfilelogging(...)
+ return startlogging("logfile",...)
+ end
+ logs.stopfilelogging=stoplogging
+ local done=false
+ function logs.starterrorlogging(r,w,...)
+ if not done then
+ pushtarget("terminal")
+ newline()
+ logs.report("error logging","start possible issues")
+ poptarget()
+ done=true
+ end
+ if fatalerrors[w] then
+ possiblefatal[w]=true
+ end
+ return startlogging("terminal",r,w,...)
+ end
+ logs.stoperrorlogging=stoplogging
+ function logs.finalactions()
+ if #finalactions>0 then
+ for i=1,#finalactions do
+ finalactions[i]()
+ end
+ if done then
+ pushtarget("terminal")
newline()
- if s then
- report("start %s: %s",what,s)
- else
- report("start %s",what)
- end
- if target=="logfile" then
- newline()
- end
- return report
- end
- local function stoplogging()
- if target=="logfile" then
- newline()
- end
- report("stop %s",what)
- if target=="logfile" then
- newline()
- end
+ logs.report("error logging","stop possible issues")
poptarget()
- state=oldstate
- end
- function logs.startfilelogging(...)
- return startlogging("logfile",...)
- end
- logs.stopfilelogging=stoplogging
- local done=false
- function logs.starterrorlogging(r,w,...)
- if not done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","start possible issues")
- poptarget()
- done=true
- end
- if fatalerrors[w] then
- possiblefatal[w]=true
- end
- return startlogging("terminal",r,w,...)
- end
- logs.stoperrorlogging=stoplogging
- function logs.finalactions()
- if #finalactions>0 then
- for i=1,#finalactions do
- finalactions[i]()
- end
- if done then
- pushtarget("terminal")
- newline()
- logs.report("error logging","stop possible issues")
- poptarget()
- end
- return next(possiblefatal) and sortedkeys(possiblefatal) or false
- end
+ end
+ return next(possiblefatal) and sortedkeys(possiblefatal) or false
end
+ end
end
@@ -10167,14 +13559,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-inf"] = package.loaded["trac-inf"] or true
--- original size: 8097, stripped down to: 5534
+-- original size: 9072, stripped down to: 6055
if not modules then modules={} end modules ['trac-inf']={
- version=1.001,
- comment="companion to trac-inf.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 trac-inf.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local type,tonumber,select=type,tonumber,select
local format,lower,find=string.format,string.lower,string.find
@@ -10189,161 +13581,191 @@ statistics.enable=true
statistics.threshold=0.01
local statusinfo,n,registered,timers={},0,{},{}
setmetatableindex(timers,function(t,k)
- local v={ timing=0,loadtime=0 }
- t[k]=v
- return v
+ local v={ timing=0,loadtime=0 }
+ t[k]=v
+ return v
end)
local function hastiming(instance)
- return instance and timers[instance]
+ return instance and timers[instance]
end
local function resettiming(instance)
- timers[instance or "notimer"]={ timing=0,loadtime=0 }
+ timers[instance or "notimer"]={ timing=0,loadtime=0 }
end
local ticks=clock
local seconds=function(n) return n or 0 end
-local function starttiming(instance)
- local timer=timers[instance or "notimer"]
- local it=timer.timing
- if it==0 then
- timer.starttime=ticks()
- if not timer.loadtime then
- timer.loadtime=0
- end
- end
- timer.timing=it+1
+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
+ timer.loadtime=0
+ end
+ end
+ timer.timing=it+1
end
local function stoptiming(instance)
+ local timer=timers[instance or "notimer"]
+ local it=timer.timing
+ if it>1 then
+ timer.timing=it-1
+ else
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ local stoptime=ticks()
+ local loadtime=stoptime-starttime
+ timer.stoptime=stoptime
+ timer.loadtime=timer.loadtime+loadtime
+ timer.timing=0
+ timer.starttime=0
+ return loadtime
+ end
+ end
+ return 0
+end
+local function elapsed(instance)
+ if type(instance)=="number" then
+ return instance
+ else
+ local timer=timers[instance or "notimer"]
+ return timer and seconds(timer.loadtime) or 0
+ 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
- timer.timing=it-1
else
- local starttime=timer.starttime
- if starttime and starttime>0 then
- local stoptime=ticks()
- local loadtime=stoptime-starttime
- timer.stoptime=stoptime
- timer.loadtime=timer.loadtime+loadtime
- timer.timing=0
- timer.starttime=0
- return loadtime
- end
+ local starttime=timer.starttime
+ if starttime and starttime>0 then
+ return seconds(timer.loadtime+ticks()-starttime)
+ end
end
return 0
-end
-local function elapsed(instance)
- if type(instance)=="number" then
- return instance
- else
- local timer=timers[instance or "notimer"]
- return timer and seconds(timer.loadtime) or 0
- end
+ end
end
local function elapsedtime(instance)
- return format("%0.3f",elapsed(instance))
+ return format("%0.3f",elapsed(instance))
end
local function elapsedindeed(instance)
- return elapsed(instance)>statistics.threshold
+ return elapsed(instance)>statistics.threshold
end
local function elapsedseconds(instance,rest)
- if elapsedindeed(instance) then
- return format("%0.3f seconds %s",elapsed(instance),rest or "")
- end
+ if elapsedindeed(instance) then
+ return format("%0.3f seconds %s",elapsed(instance),rest or "")
+ end
end
statistics.hastiming=hastiming
statistics.resettiming=resettiming
statistics.starttiming=starttiming
statistics.stoptiming=stoptiming
+statistics.currenttime=currenttime
statistics.elapsed=elapsed
statistics.elapsedtime=elapsedtime
statistics.elapsedindeed=elapsedindeed
statistics.elapsedseconds=elapsedseconds
function statistics.register(tag,fnc)
- if statistics.enable and type(fnc)=="function" then
- local rt=registered[tag] or (#statusinfo+1)
- statusinfo[rt]={ tag,fnc }
- registered[tag]=rt
- if #tag>n then n=#tag end
- end
+ if statistics.enable and type(fnc)=="function" then
+ local rt=registered[tag] or (#statusinfo+1)
+ statusinfo[rt]={ tag,fnc }
+ registered[tag]=rt
+ if #tag>n then n=#tag end
+ end
end
local report=logs.reporter("mkiv lua stats")
function statistics.show()
- if statistics.enable then
- local register=statistics.register
- register("used platform",function()
- return format("%s, type: %s, binary subtree: %s",
- os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
- end)
- register("used engine",function()
- return format("%s version %s with functionality level %s, banner: %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
- end)
- register("control sequences",function()
- return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
- end)
- register("callbacks",statistics.callbacks)
- if TEXENGINE=="luajittex" and JITSUPPORTED then
- local jitstatus=jit.status
- if jitstatus then
- local jitstatus={ jitstatus() }
- if jitstatus[1] then
- register("luajit options",concat(jitstatus," ",2))
- end
- end
- end
- register("lua properties",function()
- local hashchar=tonumber(status.luatex_hashchars)
- local hashtype=status.luatex_hashtype
- local mask=lua.mask or "ascii"
- return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
- jit and "luajit" or "lua",
- LUAVERSION,
- statistics.memused(),
- hashtype or "default",
- hashchar and 2^hashchar or "unknown",
- mask,
- mask=="utf" and "τεχ" or "tex")
- end)
- register("runtime",statistics.runtime)
- logs.newline()
- for i=1,#statusinfo do
- local s=statusinfo[i]
- local r=s[2]()
- if r then
- report("%s: %s",s[1],r)
- end
+ if statistics.enable then
+ local register=statistics.register
+ register("used platform",function()
+ return format("%s, type: %s, binary subtree: %s",
+ os.platform or "unknown",os.type or "unknown",environment.texos or "unknown")
+ end)
+ register("used engine",function()
+ return format("%s version %s with functionality level %s, banner: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
+ end)
+ register("control sequences",function()
+ return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
+ end)
+ register("callbacks",statistics.callbacks)
+ if TEXENGINE=="luajittex" and JITSUPPORTED then
+ local jitstatus=jit.status
+ if jitstatus then
+ local jitstatus={ jitstatus() }
+ if jitstatus[1] then
+ register("luajit options",concat(jitstatus," ",2))
end
- statistics.enable=false
+ end
end
+ register("lua properties",function()
+ local hashchar=tonumber(status.luatex_hashchars)
+ local hashtype=status.luatex_hashtype
+ local mask=lua.mask or "ascii"
+ return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)",
+ jit and "luajit" or "lua",
+ LUAVERSION,
+ statistics.memused(),
+ hashtype or "default",
+ hashchar and 2^hashchar or "unknown",
+ mask,
+ mask=="utf" and "τεχ" or "tex")
+ end)
+ register("runtime",statistics.runtime)
+ logs.newline()
+ for i=1,#statusinfo do
+ local s=statusinfo[i]
+ local r=s[2]()
+ if r then
+ report("%s: %s",s[1],r)
+ end
+ end
+ statistics.enable=false
+ end
end
function statistics.memused()
- local round=math.round or math.floor
- return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
+ local round=math.round or math.floor
+ return format("%s MB (ctx: %s MB)",round(collectgarbage("count")/1000),round(status.luastate_bytes/1000000))
end
starttiming(statistics)
function statistics.formatruntime(runtime)
- return format("%s seconds",runtime)
+ return format("%s seconds",runtime)
end
function statistics.runtime()
- stoptiming(statistics)
- return statistics.formatruntime(elapsedtime(statistics))
+ stoptiming(statistics)
+ local runtime=lua.getruntime and lua.getruntime() or elapsedtime(statistics)
+ return statistics.formatruntime(runtime)
end
local report=logs.reporter("system")
-function statistics.timed(action)
- starttiming("run")
- action()
- stoptiming("run")
- report("total runtime: %s seconds",elapsedtime("run"))
+function statistics.timed(action,all)
+ starttiming("run")
+ action()
+ stoptiming("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
function statistics.tracefunction(base,tag,...)
- for i=1,select("#",...) do
- local name=select(i,...)
- local stat={}
- local func=base[name]
- setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
- base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
- statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
- end
+ for i=1,select("#",...) do
+ local name=select(i,...)
+ local stat={}
+ local func=base[name]
+ setmetatableindex(stat,function(t,k) t[k]=0 return 0 end)
+ base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end
+ statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end)
+ end
end
@@ -10353,144 +13775,144 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-pro"] = package.loaded["trac-pro"] or true
--- original size: 5841, stripped down to: 3511
+-- original size: 5841, stripped down to: 3352
if not modules then modules={} end modules ['trac-pro']={
- 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 getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next
-local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
+local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end)
local report_system=logs.reporter("system","protection")
namespaces=namespaces or {}
local namespaces=namespaces
local registered={}
local function report_index(k,name)
- if trace_namespaces then
- report_system("reference to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("reference to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("reference to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("reference to %a in protected namespace %a",k,name)
+ end
end
local function report_newindex(k,name)
- if trace_namespaces then
- report_system("assignment to %a in protected namespace %a: %s",k,name)
- debugger.showtraceback(report_system)
- else
- report_system("assignment to %a in protected namespace %a",k,name)
- end
+ if trace_namespaces then
+ report_system("assignment to %a in protected namespace %a: %s",k,name)
+ debugger.showtraceback(report_system)
+ else
+ report_system("assignment to %a in protected namespace %a",k,name)
+ end
end
local function register(name)
- local data=name=="global" and _G or _G[name]
- if not data then
- return
- end
- registered[name]=data
- local m=getmetatable(data)
- if not m then
- m={}
- setmetatable(data,m)
- end
- local index,newindex={},{}
- m.__saved__index=m.__index
- m.__no__index=function(t,k)
- if not index[k] then
- index[k]=true
- report_index(k,name)
- end
- return nil
+ local data=name=="global" and _G or _G[name]
+ if not data then
+ return
+ end
+ registered[name]=data
+ local m=getmetatable(data)
+ if not m then
+ m={}
+ setmetatable(data,m)
+ end
+ local index,newindex={},{}
+ m.__saved__index=m.__index
+ m.__no__index=function(t,k)
+ if not index[k] then
+ index[k]=true
+ report_index(k,name)
end
- m.__saved__newindex=m.__newindex
- m.__no__newindex=function(t,k,v)
- if not newindex[k] then
- newindex[k]=true
- report_newindex(k,name)
- end
- rawset(t,k,v)
+ return nil
+ end
+ m.__saved__newindex=m.__newindex
+ m.__no__newindex=function(t,k,v)
+ if not newindex[k] then
+ newindex[k]=true
+ report_newindex(k,name)
end
- m.__protection__depth=0
+ rawset(t,k,v)
+ end
+ m.__protection__depth=0
end
local function private(name)
- local data=registered[name]
+ local data=registered[name]
+ if not data then
+ data=_G[name]
if not data then
- data=_G[name]
- if not data then
- data={}
- _G[name]=data
- end
- register(name)
+ data={}
+ _G[name]=data
end
- return data
+ register(name)
+ end
+ return data
end
local function protect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>0 then
- m.__protection__depth=pd+1
- else
- m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
- m.__index,m.__newindex=m.__no__index,m.__no__newindex
- m.__protection__depth=1
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>0 then
+ m.__protection__depth=pd+1
+ else
+ m.__save_d_index,m.__saved__newindex=m.__index,m.__newindex
+ m.__index,m.__newindex=m.__no__index,m.__no__newindex
+ m.__protection__depth=1
+ end
end
local function unprotect(name)
- local data=registered[name]
- if not data then
- return
- end
- local m=getmetatable(data)
- local pd=m.__protection__depth
- if pd>1 then
- m.__protection__depth=pd-1
- else
- m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
- m.__protection__depth=0
- end
+ local data=registered[name]
+ if not data then
+ return
+ end
+ local m=getmetatable(data)
+ local pd=m.__protection__depth
+ if pd>1 then
+ m.__protection__depth=pd-1
+ else
+ m.__index,m.__newindex=m.__saved__index,m.__saved__newindex
+ m.__protection__depth=0
+ end
end
local function protectall()
- for name,_ in next,registered do
- if name~="global" then
- protect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ protect(name)
end
+ end
end
local function unprotectall()
- for name,_ in next,registered do
- if name~="global" then
- unprotect(name)
- end
+ for name,_ in next,registered do
+ if name~="global" then
+ unprotect(name)
end
+ end
end
-namespaces.register=register
-namespaces.private=private
+namespaces.register=register
+namespaces.private=private
namespaces.protect=protect
namespaces.unprotect=unprotect
namespaces.protectall=protectall
namespaces.unprotectall=unprotectall
namespaces.private("namespaces") registered={} register("global")
directives.register("system.protect",function(v)
- if v then
- protectall()
- else
- unprotectall()
- end
+ if v then
+ protectall()
+ else
+ unprotectall()
+ end
end)
directives.register("system.checkglobals",function(v)
- if v then
- report_system("enabling global namespace guard")
- protect("global")
- else
- report_system("disabling global namespace guard")
- unprotect("global")
- end
+ if v then
+ report_system("enabling global namespace guard")
+ protect("global")
+ else
+ report_system("disabling global namespace guard")
+ unprotect("global")
+ end
end)
@@ -10500,15 +13922,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lua"] = package.loaded["util-lua"] or true
--- original size: 6621, stripped down to: 4764
+-- original size: 6664, stripped down to: 4589
if not modules then modules={} end modules ['util-lua']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment="the strip code is written by Peter Cawley",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="companion to luat-lib.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ comment="the strip code is written by Peter Cawley",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format
local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage
@@ -10519,150 +13941,151 @@ local report_lua=logs.reporter("system","lua")
local report_mem=logs.reporter("system","lua memory")
local tracestripping=false
local tracememory=false
-luautilities.stripcode=true
+luautilities.stripcode=true
luautilities.alwaysstripcode=false
luautilities.nofstrippedchunks=0
luautilities.nofstrippedbytes=0
local strippedchunks={}
luautilities.strippedchunks=strippedchunks
luautilities.suffixes={
- tma="tma",
- tmc=jit and "tmb" or "tmc",
- lua="lua",
- luc=jit and "lub" or "luc",
- lui="lui",
- luv="luv",
- luj="luj",
- tua="tua",
- tuc="tuc",
+ tma="tma",
+ tmc=jit and "tmb" or "tmc",
+ lua="lua",
+ luc=jit and "lub" or "luc",
+ lui="lui",
+ luv="luv",
+ luj="luj",
+ tua="tua",
+ tuc="tuc",
}
local function register(name)
- if tracestripping then
- report_lua("stripped bytecode from %a",name or "unknown")
- end
- strippedchunks[#strippedchunks+1]=name
- luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
+ if tracestripping then
+ report_lua("stripped bytecode from %a",name or "unknown")
+ end
+ strippedchunks[#strippedchunks+1]=name
+ luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1
end
local function stupidcompile(luafile,lucfile,strip)
- local code=io.loaddata(luafile)
- if code and code~="" then
- code=load(code)
- if code then
- code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
- if code and code~="" then
- register(name)
- io.savedata(lucfile,code)
- return true,0
- end
- else
- report_lua("fatal error %a in file %a",1,luafile)
- end
- else
- report_lua("fatal error %a in file %a",2,luafile)
- end
- return false,0
-end
-function luautilities.loadedluacode(fullname,forcestrip,name,macros)
- name=name or fullname
- if macros then
- macros=lua.macros
- end
- local code,message
- if macros then
- code,message=macros.loaded(fullname,true,false)
- else
- code,message=loadfile(fullname)
- end
+ local code=io.loaddata(luafile)
+ if code and code~="" then
+ code=load(code)
if code then
- code()
- else
- report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip)=="function" then
- forcestrip=forcestrip(fullname)
- end
- if forcestrip or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
- elseif luautilities.alwaysstripcode then
+ code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode)
+ if code and code~="" then
register(name)
- return load(dump(code,true)),0
+ io.savedata(lucfile,code)
+ return true,0
+ end
else
- return code,0
+ report_lua("fatal error %a in file %a",1,luafile)
end
+ else
+ report_lua("fatal error %a in file %a",2,luafile)
+ end
+ return false,0
+end
+function luautilities.loadedluacode(fullname,forcestrip,name,macros)
+ name=name or fullname
+ if macros then
+ macros=lua.macros
+ end
+ local code,message
+ if macros then
+ code,message=macros.loaded(fullname,true,false)
+ else
+ code,message=loadfile(fullname)
+ end
+ if code then
+ 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
+ forcestrip=forcestrip(fullname)
+ end
+ if forcestrip or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
+ elseif luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.strippedloadstring(code,name,forcestrip)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
- register(name)
- return load(dump(code,true)),0
- else
- return code,0
- end
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then
+ register(name)
+ return load(dump(code,true)),0
+ else
+ return code,0
+ end
end
function luautilities.loadstring(code,name)
- local code,message=load(code)
- if not code then
- report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
- end
- return code,0
+ local code,message=load(code)
+ if not code then
+ report_lua("loading of file %a failed:\n\t%s",name,message or "no message")
+ end
+ return code,0
end
function luautilities.compile(luafile,lucfile,cleanup,strip,fallback)
- report_lua("compiling %a into %a",luafile,lucfile)
- os.remove(lucfile)
- local done=stupidcompile(luafile,lucfile,strip~=false)
- if done then
- report_lua("dumping %a into %a stripped",luafile,lucfile)
- if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
- report_lua("removing %a",luafile)
- os.remove(luafile)
- end
- end
- return done
+ report_lua("compiling %a into %a",luafile,lucfile)
+ os.remove(lucfile)
+ local done=stupidcompile(luafile,lucfile,strip~=false)
+ if done then
+ report_lua("dumping %a into %a stripped",luafile,lucfile)
+ if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+ report_lua("removing %a",luafile)
+ os.remove(luafile)
+ end
+ end
+ return done
end
function luautilities.loadstripped(...)
- local l=load(...)
- if l then
- return load(dump(l,true))
- end
+ local l=load(...)
+ if l then
+ return load(dump(l,true))
+ end
end
local finalizers={}
setmetatable(finalizers,{
- __gc=function(t)
- for i=1,#t do
- pcall(t[i])
- end
+ __gc=function(t)
+ for i=1,#t do
+ pcall(t[i])
end
+ end
} )
function luautilities.registerfinalizer(f)
- finalizers[#finalizers+1]=f
+ finalizers[#finalizers+1]=f
end
function luautilities.checkmemory(previous,threshold,trace)
- local current=collectgarbage("count")
- if previous then
- local checked=(threshold or 64)*1024
- local delta=current-previous
- if current-previous>checked then
- 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",
- 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",
- previous/1024,current/1024,delta/1024,threshold)
- end
+ local current=collectgarbage("count")
+ if previous then
+ local checked=(threshold or 64)*1024
+ local delta=current-previous
+ if current-previous>checked then
+ collectgarbage("collect")
+ local afterwards=collectgarbage("count")
+ if trace or tracememory then
+ 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 %r MB, current %r MB, delta %r MB, threshold %r MB",
+ previous/1024,current/1024,delta/1024,threshold)
end
- return current
+ end
+ return current
end
@@ -10672,17 +14095,15 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-deb"] = package.loaded["util-deb"] or true
--- original size: 8984, stripped down to: 6573
+-- original size: 9955, stripped down to: 6693
if not modules then modules={} end modules ['util-deb']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- 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 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
@@ -10700,228 +14121,266 @@ local names={}
local initialize=false
if not (FFISUPPORTED and ffi) then
elseif os.type=="windows" then
- initialize=function()
- local kernel=ffilib("kernel32","system")
- if kernel then
- local tonumber=ffi.number or tonumber
- ffi.cdef[[
+ initialize=function()
+ local kernel=ffilib("kernel32","system")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
int QueryPerformanceFrequency(int64_t *lpFrequency);
int QueryPerformanceCounter(int64_t *lpPerformanceCount);
]]
- local target=ffi.new("__int64[1]")
- ticks=function()
- if kernel.QueryPerformanceCounter(target)==1 then
- return tonumber(target[0])
- else
- return 0
- end
- end
- local target=ffi.new("__int64[1]")
- seconds=function(ticks)
- if kernel.QueryPerformanceFrequency(target)==1 then
- return ticks/tonumber(target[0])
- else
- return 0
- end
- end
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
end
- initialize=false
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
end
+ initialize=false
+ end
elseif os.type=="unix" then
- initialize=function()
- local C=ffi.C
- local tonumber=ffi.number or tonumber
- ffi.cdef [[
+ initialize=function()
+ local C=ffi.C
+ local tonumber=ffi.number or tonumber
+ ffi.cdef [[
/* what a mess */
typedef int clk_id_t;
typedef enum { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID } clk_id;
typedef struct timespec { long sec; long nsec; } ctx_timespec;
int clock_gettime(clk_id_t timerid, struct timespec *t);
]]
- local target=ffi.new("ctx_timespec[?]",1)
- local clock=C.CLOCK_PROCESS_CPUTIME_ID
- ticks=function ()
- C.clock_gettime(clock,target)
- return tonumber(target[0].sec*1000000000+target[0].nsec)
- end
- seconds=function(ticks)
- return ticks/1000000000
- end
- initialize=false
+ local target=ffi.new("ctx_timespec[?]",1)
+ local clock=C.CLOCK_PROCESS_CPUTIME_ID
+ ticks=function ()
+ C.clock_gettime(clock,target)
+ return tonumber(target[0].sec*1000000000+target[0].nsec)
+ end
+ seconds=function(ticks)
+ return ticks/1000000000
end
+ initialize=false
+ end
end
setmetatableindex(names,function(t,name)
- local v=setmetatableindex(function(t,source)
- local v=setmetatableindex(function(t,line)
- local v={ total=0,count=0 }
- t[line]=v
- return v
- end)
- t[source]=v
- return v
+ local v=setmetatableindex(function(t,source)
+ local v=setmetatableindex(function(t,line)
+ local v={ total=0,count=0,nesting=0 }
+ t[line]=v
+ return v
end)
- t[name]=v
+ t[source]=v
return v
+ end)
+ t[name]=v
+ return v
end)
+local getinfo=nil
+local sethook=nil
local function hook(where)
- local f=getinfo(2,"nSl")
- if f then
- local source=f.short_src
- if not source then
- return
- end
- local line=f.linedefined or 0
- local name=f.name
- if not name then
- local what=f.what
- if what=="C" then
- name="<anonymous>"
- else
- name=f.namewhat or what or "<unknown>"
- end
- end
- local data=names[name][source][line]
- if where=="call" then
- data.count=data.count+1
- insert(data,ticks())
- elseif where=="return" then
- local t=remove(data)
- if t then
- data.total=data.total+ticks()-t
- end
+ local f=getinfo(2,"nSl")
+ if f then
+ local source=f.short_src
+ if not source then
+ return
+ end
+ local line=f.linedefined or 0
+ local name=f.name
+ if not name then
+ local what=f.what
+ if what=="C" then
+ name="<anonymous>"
+ else
+ name=f.namewhat or what or "<unknown>"
+ end
+ end
+ local data=names[name][source][line]
+ if where=="call" then
+ 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 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
end
function debugger.showstats(printer,threshold)
- local printer=printer or report
- local calls=0
- local functions=0
- local dataset={}
- local length=0
- local realtime=0
- local totaltime=0
- local threshold=threshold or 0
- for name,sources in next,names do
- for source,lines in next,sources do
- for line,data in next,lines do
- local count=data.count
- if count>threshold then
- if #name>length then
- length=#name
- end
- local total=data.total
- local real=total
- if real>0 then
- real=total-(count*overhead/dummycalls)
- if real<0 then
- real=0
- end
- realtime=realtime+real
- end
- totaltime=totaltime+total
- if line<0 then
- line=0
- end
- dataset[#dataset+1]={ real,total,count,name,source,line }
- end
- end
+ local printer=printer or report
+ local calls=0
+ local functions=0
+ local dataset={}
+ local length=0
+ local realtime=0
+ local totaltime=0
+ local threshold=threshold or 0
+ for name,sources in next,names do
+ for source,lines in next,sources do
+ for line,data in next,lines do
+ local count=data.count
+ if count>threshold then
+ if #name>length then
+ length=#name
+ end
+ local total=data.total
+ local real=total
+ if real>0 then
+ real=total-(count*overhead/dummycalls)
+ if real<0 then
+ real=0
+ end
+ realtime=realtime+real
+ end
+ totaltime=totaltime+total
+ if line<0 then
+ line=0
+ end
+ dataset[#dataset+1]={ real,total,count,name,source,line }
end
+ end
end
- sort(dataset,function(a,b)
- if a[1]==b[1] then
- if a[2]==b[2] then
- if a[3]==b[3] then
- if a[4]==b[4] then
- if a[5]==b[5] then
- return a[6]<b[6]
- else
- return a[5]<b[5]
- end
- else
- return a[4]<b[4]
- end
- else
- return b[3]<a[3]
- end
+ end
+ sort(dataset,function(a,b)
+ if a[1]==b[1] then
+ if a[2]==b[2] then
+ if a[3]==b[3] then
+ if a[4]==b[4] then
+ if a[5]==b[5] then
+ return a[6]<b[6]
else
- return b[2]<a[2]
+ return a[5]<b[5]
end
+ else
+ return a[4]<b[4]
+ end
else
- return b[1]<a[1]
+ return b[3]<a[3]
end
- end)
- if length>50 then
- length=50
- end
- local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
- for i=1,#dataset do
- local data=dataset[i]
- local real=data[1]
- local total=data[2]
- local count=data[3]
- local name=data[4]
- local source=data[5]
- local line=data[6]
- calls=calls+count
- functions=functions+1
- name=gsub(name,"%s+"," ")
- if #name>length then
- name=sub(name,1,length)
- end
- printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
- end
- printer("")
- printer(format("functions : %i",functions))
- printer(format("calls : %i",calls))
- printer(format("overhead : %f",seconds(overhead/1000)))
+ else
+ return b[2]<a[2]
+ end
+ else
+ return b[1]<a[1]
+ end
+ end)
+ if length>50 then
+ length=50
+ end
+ local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"]
+ for i=1,#dataset do
+ local data=dataset[i]
+ local real=data[1]
+ local total=data[2]
+ local count=data[3]
+ local name=data[4]
+ local source=data[5]
+ local line=data[6]
+ calls=calls+count
+ functions=functions+1
+ name=gsub(name,"%s+"," ")
+ if #name>length then
+ name=sub(name,1,length)
+ end
+ printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source))
+ end
+ printer("")
+ printer(format("functions : %i",functions))
+ printer(format("calls : %i",calls))
+ printer(format("overhead : %f",seconds(overhead/1000)))
+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
- debugger.showstats(function(str) f:write(str,"\n") end,threshold)
- f:close()
- end
+ local f=io.open(filename,'w')
+ if f then
+ debugger.showstats(function(str) f:write(str,"\n") end,threshold)
+ f:close()
+ end
end
function debugger.enable()
- if nesting==0 then
- running=true
- if initialize then
- initialize()
- end
- sethook(hook,"cr")
- local function dummy() end
- local t=ticks()
- for i=1,dummycalls do
- dummy()
- end
- overhead=ticks()-t
- end
- if nesting>0 then
- nesting=nesting+1
- end
+ getdebug()
+ if sethook and getinfo and nesting==0 then
+ running=true
+ if initialize then
+ initialize()
+ end
+ sethook(hook,"cr")
+ local function dummy() end
+ local t=ticks()
+ for i=1,dummycalls do
+ dummy()
+ end
+ overhead=ticks()-t
+ end
+ if nesting>0 then
+ nesting=nesting+1
+ end
end
function debugger.disable()
- if nesting>0 then
- nesting=nesting-1
- end
- if nesting==0 then
- sethook()
- end
+ if nesting>0 then
+ nesting=nesting-1
+ end
+ if sethook and getinfo and nesting==0 then
+ sethook()
+ end
end
local function showtraceback(rep)
+ getdebug()
+ if getinfo then
local level=2
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
+ 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
+ end
end
debugger.showtraceback=showtraceback
@@ -10932,91 +14391,91 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tpl"] = package.loaded["util-tpl"] or true
--- original size: 7112, stripped down to: 3988
+-- original size: 7112, stripped down to: 3887
if not modules then modules={} end modules ['util-tpl']={
- version=1.001,
- comment="companion to luat-lib.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ 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.templates=utilities.templates or {}
local templates=utilities.templates
-local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
+local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end)
local report_template=logs.reporter("template")
local tostring,next=tostring,next
local format,sub,byte=string.format,string.sub,string.byte
local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns
local replacer
local function replacekey(k,t,how,recursive)
- local v=t[k]
- if not v then
- if trace_template then
- report_template("unknown key %a",k)
- end
- return ""
+ local v=t[k]
+ if not v then
+ if trace_template then
+ report_template("unknown key %a",k)
+ end
+ return ""
+ else
+ v=tostring(v)
+ if trace_template then
+ report_template("setting key %a to value %a",k,v)
+ end
+ if recursive then
+ return lpegmatch(replacer,v,1,t,how,recursive)
else
- v=tostring(v)
- if trace_template then
- report_template("setting key %a to value %a",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t,how,recursive)
- else
- return v
- end
+ return v
end
+ end
end
local sqlescape=lpeg.replacer {
- { "'","''" },
- { "\\","\\\\" },
- { "\r\n","\\n" },
- { "\r","\\n" },
+ { "'","''" },
+ { "\\","\\\\" },
+ { "\r\n","\\n" },
+ { "\r","\\n" },
}
local sqlquoted=Cs(Cc("'")*sqlescape*Cc("'"))
lpegpatterns.sqlescape=sqlescape
lpegpatterns.sqlquoted=sqlquoted
local luaescape=lpegpatterns.luaescape
local escapers={
- lua=function(s)
- return lpegmatch(luaescape,s)
- end,
- sql=function(s)
- return lpegmatch(sqlescape,s)
- end,
+ lua=function(s)
+ return lpegmatch(luaescape,s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlescape,s)
+ end,
}
local quotedescapers={
- lua=function(s)
- return format("%q",s)
- end,
- sql=function(s)
- return lpegmatch(sqlquoted,s)
- end,
+ lua=function(s)
+ return format("%q",s)
+ end,
+ sql=function(s)
+ return lpegmatch(sqlquoted,s)
+ end,
}
local luaescaper=escapers.lua
local quotedluaescaper=quotedescapers.lua
local function replacekeyunquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and escapers[how] or luaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and escapers[how] or luaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replacekeyquoted(s,t,how,recurse)
- if how==false then
- return replacekey(s,t,how,recurse)
- else
- local escaper=how and quotedescapers[how] or quotedluaescaper
- return escaper(replacekey(s,t,how,recurse))
- end
+ if how==false then
+ return replacekey(s,t,how,recurse)
+ else
+ local escaper=how and quotedescapers[how] or quotedluaescaper
+ return escaper(replacekey(s,t,how,recurse))
+ end
end
local function replaceoptional(l,m,r,t,how,recurse)
- local v=t[l]
- return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
+ local v=t[l]
+ return v and v~="" and lpegmatch(replacer,r,1,t,how or "lua",recurse or false) or ""
end
-local single=P("%")
+local single=P("%")
local double=P("%%")
local lquoted=P("%[")
local rquoted=P("]%")
@@ -11033,41 +14492,41 @@ local noloptional=P("%?")/''
local noroptional=P("?%")/''
local nomoptional=P(":")/''
local args=Carg(1)*Carg(2)*Carg(3)
-local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
-local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
-local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
+local key=nosingle*((C((1-nosingle )^1)*args)/replacekey )*nosingle
+local quoted=nolquotedq*((C((1-norquotedq )^1)*args)/replacekeyquoted )*norquotedq
+local unquoted=nolquoted*((C((1-norquoted )^1)*args)/replacekeyunquoted)*norquoted
local optional=noloptional*((C((1-nomoptional)^1)*nomoptional*C((1-noroptional)^1)*args)/replaceoptional)*noroptional
local any=P(1)
replacer=Cs((unquoted+quoted+escape+optional+key+any)^0)
local function replace(str,mapping,how,recurse)
- if mapping and str then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
+ if mapping and str then
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ else
+ return str
+ end
end
templates.replace=replace
function templates.replacer(str,how,recurse)
- return function(mapping)
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- end
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
end
function templates.load(filename,mapping,how,recurse)
- local data=io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
+ local data=io.loaddata(filename) or ""
+ if mapping and next(mapping) then
+ return replace(data,mapping,how,recurse)
+ else
+ return data
+ end
end
function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping=t
- end
- for k,v in next,t do
- t[k]=replace(v,mapping,how,recurse)
- end
- return t
+ if not mapping then
+ mapping=t
+ end
+ for k,v in next,t do
+ t[k]=replace(v,mapping,how,recurse)
+ end
+ return t
end
@@ -11077,14 +14536,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-sbx"] = package.loaded["util-sbx"] or true
--- original size: 20393, stripped down to: 13924
+-- original size: 20393, stripped down to: 13121
if not modules then modules={} end modules ['util-sbx']={
- 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 sandbox then require("l-sandbox") end
local next,type=next,type
@@ -11117,144 +14576,144 @@ local report=logs.reporter("sandbox")
trackers.register("sandbox",function(v) trace=v end)
sandbox.setreporter(report)
sandbox.finalizer {
- category="files",
- action=function()
- finalized=true
- end
+ category="files",
+ action=function()
+ finalized=true
+ end
}
local function registerroot(root,what)
- if finalized then
- report("roots are already finalized")
- else
- if type(root)=="table" then
- root,what=root[1],root[2]
- end
- if type(root)=="string" and root~="" then
- root=collapsepath(expandname(root))
- if what=="r" or what=="ro" or what=="readable" then
- what="read"
- elseif what=="w" or what=="wo" or what=="writable" then
- what="write"
- end
- validroots[root]=what=="write" or false
- end
+ if finalized then
+ report("roots are already finalized")
+ else
+ if type(root)=="table" then
+ root,what=root[1],root[2]
+ end
+ if type(root)=="string" and root~="" then
+ root=collapsepath(expandname(root))
+ if what=="r" or what=="ro" or what=="readable" then
+ what="read"
+ elseif what=="w" or what=="wo" or what=="writable" then
+ what="write"
+ end
+ validroots[root]=what=="write" or false
end
+ end
end
sandbox.finalizer {
- category="files",
- action=function()
+ category="files",
+ action=function()
+ if p_validroot then
+ report("roots are already initialized")
+ else
+ sandbox.registerroot(".","write")
+ for name in sortedhash(validroots) do
if p_validroot then
- report("roots are already initialized")
+ p_validroot=P(name)+p_validroot
else
- sandbox.registerroot(".","write")
- for name in sortedhash(validroots) do
- if p_validroot then
- p_validroot=P(name)+p_validroot
- else
- p_validroot=P(name)
- end
- end
- p_validroot=p_validroot/validroots
+ p_validroot=P(name)
end
+ end
+ p_validroot=p_validroot/validroots
end
+ end
}
local function registerbinary(name)
- if finalized then
- report("binaries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validbinaries then
- return
- end
- if validbinaries==true then
- validbinaries={ [name]=true }
- else
- validbinaries[name]=true
- end
- elseif name==true then
- validbinaries={}
+ if finalized then
+ report("binaries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validbinaries then
+ return
+ end
+ if validbinaries==true then
+ validbinaries={ [name]=true }
+ else
+ validbinaries[name]=true
end
+ elseif name==true then
+ validbinaries={}
+ end
end
local function registerlibrary(name)
- if finalized then
- report("libraries are already finalized")
- elseif type(name)=="string" and name~="" then
- if not validlibraries then
- return
- end
- if validlibraries==true then
- validlibraries={ [nameonly(name)]=true }
- else
- validlibraries[nameonly(name)]=true
- end
- elseif name==true then
- validlibraries={}
+ if finalized then
+ report("libraries are already finalized")
+ elseif type(name)=="string" and name~="" then
+ if not validlibraries then
+ return
+ end
+ if validlibraries==true then
+ validlibraries={ [nameonly(name)]=true }
+ else
+ validlibraries[nameonly(name)]=true
end
+ elseif name==true then
+ validlibraries={}
+ end
end
local p_write=S("wa") p_write=(1-p_write)^0*p_write
-local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
+local p_path=S("\\/~$%:") p_path=(1-p_path )^0*p_path
local function normalized(name)
- if platform=="windows" then
- name=gsub(name,"/","\\")
- end
- return name
+ if platform=="windows" then
+ name=gsub(name,"/","\\")
+ end
+ return name
end
function sandbox.possiblepath(name)
- return lpegmatch(p_path,name) and true or false
+ return lpegmatch(p_path,name) and true or false
end
local filenamelogger=false
function sandbox.setfilenamelogger(l)
- filenamelogger=type(l)=="function" and l or false
+ filenamelogger=type(l)=="function" and l or false
end
local function validfilename(name,what)
- if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
- local asked=collapsepath(expandname(name))
- local okay=lpegmatch(p_validroot,asked)
- if okay==true then
- if filenamelogger then
- filenamelogger(name,"w",asked,true)
- end
- return name
- elseif okay==false then
- if not what then
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- elseif lpegmatch(p_write,what) then
- if filenamelogger then
- filenamelogger(name,"w",asked,false)
- end
- return
- else
- if filenamelogger then
- filenamelogger(name,"r",asked,true)
- end
- return name
- end
- elseif filenamelogger then
- filenamelogger(name,"*",name,false)
+ if p_validroot and type(name)=="string" and lpegmatch(p_path,name) then
+ local asked=collapsepath(expandname(name))
+ local okay=lpegmatch(p_validroot,asked)
+ if okay==true then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,true)
+ end
+ return name
+ elseif okay==false then
+ if not what then
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
end
- else
return name
+ elseif lpegmatch(p_write,what) then
+ if filenamelogger then
+ filenamelogger(name,"w",asked,false)
+ end
+ return
+ else
+ if filenamelogger then
+ filenamelogger(name,"r",asked,true)
+ end
+ return name
+ end
+ elseif filenamelogger then
+ filenamelogger(name,"*",name,false)
end
+ else
+ return name
+ end
end
local function readable(name,finalized)
- return validfilename(name,"r")
+ return validfilename(name,"r")
end
local function normalizedreadable(name,finalized)
- local valid=validfilename(name,"r")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"r")
+ if valid then
+ return normalized(valid)
+ end
end
local function writeable(name,finalized)
- return validfilename(name,"w")
+ return validfilename(name,"w")
end
local function normalizedwriteable(name,finalized)
- local valid=validfilename(name,"w")
- if valid then
- return normalized(valid)
- end
+ local valid=validfilename(name,"w")
+ if valid then
+ return normalized(valid)
+ end
end
validators.readable=readable
validators.writeable=normalizedwriteable
@@ -11262,316 +14721,316 @@ validators.normalizedreadable=normalizedreadable
validators.normalizedwriteable=writeable
validators.filename=readable
table.setmetatableindex(validators,function(t,k)
- if k then
- t[k]=readable
- end
- return readable
+ if k then
+ t[k]=readable
+ end
+ return readable
end)
function validators.string(s,finalized)
- if finalized and suspicious(s) then
- return ""
- else
- return s
- end
+ if finalized and suspicious(s) then
+ return ""
+ else
+ return s
+ end
end
function validators.cache(s)
- if finalized then
- return basename(s)
- else
- return s
- end
+ if finalized then
+ return basename(s)
+ else
+ return s
+ end
end
function validators.url(s)
- if finalized and find("^file:") then
- return ""
- else
- return s
- end
+ if finalized and find("^file:") then
+ return ""
+ else
+ return s
+ end
end
local function filehandlerone(action,one,...)
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
+ else
+ end
end
local function filehandlertwo(action,one,two,...)
- local checkedone=validfilename(one)
- if checkedone then
- local checkedtwo=validfilename(two)
- if checkedtwo then
- return action(one,two,...)
- else
- end
+ local checkedone=validfilename(one)
+ if checkedone then
+ local checkedtwo=validfilename(two)
+ if checkedtwo then
+ return action(one,two,...)
else
end
+ else
+ end
end
local function iohandler(action,one,...)
- if type(one)=="string" then
- local checkedone=validfilename(one)
- if checkedone then
- return action(one,...)
- end
- elseif one then
- return action(one,...)
- else
- return action()
+ if type(one)=="string" then
+ local checkedone=validfilename(one)
+ if checkedone then
+ return action(one,...)
end
+ elseif one then
+ return action(one,...)
+ else
+ return action()
+ end
end
local osexecute=sandbox.original(os.execute)
local iopopen=sandbox.original(io.popen)
local reported={}
local function validcommand(name,program,template,checkers,defaults,variables,reporter,strict)
- if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
- if variables then
- for variable,value in next,variables do
- local checker=validators[checkers[variable]]
- if checker then
- value=checker(unquoted(value),strict)
- if value then
- variables[variable]=optionalquoted(value)
- else
- report("variable %a with value %a fails the check",variable,value)
- return
- end
- else
- report("variable %a has no checker",variable)
- return
- end
- end
- for variable,default in next,defaults do
- local value=variables[variable]
- if not value or value=="" then
- local checker=validators[checkers[variable]]
- if checker then
- default=checker(unquoted(default),strict)
- if default then
- variables[variable]=optionalquoted(default)
- else
- report("variable %a with default %a fails the check",variable,default)
- return
- end
- end
- end
- end
- end
- local command=program.." "..replace(template,variables)
- if reporter then
- reporter("executing runner %a: %s",name,command)
- elseif trace then
- report("executing runner %a: %s",name,command)
- end
- return command
- elseif not reported[name] then
- report("executing program %a of runner %a is not permitted",program,name)
- reported[name]=true
- end
-end
-local runners={
- resultof=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("resultof: %s",command)
- end
- local handle=iopopen(command,"r")
- if handle then
- local result=handle:read("*all") or ""
- handle:close()
- return result
- end
- end
- end,
- execute=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("execute: %s",command)
- end
- return osexecute(command)
+ if validbinaries~=false and (validbinaries==true or validbinaries[program]) then
+ if variables then
+ for variable,value in next,variables do
+ local checker=validators[checkers[variable]]
+ if checker then
+ value=checker(unquoted(value),strict)
+ if value then
+ variables[variable]=optionalquoted(value)
+ else
+ report("variable %a with value %a fails the check",variable,value)
+ return
+ end
+ else
+ report("variable %a has no checker",variable)
+ return
end
- end,
- pipeto=function(...)
- local command=validcommand(...)
- if command then
- if trace then
- report("pipeto: %s",command)
+ end
+ for variable,default in next,defaults do
+ local value=variables[variable]
+ if not value or value=="" then
+ local checker=validators[checkers[variable]]
+ if checker then
+ default=checker(unquoted(default),strict)
+ if default then
+ variables[variable]=optionalquoted(default)
+ else
+ report("variable %a with default %a fails the check",variable,default)
+ return
end
- return iopopen(command,"w")
- end
- end,
-}
-function sandbox.registerrunner(specification)
- if type(specification)=="string" then
- local wrapped=validrunners[specification]
- inspect(table.sortedkeys(validrunners))
- if wrapped then
- return wrapped
- else
- report("unknown predefined runner %a",specification)
- return
+ end
end
+ end
end
- if type(specification)~="table" then
- report("specification should be a table (or string)")
- return
- end
- local name=specification.name
- if type(name)~="string" then
- report("invalid name, string expected",name)
- return
- end
- if validrunners[name] then
- report("invalid name, runner %a already defined")
- return
- end
- local program=specification.program
- if type(program)=="string" then
- elseif type(program)=="table" then
- program=program[platform] or program.default or program.unix
- end
- if type(program)~="string" or program=="" then
- report("invalid runner %a specified for platform %a",name,platform)
- return
+ local command=program.." "..replace(template,variables)
+ if reporter then
+ reporter("executing runner %a: %s",name,command)
+ elseif trace then
+ report("executing runner %a: %s",name,command)
end
- local template=specification.template
- if not template then
- report("missing template for runner %a",name)
- return
+ return command
+ elseif not reported[name] then
+ report("executing program %a of runner %a is not permitted",program,name)
+ reported[name]=true
+ end
+end
+local runners={
+ resultof=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("resultof: %s",command)
+ end
+ local handle=iopopen(command,"r")
+ if handle then
+ local result=handle:read("*all") or ""
+ handle:close()
+ return result
+ end
end
- local method=specification.method or "execute"
- local checkers=specification.checkers or {}
- local defaults=specification.defaults or {}
- local runner=runners[method]
- if runner then
- local finalized=finalized
- local wrapped=function(variables)
- return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
- end
- validrunners[name]=wrapped
- return wrapped
- else
- validrunners[name]=nil
- report("invalid method for runner %a",name)
+ end,
+ execute=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("execute: %s",command)
+ end
+ return osexecute(command)
+ end
+ end,
+ pipeto=function(...)
+ local command=validcommand(...)
+ if command then
+ if trace then
+ report("pipeto: %s",command)
+ end
+ return iopopen(command,"w")
end
+ end,
+}
+function sandbox.registerrunner(specification)
+ if type(specification)=="string" then
+ local wrapped=validrunners[specification]
+ inspect(table.sortedkeys(validrunners))
+ if wrapped then
+ return wrapped
+ else
+ report("unknown predefined runner %a",specification)
+ return
+ end
+ end
+ if type(specification)~="table" then
+ report("specification should be a table (or string)")
+ return
+ end
+ local name=specification.name
+ if type(name)~="string" then
+ report("invalid name, string expected",name)
+ return
+ end
+ if validrunners[name] then
+ report("invalid name, runner %a already defined")
+ return
+ end
+ local program=specification.program
+ if type(program)=="string" then
+ elseif type(program)=="table" then
+ program=program[platform] or program.default or program.unix
+ end
+ if type(program)~="string" or program=="" then
+ report("invalid runner %a specified for platform %a",name,platform)
+ return
+ end
+ local template=specification.template
+ if not template then
+ report("missing template for runner %a",name)
+ return
+ end
+ local method=specification.method or "execute"
+ local checkers=specification.checkers or {}
+ local defaults=specification.defaults or {}
+ local runner=runners[method]
+ if runner then
+ local finalized=finalized
+ local wrapped=function(variables)
+ return runner(name,program,template,checkers,defaults,variables,specification.reporter,finalized)
+ end
+ validrunners[name]=wrapped
+ return wrapped
+ else
+ validrunners[name]=nil
+ report("invalid method for runner %a",name)
+ end
end
function sandbox.getrunner(name)
- return name and validrunners[name]
+ return name and validrunners[name]
end
local function suspicious(str)
- return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
+ return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false
end
local function binaryrunner(action,command,...)
- if validbinaries==false then
- report("no binaries permitted, ignoring command: %s",command)
- return
- end
- if type(command)~="string" then
- report("command should be a string")
- return
- end
- local program=lpegmatch(p_split,command)
- if not program or program=="" then
- report("unable to filter binary from command: %s",command)
- return
- end
- if validbinaries==true then
- elseif not validbinaries[program] then
- report("binary not permitted, ignoring command: %s",command)
- return
- elseif suspicious(command) then
- report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
- return
- end
- return action(command,...)
+ if validbinaries==false then
+ report("no binaries permitted, ignoring command: %s",command)
+ return
+ end
+ if type(command)~="string" then
+ report("command should be a string")
+ return
+ end
+ local program=lpegmatch(p_split,command)
+ if not program or program=="" then
+ report("unable to filter binary from command: %s",command)
+ return
+ end
+ if validbinaries==true then
+ elseif not validbinaries[program] then
+ report("binary not permitted, ignoring command: %s",command)
+ return
+ elseif suspicious(command) then
+ report("/ \\ or .. found, ignoring command (use sandbox.registerrunner): %s",command)
+ return
+ end
+ return action(command,...)
end
local function dummyrunner(action,command,...)
- if type(command)=="table" then
- command=concat(command," ",command[0] and 0 or 1)
- end
- report("ignoring command: %s",command)
+ if type(command)=="table" then
+ command=concat(command," ",command[0] and 0 or 1)
+ end
+ report("ignoring command: %s",command)
end
sandbox.filehandlerone=filehandlerone
sandbox.filehandlertwo=filehandlertwo
sandbox.iohandler=iohandler
function sandbox.disablerunners()
- validbinaries=false
+ validbinaries=false
end
function sandbox.disablelibraries()
- validlibraries=false
+ validlibraries=false
end
if FFISUPPORTED and ffi then
- function sandbox.disablelibraries()
- validlibraries=false
- for k,v in next,ffi do
- if k~="gc" then
- ffi[k]=nil
- end
- end
+ function sandbox.disablelibraries()
+ validlibraries=false
+ for k,v in next,ffi do
+ if k~="gc" then
+ ffi[k]=nil
+ end
end
- local fiiload=ffi.load
- if fiiload then
- local reported={}
- function ffi.load(name,...)
- if validlibraries==false then
- elseif validlibraries==true then
- return fiiload(name,...)
- elseif validlibraries[nameonly(name)] then
- return fiiload(name,...)
- else
- end
- if not reported[name] then
- report("using library %a is not permitted",name)
- reported[name]=true
- end
- return nil
- end
+ end
+ local fiiload=ffi.load
+ if fiiload then
+ local reported={}
+ function ffi.load(name,...)
+ if validlibraries==false then
+ elseif validlibraries==true then
+ return fiiload(name,...)
+ elseif validlibraries[nameonly(name)] then
+ return fiiload(name,...)
+ else
+ end
+ if not reported[name] then
+ report("using library %a is not permitted",name)
+ reported[name]=true
+ end
+ return nil
end
+ end
end
local overload=sandbox.overload
local register=sandbox.register
- overload(loadfile,filehandlerone,"loadfile")
+ overload(loadfile,filehandlerone,"loadfile")
if io then
- overload(io.open,filehandlerone,"io.open")
- overload(io.popen,binaryrunner,"io.popen")
- overload(io.input,iohandler,"io.input")
- overload(io.output,iohandler,"io.output")
- overload(io.lines,filehandlerone,"io.lines")
+ overload(io.open,filehandlerone,"io.open")
+ overload(io.popen,binaryrunner,"io.popen")
+ overload(io.input,iohandler,"io.input")
+ overload(io.output,iohandler,"io.output")
+ overload(io.lines,filehandlerone,"io.lines")
end
if os then
- overload(os.execute,binaryrunner,"os.execute")
- overload(os.spawn,dummyrunner,"os.spawn")
- overload(os.exec,dummyrunner,"os.exec")
- overload(os.resultof,binaryrunner,"os.resultof")
- overload(os.pipeto,binaryrunner,"os.pipeto")
- overload(os.rename,filehandlertwo,"os.rename")
- overload(os.remove,filehandlerone,"os.remove")
+ overload(os.execute,binaryrunner,"os.execute")
+ overload(os.spawn,dummyrunner,"os.spawn")
+ overload(os.exec,dummyrunner,"os.exec")
+ overload(os.resultof,binaryrunner,"os.resultof")
+ overload(os.pipeto,binaryrunner,"os.pipeto")
+ overload(os.rename,filehandlertwo,"os.rename")
+ overload(os.remove,filehandlerone,"os.remove")
end
if lfs then
- overload(lfs.chdir,filehandlerone,"lfs.chdir")
- overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
- overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
- overload(lfs.isfile,filehandlerone,"lfs.isfile")
- overload(lfs.isdir,filehandlerone,"lfs.isdir")
- overload(lfs.attributes,filehandlerone,"lfs.attributes")
- overload(lfs.dir,filehandlerone,"lfs.dir")
- overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
- overload(lfs.touch,filehandlerone,"lfs.touch")
- overload(lfs.link,filehandlertwo,"lfs.link")
- overload(lfs.setmode,filehandlerone,"lfs.setmode")
- overload(lfs.readlink,filehandlerone,"lfs.readlink")
- overload(lfs.shortname,filehandlerone,"lfs.shortname")
- overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
+ overload(lfs.chdir,filehandlerone,"lfs.chdir")
+ overload(lfs.mkdir,filehandlerone,"lfs.mkdir")
+ overload(lfs.rmdir,filehandlerone,"lfs.rmdir")
+ overload(lfs.isfile,filehandlerone,"lfs.isfile")
+ overload(lfs.isdir,filehandlerone,"lfs.isdir")
+ overload(lfs.attributes,filehandlerone,"lfs.attributes")
+ overload(lfs.dir,filehandlerone,"lfs.dir")
+ overload(lfs.lock_dir,filehandlerone,"lfs.lock_dir")
+ overload(lfs.touch,filehandlerone,"lfs.touch")
+ overload(lfs.link,filehandlertwo,"lfs.link")
+ overload(lfs.setmode,filehandlerone,"lfs.setmode")
+ overload(lfs.readlink,filehandlerone,"lfs.readlink")
+ overload(lfs.shortname,filehandlerone,"lfs.shortname")
+ overload(lfs.symlinkattributes,filehandlerone,"lfs.symlinkattributes")
end
if zip then
- zip.open=register(zip.open,filehandlerone,"zip.open")
+ zip.open=register(zip.open,filehandlerone,"zip.open")
end
if fontloader then
- fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
- fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
+ fontloader.open=register(fontloader.open,filehandlerone,"fontloader.open")
+ fontloader.info=register(fontloader.info,filehandlerone,"fontloader.info")
end
if epdf then
- epdf.open=register(epdf.open,filehandlerone,"epdf.open")
+ epdf.open=register(epdf.open,filehandlerone,"epdf.open")
end
sandbox.registerroot=registerroot
sandbox.registerbinary=registerbinary
@@ -11585,14 +15044,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-mrg"] = package.loaded["util-mrg"] or true
--- original size: 7757, stripped down to: 6015
+-- original size: 7819, stripped down to: 5881
if not modules then modules={} end modules ['util-mrg']={
- 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 gsub,format=string.gsub,string.format
local concat=table.concat
@@ -11620,19 +15079,19 @@ local m_report=[[
]]
local m_preloaded=[[package.loaded[%q] = package.loaded[%q] or true]]
local function self_fake()
- return m_faked
+ return m_faked
end
local function self_nothing()
- return ""
+ return ""
end
local function self_load(name)
- local data=io.loaddata(name) or ""
- if data=="" then
- report("unknown file %a",name)
- else
- report("inserting file %a",name)
- end
- return data or ""
+ local data=io.loaddata(name) or ""
+ if data=="" then
+ report("unknown file %a",name)
+ else
+ report("inserting file %a",name)
+ end
+ return data or ""
end
local space=patterns.space
local eol=patterns.newline
@@ -11661,98 +15120,99 @@ local mandatespacing=(eol+space)^1/""
local pack=digit*space^1*operator4*optionalspacing+optionalspacing*operator1*optionalspacing+optionalspacing*operator2*optionalspaces+mandatespacing*operator3*mandatespaces+optionalspaces*separator*optionalspaces
local lines=emptyline^2/"\n"
local spaces=(space*space)/" "
+local spaces=(space*space*space*space)/" "
local compact=Cs ((
- ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
+ ignore+strings+longcmt+longstr+comment+pack+lines+spaces+1
)^1 )
local strip=Cs((emptyline^2/"\n"+1)^0)
local stripreturn=Cs((1-P("return")*space^1*P(1-space-eol)^1*(space+eol)^0*P(-1))^1)
function merger.compact(data)
- return lpegmatch(strip,lpegmatch(compact,data))
+ return lpegmatch(strip,lpegmatch(compact,data))
end
local function self_compact(data)
- local delta=0
- if merger.strip_comment then
- local before=#data
- data=lpegmatch(compact,data)
- data=lpegmatch(strip,data)
- local after=#data
- delta=before-after
- report("original size %s, compacted to %s, stripped %s",before,after,delta)
- data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
- end
- return lpegmatch(stripreturn,data) or data,delta
+ local delta=0
+ if merger.strip_comment then
+ local before=#data
+ data=lpegmatch(compact,data)
+ data=lpegmatch(strip,data)
+ local after=#data
+ delta=before-after
+ report("original size %s, compacted to %s, stripped %s",before,after,delta)
+ data=format("-- original size: %s, stripped down to: %s\n\n%s",before,after,data)
+ end
+ return lpegmatch(stripreturn,data) or data,delta
end
local function self_save(name,data)
- if data~="" then
- io.savedata(name,data)
- report("saving %s with size %s",name,#data)
- end
+ if data~="" then
+ io.savedata(name,data)
+ report("saving %s with size %s",name,#data)
+ end
end
local function self_swap(data,code)
- return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
+ return data~="" and (gsub(data,m_pattern,function() return format(m_format,code) end,1)) or ""
end
local function self_libs(libs,list)
- local result,f,frozen,foundpath={},nil,false,nil
- result[#result+1]="\n"
- if type(libs)=='string' then libs={ libs } end
- if type(list)=='string' then list={ list } end
+ local result,f,frozen,foundpath={},nil,false,nil
+ result[#result+1]="\n"
+ if type(libs)=='string' then libs={ libs } end
+ if type(list)=='string' then list={ list } end
+ for i=1,#libs do
+ local lib=libs[i]
+ for j=1,#list do
+ local pth=gsub(list[j],"\\","/")
+ report("checking library path %a",pth)
+ local name=pth.."/"..lib
+ if lfs.isfile(name) then
+ foundpath=pth
+ end
+ end
+ if foundpath then break end
+ end
+ if foundpath then
+ report("using library path %a",foundpath)
+ local right,wrong,original,stripped={},{},0,0
for i=1,#libs do
- local lib=libs[i]
- for j=1,#list do
- local pth=gsub(list[j],"\\","/")
- report("checking library path %a",pth)
- local name=pth.."/"..lib
- if lfs.isfile(name) then
- foundpath=pth
- end
- end
- if foundpath then break end
- end
- if foundpath then
- report("using library path %a",foundpath)
- local right,wrong,original,stripped={},{},0,0
- for i=1,#libs do
- local lib=libs[i]
- local fullname=foundpath.."/"..lib
- if lfs.isfile(fullname) then
- report("using library %a",fullname)
- local preloaded=file.nameonly(lib)
- local data=io.loaddata(fullname,true)
- original=original+#data
- local data,delta=self_compact(data)
- right[#right+1]=lib
- result[#result+1]=m_begin_closure
- result[#result+1]=format(m_preloaded,preloaded,preloaded)
- result[#result+1]=data
- result[#result+1]=m_end_closure
- stripped=stripped+delta
- else
- report("skipping library %a",fullname)
- wrong[#wrong+1]=lib
- end
- end
- right=#right>0 and concat(right," ") or "-"
- wrong=#wrong>0 and concat(wrong," ") or "-"
- report("used libraries: %a",right)
- report("skipped libraries: %a",wrong)
- report("original bytes: %a",original)
- report("stripped bytes: %a",stripped)
- result[#result+1]=format(m_report,right,wrong,original,stripped)
- else
- report("no valid library path found")
+ local lib=libs[i]
+ local fullname=foundpath.."/"..lib
+ if lfs.isfile(fullname) then
+ report("using library %a",fullname)
+ local preloaded=file.nameonly(lib)
+ local data=io.loaddata(fullname,true)
+ original=original+#data
+ local data,delta=self_compact(data)
+ right[#right+1]=lib
+ result[#result+1]=m_begin_closure
+ result[#result+1]=format(m_preloaded,preloaded,preloaded)
+ result[#result+1]=data
+ result[#result+1]=m_end_closure
+ stripped=stripped+delta
+ else
+ report("skipping library %a",fullname)
+ wrong[#wrong+1]=lib
+ end
end
- return concat(result,"\n\n")
+ right=#right>0 and concat(right," ") or "-"
+ wrong=#wrong>0 and concat(wrong," ") or "-"
+ report("used libraries: %a",right)
+ report("skipped libraries: %a",wrong)
+ report("original bytes: %a",original)
+ report("stripped bytes: %a",stripped)
+ result[#result+1]=format(m_report,right,wrong,original,stripped)
+ else
+ report("no valid library path found")
+ end
+ return concat(result,"\n\n")
end
function merger.selfcreate(libs,list,target)
- if target then
- self_save(target,self_swap(self_fake(),self_libs(libs,list)))
- end
+ if target then
+ self_save(target,self_swap(self_fake(),self_libs(libs,list)))
+ end
end
function merger.selfmerge(name,libs,list,target)
- self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
+ self_save(target or name,self_swap(self_load(name),self_libs(libs,list)))
end
function merger.selfclean(name)
- self_save(name,self_swap(self_load(name),self_nothing()))
+ self_save(name,self_swap(self_load(name),self_nothing()))
end
@@ -11762,14 +15222,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-env"] = package.loaded["util-env"] or true
--- original size: 9400, stripped down to: 5499
+-- original size: 9738, stripped down to: 5531
if not modules then modules={} end modules ['util-env']={
- 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 allocate,mark=utilities.storage.allocate,utilities.storage.mark
local format,sub,match,gsub,find=string.format,string.sub,string.match,string.gsub,string.find
@@ -11781,178 +15241,193 @@ local setlocale=os.setlocale
setlocale(nil,nil)
local report=logs.reporter("system")
function os.setlocale(a,b)
- if a or b then
- if report then
- report()
- report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
- report("now on are on your own and without support. Crashes or unexpected side effects")
- report("can happen but don't bother the luatex and context developer team with it.")
- report()
- report=nil
- end
- setlocale(a,b)
- end
+ if a or b then
+ if report then
+ report()
+ report("You're messing with os.locale in a supposedly locale neutral enviroment. From")
+ report("now on are on your own and without support. Crashes or unexpected side effects")
+ report("can happen but don't bother the luatex and context developer team with it.")
+ report()
+ report=nil
+ end
+ setlocale(a,b)
+ end
end
local validengines=allocate {
- ["luatex"]=true,
- ["luajittex"]=true,
+ ["luatex"]=true,
+ ["luajittex"]=true,
}
local basicengines=allocate {
- ["luatex"]="luatex",
- ["texlua"]="luatex",
- ["texluac"]="luatex",
- ["luajittex"]="luajittex",
- ["texluajit"]="luajittex",
+ ["luatex"]="luatex",
+ ["texlua"]="luatex",
+ ["texluac"]="luatex",
+ ["luajittex"]="luajittex",
+ ["texluajit"]="luajittex",
}
local luaengines=allocate {
- ["lua"]=true,
- ["luajit"]=true,
+ ["lua"]=true,
+ ["luajit"]=true,
}
environment.validengines=validengines
environment.basicengines=basicengines
if not arg then
- environment.used_as_library=true
+ environment.used_as_library=true
elseif luaengines[file.removesuffix(arg[-1])] then
elseif validengines[file.removesuffix(arg[0])] then
- if arg[1]=="--luaonly" then
- arg[-1]=arg[0]
- arg[ 0]=arg[2]
- for k=3,#arg do
- arg[k-2]=arg[k]
- end
- remove(arg)
- remove(arg)
- else
- end
- local originalzero=file.basename(arg[0])
- local specialmapping={ luatools=="base" }
- if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
+ if arg[1]=="--luaonly" then
+ arg[-1]=arg[0]
+ arg[ 0]=arg[2]
+ for k=3,#arg do
+ arg[k-2]=arg[k]
+ end
+ remove(arg)
+ remove(arg)
+ else
+ end
+ local originalzero=file.basename(arg[0])
+ local specialmapping={ luatools=="base" }
+ if originalzero~="mtxrun" and originalzero~="mtxrun.lua" then
arg[0]=specialmapping[originalzero] or originalzero
insert(arg,0,"--script")
insert(arg,0,"mtxrun")
- end
+ end
end
environment.arguments=allocate()
environment.files=allocate()
environment.sortedflags=nil
function environment.initializearguments(arg)
- local arguments,files={},{}
- environment.arguments,environment.files,environment.sortedflags=arguments,files,nil
- for index=1,#arg do
- local argument=arg[index]
- if index>0 then
- local flag,value=match(argument,"^%-+(.-)=(.-)$")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=unquoted(value or "")
- else
- flag=match(argument,"^%-+(.+)")
- if flag then
- flag=gsub(flag,"^c:","")
- arguments[flag]=true
- else
- files[#files+1]=argument
- end
- end
+ 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
+ local flag,value=match(argument,"^%-+(.-)=(.-)$")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=unquoted(value or "")
+ else
+ flag=match(argument,"^%-+(.+)")
+ if flag then
+ flag=gsub(flag,"^c:","")
+ arguments[flag]=true
+ else
+ files[#files+1]=argument
end
+ 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
- environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
+ end
+ environment.ownname=file.reslash(environment.ownname or arg[0] or 'unknown.lua')
end
function environment.setargument(name,value)
- environment.arguments[name]=value
+ environment.arguments[name]=value
end
function environment.getargument(name,partial)
- local arguments,sortedflags=environment.arguments,environment.sortedflags
- if arguments[name] then
- return arguments[name]
- elseif partial then
- if not sortedflags then
- sortedflags=allocate(table.sortedkeys(arguments))
- for k=1,#sortedflags do
- sortedflags[k]="^"..sortedflags[k]
- end
- environment.sortedflags=sortedflags
- end
- for k=1,#sortedflags do
- local v=sortedflags[k]
- if find(name,v) then
- return arguments[sub(v,2,#v)]
- end
- end
+ local arguments,sortedflags=environment.arguments,environment.sortedflags
+ if arguments[name] then
+ return arguments[name]
+ elseif partial then
+ if not sortedflags then
+ sortedflags=allocate(table.sortedkeys(arguments))
+ for k=1,#sortedflags do
+ sortedflags[k]="^"..sortedflags[k]
+ end
+ environment.sortedflags=sortedflags
end
- return nil
+ for k=1,#sortedflags do
+ local v=sortedflags[k]
+ if find(name,v) then
+ return arguments[sub(v,2,#v)]
+ end
+ end
+ end
+ return nil
end
environment.argument=environment.getargument
function environment.splitarguments(separator)
- local done,before,after=false,{},{}
- local originalarguments=environment.originalarguments
- for k=1,#originalarguments do
- local v=originalarguments[k]
- if not done and v==separator then
- done=true
- elseif done then
- after[#after+1]=v
- else
- before[#before+1]=v
- end
+ local done,before,after=false,{},{}
+ local originalarguments=environment.originalarguments
+ for k=1,#originalarguments do
+ local v=originalarguments[k]
+ if not done and v==separator then
+ done=true
+ elseif done then
+ after[#after+1]=v
+ else
+ before[#before+1]=v
end
- return before,after
+ end
+ return before,after
end
function environment.reconstructcommandline(arg,noquote)
- local resolveprefix=resolvers.resolve
- arg=arg or environment.originalarguments
- if noquote and #arg==1 then
- return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
- elseif #arg>0 then
- local result={}
- for i=1,#arg do
- result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
- end
- return concat(result," ")
- else
- return ""
+ local resolveprefix=resolvers.resolve
+ arg=arg or environment.originalarguments
+ if noquote and #arg==1 then
+ return unquoted(resolveprefix and resolveprefix(arg[1]) or arg[1])
+ elseif #arg>0 then
+ local result={}
+ for i=1,#arg do
+ result[i]=optionalquoted(resolveprefix and resolveprefix(arg[i]) or resolveprefix)
end
+ return concat(result," ")
+ else
+ return ""
+ end
end
function environment.relativepath(path,root)
- if not path then
- path=""
+ if not path then
+ path=""
+ end
+ if not file.is_rootbased_path(path) then
+ if not root then
+ root=file.pathpart(environment.ownscript or environment.ownname or ".")
end
- if not file.is_rootbased_path(path) then
- if not root then
- root=file.pathpart(environment.ownscript or environment.ownname or ".")
- end
- if root=="" then
- root="."
- end
- path=root.."/"..path
+ if root=="" then
+ root="."
end
- return file.collapsepath(path,true)
+ path=root.."/"..path
+ end
+ return file.collapsepath(path,true)
end
if arg then
- local newarg,instring={},false
- for index=1,#arg do
- local argument=arg[index]
- if find(argument,"^\"") then
- newarg[#newarg+1]=gsub(argument,"^\"","")
- if not find(argument,"\"$") then
- instring=true
- end
- elseif find(argument,"\"$") then
- newarg[#newarg]=newarg[#newarg].." "..gsub(argument,"\"$","")
- instring=false
- elseif instring then
- newarg[#newarg]=newarg[#newarg].." "..argument
- else
- newarg[#newarg+1]=argument
- end
- end
- for i=1,-5,-1 do
- newarg[i]=arg[i]
+ local newarg,instring={},false
+ for index=1,#arg do
+ local argument=arg[index]
+ if 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
+ 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
+ newarg[#newarg+1]=argument
end
- environment.initializearguments(newarg)
- environment.originalarguments=mark(newarg)
- environment.rawarguments=mark(arg)
- arg={}
+ end
+ for i=1,-5,-1 do
+ newarg[i]=arg[i]
+ end
+ environment.initializearguments(newarg)
+ environment.originalarguments=mark(newarg)
+ environment.rawarguments=mark(arg)
+ arg={}
end
@@ -11962,17 +15437,18 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-env"] = package.loaded["luat-env"] or true
--- original size: 5820, stripped down to: 4155
+-- original size: 6134, stripped down to: 4118
if not modules then modules={} end modules ['luat-env']={
- 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 rawset,rawget,loadfile,assert=rawset,rawget,loadfile,assert
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+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)
local report_lua=logs.reporter("resolvers","lua")
local luautilities=utilities.lua
local luasuffixes=luautilities.suffixes
@@ -11980,133 +15456,146 @@ local texgettoks=tex and tex.gettoks
environment=environment or {}
local environment=environment
local mt={
- __index=function(_,k)
- if k=="version" then
- local version=texgettoks and texgettoks("contextversiontoks")
- if version and version~="" then
- rawset(environment,"version",version)
- return version
- else
- return "unknown"
- end
- elseif k=="kind" then
- local kind=texgettoks and texgettoks("contextkindtoks")
- if kind and kind~="" then
- rawset(environment,"kind",kind)
- return kind
- else
- return "unknown"
- end
- elseif k=="jobname" or k=="formatname" then
- local name=tex and tex[k]
- if name or name=="" then
- rawset(environment,k,name)
- return name
- else
- return "unknown"
- end
- elseif k=="outputfilename" then
- local name=environment.jobname
- rawset(environment,k,name)
- return name
- end
+ __index=function(_,k)
+ if k=="version" then
+ local version=texgettoks and texgettoks("contextversiontoks")
+ if version and version~="" then
+ rawset(environment,"version",version)
+ return version
+ else
+ return "unknown"
+ end
+ elseif k=="kind" then
+ local kind=texgettoks and texgettoks("contextkindtoks")
+ if kind and kind~="" then
+ rawset(environment,"kind",kind)
+ return kind
+ else
+ return "unknown"
+ end
+ elseif k=="jobname" or k=="formatname" then
+ local name=tex and tex[k]
+ if name or name=="" then
+ rawset(environment,k,name)
+ return name
+ else
+ return "unknown"
+ end
+ elseif k=="outputfilename" then
+ local name=environment.jobname
+ rawset(environment,k,name)
+ return name
end
+ end
}
setmetatable(environment,mt)
function environment.texfile(filename)
- return resolvers.findfile(filename,'tex')
+ return resolvers.findfile(filename,'tex')
end
function environment.luafile(filename)
- local resolved=resolvers.findfile(filename,'tex') or ""
- if resolved~="" then
- return resolved
- end
- resolved=resolvers.findfile(filename,'texmfscripts') or ""
- if resolved~="" then
- return resolved
- end
- return resolvers.findfile(filename,'luatexlibs') or ""
-end
-local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
+ local resolved=resolvers.findfile(filename,'tex') or ""
+ if resolved~="" then
+ return resolved
+ end
+ resolved=resolvers.findfile(filename,'texmfscripts') or ""
+ if resolved~="" then
+ return resolved
+ end
+ return resolvers.findfile(filename,'luatexlibs') or ""
+end
+local stripindeed=false directives.register("system.compile.strip",function(v) stripindeed=v end)
local function strippable(filename)
- if stripindeed then
- local modu=modules[file.nameonly(filename)]
- return modu and modu.dataonly
- else
- return false
- end
+ if stripindeed then
+ local modu=modules[file.nameonly(filename)]
+ return modu and modu.dataonly
+ else
+ return false
+ end
end
function environment.luafilechunk(filename,silent,macros)
- filename=file.replacesuffix(filename,"lua")
- local fullname=environment.luafile(filename)
- if fullname and fullname~="" then
- local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
- if not silent then
- report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
- end
- return data
- else
- if not silent then
- report_lua("unknown file %a",filename)
- end
- return nil
+ filename=file.replacesuffix(filename,"lua")
+ local fullname=environment.luafile(filename)
+ if fullname and fullname~="" then
+ local data=luautilities.loadedluacode(fullname,strippable,filename,macros)
+ if not silent then
+ report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded")
+ end
+ return data
+ else
+ if not silent then
+ report_lua("unknown file %a",filename)
end
+ return nil
+ end
end
function environment.loadluafile(filename,version)
- local lucname,luaname,chunk
- local basename=file.removesuffix(filename)
- if basename==filename then
- luaname=file.addsuffix(basename,luasuffixes.lua)
- lucname=file.addsuffix(basename,luasuffixes.luc)
- else
- luaname=basename
- lucname=nil
- end
- local fullname=(lucname and environment.luafile(lucname)) or ""
- if fullname~="" then
+ local lucname,luaname,chunk
+ local basename=file.removesuffix(filename)
+ if basename==filename then
+ luaname=file.addsuffix(basename,luasuffixes.lua)
+ lucname=file.addsuffix(basename,luasuffixes.luc)
+ else
+ luaname=filename
+ lucname=nil
+ end
+ local fullname=(lucname and environment.luafile(lucname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
+ end
+ chunk=loadfile(fullname)
+ end
+ if chunk then
+ chunk()
+ if version then
+ local v=version
+ if modules and modules[filename] then
+ v=modules[filename].version
+ elseif versions and versions[filename] then
+ v=versions[filename]
+ end
+ if v==version then
+ return true
+ else
if trace_locating then
- report_lua("loading %a",fullname)
+ report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
end
- chunk=loadfile(fullname)
+ environment.loadluafile(filename)
+ end
+ else
+ return true
end
- if chunk then
- assert(chunk)()
- if version then
- local v=version
- if modules and modules[filename] then
- v=modules[filename].version
- elseif versions and versions[filename] then
- v=versions[filename]
- end
- if v==version then
- return true
- else
- if trace_locating then
- report_lua("version mismatch for %a, lua version %a, luc version %a",filename,v,version)
- end
- environment.loadluafile(filename)
- end
- else
- return true
- end
+ end
+ fullname=(luaname and environment.luafile(luaname)) or ""
+ if fullname~="" then
+ if trace_locating then
+ report_lua("loading %a",fullname)
end
- fullname=(luaname and environment.luafile(luaname)) or ""
- if fullname~="" then
- if trace_locating then
- report_lua("loading %a",fullname)
- end
- chunk=loadfile(fullname)
- if not chunk then
- if trace_locating then
- report_lua("unknown file %a",filename)
- end
- else
- assert(chunk)()
- return true
- end
+ chunk=loadfile(fullname)
+ if not chunk then
+ if trace_locating then
+ report_lua("unknown file %a",filename)
+ end
+ else
+ chunk()
+ return true
end
- return false
+ 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)
+ end,
+ __len=function(t)
+ return #environment.files
+ end,
+} )
end -- of closure
@@ -12115,16 +15604,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
--- original size: 60383, stripped down to: 38562
+-- original size: 60383, stripped down to: 35698
if not modules then modules={} end modules ['lxml-tab']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
+local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end)
local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end
if lpeg.setmaxstack then lpeg.setmaxstack(1000) end
xml=xml or {}
@@ -12142,17 +15631,17 @@ xml.xmlns=xml.xmlns or {}
local check=P(false)
local parse=check
function xml.registerns(namespace,pattern)
- check=check+C(P(lower(pattern)))/namespace
- parse=P { P(check)+1*V(1) }
+ check=check+C(P(lower(pattern)))/namespace
+ parse=P { P(check)+1*V(1) }
end
function xml.checkns(namespace,url)
- local ns=lpegmatch(parse,lower(url))
- if ns and namespace~=ns then
- xml.xmlns[namespace]=ns
- end
+ local ns=lpegmatch(parse,lower(url))
+ if ns and namespace~=ns then
+ xml.xmlns[namespace]=ns
+ end
end
function xml.resolvens(url)
- return lpegmatch(parse,lower(url)) or ""
+ return lpegmatch(parse,lower(url)) or ""
end
end
local nsremap,resolvens=xml.xmlns,xml.resolvens
@@ -12170,661 +15659,661 @@ local handle_dec_entity
local handle_any_entity_dtd
local handle_any_entity_text
local function preparexmlstate(settings)
- if settings then
- linenumbers=settings.linenumbers
- stack={}
- level=0
- top={}
- at={}
- mt={}
- dt={}
- nt=0
- xmlns={}
- errorstr=nil
- strip=settings.strip_cm_and_dt
- utfize=settings.utfize_entities
- resolve=settings.resolve_entities
- resolve_predefined=settings.resolve_predefined_entities
- unify_predefined=settings.unify_predefined_entities
- cleanup=settings.text_cleanup
- entities=settings.entities or {}
- currentfilename=settings.currentresource
- currentline=1
- parameters={}
- reported_at_errors={}
- dcache={}
- hcache={}
- acache={}
- if utfize==nil then
- settings.utfize_entities=true
- utfize=true
- end
- if resolve_predefined==nil then
- settings.resolve_predefined_entities=true
- resolve_predefined=true
- end
- else
- linenumbers=false
- stack=nil
- level=nil
- top=nil
- at=nil
- mt=nil
- dt=nil
- nt=nil
- xmlns=nil
- errorstr=nil
- strip=nil
- utfize=nil
- resolve=nil
- resolve_predefined=nil
- unify_predefined=nil
- cleanup=nil
- entities=nil
- parameters=nil
- reported_at_errors=nil
- dcache=nil
- hcache=nil
- acache=nil
- currentfilename=nil
- currentline=1
- end
+ if settings then
+ linenumbers=settings.linenumbers
+ stack={}
+ level=0
+ top={}
+ at={}
+ mt={}
+ dt={}
+ nt=0
+ xmlns={}
+ errorstr=nil
+ strip=settings.strip_cm_and_dt
+ utfize=settings.utfize_entities
+ resolve=settings.resolve_entities
+ resolve_predefined=settings.resolve_predefined_entities
+ unify_predefined=settings.unify_predefined_entities
+ cleanup=settings.text_cleanup
+ entities=settings.entities or {}
+ currentfilename=settings.currentresource
+ currentline=1
+ parameters={}
+ reported_at_errors={}
+ dcache={}
+ hcache={}
+ acache={}
+ if utfize==nil then
+ settings.utfize_entities=true
+ utfize=true
+ end
+ if resolve_predefined==nil then
+ settings.resolve_predefined_entities=true
+ resolve_predefined=true
+ end
+ else
+ linenumbers=false
+ stack=nil
+ level=nil
+ top=nil
+ at=nil
+ mt=nil
+ dt=nil
+ nt=nil
+ xmlns=nil
+ errorstr=nil
+ strip=nil
+ utfize=nil
+ resolve=nil
+ resolve_predefined=nil
+ unify_predefined=nil
+ cleanup=nil
+ entities=nil
+ parameters=nil
+ reported_at_errors=nil
+ dcache=nil
+ hcache=nil
+ acache=nil
+ currentfilename=nil
+ currentline=1
+ end
end
local function initialize_mt(root)
- mt={ __index=root }
+ mt={ __index=root }
end
function xml.setproperty(root,k,v)
- getmetatable(root).__index[k]=v
+ getmetatable(root).__index[k]=v
end
function xml.checkerror(top,toclose)
- return ""
+ return ""
end
local checkns=xml.checkns
local function add_attribute(namespace,tag,value)
- if cleanup and value~="" then
- value=cleanup(value)
- end
- if tag=="xmlns" then
- xmlns[#xmlns+1]=resolvens(value)
- at[tag]=value
- elseif namespace=="" then
- at[tag]=value
- elseif namespace=="xmlns" then
- checkns(tag,value)
- at["xmlns:"..tag]=value
- else
- at[namespace..":"..tag]=value
- end
+ if cleanup and value~="" then
+ value=cleanup(value)
+ end
+ if tag=="xmlns" then
+ xmlns[#xmlns+1]=resolvens(value)
+ at[tag]=value
+ elseif namespace=="" then
+ at[tag]=value
+ elseif namespace=="xmlns" then
+ checkns(tag,value)
+ at["xmlns:"..tag]=value
+ else
+ at[namespace..":"..tag]=value
+ end
end
local function add_empty(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- top=stack[level]
- dt=top.dt
- nt=#dt+1
- local t=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- cf=currentfilename,
- cl=currentline,
- __p__=top,
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt={},
- ni=nt,
- __p__=top,
- }
- dt[nt]=t
- setmetatable(t,mt)
- if at.xmlns then
- remove(xmlns)
- end
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ top=stack[level]
+ dt=top.dt
+ nt=#dt+1
+ local t=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=top,
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt={},
+ ni=nt,
+ __p__=top,
+ }
+ dt[nt]=t
+ setmetatable(t,mt)
+ if at.xmlns then
+ remove(xmlns)
+ end
+ at={}
end
local function add_begin(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
- dt={}
- top=linenumbers and {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- cf=currentfilename,
- cl=currentline,
- __p__=stack[level],
- } or {
- ns=namespace or "",
- rn=resolved,
- tg=tag,
- at=at,
- dt=dt,
- ni=nil,
- __p__=stack[level],
- }
- setmetatable(top,mt)
- nt=0
- level=level+1
- stack[level]=top
- at={}
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace
+ dt={}
+ top=linenumbers and {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ cf=currentfilename,
+ cl=currentline,
+ __p__=stack[level],
+ } or {
+ ns=namespace or "",
+ rn=resolved,
+ tg=tag,
+ at=at,
+ dt=dt,
+ ni=nil,
+ __p__=stack[level],
+ }
+ setmetatable(top,mt)
+ nt=0
+ level=level+1
+ stack[level]=top
+ at={}
end
local function add_end(spacing,namespace,tag)
- if spacing~="" then
- nt=nt+1
- dt[nt]=spacing
- end
- local toclose=stack[level]
- level=level-1
- top=stack[level]
- if level<1 then
- errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- elseif toclose.tg~=tag then
- errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
- report_xml(errorstr)
- end
- dt=top.dt
- nt=#dt+1
- dt[nt]=toclose
- toclose.ni=nt
- if toclose.at.xmlns then
- remove(xmlns)
- end
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ local toclose=stack[level]
+ level=level-1
+ top=stack[level]
+ if level<1 then
+ errorstr=formatters["unable to close %s %s"](tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ elseif toclose.tg~=tag then
+ errorstr=formatters["unable to close %s with %s %s"](toclose.tg,tag,xml.checkerror(top,toclose) or "")
+ report_xml(errorstr)
+ end
+ dt=top.dt
+ nt=#dt+1
+ dt[nt]=toclose
+ toclose.ni=nt
+ if toclose.at.xmlns then
+ remove(xmlns)
+ end
end
local function add_text(text)
- if text=="" then
- return
- end
- if cleanup then
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..cleanup(text)
- else
- nt=nt+1
- dt[nt]=cleanup(text)
- end
- else
- nt=1
- dt[1]=cleanup(text)
- end
+ if text=="" then
+ return
+ end
+ if cleanup then
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..cleanup(text)
+ else
+ nt=nt+1
+ dt[nt]=cleanup(text)
+ end
else
- if nt>0 then
- local s=dt[nt]
- if type(s)=="string" then
- dt[nt]=s..text
- else
- nt=nt+1
- dt[nt]=text
- end
- else
- nt=1
- dt[1]=text
- end
+ nt=1
+ dt[1]=cleanup(text)
end
-end
-local function add_special(what,spacing,text)
- if spacing~="" then
+ else
+ if nt>0 then
+ local s=dt[nt]
+ if type(s)=="string" then
+ dt[nt]=s..text
+ else
nt=nt+1
- dt[nt]=spacing
- end
- if strip and (what=="@cm@" or what=="@dt@") then
+ dt[nt]=text
+ end
else
- nt=nt+1
- dt[nt]=linenumbers and {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- cf=currentfilename,
- cl=currentline,
- } or {
- special=true,
- ns="",
- tg=what,
- ni=nil,
- dt={ text },
- }
+ nt=1
+ dt[1]=text
end
+ end
+end
+local function add_special(what,spacing,text)
+ if spacing~="" then
+ nt=nt+1
+ dt[nt]=spacing
+ end
+ if strip and (what=="@cm@" or what=="@dt@") then
+ else
+ nt=nt+1
+ dt[nt]=linenumbers and {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ cf=currentfilename,
+ cl=currentline,
+ } or {
+ special=true,
+ ns="",
+ tg=what,
+ ni=nil,
+ dt={ text },
+ }
+ end
end
local function set_message(txt)
- errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
+ errorstr="garbage at the end of the file: "..gsub(txt,"([ \n\r\t]*)","")
end
local function attribute_value_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute value %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute value %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
local function attribute_specification_error(str)
- if not reported_at_errors[str] then
- report_xml("invalid attribute specification %a",str)
- reported_at_errors[str]=true
- at._error_=str
- end
- return str
+ if not reported_at_errors[str] then
+ report_xml("invalid attribute specification %a",str)
+ reported_at_errors[str]=true
+ at._error_=str
+ end
+ return str
end
do
- local badentity="&"
- xml.placeholders={
- unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
- unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
- unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
- }
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return utfchar(n)
- else
- return formatters["h:%s"](s),true
+ local badentity="&"
+ xml.placeholders={
+ unknown_dec_entity=function(str) return str=="" and badentity or formatters["&%s;"](str) end,
+ unknown_hex_entity=function(str) return formatters["&#x%s;"](str) end,
+ unknown_any_entity=function(str) return formatters["&#x%s;"](str) end,
+ }
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return utfchar(n)
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local p_rest=(1-P(";"))^0
+ local p_many=P(1)^0
+ local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
+ xml.parsedentitylpeg=parsedentity
+ local predefined_unified={
+ [38]="&amp;",
+ [42]="&quot;",
+ [47]="&apos;",
+ [74]="&lt;",
+ [76]="&gt;",
+ }
+ local predefined_simplified={
+ [38]="&",amp="&",
+ [42]='"',quot='"',
+ [47]="'",apos="'",
+ [74]="<",lt="<",
+ [76]=">",gt=">",
+ }
+ local nofprivates=0xF0000
+ local privates_u={
+ [ [[&]] ]="&amp;",
+ [ [["]] ]="&quot;",
+ [ [[']] ]="&apos;",
+ [ [[<]] ]="&lt;",
+ [ [[>]] ]="&gt;",
+ }
+ local privates_p={
+ }
+ local privates_s={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[&]] ]="&U+26;",
+ [ [[']] ]="&U+27;",
+ [ [[<]] ]="&U+3C;",
+ [ [[>]] ]="&U+3E;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_x={
+ [ [["]] ]="&U+22;",
+ [ [[#]] ]="&U+23;",
+ [ [[$]] ]="&U+24;",
+ [ [[%]] ]="&U+25;",
+ [ [[']] ]="&U+27;",
+ [ [[\]] ]="&U+5C;",
+ [ [[{]] ]="&U+7B;",
+ [ [[|]] ]="&U+7C;",
+ [ [[}]] ]="&U+7D;",
+ [ [[~]] ]="&U+7E;",
+ }
+ local privates_n={
+ }
+ local escaped=utf.remapper(privates_u,"dynamic")
+ local unprivatized=utf.remapper(privates_p,"dynamic")
+ local unspecialized=utf.remapper(privates_s,"dynamic")
+ local despecialized=utf.remapper(privates_x,"dynamic")
+ xml.unprivatized=unprivatized
+ xml.unspecialized=unspecialized
+ xml.despecialized=despecialized
+ xml.escaped=escaped
+ local function unescaped(s)
+ local p=privates_n[s]
+ if not p then
+ nofprivates=nofprivates+1
+ p=utfchar(nofprivates)
+ privates_n[s]=p
+ s="&"..s..";"
+ privates_u[p]=s
+ privates_p[p]=s
+ privates_s[p]=s
+ end
+ return p
+ end
+ xml.privatetoken=unescaped
+ xml.privatecodes=privates_n
+ xml.specialcodes=privates_s
+ function xml.addspecialcode(key,value)
+ privates_s[key]=value or "&"..s..";"
+ end
+ handle_hex_entity=function(str)
+ local h=hcache[str]
+ if not h then
+ local n=tonumber(str,16)
+ h=unify_predefined and predefined_unified[n]
+ if h then
+ if trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ elseif utfize then
+ h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring hex entity &#x%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#x%s;",str)
end
+ h="&#x"..str..";"
+ end
+ hcache[str]=h
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return utfchar(n)
- else
- return formatters["d:%s"](s),true
- end
- end
- local p_rest=(1-P(";"))^0
- local p_many=P(1)^0
- local parsedentity=P("&#")*(P("x")*(p_rest/fromhex)+(p_rest/fromdec))*P(";")*P(-1)+P ("#")*(P("x")*(p_many/fromhex)+(p_many/fromdec))
- xml.parsedentitylpeg=parsedentity
- local predefined_unified={
- [38]="&amp;",
- [42]="&quot;",
- [47]="&apos;",
- [74]="&lt;",
- [76]="&gt;",
- }
- local predefined_simplified={
- [38]="&",amp="&",
- [42]='"',quot='"',
- [47]="'",apos="'",
- [74]="<",lt="<",
- [76]=">",gt=">",
- }
- local nofprivates=0xF0000
- local privates_u={
- [ [[&]] ]="&amp;",
- [ [["]] ]="&quot;",
- [ [[']] ]="&apos;",
- [ [[<]] ]="&lt;",
- [ [[>]] ]="&gt;",
- }
- local privates_p={
- }
- local privates_s={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[&]] ]="&U+26;",
- [ [[']] ]="&U+27;",
- [ [[<]] ]="&U+3C;",
- [ [[>]] ]="&U+3E;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_x={
- [ [["]] ]="&U+22;",
- [ [[#]] ]="&U+23;",
- [ [[$]] ]="&U+24;",
- [ [[%]] ]="&U+25;",
- [ [[']] ]="&U+27;",
- [ [[\]] ]="&U+5C;",
- [ [[{]] ]="&U+7B;",
- [ [[|]] ]="&U+7C;",
- [ [[}]] ]="&U+7D;",
- [ [[~]] ]="&U+7E;",
- }
- local privates_n={
- }
- local escaped=utf.remapper(privates_u,"dynamic")
- local unprivatized=utf.remapper(privates_p,"dynamic")
- local unspecialized=utf.remapper(privates_s,"dynamic")
- local despecialized=utf.remapper(privates_x,"dynamic")
- xml.unprivatized=unprivatized
- xml.unspecialized=unspecialized
- xml.despecialized=despecialized
- xml.escaped=escaped
- local function unescaped(s)
- local p=privates_n[s]
- if not p then
- nofprivates=nofprivates+1
- p=utfchar(nofprivates)
- privates_n[s]=p
- s="&"..s..";"
- privates_u[p]=s
- privates_p[p]=s
- privates_s[p]=s
- end
- return p
- end
- xml.privatetoken=unescaped
- xml.privatecodes=privates_n
- xml.specialcodes=privates_s
- function xml.addspecialcode(key,value)
- privates_s[key]=value or "&"..s..";"
- end
- handle_hex_entity=function(str)
- local h=hcache[str]
- if not h then
- local n=tonumber(str,16)
- h=unify_predefined and predefined_unified[n]
- if h then
- if trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- elseif utfize then
- h=(n and utfchar(n)) or xml.unknown_hex_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring hex entity &#x%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting hex entity &#x%s; into %a",str,h)
- end
- else
- if trace_entities then
- report_xml("found entity &#x%s;",str)
- end
- h="&#x"..str..";"
- end
- hcache[str]=h
- end
- return h
- end
- handle_dec_entity=function(str)
- local d=dcache[str]
- if not d then
- local n=tonumber(str)
- d=unify_predefined and predefined_unified[n]
- if d then
- if trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- elseif utfize then
- d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
- if not n then
- report_xml("utfize, ignoring dec entity &#%s;",str)
- elseif trace_entities then
- report_xml("utfize, converting dec entity &#%s; into %a",str,d)
- end
- else
- if trace_entities then
- report_xml("found entity &#%s;",str)
- end
- d="&#"..str..";"
- end
- dcache[str]=d
+ return h
+ end
+ handle_dec_entity=function(str)
+ local d=dcache[str]
+ if not d then
+ local n=tonumber(str)
+ d=unify_predefined and predefined_unified[n]
+ if d then
+ if trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ elseif utfize then
+ d=(n and utfchar(n)) or placeholders.unknown_dec_entity(str) or ""
+ if not n then
+ report_xml("utfize, ignoring dec entity &#%s;",str)
+ elseif trace_entities then
+ report_xml("utfize, converting dec entity &#%s; into %a",str,d)
+ end
+ else
+ if trace_entities then
+ report_xml("found entity &#%s;",str)
end
- return d
+ d="&#"..str..";"
+ end
+ dcache[str]=d
end
- handle_any_entity_dtd=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
- end
- return a
+ return d
+ end
+ handle_any_entity_dtd=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
- end
- return a
+ a=entities[str]
end
- end
- handle_any_entity_text=function(str)
- if resolve then
- local a=resolve_predefined and predefined_simplified[str]
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to predefined %a",str,a)
- end
- else
- if type(resolve)=="function" then
- a=resolve(str,entities) or entities[str]
- else
- a=entities[str]
- end
- if a then
- if type(a)=="function" then
- if trace_entities then
- report_xml("expanding entity &%s; to function call",str)
- end
- a=a(str) or ""
- end
- a=lpegmatch(grammar_parsed_text_two,a) or a
- if type(a)=="number" then
- return ""
- else
- a=lpegmatch(parsedentity,a) or a
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- end
- if trace_entities then
- report_xml("resolving entity &%s; to internal %a",str,a)
- end
- else
- local unknown_any_entity=placeholders.unknown_any_entity
- if unknown_any_entity then
- a=unknown_any_entity(str) or ""
- end
- if a then
- if trace_entities then
- report_xml("resolving entity &%s; to external %s",str,a)
- end
- else
- if trace_entities then
- report_xml("keeping entity &%s;",str)
- end
- if str=="" then
- a=badentity
- else
- a="&"..str..";"
- end
- end
- end
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
end
- return a
+ a=a(str) or ""
+ end
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- local a=acache[str]
- if not a then
- a=resolve_predefined and predefined_simplified[str]
- if a then
- acache[str]=a
- if trace_entities then
- report_xml("entity &%s; becomes %a",str,a)
- end
- elseif str=="" then
- if trace_entities then
- report_xml("invalid entity &%s;",str)
- end
- a=badentity
- acache[str]=a
- else
- if trace_entities then
- report_xml("entity &%s; is made private",str)
- end
- a=unescaped(str)
- acache[str]=a
- end
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
end
- return a
- end
- end
- local p_rest=(1-P(";"))^1
- local spec={
- [0x23]="\\Ux{23}",
- [0x24]="\\Ux{24}",
- [0x25]="\\Ux{25}",
- [0x5C]="\\Ux{5C}",
- [0x7B]="\\Ux{7B}",
- [0x7C]="\\Ux{7C}",
- [0x7D]="\\Ux{7D}",
- [0x7E]="\\Ux{7E}",
- }
- local hash=table.setmetatableindex(spec,function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
- else
- return formatters["u:%s"](s),true
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
- end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
+ end
+ return a
+ end
+ end
+ handle_any_entity_text=function(str)
+ if resolve then
+ local a=resolve_predefined and predefined_simplified[str]
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to predefined %a",str,a)
+ end
+ else
+ if type(resolve)=="function" then
+ a=resolve(str,entities) or entities[str]
else
- return formatters["d:%s"](s),true
+ a=entities[str]
end
- end
- local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- local hash=table.setmetatableindex(function(t,k)
- local v=utfchar(k)
- t[k]=v
- return v
- end)
- local function fromuni(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ if a then
+ if type(a)=="function" then
+ if trace_entities then
+ report_xml("expanding entity &%s; to function call",str)
+ end
+ a=a(str) or ""
+ end
+ a=lpegmatch(grammar_parsed_text_two,a) or a
+ if type(a)=="number" then
+ return ""
+ else
+ a=lpegmatch(parsedentity,a) or a
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
+ end
+ if trace_entities then
+ report_xml("resolving entity &%s; to internal %a",str,a)
+ end
else
- return formatters["u:%s"](s),true
+ local unknown_any_entity=placeholders.unknown_any_entity
+ if unknown_any_entity then
+ a=unknown_any_entity(str) or ""
+ end
+ if a then
+ if trace_entities then
+ report_xml("resolving entity &%s; to external %s",str,a)
+ end
+ else
+ if trace_entities then
+ report_xml("keeping entity &%s;",str)
+ end
+ if str=="" then
+ a=badentity
+ else
+ a="&"..str..";"
+ end
+ end
end
- end
- local function fromhex(s)
- local n=tonumber(s,16)
- if n then
- return hash[n]
+ end
+ return a
+ else
+ local a=acache[str]
+ if not a then
+ a=resolve_predefined and predefined_simplified[str]
+ if a then
+ acache[str]=a
+ if trace_entities then
+ report_xml("entity &%s; becomes %a",str,a)
+ end
+ elseif str=="" then
+ if trace_entities then
+ report_xml("invalid entity &%s;",str)
+ end
+ a=badentity
+ acache[str]=a
else
- return formatters["h:%s"](s),true
+ if trace_entities then
+ report_xml("entity &%s; is made private",str)
+ end
+ a=unescaped(str)
+ acache[str]=a
end
+ end
+ return a
+ end
+ end
+ local p_rest=(1-P(";"))^1
+ local spec={
+ [0x23]="\\Ux{23}",
+ [0x24]="\\Ux{24}",
+ [0x25]="\\Ux{25}",
+ [0x5C]="\\Ux{5C}",
+ [0x7B]="\\Ux{7B}",
+ [0x7C]="\\Ux{7C}",
+ [0x7D]="\\Ux{7D}",
+ [0x7E]="\\Ux{7E}",
+ }
+ local hash=table.setmetatableindex(spec,function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
end
- local function fromdec(s)
- local n=tonumber(s)
- if n then
- return hash[n]
- else
- return formatters["d:%s"](s),true
- end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
end
- local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
- P("x")*(p_rest/fromhex)+p_rest/fromdec
- )
- xml.reparsedentitylpeg=reparsedentity
- xml.unescapedentitylpeg=unescapedentity
+ end
+ local reparsedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ local hash=table.setmetatableindex(function(t,k)
+ local v=utfchar(k)
+ t[k]=v
+ return v
+ end)
+ local function fromuni(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["u:%s"](s),true
+ end
+ end
+ local function fromhex(s)
+ local n=tonumber(s,16)
+ if n then
+ return hash[n]
+ else
+ return formatters["h:%s"](s),true
+ end
+ end
+ local function fromdec(s)
+ local n=tonumber(s)
+ if n then
+ return hash[n]
+ else
+ return formatters["d:%s"](s),true
+ end
+ end
+ local unescapedentity=P("U+")*(p_rest/fromuni)+P("#")*(
+ P("x")*(p_rest/fromhex)+p_rest/fromdec
+ )
+ xml.reparsedentitylpeg=reparsedentity
+ xml.unescapedentitylpeg=unescapedentity
end
local escaped=xml.escaped
local unescaped=xml.unescaped
local placeholders=xml.placeholders
local function handle_end_entity(str)
- report_xml("error in entity, %a found without ending %a",str,";")
- return str
+ report_xml("error in entity, %a found without ending %a",str,";")
+ return str
end
local function handle_crap_error(chr)
- report_xml("error in parsing, unexpected %a found ",chr)
- add_text(chr)
- return chr
+ report_xml("error in parsing, unexpected %a found ",chr)
+ add_text(chr)
+ return chr
end
local function handlenewline()
- currentline=currentline+1
+ currentline=currentline+1
end
local spacetab=S(' \t')
local space=S(' \r\n\t')
@@ -12849,141 +16338,141 @@ local space_nl=spacetab+newline
local spacing_nl=Cs((space_nl)^0)
local anything_nl=newline+P(1)
local function weirdentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","weird",k,v)
- end
- parameters[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","weird",k,v)
+ end
+ parameters[k]=v
end
local function normalentity(k,v)
- if trace_entities then
- report_xml("registering %s entity %a as %a","normal",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","normal",k,v)
+ end
+ entities[k]=v
end
local function systementity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","system",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","system",k,v)
+ end
+ entities[k]=v
end
local function publicentity(k,v,n)
- if trace_entities then
- report_xml("registering %s entity %a as %a","public",k,v)
- end
- entities[k]=v
+ if trace_entities then
+ report_xml("registering %s entity %a as %a","public",k,v)
+ end
+ entities[k]=v
end
local function entityfile(pattern,k,v,n)
- if n then
- local okay,data
- if resolvers then
- okay,data=resolvers.loadbinfile(n)
- else
- data=io.loaddata(n)
- okay=data and data~=""
- end
- if okay then
- if trace_entities then
- report_xml("loading public entities %a as %a from %a",k,v,n)
- end
- lpegmatch(pattern,data)
- return
- end
+ if n then
+ local okay,data
+ if resolvers then
+ okay,data=resolvers.loadbinfile(n)
+ else
+ data=io.loaddata(n)
+ okay=data and data~=""
end
- report_xml("ignoring public entities %a as %a from %a",k,v,n)
+ if okay then
+ if trace_entities then
+ report_xml("loading public entities %a as %a from %a",k,v,n)
+ end
+ lpegmatch(pattern,data)
+ return
+ end
+ end
+ report_xml("ignoring public entities %a as %a from %a",k,v,n)
end
local function install(spacenewline,spacing,anything)
- local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
- local hexentitycontent=R("AF","af","09")^1
- local decentitycontent=R("09")^1
- local parsedentity=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_dtd)
- local parsedentity_text=P("#")/""*(
- P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
- )+(anyentitycontent/handle_any_entity_text)
- local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
- local text_unparsed=Cs((anything-open)^1)
- local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
- local somespace=(spacenewline)^1
- local optionalspace=(spacenewline)^0
- local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
- local endofattributes=slash*close+close
- local whatever=space*name*optionalspace*equal
- local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
- local attributevalue=value+wrongvalue
- local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
- local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
- local parsedtext=text_parsed
- local unparsedtext=text_unparsed/add_text
- local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
- local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
- local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
- local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
- local begincomment=open*P("!--")
- local endcomment=P("--")*close
- local begininstruction=open*P("?")
- local endinstruction=P("?")*close
- local begincdata=open*P("![CDATA[")
- local endcdata=P("]]")*close
- local someinstruction=C((anything-endinstruction)^0)
- local somecomment=C((anything-endcomment )^0)
- local somecdata=C((anything-endcdata )^0)
- local begindoctype=open*P("!DOCTYPE")
- local enddoctype=close
- local beginset=P("[")
- local endset=P("]")
- local wrdtypename=C((anything-somespace-P(";"))^1)
- local doctypename=C((anything-somespace-close)^0)
- local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
- local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
- local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
- local normalentitytype=(doctypename*somespace*value)/normalentity
- local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
- local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
- local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
- local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
- entityfile(entitydoctype,...)
- end
- local function weirdresolve(s)
- lpegmatch(entitydoctype,parameters[s])
- end
- local function normalresolve(s)
- lpegmatch(entitydoctype,entities[s])
- end
- local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
- entitydoctype=entitydoctype+entityresolve
- local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
- local definitiondoctype=doctypename*somespace*doctypeset
- local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
- local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
- local simpledoctype=(anything-close)^1
- local somedoctype=C((somespace*(
+ local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0
+ local hexentitycontent=R("AF","af","09")^1
+ local decentitycontent=R("09")^1
+ local parsedentity=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_dtd)
+ local parsedentity_text=P("#")/""*(
+ P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity)
+ )+(anyentitycontent/handle_any_entity_text)
+ local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity)
+ local text_unparsed=Cs((anything-open)^1)
+ local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1
+ local somespace=(spacenewline)^1
+ local optionalspace=(spacenewline)^0
+ local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote)
+ local endofattributes=slash*close+close
+ local whatever=space*name*optionalspace*equal
+ local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error
+ local attributevalue=value+wrongvalue
+ local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute
+ local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0
+ local parsedtext=text_parsed
+ local unparsedtext=text_unparsed/add_text
+ local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" }
+ local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty
+ local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin
+ local endelement=(spacing*open*slash*name*optionalspace*close)/add_end
+ local begincomment=open*P("!--")
+ local endcomment=P("--")*close
+ local begininstruction=open*P("?")
+ local endinstruction=P("?")*close
+ local begincdata=open*P("![CDATA[")
+ local endcdata=P("]]")*close
+ local someinstruction=C((anything-endinstruction)^0)
+ local somecomment=C((anything-endcomment )^0)
+ local somecdata=C((anything-endcdata )^0)
+ local begindoctype=open*P("!DOCTYPE")
+ local enddoctype=close
+ local beginset=P("[")
+ local endset=P("]")
+ local wrdtypename=C((anything-somespace-P(";"))^1)
+ local doctypename=C((anything-somespace-close)^0)
+ local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close
+ local basiccomment=begincomment*((anything-endcomment)^0)*endcomment
+ local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity
+ local normalentitytype=(doctypename*somespace*value)/normalentity
+ local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity
+ local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity
+ local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close
+ local publicentityfile=(doctypename*somespace*P("PUBLIC")*somespace*value*(somespace*value)^0)/function(...)
+ entityfile(entitydoctype,...)
+ end
+ local function weirdresolve(s)
+ lpegmatch(entitydoctype,parameters[s])
+ end
+ local function normalresolve(s)
+ lpegmatch(entitydoctype,entities[s])
+ end
+ local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";")
+ entitydoctype=entitydoctype+entityresolve
+ local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset
+ local definitiondoctype=doctypename*somespace*doctypeset
+ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset
+ local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset
+ local simpledoctype=(anything-close)^1
+ local somedoctype=C((somespace*(
publicentityfile+publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0)
- local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
- local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
- local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
- local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
- local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
- local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
- local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
- local trailer=space^0*(text_unparsed/set_message)^0
- local grammar_parsed_text_one=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
- }
- local grammar_parsed_text_two=P { "followup",
- followup=V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
- }
- local grammar_unparsed_text=P { "preamble",
- preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
- parent=beginelement*V("children")^0*endelement,
- children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
- }
- return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
+ local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end
+ local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end
+ local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end
+ local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end
+ local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand
+ local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error
+ local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error
+ local trailer=space^0*(text_unparsed/set_message)^0
+ local grammar_parsed_text_one=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0,
+ }
+ local grammar_parsed_text_two=P { "followup",
+ followup=V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap,
+ }
+ local grammar_unparsed_text=P { "preamble",
+ preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer,
+ parent=beginelement*V("children")^0*endelement,
+ children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap,
+ }
+ return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text
end
grammar_parsed_text_one_nop,
grammar_parsed_text_two_nop,
@@ -12992,576 +16481,576 @@ grammar_parsed_text_one_yes,
grammar_parsed_text_two_yes,
grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl)
local function _xmlconvert_(data,settings,detail)
- settings=settings or {}
- preparexmlstate(settings)
- if settings.linenumbers then
- grammar_parsed_text_one=grammar_parsed_text_one_yes
- grammar_parsed_text_two=grammar_parsed_text_two_yes
- grammar_unparsed_text=grammar_unparsed_text_yes
- else
- grammar_parsed_text_one=grammar_parsed_text_one_nop
- grammar_parsed_text_two=grammar_parsed_text_two_nop
- grammar_unparsed_text=grammar_unparsed_text_nop
- end
- local preprocessor=settings.preprocessor
- if data and data~="" and type(preprocessor)=="function" then
- data=preprocessor(data,settings) or data
+ settings=settings or {}
+ preparexmlstate(settings)
+ if settings.linenumbers then
+ grammar_parsed_text_one=grammar_parsed_text_one_yes
+ grammar_parsed_text_two=grammar_parsed_text_two_yes
+ grammar_unparsed_text=grammar_unparsed_text_yes
+ else
+ grammar_parsed_text_one=grammar_parsed_text_one_nop
+ grammar_parsed_text_two=grammar_parsed_text_two_nop
+ grammar_unparsed_text=grammar_unparsed_text_nop
+ end
+ local preprocessor=settings.preprocessor
+ if data and data~="" and type(preprocessor)=="function" then
+ data=preprocessor(data,settings) or data
+ end
+ if settings.parent_root then
+ mt=getmetatable(settings.parent_root)
+ else
+ initialize_mt(top)
+ end
+ level=level+1
+ stack[level]=top
+ top.dt={}
+ dt=top.dt
+ nt=0
+ if not data or data=="" then
+ errorstr="empty xml file"
+ elseif data==true then
+ errorstr=detail or "problematic xml file"
+ elseif utfize or resolve then
+ local m=lpegmatch(grammar_parsed_text_one,data)
+ if m then
+ m=lpegmatch(grammar_parsed_text_two,data,m)
end
- if settings.parent_root then
- mt=getmetatable(settings.parent_root)
- else
- initialize_mt(top)
- end
- level=level+1
- stack[level]=top
- top.dt={}
- dt=top.dt
- nt=0
- if not data or data=="" then
- errorstr="empty xml file"
- elseif data==true then
- errorstr=detail or "problematic xml file"
- elseif utfize or resolve then
- local m=lpegmatch(grammar_parsed_text_one,data)
- if m then
- m=lpegmatch(grammar_parsed_text_two,data,m)
- end
- if m then
- else
- errorstr="invalid xml file - parsed text"
- end
- elseif type(data)=="string" then
- if lpegmatch(grammar_unparsed_text,data) then
- errorstr=""
- else
- errorstr="invalid xml file - unparsed text"
- end
+ if m then
else
- errorstr="invalid xml file - no text at all"
- end
- local result
- if errorstr and errorstr~="" then
- result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
- setmetatable(result,mt)
- setmetatable(result.dt[1],mt)
- setmetatable(stack,mt)
- local errorhandler=settings.error_handler
- if errorhandler==false then
+ errorstr="invalid xml file - parsed text"
+ end
+ elseif type(data)=="string" then
+ if lpegmatch(grammar_unparsed_text,data) then
+ errorstr=""
+ else
+ errorstr="invalid xml file - unparsed text"
+ end
+ else
+ errorstr="invalid xml file - no text at all"
+ end
+ local result
+ if errorstr and errorstr~="" then
+ result={ dt={ { ns="",tg="error",dt={ errorstr },at={},er=true } } }
+ setmetatable(result,mt)
+ setmetatable(result.dt[1],mt)
+ setmetatable(stack,mt)
+ local errorhandler=settings.error_handler
+ if errorhandler==false then
+ else
+ errorhandler=errorhandler or xml.errorhandler
+ if errorhandler then
+ local currentresource=settings.currentresource
+ if currentresource and currentresource~="" then
+ xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
else
- errorhandler=errorhandler or xml.errorhandler
- if errorhandler then
- local currentresource=settings.currentresource
- if currentresource and currentresource~="" then
- xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource)
- else
- xml.errorhandler(formatters["load error: %s"](errorstr))
- end
- end
- end
- else
- result=stack[1]
- end
- if not settings.no_root then
- result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
- setmetatable(result,mt)
- local rdt=result.dt
- for k=1,#rdt do
- local v=rdt[k]
- if type(v)=="table" and not v.special then
- result.ri=k
- v.__p__=result
- break
- end
+ xml.errorhandler(formatters["load error: %s"](errorstr))
end
+ end
end
- if errorstr and errorstr~="" then
- result.error=true
- else
- errorstr=nil
- end
- result.statistics={
- errormessage=errorstr,
- entities={
- decimals=dcache,
- hexadecimals=hcache,
- names=acache,
- intermediates=parameters,
- }
+ else
+ result=stack[1]
+ end
+ if not settings.no_root then
+ result={ special=true,ns="",tg='@rt@',dt=result.dt,at={},entities=entities,settings=settings }
+ setmetatable(result,mt)
+ local rdt=result.dt
+ for k=1,#rdt do
+ local v=rdt[k]
+ if type(v)=="table" and not v.special then
+ result.ri=k
+ v.__p__=result
+ break
+ end
+ end
+ end
+ if errorstr and errorstr~="" then
+ result.error=true
+ else
+ errorstr=nil
+ end
+ result.statistics={
+ errormessage=errorstr,
+ entities={
+ decimals=dcache,
+ hexadecimals=hcache,
+ names=acache,
+ intermediates=parameters,
}
- preparexmlstate()
- return result
+ }
+ preparexmlstate()
+ return result
end
local function xmlconvert(data,settings)
- local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
- if ok then
- return result
- elseif type(result)=="string" then
- return _xmlconvert_(true,settings,result)
- else
- return _xmlconvert_(true,settings)
- end
+ local ok,result=pcall(function() return _xmlconvert_(data,settings) end)
+ if ok then
+ return result
+ elseif type(result)=="string" then
+ return _xmlconvert_(true,settings,result)
+ else
+ return _xmlconvert_(true,settings)
+ end
end
xml.convert=xmlconvert
function xml.inheritedconvert(data,xmldata)
- local settings=xmldata.settings
- if settings then
- settings.parent_root=xmldata
- end
- local xc=xmlconvert(data,settings)
- return xc
+ local settings=xmldata.settings
+ if settings then
+ settings.parent_root=xmldata
+ end
+ local xc=xmlconvert(data,settings)
+ return xc
end
function xml.is_valid(root)
- return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
+ return root and root.dt and root.dt[1] and type(root.dt[1])=="table" and not root.dt[1].er
end
function xml.package(tag,attributes,data)
- local ns,tg=match(tag,"^(.-):?([^:]+)$")
- local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
- setmetatable(t,mt)
- return t
+ local ns,tg=match(tag,"^(.-):?([^:]+)$")
+ local t={ ns=ns,tg=tg,dt=data or "",at=attributes or {} }
+ setmetatable(t,mt)
+ return t
end
function xml.is_valid(root)
- return root and not root.error
+ return root and not root.error
end
xml.errorhandler=report_xml
function xml.load(filename,settings)
- local data=""
- if type(filename)=="string" then
- local f=io.open(filename,'r')
- if f then
- data=f:read("*all")
- f:close()
- end
- elseif filename then
- data=filename:read("*all")
- end
- if settings then
- settings.currentresource=filename
- local result=xmlconvert(data,settings)
- settings.currentresource=nil
- return result
- else
- return xmlconvert(data,{ currentresource=filename })
- end
+ local data=""
+ if type(filename)=="string" then
+ local f=io.open(filename,'r')
+ if f then
+ data=f:read("*all")
+ f:close()
+ end
+ elseif filename then
+ data=filename:read("*all")
+ end
+ if settings then
+ settings.currentresource=filename
+ local result=xmlconvert(data,settings)
+ settings.currentresource=nil
+ return result
+ else
+ return xmlconvert(data,{ currentresource=filename })
+ end
end
local no_root={ no_root=true }
function xml.toxml(data)
- if type(data)=="string" then
- local root={ xmlconvert(data,no_root) }
- return (#root>1 and root) or root[1]
- else
- return data
- end
+ if type(data)=="string" then
+ local root={ xmlconvert(data,no_root) }
+ return (#root>1 and root) or root[1]
+ else
+ return data
+ end
end
local function copy(old,p)
- if old then
- local new={}
- for k,v in next,old do
- local t=type(v)=="table"
- if k=="at" then
- local t={}
- for k,v in next,v do
- t[k]=v
- end
- new[k]=t
- elseif k=="dt" then
- v.__p__=nil
- v=copy(v,new)
- new[k]=v
- v.__p__=p
- else
- new[k]=v
- end
- end
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ local t=type(v)=="table"
+ if k=="at" then
+ local t={}
+ for k,v in next,v do
+ t[k]=v
+ end
+ new[k]=t
+ elseif k=="dt" then
+ v.__p__=nil
+ v=copy(v,new)
+ new[k]=v
+ v.__p__=p
+ else
+ new[k]=v
+ end
end
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
+ return new
+ else
+ return {}
+ end
end
xml.copy=copy
function xml.checkbom(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
- return
- end
- end
- insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
- insert(dt,2,"\n" )
+ if root.ri then
+ local dt=root.dt
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="table" and v.special and v.tg=="@pi@" and find(v.dt[1],"xml.*version=") then
+ return
+ end
end
+ insert(dt,1,{ special=true,ns="",tg="@pi@",dt={ "xml version='1.0' standalone='yes'" } } )
+ insert(dt,2,"\n" )
+ end
end
local f_attribute=formatters['%s=%q']
local function verbose_element(e,handlers,escape)
- local handle=handlers.handle
- local serialize=handlers.serialize
- local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
- local ats=eat and next(eat) and {}
- if ats then
- local n=0
- for k in next,eat do
- n=n+1
- ats[n]=k
- end
- if n==1 then
- local k=ats[1]
- ats=f_attribute(k,escaped(eat[k]))
- else
- sort(ats)
- for i=1,n do
- local k=ats[i]
- ats[i]=f_attribute(k,escaped(eat[k]))
- end
- ats=concat(ats," ")
- end
- end
- if ern and trace_entities and ern~=ens then
- ens=ern
+ local handle=handlers.handle
+ local serialize=handlers.serialize
+ local ens,etg,eat,edt,ern=e.ns,e.tg,e.at,e.dt,e.rn
+ local ats=eat and next(eat) and {}
+ if ats then
+ local n=0
+ for k in next,eat do
+ n=n+1
+ ats[n]=k
end
- local n=edt and #edt
- if ens~="" then
- if n and n>0 then
- if ats then
- handle("<",ens,":",etg," ",ats,">")
- else
- handle("<",ens,":",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",ens,":",etg,">")
+ if n==1 then
+ local k=ats[1]
+ ats=f_attribute(k,escaped(eat[k]))
+ else
+ sort(ats)
+ for i=1,n do
+ local k=ats[i]
+ ats[i]=f_attribute(k,escaped(eat[k]))
+ end
+ ats=concat(ats," ")
+ end
+ end
+ if ern and trace_entities and ern~=ens then
+ ens=ern
+ end
+ local n=edt and #edt
+ if ens~="" then
+ if n and n>0 then
+ if ats then
+ handle("<",ens,":",etg," ",ats,">")
+ else
+ handle("<",ens,":",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",ens,":",etg," ",ats,"/>")
- else
- handle("<",ens,":",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",ens,":",etg,">")
else
- if n and n>0 then
- if ats then
- handle("<",etg," ",ats,">")
- else
- handle("<",etg,">")
- end
- for i=1,n do
- local e=edt[i]
- if type(e)=="string" then
- handle(escaped(e))
- else
- serialize(e,handlers)
- end
- end
- handle("</",etg,">")
+ if ats then
+ handle("<",ens,":",etg," ",ats,"/>")
+ else
+ handle("<",ens,":",etg,"/>")
+ end
+ end
+ else
+ if n and n>0 then
+ if ats then
+ handle("<",etg," ",ats,">")
+ else
+ handle("<",etg,">")
+ end
+ for i=1,n do
+ local e=edt[i]
+ if type(e)=="string" then
+ handle(escaped(e))
else
- if ats then
- handle("<",etg," ",ats,"/>")
- else
- handle("<",etg,"/>")
- end
+ serialize(e,handlers)
end
+ end
+ handle("</",etg,">")
+ else
+ if ats then
+ handle("<",etg," ",ats,"/>")
+ else
+ handle("<",etg,"/>")
+ end
end
+ end
end
local function verbose_pi(e,handlers)
- handlers.handle("<?",e.dt[1],"?>")
+ handlers.handle("<?",e.dt[1],"?>")
end
local function verbose_comment(e,handlers)
- handlers.handle("<!--",e.dt[1],"-->")
+ handlers.handle("<!--",e.dt[1],"-->")
end
local function verbose_cdata(e,handlers)
- handlers.handle("<![CDATA[",e.dt[1],"]]>")
+ handlers.handle("<![CDATA[",e.dt[1],"]]>")
end
local function verbose_doctype(e,handlers)
- handlers.handle("<!DOCTYPE",e.dt[1],">")
+ handlers.handle("<!DOCTYPE",e.dt[1],">")
end
local function verbose_root(e,handlers)
- handlers.serialize(e.dt,handlers)
+ handlers.serialize(e.dt,handlers)
end
local function verbose_text(e,handlers)
- handlers.handle(escaped(e))
+ handlers.handle(escaped(e))
end
local function verbose_document(e,handlers)
- local serialize=handlers.serialize
- local functions=handlers.functions
- for i=1,#e do
- local ei=e[i]
- if type(ei)=="string" then
- functions["@tx@"](ei,handlers)
- else
- serialize(ei,handlers)
- end
+ local serialize=handlers.serialize
+ local functions=handlers.functions
+ for i=1,#e do
+ local ei=e[i]
+ if type(ei)=="string" then
+ functions["@tx@"](ei,handlers)
+ else
+ serialize(ei,handlers)
end
+ end
end
local function serialize(e,handlers,...)
- if e then
- local initialize=handlers.initialize
- local finalize=handlers.finalize
- local functions=handlers.functions
- if initialize then
- local state=initialize(...)
- if not state==true then
- return state
- end
- end
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
- if finalize then
- return finalize()
- end
+ if e then
+ local initialize=handlers.initialize
+ local finalize=handlers.finalize
+ local functions=handlers.functions
+ if initialize then
+ local state=initialize(...)
+ if not state==true then
+ return state
+ end
end
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
+ end
+ if finalize then
+ return finalize()
+ end
+ end
end
local function xserialize(e,handlers)
- if e then
- local functions=handlers.functions
- local etg=e.tg
- if etg then
- (functions[etg] or functions["@el@"])(e,handlers)
- else
- functions["@dc@"](e,handlers)
- end
+ if e then
+ local functions=handlers.functions
+ local etg=e.tg
+ if etg then
+ (functions[etg] or functions["@el@"])(e,handlers)
+ else
+ functions["@dc@"](e,handlers)
end
+ end
end
local handlers={}
local function newhandlers(settings)
- local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
- if settings then
- for k,v in next,settings do
- if type(v)=="table" then
- local tk=t[k] if not tk then tk={} t[k]=tk end
- for kk,vv in next,v do
- tk[kk]=vv
- end
- else
- t[k]=v
- end
- end
- if settings.name then
- handlers[settings.name]=t
- end
+ local t=table.copy(handlers[settings and settings.parent or "verbose"] or {})
+ if settings then
+ for k,v in next,settings do
+ if type(v)=="table" then
+ local tk=t[k] if not tk then tk={} t[k]=tk end
+ for kk,vv in next,v do
+ tk[kk]=vv
+ end
+ else
+ t[k]=v
+ end
end
- utilities.storage.mark(t)
- return t
+ if settings.name then
+ handlers[settings.name]=t
+ end
+ end
+ utilities.storage.mark(t)
+ return t
end
local nofunction=function() end
function xml.sethandlersfunction(handler,name,fnc)
- handler.functions[name]=fnc or nofunction
+ handler.functions[name]=fnc or nofunction
end
function xml.gethandlersfunction(handler,name)
- return handler.functions[name]
+ return handler.functions[name]
end
function xml.gethandlers(name)
- return handlers[name]
+ return handlers[name]
end
newhandlers {
- name="verbose",
- initialize=false,
- finalize=false,
- serialize=xserialize,
- handle=print,
- functions={
- ["@dc@"]=verbose_document,
- ["@dt@"]=verbose_doctype,
- ["@rt@"]=verbose_root,
- ["@el@"]=verbose_element,
- ["@pi@"]=verbose_pi,
- ["@cm@"]=verbose_comment,
- ["@cd@"]=verbose_cdata,
- ["@tx@"]=verbose_text,
- }
+ name="verbose",
+ initialize=false,
+ finalize=false,
+ serialize=xserialize,
+ handle=print,
+ functions={
+ ["@dc@"]=verbose_document,
+ ["@dt@"]=verbose_doctype,
+ ["@rt@"]=verbose_root,
+ ["@el@"]=verbose_element,
+ ["@pi@"]=verbose_pi,
+ ["@cm@"]=verbose_comment,
+ ["@cd@"]=verbose_cdata,
+ ["@tx@"]=verbose_text,
+ }
}
local result
local xmlfilehandler=newhandlers {
- name="file",
- initialize=function(name)
- result=io.open(name,"wb")
- return result
- end,
- finalize=function()
- result:close()
- return true
- end,
- handle=function(...)
- result:write(...)
- end,
+ name="file",
+ initialize=function(name)
+ result=io.open(name,"wb")
+ return result
+ end,
+ finalize=function()
+ result:close()
+ return true
+ end,
+ handle=function(...)
+ result:write(...)
+ end,
}
function xml.save(root,name)
- serialize(root,xmlfilehandler,name)
+ serialize(root,xmlfilehandler,name)
end
local result,r,threshold={},0,512
local xmlstringhandler=newhandlers {
- name="string",
- initialize=function()
- r=0
- return result
- end,
- finalize=function()
- local done=concat(result,"",1,r)
- r=0
- if r>threshold then
- result={}
- end
- return done
- end,
- handle=function(...)
- for i=1,select("#",...) do
- r=r+1
- result[r]=select(i,...)
- end
- end,
+ name="string",
+ initialize=function()
+ r=0
+ return result
+ end,
+ finalize=function()
+ local done=concat(result,"",1,r)
+ r=0
+ if r>threshold then
+ result={}
+ end
+ return done
+ end,
+ handle=function(...)
+ for i=1,select("#",...) do
+ r=r+1
+ result[r]=select(i,...)
+ end
+ end,
}
local function xmltostring(root)
- if not root then
- return ""
- elseif type(root)=="string" then
- return root
- else
- return serialize(root,xmlstringhandler) or ""
- end
+ if not root then
+ return ""
+ elseif type(root)=="string" then
+ return root
+ else
+ return serialize(root,xmlstringhandler) or ""
+ end
end
local function __tostring(root)
- return (root and xmltostring(root)) or ""
+ return (root and xmltostring(root)) or ""
end
initialize_mt=function(root)
- mt={ __tostring=__tostring,__index=root }
+ mt={ __tostring=__tostring,__index=root }
end
xml.defaulthandlers=handlers
xml.newhandlers=newhandlers
xml.serialize=serialize
xml.tostring=xmltostring
local function xmlstring(e,handle)
- if not handle or (e.special and e.tg~="@rt@") then
- elseif e.tg then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- xmlstring(edt[i],handle)
- end
- end
- else
- handle(e)
+ if not handle or (e.special and e.tg~="@rt@") then
+ elseif e.tg then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ xmlstring(edt[i],handle)
+ end
end
+ else
+ handle(e)
+ end
end
xml.string=xmlstring
function xml.settings(e)
- while e do
- local s=e.settings
- if s then
- return s
- else
- e=e.__p__
- end
+ while e do
+ local s=e.settings
+ if s then
+ return s
+ else
+ e=e.__p__
end
- return nil
+ end
+ return nil
end
function xml.root(e)
- local r=e
- while e do
- e=e.__p__
- if e then
- r=e
- end
+ local r=e
+ while e do
+ e=e.__p__
+ if e then
+ r=e
end
- return r
+ end
+ return r
end
function xml.parent(root)
- return root.__p__
+ return root.__p__
end
function xml.body(root)
- return root.ri and root.dt[root.ri] or root
+ return root.ri and root.dt[root.ri] or root
end
function xml.name(root)
- if not root then
- return ""
- end
- local ns=root.ns
- local tg=root.tg
- if ns=="" then
- return tg
- else
- return ns..":"..tg
- end
+ if not root then
+ return ""
+ end
+ local ns=root.ns
+ local tg=root.tg
+ if ns=="" then
+ return tg
+ else
+ return ns..":"..tg
+ end
end
function xml.erase(dt,k)
- if dt then
- if k then
- dt[k]=""
- else for k=1,#dt do
- dt[1]={ "" }
- end end
- end
+ if dt then
+ if k then
+ dt[k]=""
+ else for k=1,#dt do
+ dt[1]={ "" }
+ end end
+ end
end
function xml.assign(dt,k,root)
- if dt and k then
- dt[k]=type(root)=="table" and xml.body(root) or root
- return dt[k]
- else
- return xml.body(root)
- end
+ if dt and k then
+ dt[k]=type(root)=="table" and xml.body(root) or root
+ return dt[k]
+ else
+ return xml.body(root)
+ end
end
function xml.tocdata(e,wrapper)
- local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
- if wrapper then
- whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
- end
- local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
- setmetatable(t,getmetatable(e))
- e.dt={ t }
+ local whatever=type(e)=="table" and xmltostring(e.dt) or e or ""
+ if wrapper then
+ whatever=formatters["<%s>%s</%s>"](wrapper,whatever,wrapper)
+ end
+ local t={ special=true,ns="",tg="@cd@",at={},rn="",dt={ whatever },__p__=e }
+ setmetatable(t,getmetatable(e))
+ e.dt={ t }
end
function xml.makestandalone(root)
- if root.ri then
- local dt=root.dt
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="table" and v.special and v.tg=="@pi@" then
- local txt=v.dt[1]
- if find(txt,"xml.*version=") then
- v.dt[1]=txt.." standalone='yes'"
- break
- end
- end
+ if root.ri then
+ local dt=root.dt
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="table" and v.special and v.tg=="@pi@" then
+ local txt=v.dt[1]
+ if find(txt,"xml.*version=") then
+ v.dt[1]=txt.." standalone='yes'"
+ break
end
+ end
end
- return root
+ end
+ return root
end
function xml.kind(e)
- local dt=e and e.dt
- if dt then
- local n=#dt
- if n==1 then
- local d=dt[1]
- if d.special then
- local tg=d.tg
- if tg=="@cd@" then
- return "cdata"
- elseif tg=="@cm" then
- return "comment"
- elseif tg=="@pi@" then
- return "instruction"
- elseif tg=="@dt@" then
- return "declaration"
- end
- elseif type(d)=="string" then
- return "text"
- end
- return "element"
- elseif n>0 then
- return "mixed"
- end
+ local dt=e and e.dt
+ if dt then
+ local n=#dt
+ if n==1 then
+ local d=dt[1]
+ if d.special then
+ local tg=d.tg
+ if tg=="@cd@" then
+ return "cdata"
+ elseif tg=="@cm" then
+ return "comment"
+ elseif tg=="@pi@" then
+ return "instruction"
+ elseif tg=="@dt@" then
+ return "declaration"
+ end
+ elseif type(d)=="string" then
+ return "text"
+ end
+ return "element"
+ elseif n>0 then
+ return "mixed"
end
- return "empty"
+ end
+ return "empty"
end
@@ -13571,14 +17060,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true
--- original size: 53301, stripped down to: 32477
+-- original size: 55145, stripped down to: 30992
if not modules then modules={} end modules ['lxml-lpt']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local concat,remove,insert=table.concat,table.remove,table.insert
local type,next,tonumber,tostring,setmetatable,load,select=type,next,tonumber,tostring,setmetatable,load,select
@@ -13591,21 +17080,21 @@ local trace_lparse=false
local trace_lprofile=false
local report_lpath=logs.reporter("xml","lpath")
if trackers then
- trackers.register("xml.path",function(v)
- trace_lpath=v
- end)
- trackers.register("xml.parse",function(v)
- trace_lparse=v
- end)
- trackers.register("xml.profile",function(v)
- trace_lpath=v
- trace_lparse=v
- trace_lprofile=v
- end)
+ trackers.register("xml.path",function(v)
+ trace_lpath=v
+ end)
+ trackers.register("xml.parse",function(v)
+ trace_lparse=v
+ end)
+ trackers.register("xml.profile",function(v)
+ trace_lpath=v
+ trace_lparse=v
+ trace_lprofile=v
+ end)
end
local xml=xml
-local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
-local lpathcached=0 function xml.lpathcached() return lpathcached end
+local lpathcalls=0 function xml.lpathcalls () return lpathcalls end
+local lpathcached=0 function xml.lpathcached() return lpathcached end
xml.functions=xml.functions or {}
local functions=xml.functions
xml.expressions=xml.expressions or {}
@@ -13619,216 +17108,271 @@ local xmlpatterns=lpegpatterns.xml
finalizers.xml=finalizers.xml or {}
finalizers.tex=finalizers.tex or {}
local function fallback (t,name)
- local fn=finalizers[name]
- if fn then
- t[name]=fn
- else
- report_lpath("unknown sub finalizer %a",name)
- fn=function() end
- end
- return fn
+ local fn=finalizers[name]
+ if fn then
+ t[name]=fn
+ else
+ report_lpath("unknown sub finalizer %a",name)
+ fn=function() end
+ end
+ return fn
end
setmetatableindex(finalizers.xml,fallback)
setmetatableindex(finalizers.tex,fallback)
xml.defaultprotocol="xml"
local apply_axis={}
apply_axis['root']=function(list)
- local collected={}
- for l=1,#list do
- local ll=list[l]
- local rt=ll
- while ll do
- ll=ll.__p__
- if ll then
- rt=ll
- end
- end
- collected[l]=rt
+ local collected={}
+ for l=1,#list do
+ local ll=list[l]
+ local rt=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
+ rt=ll
+ end
end
- return collected
+ collected[l]=rt
+ end
+ return collected
end
apply_axis['self']=function(list)
- return list
+ return list
end
apply_axis['child']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local dt=ll.dt
- if dt then
- local en=0
- for k=1,#dt do
- local dk=dt[k]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- end
- end
- ll.en=en
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ local dt=ll.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ end
end
+ ll.en=en
+ end
end
- return collected
+ end
+ return collected
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]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- c=collect(dk,collected,c)
- end
+ local dt=list.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ c=collect(dk,collected,c)
end
- list.en=en
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant']=function(list)
- local collected,c={},0
- for l=1,#list do
- c=collect(list[l],collected,c)
- end
- return collected
+ local collected={}
+ local c=0
+ for l=1,#list do
+ c=collect(list[l],collected,c)
+ end
+ return collected
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]
- if dk.tg then
- c=c+1
- collected[c]=dk
- dk.ni=k
- en=en+1
- dk.ei=en
- c=collect(dk,collected,c)
- end
+ local dt=list.dt
+ if dt then
+ 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=1
+ 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
+ dk.ei=en
+ c=collect(dk,collected,c)
end
- list.en=en
+ end
+ list.en=en
end
- return c
+ end
+ return c
end
apply_axis['descendant-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- if ll.special~=true then
- c=c+1
- collected[c]=ll
- end
- c=collect(ll,collected,c)
- end
- return collected
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ if ll.special~=true then
+ c=c+1
+ collected[c]=ll
+ end
+ c=collect(ll,collected,c)
+ end
+ return collected
end
apply_axis['ancestor']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ while ll do
+ ll=ll.__p__
+ if ll then
+ c=c+1
+ collected[c]=ll
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['ancestor-or-self']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ c=c+1
+ collected[c]=ll
+ while ll do
+ ll=ll.__p__
+ if ll then
c=c+1
collected[c]=ll
- while ll do
- ll=ll.__p__
- if ll then
- c=c+1
- collected[c]=ll
- end
- end
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['parent']=function(list)
- local collected,c={},0
- for l=1,#list do
- local pl=list[l].__p__
- if pl then
- c=c+1
- collected[c]=pl
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local pl=list[l].__p__
+ if pl then
+ c=c+1
+ collected[c]=pl
end
- return collected
+ end
+ return collected
end
apply_axis['attribute']=function(list)
- return {}
+ return {}
end
apply_axis['namespace']=function(list)
- return {}
+ return {}
end
apply_axis['following']=function(list)
- return {}
+ return {}
end
apply_axis['preceding']=function(list)
- return {}
+ return {}
end
apply_axis['following-sibling']=function(list)
- 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
- end
- end
+ 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,#d do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['preceding-sibling']=function(list)
- local collected,c={},0
- for l=1,#list do
- local ll=list[l]
- local p=ll.__p__
- local d=p.dt
- for i=1,ll.ni-1 do
- local di=d[i]
- if type(di)=="table" then
- c=c+1
- collected[c]=di
- end
- end
+ local collected={}
+ local c=0
+ for l=1,#list do
+ local ll=list[l]
+ local p=ll.__p__
+ local d=p.dt
+ for i=1,ll.ni-1 do
+ local di=d[i]
+ if type(di)=="table" then
+ c=c+1
+ collected[c]=di
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['reverse-sibling']=function(list)
- 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
- end
- end
+ 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
+ end
end
- return collected
+ end
+ return collected
end
apply_axis['auto-descendant-or-self']=apply_axis['descendant-or-self']
apply_axis['auto-descendant']=apply_axis['descendant']
@@ -13836,130 +17380,147 @@ apply_axis['auto-child']=apply_axis['child']
apply_axis['auto-self']=apply_axis['self']
apply_axis['initial-child']=apply_axis['child']
local function apply_nodes(list,directive,nodes)
- local maxn=#nodes
- if maxn==3 then
- local nns,ntg=nodes[2],nodes[3]
- if not nns and not ntg then
+ local maxn=#nodes
+ if maxn==3 then
+ local nns=nodes[2]
+ local ntg=nodes[3]
+ if not nns and not ntg then
+ if directive then
+ return list
+ else
+ return {}
+ end
+ else
+ local collected={}
+ local c=0
+ local m=0
+ local p=nil
+ if not nns then
+ for l=1,#list do
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
if directive then
- return list
- else
- return {}
+ if ntg==ltg then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif ntg~=ltg then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- else
- local collected,c,m,p={},0,0,nil
- if not nns then
- for l=1,#list do
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif ntg~=ltg then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- elseif not ntg then
- for l=1,#list do
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif lns~=nns then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
- else
- for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- 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
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- end
- end
+ end
+ end
+ elseif not ntg then
+ for l=1,#list do
+ 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=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif lns~=nns then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- return collected
+ end
end
- else
- local collected,c,m,p={},0,0,nil
+ else
for l=1,#list do
- local ll=list[l]
- local ltg=ll.tg
- if ltg then
- local lns=ll.rn or ll.ns
- local ok=false
- for n=1,maxn,3 do
- local nns,ntg=nodes[n+1],nodes[n+2]
- ok=(not ntg or ltg==ntg) and (not nns or lns==nns)
- if ok then
- break
- end
- end
- if directive then
- if ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
- elseif not ok then
- local llp=ll.__p__;if llp~=p then p,m=llp,1 else m=m+1 end
- c=c+1
- collected[c],ll.mi=ll,m
- end
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=ltg==ntg and lns==nns
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
+ end
end
- return collected
+ end
+ return collected
end
-end
-local quit_expression=false
-local function apply_expression(list,expression,order)
- local collected,c={},0
- quit_expression=false
+ else
+ local collected={}
+ local c=0
+ local m=0
+ local p=nil
for l=1,#list do
- local ll=list[l]
- if expression(list,ll,l,order) then
+ local ll=list[l]
+ local ltg=ll.tg
+ if ltg then
+ local lns=ll.rn or ll.ns
+ local ok=false
+ for n=1,maxn,3 do
+ 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
+ end
+ end
+ if directive then
+ if ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
c=c+1
collected[c]=ll
+ ll.mi=m
+ end
+ elseif not ok then
+ local llp=ll.__p__;if llp~=p then p=llp;m=1 else m=m+1 end
+ c=c+1
+ collected[c]=ll
+ ll.mi=m
end
- if quit_expression then
- break
- end
+ end
end
return collected
+ end
end
-local function apply_selector(list,specification)
- if xml.applyselector then
- apply_selector=xml.applyselector
- return apply_selector(list,specification)
- else
- return list
+local quit_expression=false
+local function apply_expression(list,expression,order)
+ local collected={}
+ local c=0
+ quit_expression=false
+ for l=1,#list do
+ local ll=list[l]
+ if expression(list,ll,l,order) then
+ c=c+1
+ collected[c]=ll
+ end
+ if quit_expression then
+ break
end
+ end
+ return collected
+end
+local function apply_selector(list,specification)
+ if xml.applyselector then
+ apply_selector=xml.applyselector
+ return apply_selector(list,specification)
+ else
+ return list
+ end
end
local P,V,C,Cs,Cc,Ct,R,S,Cg,Cb=lpeg.P,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.R,lpeg.S,lpeg.Cg,lpeg.Cb
local spaces=S(" \n\r\t\f")^0
@@ -13970,24 +17531,24 @@ local lp_doequal=P("=")/"=="
local lp_or=P("|")/" or "
local lp_and=P("&")/" and "
local builtin={
- text="(ll.dt[1] or '')",
- content="ll.dt",
- name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
- tag="ll.tg",
- position="l",
- firstindex="1",
- firstelement="1",
- first="1",
- lastindex="(#ll.__p__.dt or 1)",
- lastelement="(ll.__p__.en or 1)",
- last="#list",
- rootposition="order",
- order="order",
- element="(ll.ei or 1)",
- index="(ll.ni or 1)",
- match="(ll.mi or 1)",
- namespace="ll.ns",
- ns="ll.ns",
+ text="(ll.dt[1] or '')",
+ content="ll.dt",
+ name="((ll.ns~='' and ll.ns..':'..ll.tg) or ll.tg)",
+ tag="ll.tg",
+ position="l",
+ firstindex="1",
+ firstelement="1",
+ first="1",
+ lastindex="(#ll.__p__.dt or 1)",
+ lastelement="(ll.__p__.en or 1)",
+ last="#list",
+ rootposition="order",
+ order="order",
+ element="(ll.ei or 1)",
+ index="(ll.ni or 1)",
+ match="(ll.mi or 1)",
+ namespace="ll.ns",
+ ns="ll.ns",
}
local lp_builtin=lpeg.utfchartabletopattern(builtin)/builtin*((spaces*P("(")*spaces*P(")"))/"")
local lp_attribute=(P("@")+P("attribute::"))/""*Cc("(ll.at and ll.at['")*((R("az","AZ")+S("-_:"))^1)*Cc("'])")
@@ -13997,11 +17558,11 @@ local lp_fastpos=lp_fastpos_n+lp_fastpos_p
local lp_reserved=C("and")+C("or")+C("not")+C("div")+C("mod")+C("true")+C("false")
local lp_lua_function=Cs((R("az","AZ","__")^1*(P(".")*R("az","AZ","__")^1)^1)*("("))/"%0"
local lp_function=C(R("az","AZ","__")^1)*P("(")/function(t)
- if expressions[t] then
- return "expr."..t.."("
- else
- return "expr.error("
- end
+ if expressions[t] then
+ return "expr."..t.."("
+ else
+ return "expr.error("
+ end
end
local lparent=P("(")
local rparent=P(")")
@@ -14014,24 +17575,24 @@ local lp_string=Cc("'")*R("az","AZ","--","__")^1*Cc("'")
local lp_content=(P("'")*(1-P("'"))^0*P("'")+P('"')*(1-P('"'))^0*P('"'))
local cleaner
local lp_special=(C(P("name")+P("text")+P("tag")+P("count")+P("child")))*value/function(t,s)
- if expressions[t] then
- s=s and s~="" and lpegmatch(cleaner,s)
- if s and s~="" then
- return "expr."..t.."(ll,"..s..")"
- else
- return "expr."..t.."(ll)"
- end
+ if expressions[t] then
+ s=s and s~="" and lpegmatch(cleaner,s)
+ if s and s~="" then
+ return "expr."..t.."(ll,"..s..")"
else
- return "expr.error("..t..")"
+ return "expr."..t.."(ll)"
end
+ else
+ return "expr.error("..t..")"
+ end
end
local content=lp_builtin+lp_attribute+lp_special+lp_noequal+lp_doequal+lp_or+lp_and+lp_reserved+lp_lua_function+lp_function+lp_content+
- lp_child+lp_any
+ lp_child+lp_any
local converter=Cs (
- lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
+ lp_fastpos+(P { lparent*(V(1))^0*rparent+content } )^0
)
cleaner=Cs ((
- lp_reserved+lp_number+lp_string+1 )^1 )
+ lp_reserved+lp_number+lp_string+1 )^1 )
local template_e=[[
local expr = xml.expressions
return function(list,ll,l,order)
@@ -14047,75 +17608,75 @@ local template_f_y=[[
local template_f_n=[[
return xml.finalizers['%s']['%s']
]]
-local register_last_match={ kind="axis",axis="last-match" }
-local register_self={ kind="axis",axis="self" }
-local register_parent={ kind="axis",axis="parent" }
-local register_descendant={ kind="axis",axis="descendant" }
-local register_child={ kind="axis",axis="child" }
+local register_last_match={ kind="axis",axis="last-match" }
+local register_self={ kind="axis",axis="self" }
+local register_parent={ kind="axis",axis="parent" }
+local register_descendant={ kind="axis",axis="descendant" }
+local register_child={ kind="axis",axis="child" }
local register_descendant_or_self={ kind="axis",axis="descendant-or-self" }
-local register_root={ kind="axis",axis="root" }
-local register_ancestor={ kind="axis",axis="ancestor" }
-local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
-local register_attribute={ kind="axis",axis="attribute" }
-local register_namespace={ kind="axis",axis="namespace" }
-local register_following={ kind="axis",axis="following" }
+local register_root={ kind="axis",axis="root" }
+local register_ancestor={ kind="axis",axis="ancestor" }
+local register_ancestor_or_self={ kind="axis",axis="ancestor-or-self" }
+local register_attribute={ kind="axis",axis="attribute" }
+local register_namespace={ kind="axis",axis="namespace" }
+local register_following={ kind="axis",axis="following" }
local register_following_sibling={ kind="axis",axis="following-sibling" }
-local register_preceding={ kind="axis",axis="preceding" }
+local register_preceding={ kind="axis",axis="preceding" }
local register_preceding_sibling={ kind="axis",axis="preceding-sibling" }
-local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
+local register_reverse_sibling={ kind="axis",axis="reverse-sibling" }
local register_auto_descendant_or_self={ kind="axis",axis="auto-descendant-or-self" }
-local register_auto_descendant={ kind="axis",axis="auto-descendant" }
-local register_auto_self={ kind="axis",axis="auto-self" }
-local register_auto_child={ kind="axis",axis="auto-child" }
-local register_initial_child={ kind="axis",axis="initial-child" }
+local register_auto_descendant={ kind="axis",axis="auto-descendant" }
+local register_auto_self={ kind="axis",axis="auto-self" }
+local register_auto_child={ kind="axis",axis="auto-child" }
+local register_initial_child={ kind="axis",axis="initial-child" }
local register_all_nodes={ kind="nodes",nodetest=true,nodes={ true,false,false } }
local skip={}
local function errorrunner_e(str,cnv)
- if not skip[str] then
- report_lpath("error in expression: %s => %s",str,cnv)
- skip[str]=cnv or str
- end
- return false
+ if not skip[str] then
+ report_lpath("error in expression: %s => %s",str,cnv)
+ skip[str]=cnv or str
+ end
+ return false
end
local function errorrunner_f(str,arg)
- report_lpath("error in finalizer: %s(%s)",str,arg or "")
- return false
+ report_lpath("error in finalizer: %s(%s)",str,arg or "")
+ return false
end
local function register_nodes(nodetest,nodes)
- return { kind="nodes",nodetest=nodetest,nodes=nodes }
+ return { kind="nodes",nodetest=nodetest,nodes=nodes }
end
local function register_selector(specification)
- return { kind="selector",specification=specification }
+ return { kind="selector",specification=specification }
end
local function register_expression(expression)
- local converted=lpegmatch(converter,expression)
- local runner=load(format(template_e,converted))
- runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
- return { kind="expression",expression=expression,converted=converted,evaluator=runner }
+ local converted=lpegmatch(converter,expression)
+ local runner=load(format(template_e,converted))
+ runner=(runner and runner()) or function() errorrunner_e(expression,converted) end
+ return { kind="expression",expression=expression,converted=converted,evaluator=runner }
end
local function register_finalizer(protocol,name,arguments)
- local runner
- if arguments and arguments~="" then
- runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
- else
- runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
- end
- runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
- return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
+ local runner
+ if arguments and arguments~="" then
+ runner=load(format(template_f_y,protocol or xml.defaultprotocol,name,arguments))
+ else
+ runner=load(format(template_f_n,protocol or xml.defaultprotocol,name))
+ end
+ runner=(runner and runner()) or function() errorrunner_f(name,arguments) end
+ return { kind="finalizer",name=name,arguments=arguments,finalizer=runner }
end
local expression=P { "ex",
- ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
- sq="'"*(1-S("'"))^0*"'",
- dq='"'*(1-S('"'))^0*'"',
+ ex="["*C((V("sq")+V("dq")+(1-S("[]"))+V("ex"))^0)*"]",
+ sq="'"*(1-S("'"))^0*"'",
+ dq='"'*(1-S('"'))^0*'"',
}
local arguments=P { "ar",
- ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
- nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
- sq=P("'")*(1-P("'"))^0*P("'"),
- dq=P('"')*(1-P('"'))^0*P('"'),
+ ar="("*Cs((V("sq")+V("dq")+V("nq")+P(1-P(")")))^0)*")",
+ nq=((1-S("),'\""))^1)/function(s) return format("%q",s) end,
+ sq=P("'")*(1-P("'"))^0*P("'"),
+ dq=P('"')*(1-P('"'))^0*P('"'),
}
local function register_error(str)
- return { kind="error",error=format("unparsed: %s",str) }
+ return { kind="error",error=format("unparsed: %s",str) }
end
local special_1=P("*")*Cc(register_auto_descendant)*Cc(register_all_nodes)
local special_2=P("/")*Cc(register_auto_self)
@@ -14123,367 +17684,368 @@ local special_3=P("")*Cc(register_auto_self)
local no_nextcolon=P(-1)+#(1-P(":"))
local no_nextlparent=P(-1)+#(1-P("("))
local pathparser=Ct { "patterns",
- patterns=spaces*V("protocol")*spaces*(
- (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
- ),
- protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
- step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
- axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
- special=special_1+special_2+special_3,
- initial=(P("/")*spaces*Cc(register_initial_child))^-1,
- error=(P(1)^1)/register_error,
- shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
- shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
- s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
- s_descendant=P("**")*Cc(register_descendant),
- s_child=P("*")*no_nextcolon*Cc(register_child),
- s_parent=P("..")*Cc(register_parent),
- s_self=P("." )*Cc(register_self),
- s_root=P("^^")*Cc(register_root),
- s_ancestor=P("^")*Cc(register_ancestor),
- s_lastmatch=P("=")*Cc(register_last_match),
- descendant=P("descendant::")*Cc(register_descendant),
- child=P("child::")*Cc(register_child),
- parent=P("parent::")*Cc(register_parent),
- self=P("self::")*Cc(register_self),
- root=P('root::')*Cc(register_root),
- ancestor=P('ancestor::')*Cc(register_ancestor),
- descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
- ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
- following=P('following::')*Cc(register_following),
- following_sibling=P('following-sibling::')*Cc(register_following_sibling),
- preceding=P('preceding::')*Cc(register_preceding),
- preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
- reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
- last_match=P('last-match::')*Cc(register_last_match),
- selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
- nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
- expressions=expression/register_expression,
- letters=R("az")^1,
- name=(1-S("/[]()|:*!"))^1,
- negate=P("!")*Cc(false),
- nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
- nodetest=V("negate")+Cc(true),
- nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
- wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
- nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
- finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
+ patterns=spaces*V("protocol")*spaces*(
+ (V("special")*spaces*P(-1) )+(V("initial")*spaces*V("step")*spaces*(P("/")*spaces*V("step")*spaces)^0 )
+ ),
+ protocol=Cg(V("letters"),"protocol")*P("://")+Cg(Cc(nil),"protocol"),
+ step=((V("shortcuts")+V("selector")+P("/")+V("axis"))*spaces*V("nodes")^0+V("error"))*spaces*V("expressions")^0*spaces*V("finalizer")^0,
+ axis=V("last_match")+V("descendant")+V("child")+V("parent")+V("self")+V("root")+V("ancestor")+V("descendant_or_self")+V("following_sibling")+V("following")+V("reverse_sibling")+V("preceding_sibling")+V("preceding")+V("ancestor_or_self")+#(1-P(-1))*Cc(register_auto_child),
+ special=special_1+special_2+special_3,
+ initial=(P("/")*spaces*Cc(register_initial_child))^-1,
+ error=(P(1)^1)/register_error,
+ shortcuts_a=V("s_descendant_or_self")+V("s_descendant")+V("s_child")+V("s_parent")+V("s_self")+V("s_root")+V("s_ancestor")+V("s_lastmatch"),
+ shortcuts=V("shortcuts_a")*(spaces*"/"*spaces*V("shortcuts_a"))^0,
+ s_descendant_or_self=(P("***/")+P("/"))*Cc(register_descendant_or_self),
+ s_descendant=P("**")*Cc(register_descendant),
+ s_child=P("*")*no_nextcolon*Cc(register_child),
+ s_parent=P("..")*Cc(register_parent),
+ s_self=P("." )*Cc(register_self),
+ s_root=P("^^")*Cc(register_root),
+ s_ancestor=P("^")*Cc(register_ancestor),
+ s_lastmatch=P("=")*Cc(register_last_match),
+ descendant=P("descendant::")*Cc(register_descendant),
+ child=P("child::")*Cc(register_child),
+ parent=P("parent::")*Cc(register_parent),
+ self=P("self::")*Cc(register_self),
+ root=P('root::')*Cc(register_root),
+ ancestor=P('ancestor::')*Cc(register_ancestor),
+ descendant_or_self=P('descendant-or-self::')*Cc(register_descendant_or_self),
+ ancestor_or_self=P('ancestor-or-self::')*Cc(register_ancestor_or_self),
+ following=P('following::')*Cc(register_following),
+ following_sibling=P('following-sibling::')*Cc(register_following_sibling),
+ preceding=P('preceding::')*Cc(register_preceding),
+ preceding_sibling=P('preceding-sibling::')*Cc(register_preceding_sibling),
+ reverse_sibling=P('reverse-sibling::')*Cc(register_reverse_sibling),
+ last_match=P('last-match::')*Cc(register_last_match),
+ selector=P("{")*C((1-P("}"))^1)*P("}")/register_selector,
+ nodes=(V("nodefunction")*spaces*P("(")*V("nodeset")*P(")")+V("nodetest")*V("nodeset"))/register_nodes,
+ expressions=expression/register_expression,
+ letters=R("az")^1,
+ name=(1-S("/[]()|:*!"))^1,
+ negate=P("!")*Cc(false),
+ nodefunction=V("negate")+P("not")*Cc(false)+Cc(true),
+ nodetest=V("negate")+Cc(true),
+ nodename=(V("negate")+Cc(true))*spaces*((V("wildnodename")*P(":")*V("wildnodename"))+(Cc(false)*V("wildnodename"))),
+ wildnodename=(C(V("name"))+P("*")*Cc(false))*no_nextlparent,
+ nodeset=spaces*Ct(V("nodename")*(spaces*P("|")*spaces*V("nodename"))^0)*spaces,
+ finalizer=(Cb("protocol")*P("/")^-1*C(V("name"))*arguments*P(-1))/register_finalizer,
}
xmlpatterns.pathparser=pathparser
local cache={}
local function nodesettostring(set,nodetest)
- local t={}
- for i=1,#set,3 do
- local directive,ns,tg=set[i],set[i+1],set[i+2]
- if not ns or ns=="" then ns="*" end
- if not tg or tg=="" then tg="*" end
- tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
- t[#t+1]=(directive and tg) or format("not(%s)",tg)
- end
- if nodetest==false then
- return format("not(%s)",concat(t,"|"))
- else
- return concat(t,"|")
- end
+ local t={}
+ for i=1,#set,3 do
+ local directive,ns,tg=set[i],set[i+1],set[i+2]
+ if not ns or ns=="" then ns="*" end
+ if not tg or tg=="" then tg="*" end
+ tg=(tg=="@rt@" and "[root]") or format("%s:%s",ns,tg)
+ t[#t+1]=(directive and tg) or format("not(%s)",tg)
+ end
+ if nodetest==false then
+ return format("not(%s)",concat(t,"|"))
+ else
+ return concat(t,"|")
+ end
end
local function tagstostring(list)
- if #list==0 then
- return "no elements"
- else
- local t={}
- for i=1,#list do
- local li=list[i]
- local ns,tg=li.ns,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)
- end
- return concat(t," ")
+ if #list==0 then
+ return "no elements"
+ else
+ local t={}
+ for i=1,#list do
+ local li=list[i]
+ 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)
end
+ return concat(t," ")
+ end
end
xml.nodesettostring=nodesettostring
local lpath
local function lshow(parsed)
- if type(parsed)=="string" then
- parsed=lpath(parsed)
- end
- report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
- table.serialize(parsed,false))
+ if type(parsed)=="string" then
+ parsed=lpath(parsed)
+ end
+ report_lpath("%s://%s => %s",parsed.protocol or xml.defaultprotocol,parsed.pattern,
+ table.serialize(parsed,false))
end
xml.lshow=lshow
local function add_comment(p,str)
- local pc=p.comment
- if not pc then
- p.comment={ str }
- else
- pc[#pc+1]=str
- end
+ local pc=p.comment
+ if not pc then
+ p.comment={ str }
+ else
+ pc[#pc+1]=str
+ end
end
lpath=function (pattern)
- lpathcalls=lpathcalls+1
- if type(pattern)=="table" then
- return pattern
- else
- local parsed=cache[pattern]
- if parsed then
- lpathcached=lpathcached+1
+ lpathcalls=lpathcalls+1
+ if type(pattern)=="table" then
+ return pattern
+ else
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcached=lpathcached+1
+ else
+ parsed=lpegmatch(pathparser,pattern)
+ if parsed then
+ parsed.pattern=pattern
+ local np=#parsed
+ if np==0 then
+ parsed={ pattern=pattern,register_self,state="parsing error" }
+ report_lpath("parsing error in pattern: %s",pattern)
+ lshow(parsed)
else
- parsed=lpegmatch(pathparser,pattern)
- if parsed then
- parsed.pattern=pattern
- local np=#parsed
- if np==0 then
- parsed={ pattern=pattern,register_self,state="parsing error" }
- report_lpath("parsing error in pattern: %s",pattern)
- lshow(parsed)
- else
- local pi=parsed[1]
- if pi.axis=="auto-child" then
- if false then
- add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
- parsed[1]=register_auto_descendant_or_self
- else
- add_comment(parsed,"auto-child replaced by auto-descendant")
- parsed[1]=register_auto_descendant
- end
- elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
- add_comment(parsed,"initial-child removed")
- remove(parsed,1)
- end
- local np=#parsed
- if np>1 then
- local pnp=parsed[np]
- if pnp.kind=="nodes" and pnp.nodetest==true then
- local nodes=pnp.nodes
- if nodes[1]==true and nodes[2]==false and nodes[3]==false then
- add_comment(parsed,"redundant final wildcard filter removed")
- remove(parsed,np)
- end
- end
- end
- end
+ local pi=parsed[1]
+ if pi.axis=="auto-child" then
+ if false then
+ add_comment(parsed,"auto-child replaced by auto-descendant-or-self")
+ parsed[1]=register_auto_descendant_or_self
else
- parsed={ pattern=pattern }
+ add_comment(parsed,"auto-child replaced by auto-descendant")
+ parsed[1]=register_auto_descendant
end
- cache[pattern]=parsed
- if trace_lparse and not trace_lprofile then
- lshow(parsed)
+ elseif pi.axis=="initial-child" and np>1 and parsed[2].axis then
+ add_comment(parsed,"initial-child removed")
+ remove(parsed,1)
+ end
+ local np=#parsed
+ if np>1 then
+ local pnp=parsed[np]
+ if pnp.kind=="nodes" and pnp.nodetest==true then
+ local nodes=pnp.nodes
+ if nodes[1]==true and nodes[2]==false and nodes[3]==false then
+ add_comment(parsed,"redundant final wildcard filter removed")
+ remove(parsed,np)
+ end
end
+ end
end
- return parsed
+ else
+ parsed={ pattern=pattern }
+ end
+ cache[pattern]=parsed
+ if trace_lparse and not trace_lprofile then
+ lshow(parsed)
+ end
end
+ return parsed
+ end
end
xml.lpath=lpath
do
- local profiled={}
- xml.profiled=profiled
- local lastmatch=nil
- local keepmatch=nil
- if directives then
- directives.register("xml.path.keeplastmatch",function(v)
- keepmatch=v
- lastmatch=nil
- end)
- end
- apply_axis["last-match"]=function()
- return lastmatch or {}
- end
- local function profiled_apply(list,parsed,nofparsed,order)
- local p=profiled[parsed.pattern]
- if p then
- p.tested=p.tested+1
- else
- p={ tested=1,matched=0,finalized=0 }
- profiled[parsed.pattern]=p
- end
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- p.matched=p.matched+1
- p.finalized=p.finalized+1
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- p.finalized=p.finalized+1
- return collected
- end
- return nil
- end
- end
- if collected then
- p.matched=p.matched+1
- end
- return collected
- end
- local function traced_apply(list,parsed,nofparsed,order)
- if trace_lparse then
- lshow(parsed)
- end
- report_lpath("collecting: %s",parsed.pattern)
- report_lpath("root tags : %s",tagstostring(list))
- report_lpath("order : %s",order or "unset")
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- collected=apply_axis[pi.axis](collected)
- report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
- elseif kind=="finalizer" then
- collected=pi.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
- return collected
- end
- if not collected or #collected==0 then
- local pn=i<nofparsed and parsed[nofparsed]
- if pn and pn.kind=="finalizer" then
- collected=pn.finalizer(collected)
- report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
- return collected
- end
- return nil
- end
- end
+ local profiled={}
+ xml.profiled=profiled
+ local lastmatch=nil
+ local keepmatch=nil
+ if directives then
+ directives.register("xml.path.keeplastmatch",function(v)
+ keepmatch=v
+ lastmatch=nil
+ end)
+ end
+ apply_axis["last-match"]=function()
+ return lastmatch or {}
+ end
+ local function profiled_apply(list,parsed,nofparsed,order)
+ local p=profiled[parsed.pattern]
+ if p then
+ p.tested=p.tested+1
+ else
+ p={ tested=1,matched=0,finalized=0 }
+ profiled[parsed.pattern]=p
+ end
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ p.matched=p.matched+1
+ p.finalized=p.finalized+1
return collected
- end
- local function normal_apply(list,parsed,nofparsed,order)
- local collected=list
- for i=1,nofparsed do
- local pi=parsed[i]
- local kind=pi.kind
- if kind=="axis" then
- local axis=pi.axis
- if axis~="self" then
- collected=apply_axis[axis](collected)
- end
- elseif kind=="nodes" then
- collected=apply_nodes(collected,pi.nodetest,pi.nodes)
- elseif kind=="expression" then
- collected=apply_expression(collected,pi.evaluator,order)
- elseif kind=="selector" then
- collected=apply_selector(collected,pi.specification)
- elseif kind=="finalizer" then
- return pi.finalizer(collected)
- end
- if not collected or #collected==0 then
- local pf=i<nofparsed and parsed[nofparsed].finalizer
- if pf then
- return pf(collected)
- end
- return nil
- end
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ p.finalized=p.finalized+1
+ return collected
end
- return collected
+ return nil
+ end
end
- local apply=normal_apply
- if trackers then
- trackers.register("xml.path,xml.parse,xml.profile",function()
- if trace_lprofile then
- apply=profiled_apply
- elseif trace_lpath then
- apply=traced_apply
- else
- apply=normal_apply
- end
- end)
+ if collected then
+ p.matched=p.matched+1
end
- function xml.applylpath(list,pattern)
- if not list then
- lastmatch=nil
- return
- end
- local parsed=cache[pattern]
- if parsed then
- lpathcalls=lpathcalls+1
- lpathcached=lpathcached+1
- elseif type(pattern)=="table" then
- lpathcalls=lpathcalls+1
- parsed=pattern
- else
- parsed=lpath(pattern) or pattern
- end
- if not parsed then
- lastmatch=nil
- return
- end
- local nofparsed=#parsed
- if nofparsed==0 then
- lastmatch=nil
- return
- end
- local collected=apply({ list },parsed,nofparsed,list.mi)
- lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ local function traced_apply(list,parsed,nofparsed,order)
+ if trace_lparse then
+ lshow(parsed)
+ end
+ report_lpath("collecting: %s",parsed.pattern)
+ report_lpath("root tags : %s",tagstostring(list))
+ report_lpath("order : %s",order or "unset")
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ collected=apply_axis[pi.axis](collected)
+ report_lpath("% 10i : ax : %s",(collected and #collected) or 0,pi.axis)
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ report_lpath("% 10i : ns : %s",(collected and #collected) or 0,nodesettostring(pi.nodes,pi.nodetest))
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ report_lpath("% 10i : ex : %s -> %s",(collected and #collected) or 0,pi.expression,pi.converted)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ report_lpath("% 10i : se : %s ",(collected and #collected) or 0,pi.specification)
+ elseif kind=="finalizer" then
+ collected=pi.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pi.name,pi.arguments or "")
return collected
+ end
+ if not collected or #collected==0 then
+ local pn=i<nofparsed and parsed[nofparsed]
+ if pn and pn.kind=="finalizer" then
+ collected=pn.finalizer(collected)
+ report_lpath("% 10i : fi : %s : %s(%s)",(type(collected)=="table" and #collected) or 0,parsed.protocol or xml.defaultprotocol,pn.name,pn.arguments or "")
+ return collected
+ end
+ return nil
+ end
end
- function xml.lastmatch()
- return lastmatch
- end
- local stack={}
- function xml.pushmatch()
- insert(stack,lastmatch)
- end
- function xml.popmatch()
- lastmatch=remove(stack)
+ return collected
+ end
+ local function normal_apply(list,parsed,nofparsed,order)
+ local collected=list
+ for i=1,nofparsed do
+ local pi=parsed[i]
+ local kind=pi.kind
+ if kind=="axis" then
+ local axis=pi.axis
+ if axis~="self" then
+ collected=apply_axis[axis](collected)
+ end
+ elseif kind=="nodes" then
+ collected=apply_nodes(collected,pi.nodetest,pi.nodes)
+ elseif kind=="expression" then
+ collected=apply_expression(collected,pi.evaluator,order)
+ elseif kind=="selector" then
+ collected=apply_selector(collected,pi.specification)
+ elseif kind=="finalizer" then
+ return pi.finalizer(collected)
+ end
+ if not collected or #collected==0 then
+ local pf=i<nofparsed and parsed[nofparsed].finalizer
+ if pf then
+ return pf(collected)
+ end
+ return nil
+ end
end
+ return collected
+ end
+ local apply=normal_apply
+ if trackers then
+ trackers.register("xml.path,xml.parse,xml.profile",function()
+ if trace_lprofile then
+ apply=profiled_apply
+ elseif trace_lpath then
+ apply=traced_apply
+ else
+ apply=normal_apply
+ end
+ end)
+ end
+ function xml.applylpath(list,pattern)
+ if not list then
+ lastmatch=nil
+ return
+ end
+ local parsed=cache[pattern]
+ if parsed then
+ lpathcalls=lpathcalls+1
+ lpathcached=lpathcached+1
+ elseif type(pattern)=="table" then
+ lpathcalls=lpathcalls+1
+ parsed=pattern
+ else
+ parsed=lpath(pattern) or pattern
+ end
+ if not parsed then
+ lastmatch=nil
+ return
+ end
+ local nofparsed=#parsed
+ if nofparsed==0 then
+ lastmatch=nil
+ return
+ end
+ local collected=apply({ list },parsed,nofparsed,list.mi)
+ lastmatch=keepmatch and collected or nil
+ return collected
+ end
+ function xml.lastmatch()
+ return lastmatch
+ end
+ local stack={}
+ function xml.pushmatch()
+ insert(stack,lastmatch)
+ end
+ function xml.popmatch()
+ lastmatch=remove(stack)
+ end
end
local applylpath=xml.applylpath
function xml.filter(root,pattern)
- return applylpath(root,pattern)
+ return applylpath(root,pattern)
end
expressions.child=function(e,pattern)
- return applylpath(e,pattern)
+ return applylpath(e,pattern)
end
expressions.count=function(e,pattern)
- local collected=applylpath(e,pattern)
- return pattern and (collected and #collected) or 0
+ local collected=applylpath(e,pattern)
+ return pattern and (collected and #collected) or 0
end
expressions.oneof=function(s,...)
- for i=1,select("#",...) do
- if s==select(i,...) then
- return true
- end
+ for i=1,select("#",...) do
+ if s==select(i,...) then
+ return true
end
- return false
+ end
+ return false
end
expressions.error=function(str)
- xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
- return false
+ xml.errorhandler(format("unknown function in lpath expression: %s",tostring(str or "?")))
+ return false
end
expressions.undefined=function(s)
- return s==nil
+ return s==nil
end
expressions.quit=function(s)
- if s or s==nil then
- quit_expression=true
- end
- return true
+ if s or s==nil then
+ quit_expression=true
+ end
+ return true
end
expressions.print=function(...)
- print(...)
- return true
+ print(...)
+ return true
end
expressions.find=find
expressions.upper=upper
@@ -14491,233 +18053,238 @@ expressions.lower=lower
expressions.number=tonumber
expressions.boolean=toboolean
function expressions.contains(str,pattern)
- local t=type(str)
- if t=="string" then
- if find(str,pattern) then
- return true
- end
- elseif t=="table" then
- for i=1,#str do
- local d=str[i]
- if type(d)=="string" and find(d,pattern) then
- return true
- end
- end
+ local t=type(str)
+ if t=="string" then
+ if find(str,pattern) then
+ return true
end
- return false
+ elseif t=="table" then
+ for i=1,#str do
+ local d=str[i]
+ if type(d)=="string" and find(d,pattern) then
+ return true
+ end
+ end
+ end
+ return false
end
function xml.expressions.idstring(str)
- return type(str)=="string" and gsub(str,"^#","") or ""
+ return type(str)=="string" and gsub(str,"^#","") or ""
end
local function traverse(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local r=e.__p__
- handle(r,r.dt,e.ni)
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local r=e.__p__
+ handle(r,r.dt,e.ni)
end
+ end
end
local function selection(root,pattern,handle)
- local collected=applylpath(root,pattern)
- if collected then
- if handle then
- for c=1,#collected do
- handle(collected[c])
- end
- else
- return collected
- end
+ local collected=applylpath(root,pattern)
+ if collected then
+ if handle then
+ for c=1,#collected do
+ handle(collected[c])
+ end
+ else
+ return collected
end
+ end
end
-xml.traverse=traverse
+xml.traverse=traverse
xml.selection=selection
local function dofunction(collected,fnc,...)
- if collected then
- local f=functions[fnc]
- if f then
- for c=1,#collected do
- f(collected[c],...)
- end
- else
- report_lpath("unknown function %a",fnc)
- end
+ if collected then
+ local f=functions[fnc]
+ if f then
+ for c=1,#collected do
+ f(collected[c],...)
+ end
+ else
+ report_lpath("unknown function %a",fnc)
end
+ end
end
finalizers.xml["function"]=dofunction
finalizers.tex["function"]=dofunction
expressions.text=function(e,n)
- local rdt=e.__p__.dt
- return rdt and rdt[n] or ""
+ local rdt=e.__p__.dt
+ return rdt and rdt[n] or ""
end
expressions.name=function(e,n)
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=type(e)=="table" and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=type(e)=="table" and e
+ elseif n<0 then
+ 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
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
end
+ end
end
- if found then
- local ns,tg=found.rn or found.ns or "",found.tg
- if ns~="" then
- return ns..":"..tg
+ else
+ 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
+ if n==1 then
+ found=di
+ break
else
- return tg
+ n=n-1
end
+ end
+ end
+ end
+ if found then
+ local ns=found.rn or found.ns or ""
+ local tg=found.tg
+ if ns~="" then
+ return ns..":"..tg
else
- return ""
+ return tg
end
+ else
+ return ""
+ end
end
expressions.tag=function(e,n)
- if not e then
- return ""
+ if not e then
+ return ""
+ else
+ local found=false
+ n=tonumber(n) or 0
+ if n==0 then
+ found=(type(e)=="table") and e
+ elseif n<0 then
+ 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
+ if n==-1 then
+ found=di
+ break
+ else
+ n=n+1
+ end
+ end
+ end
else
- local found=false
- n=tonumber(n) or 0
- if n==0 then
- found=(type(e)=="table") and e
- elseif n<0 then
- local d,k=e.__p__.dt,e.ni
- for i=k-1,1,-1 do
- local di=d[i]
- if type(di)=="table" then
- if n==-1 then
- found=di
- break
- else
- n=n+1
- end
- end
- end
- else
- local d,k=e.__p__.dt,e.ni
- for i=k+1,#d,1 do
- local di=d[i]
- if type(di)=="table" then
- if n==1 then
- found=di
- break
- else
- n=n-1
- end
- end
- end
+ 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
+ if n==1 then
+ found=di
+ break
+ else
+ n=n-1
+ end
end
- return (found and found.tg) or ""
+ end
end
+ return (found and found.tg) or ""
+ end
end
local dummy=function() end
function xml.elements(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- local e=collected[c]
- local r=e.__p__
- return r,r.dt,e.ni
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ local e=collected[c]
+ local r=e.__p__
+ return r,r.dt,e.ni
+ end
end
+ end
end
function xml.collected(root,pattern,reverse)
- local collected=applylpath(root,pattern)
- if not collected then
- return dummy
+ local collected=applylpath(root,pattern)
+ if not collected then
+ return dummy
+ end
+ local n=#collected
+ if n==0 then
+ return dummy
+ end
+ if reverse then
+ local c=n+1
+ return function()
+ if c>1 then
+ c=c-1
+ return collected[c]
+ end
end
- local n=#collected
- if n==0 then
- return dummy
- end
- if reverse then
- local c=n+1
- return function()
- if c>1 then
- c=c-1
- return collected[c]
- end
- end
- else
- local c=0
- return function()
- if c<n then
- c=c+1
- return collected[c]
- end
- end
+ else
+ local c=0
+ return function()
+ if c<n then
+ c=c+1
+ return collected[c]
+ end
end
+ end
end
function xml.inspect(collection,pattern)
- pattern=pattern or "."
- for e in xml.collected(collection,pattern or ".") do
- report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
- end
+ pattern=pattern or "."
+ for e in xml.collected(collection,pattern or ".") do
+ report_lpath("pattern: %s\n\n%s\n",pattern,xml.tostring(e))
+ end
end
local function split(e)
- local dt=e.dt
- if dt then
- for i=1,#dt do
- local dti=dt[i]
- if type(dti)=="string" then
- dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti=gsub(dti,"[\n\r]+","\n\n")
- dt[i]=dti
- else
- split(dti)
- end
- end
+ local dt=e.dt
+ if dt then
+ for i=1,#dt do
+ local dti=dt[i]
+ if type(dti)=="string" then
+ dti=gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
+ dti=gsub(dti,"[\n\r]+","\n\n")
+ dt[i]=dti
+ else
+ split(dti)
+ end
end
- return e
+ end
+ return e
end
function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
+ for i=1,#c do
+ split(c[i])
+ end
+ return c
end
@@ -14727,14 +18294,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true
--- original size: 3574, stripped down to: 1863
+-- original size: 3574, stripped down to: 1808
if not modules then modules={} end modules ['lxml-mis']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local xml,lpeg,string=xml,lpeg,string
local type=type
@@ -14745,26 +18312,26 @@ local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs
lpegpatterns.xml=lpegpatterns.xml or {}
local xmlpatterns=lpegpatterns.xml
local function xmlgsub(t,old,new)
- local dt=t.dt
- if dt then
- for k=1,#dt do
- local v=dt[k]
- if type(v)=="string" then
- dt[k]=gsub(v,old,new)
- else
- xmlgsub(v,old,new)
- end
- end
+ local dt=t.dt
+ if dt then
+ for k=1,#dt do
+ local v=dt[k]
+ if type(v)=="string" then
+ dt[k]=gsub(v,old,new)
+ else
+ xmlgsub(v,old,new)
+ end
end
+ end
end
function xml.stripleadingspaces(dk,d,k)
- if d and k then
- local dkm=d[k-1]
- if dkm and type(dkm)=="string" then
- local s=match(dkm,"\n(%s+)")
- xmlgsub(dk,"\n"..rep(" ",#s),"\n")
- end
+ if d and k then
+ local dkm=d[k-1]
+ if dkm and type(dkm)=="string" then
+ local s=match(dkm,"\n(%s+)")
+ xmlgsub(dk,"\n"..rep(" ",#s),"\n")
end
+ end
end
local normal=(1-S("<&>"))^0
local special=P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"
@@ -14776,17 +18343,17 @@ local cleansed=Cs(((P("<")*(1-P(">"))^0*P(">"))/""+1)^0)
xmlpatterns.escaped=escaped
xmlpatterns.unescaped=unescaped
xmlpatterns.cleansed=cleansed
-function xml.escaped (str) return lpegmatch(escaped,str) end
+function xml.escaped (str) return lpegmatch(escaped,str) end
function xml.unescaped(str) return lpegmatch(unescaped,str) end
-function xml.cleansed (str) return lpegmatch(cleansed,str) end
+function xml.cleansed (str) return lpegmatch(cleansed,str) end
function xml.fillin(root,pattern,str,check)
- local e=xml.first(root,pattern)
- if e then
- local n=#e.dt
- if not check or n==0 or (n==1 and e.dt[1]=="") then
- e.dt={ str }
- end
+ local e=xml.first(root,pattern)
+ if e then
+ local n=#e.dt
+ if not check or n==0 or (n==1 and e.dt[1]=="") then
+ e.dt={ str }
end
+ end
end
@@ -14796,17 +18363,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true
--- original size: 30650, stripped down to: 21793
+-- original size: 30771, stripped down to: 19680
if not modules then modules={} end modules ['lxml-aux']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
-local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
-local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
+local trace_manipulations=false trackers.register("lxml.manipulations",function(v) trace_manipulations=v end)
+local trace_inclusions=false trackers.register("lxml.inclusions",function(v) trace_inclusions=v end)
local report_xml=logs.reporter("xml")
local xml=xml
local xmlcopy,xmlname=xml.copy,xml.name
@@ -14819,308 +18386,313 @@ local utfbyte=utf.byte
local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns
local striplinepatterns=utilities.strings.striplinepatterns
local function report(what,pattern,c,e)
- report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
+ report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern)
end
local function withelements(e,handle,depth)
- if e and handle then
- local edt=e.dt
- if edt then
- depth=depth or 0
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- handle(e,depth)
- withelements(e,handle,depth+1)
- end
- end
+ if e and handle then
+ local edt=e.dt
+ if edt then
+ depth=depth or 0
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ handle(e,depth)
+ withelements(e,handle,depth+1)
end
+ end
end
+ end
end
xml.withelements=withelements
function xml.withelement(e,n,handle)
- if e and n~=0 and handle then
- local edt=e.dt
- if edt then
- if n>0 then
- for i=1,#edt do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==1 then
- handle(ei)
- return
- else
- n=n-1
- end
- end
- end
- elseif n<0 then
- for i=#edt,1,-1 do
- local ei=edt[i]
- if type(ei)=="table" then
- if n==-1 then
- handle(ei)
- return
- else
- n=n+1
- end
- end
- end
+ if e and n~=0 and handle then
+ local edt=e.dt
+ if edt then
+ if n>0 then
+ for i=1,#edt do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==1 then
+ handle(ei)
+ return
+ else
+ n=n-1
end
+ end
end
- end
-end
-function xml.each(root,pattern,handle,reverse)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- if handle then
- if reverse then
- for c=#collected,1,-1 do
- handle(collected[c])
- end
+ elseif n<0 then
+ for i=#edt,1,-1 do
+ local ei=edt[i]
+ if type(ei)=="table" then
+ if n==-1 then
+ handle(ei)
+ return
else
- for c=1,#collected do
- handle(collected[c])
- end
+ n=n+1
end
+ end
end
- return collected
+ end
end
+ end
end
-function xml.processattributes(root,pattern,handle)
- local collected=xmlapplylpath(root,pattern)
- if collected and handle then
+function xml.each(root,pattern,handle,reverse)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ if handle then
+ if reverse then
+ for c=#collected,1,-1 do
+ handle(collected[c])
+ end
+ else
for c=1,#collected do
- handle(collected[c].at)
+ handle(collected[c])
end
+ end
end
return collected
+ end
+end
+function xml.processattributes(root,pattern,handle)
+ local collected=xmlapplylpath(root,pattern)
+ if collected and handle then
+ for c=1,#collected do
+ handle(collected[c].at)
+ end
+ end
+ return collected
end
function xml.collect(root,pattern)
- return xmlapplylpath(root,pattern)
+ return xmlapplylpath(root,pattern)
end
function xml.collecttexts(root,pattern,flatten)
- local collected=xmlapplylpath(root,pattern)
- if collected and flatten then
- local xmltostring=xml.tostring
- for c=1,#collected do
- collected[c]=xmltostring(collected[c].dt)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected and flatten then
+ local xmltostring=xml.tostring
+ for c=1,#collected do
+ collected[c]=xmltostring(collected[c].dt)
end
- return collected or {}
+ end
+ return collected or {}
end
function xml.collect_tags(root,pattern,nonamespace)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- local t,n={},0
- for c=1,#collected do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace then
- t[n]=tg
- elseif ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
- end
- return t
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ local t={}
+ local n=0
+ for c=1,#collected do
+ local e=collected[c]
+ local ns=e.ns
+ local tg=e.tg
+ n=n+1
+ if nonamespace then
+ t[n]=tg
+ elseif ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
+ end
end
+ return t
+ end
end
local no_root={ no_root=true }
local function redo_ni(d)
- for k=1,#d do
- local dk=d[k]
- if type(dk)=="table" then
- dk.ni=k
- end
+ for k=1,#d do
+ local dk=d[k]
+ if type(dk)=="table" then
+ dk.ni=k
end
+ end
end
xml.reindex=redo_ni
local function xmltoelement(whatever,root)
- if not whatever then
- return nil
- end
- local element
- if type(whatever)=="string" then
- element=xmlinheritedconvert(whatever,root)
- else
- element=whatever
- end
- if element.error then
- return whatever
- end
- if element then
- end
- return element
+ if not whatever then
+ return nil
+ end
+ local element
+ if type(whatever)=="string" then
+ element=xmlinheritedconvert(whatever,root)
+ else
+ element=whatever
+ end
+ if element.error then
+ return whatever
+ end
+ if element then
+ end
+ return element
end
xml.toelement=xmltoelement
local function copiedelement(element,newparent)
- if type(element)=="string" then
- return element
- else
- element=xmlcopy(element).dt
- if newparent and type(element)=="table" then
- element.__p__=newparent
- end
- return element
+ if type(element)=="string" then
+ return element
+ else
+ element=xmlcopy(element).dt
+ if newparent and type(element)=="table" then
+ element.__p__=newparent
end
+ return element
+ end
end
function xml.delete(root,pattern)
- if not pattern or pattern=="" then
- local p=root.__p__
+ if not pattern or pattern=="" then
+ local p=root.__p__
+ if p then
+ if trace_manipulations then
+ report('deleting',"--",c,root)
+ end
+ local d=p.dt
+ remove(d,root.ni)
+ redo_ni(d)
+ end
+ else
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
if p then
- if trace_manipulations then
- report('deleting',"--",c,root)
- end
- local d=p.dt
- remove(d,root.ni)
- redo_ni(d)
- end
- else
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('deleting',pattern,c,e)
- end
- local d=p.dt
- local ni=e.ni
- if ni<=#d then
- if false then
- p.dt[ni]=""
- else
- remove(d,ni)
- redo_ni(d)
- end
- else
- end
- end
+ if trace_manipulations then
+ report('deleting',pattern,c,e)
+ end
+ local d=p.dt
+ local ni=e.ni
+ if ni<=#d then
+ if false then
+ p.dt[ni]=""
+ else
+ remove(d,ni)
+ redo_ni(d)
end
+ else
+ end
end
+ end
end
+ end
end
function xml.replace(root,pattern,whatever)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local p=e.__p__
- if p then
- if trace_manipulations then
- report('replacing',pattern,c,e)
- end
- local d=p.dt
- local n=e.ni
- local t=copiedelement(element,p)
- if type(t)=="table" then
- d[n]=t[1]
- for i=2,#t do
- n=n+1
- insert(d,n,t[i])
- end
- else
- d[n]=t
- end
- redo_ni(d)
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local p=e.__p__
+ if p then
+ if trace_manipulations then
+ report('replacing',pattern,c,e)
+ end
+ local d=p.dt
+ local n=e.ni
+ local t=copiedelement(element,p)
+ if type(t)=="table" then
+ d[n]=t[1]
+ for i=2,#t do
+ n=n+1
+ insert(d,n,t[i])
+ end
+ else
+ d[n]=t
end
+ redo_ni(d)
+ end
end
+ end
end
local function wrap(e,wrapper)
- local t={
- rn=e.rn,
- tg=e.tg,
- ns=e.ns,
- at=e.at,
- dt=e.dt,
- __p__=e,
- }
- setmetatable(t,getmetatable(e))
- e.rn=wrapper.rn or e.rn or ""
- e.tg=wrapper.tg or e.tg or ""
- e.ns=wrapper.ns or e.ns or ""
- e.at=fastcopy(wrapper.at)
- e.dt={ t }
+ local t={
+ rn=e.rn,
+ tg=e.tg,
+ ns=e.ns,
+ at=e.at,
+ dt=e.dt,
+ __p__=e,
+ }
+ setmetatable(t,getmetatable(e))
+ e.rn=wrapper.rn or e.rn or ""
+ e.tg=wrapper.tg or e.tg or ""
+ e.ns=wrapper.ns or e.ns or ""
+ e.at=fastcopy(wrapper.at)
+ e.dt={ t }
end
function xml.wrap(root,pattern,whatever)
- if whatever then
- local wrapper=xmltoelement(whatever,root)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if trace_manipulations then
- report('wrapping',pattern,c,e)
- end
- wrap(e,wrapper)
- end
+ if whatever then
+ local wrapper=xmltoelement(whatever,root)
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if trace_manipulations then
+ report('wrapping',pattern,c,e)
end
- else
- wrap(root,xmltoelement(pattern))
+ wrap(e,wrapper)
+ end
end
+ else
+ wrap(root,xmltoelement(pattern))
+ end
end
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 edt=(rri and d[rri].dt) or (d and d[k] and d[k].dt)
- if edt then
- local be,af
- local cp=copiedelement(element,e)
- if prepend then
- be,af=cp,edt
- else
- be,af=edt,cp
- end
- local bn=#be
- for i=1,#af do
- bn=bn+1
- be[bn]=af[i]
- end
- if rri then
- r.dt[rri].dt=be
- else
- d[k].dt=be
- end
- redo_ni(d)
- end
+ 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=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
+ local cp=copiedelement(element,e)
+ if prepend then
+ be,af=cp,edt
+ else
+ be,af=edt,cp
+ end
+ local bn=#be
+ for i=1,#af do
+ bn=bn+1
+ be[bn]=af[i]
+ end
+ if rri then
+ r.dt[rri].dt=be
+ else
+ d[k].dt=be
+ end
+ redo_ni(d)
end
- if not collected then
- elseif collected.tg then
- inject_e(collected)
- else
- for c=1,#collected do
- inject_e(collected[c])
- end
+ end
+ if not collected then
+ elseif collected.tg then
+ inject_e(collected)
+ else
+ for c=1,#collected do
+ inject_e(collected[c])
end
+ end
end
local function insert_element(root,pattern,whatever,before)
- local element=root and xmltoelement(whatever,root)
- local collected=element and xmlapplylpath(root,pattern)
- local function insert_e(e)
- local r=e.__p__
- local d,k=r.dt,e.ni
- if not before then
- k=k+1
- end
- insert(d,k,copiedelement(element,r))
- redo_ni(d)
- end
- if not collected then
- elseif collected.tg then
- insert_e(collected)
- else
- for c=1,#collected do
- insert_e(collected[c])
- end
+ local element=root and xmltoelement(whatever,root)
+ local collected=element and xmlapplylpath(root,pattern)
+ local function insert_e(e)
+ local r=e.__p__
+ local d=r.dt
+ local k=e.ni
+ if not before then
+ k=k+1
+ end
+ insert(d,k,copiedelement(element,r))
+ redo_ni(d)
+ end
+ if not collected then
+ elseif collected.tg then
+ insert_e(collected)
+ else
+ for c=1,#collected do
+ insert_e(collected[c])
end
+ end
end
xml.insert_element=insert_element
xml.insertafter=insert_element
@@ -15128,124 +18700,124 @@ xml.insertbefore=function(r,p,e) insert_element(r,p,e,true) end
xml.injectafter=inject_element
xml.injectbefore=function(r,p,e) inject_element(r,p,e,true) end
local function include(xmldata,pattern,attribute,recursive,loaddata,level)
- pattern=pattern or 'include'
- loaddata=loaddata or io.loaddata
- local collected=xmlapplylpath(xmldata,pattern)
- if collected then
- if not level then
- level=1
- end
- for c=1,#collected do
- local ek=collected[c]
- local name=nil
- local ekdt=ek.dt
- if ekdt then
- local ekat=ek.at
- local ekrt=ek.__p__
- if ekrt then
- local epdt=ekrt.dt
- if not attribute or attribute=="" then
- name=(type(ekdt)=="table" and ekdt[1]) or ekdt
- end
- if not name then
- for a in gmatch(attribute or "href","([^|]+)") do
- name=ekat[a]
- if name then
- break
- end
- end
- end
- local data=nil
- if name and name~="" then
- local d,n=loaddata(name)
- data=d or ""
- name=n or name
- if trace_inclusions then
- report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
- end
- end
- if not data or data=="" then
- epdt[ek.ni]=""
- elseif ekat["parse"]=="text" then
- epdt[ek.ni]=xml.escaped(data)
- else
+ pattern=pattern or 'include'
+ loaddata=loaddata or io.loaddata
+ local collected=xmlapplylpath(xmldata,pattern)
+ if collected then
+ if not level then
+ level=1
+ end
+ for c=1,#collected do
+ local ek=collected[c]
+ local name=nil
+ local ekdt=ek.dt
+ if ekdt then
+ local ekat=ek.at
+ local ekrt=ek.__p__
+ if ekrt then
+ local epdt=ekrt.dt
+ if not attribute or attribute=="" then
+ name=(type(ekdt)=="table" and ekdt[1]) or ekdt
+ end
+ if not name then
+ for a in gmatch(attribute or "href","([^|]+)") do
+ name=ekat[a]
+ if name then
+ break
+ end
+ end
+ end
+ local data=nil
+ if name and name~="" then
+ local d,n=loaddata(name)
+ data=d or ""
+ name=n or name
+ if trace_inclusions then
+ report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ")
+ end
+ end
+ if not data or data=="" then
+ epdt[ek.ni]=""
+ elseif ekat["parse"]=="text" then
+ epdt[ek.ni]=xml.escaped(data)
+ else
local settings=xmldata.settings
local savedresource=settings.currentresource
settings.currentresource=name
- local xi=xmlinheritedconvert(data,xmldata)
- if not xi then
- epdt[ek.ni]=""
- else
- if recursive then
- include(xi,pattern,attribute,recursive,loaddata,level+1)
- end
- local child=xml.body(xi)
- child.__p__=ekrt
- child.__f__=name
+ local xi=xmlinheritedconvert(data,xmldata)
+ if not xi then
+ epdt[ek.ni]=""
+ else
+ if recursive then
+ include(xi,pattern,attribute,recursive,loaddata,level+1)
+ end
+ local child=xml.body(xi)
+ child.__p__=ekrt
+ child.__f__=name
child.cf=name
- epdt[ek.ni]=child
- local settings=xmldata.settings
- local inclusions=settings and settings.inclusions
- if inclusions then
- inclusions[#inclusions+1]=name
- elseif settings then
- settings.inclusions={ name }
- else
- settings={ inclusions={ name } }
- xmldata.settings=settings
- end
- if child.er then
- local badinclusions=settings.badinclusions
- if badinclusions then
- badinclusions[#badinclusions+1]=name
- else
- settings.badinclusions={ name }
- end
- end
- end
-settings.currentresource=savedresource
- end
+ epdt[ek.ni]=child
+ local settings=xmldata.settings
+ local inclusions=settings and settings.inclusions
+ if inclusions then
+ inclusions[#inclusions+1]=name
+ elseif settings then
+ settings.inclusions={ name }
+ else
+ settings={ inclusions={ name } }
+ xmldata.settings=settings
+ end
+ if child.er then
+ local badinclusions=settings.badinclusions
+ if badinclusions then
+ badinclusions[#badinclusions+1]=name
+ else
+ settings.badinclusions={ name }
end
+ end
end
+settings.currentresource=savedresource
+ end
end
+ end
end
+ end
end
xml.include=include
function xml.inclusion(e,default)
- while e do
- local f=e.__f__
- if f then
- return f
- else
- e=e.__p__
- end
+ while e do
+ local f=e.__f__
+ if f then
+ return f
+ else
+ e=e.__p__
end
- return default
+ end
+ return default
end
local function getinclusions(key,e,sorted)
- while e do
- local settings=e.settings
- if settings then
- local inclusions=settings[key]
- if inclusions then
- inclusions=table.unique(inclusions)
- if sorted then
- table.sort(inclusions)
- end
- return inclusions
- else
- e=e.__p__
- end
- else
- e=e.__p__
- end
+ while e do
+ local settings=e.settings
+ if settings then
+ local inclusions=settings[key]
+ if inclusions then
+ inclusions=table.unique(inclusions)
+ if sorted then
+ table.sort(inclusions)
+ end
+ return inclusions
+ else
+ e=e.__p__
+ end
+ else
+ e=e.__p__
end
+ end
end
function xml.inclusions(e,sorted)
- return getinclusions("inclusions",e,sorted)
+ return getinclusions("inclusions",e,sorted)
end
function xml.badinclusions(e,sorted)
- return getinclusions("badinclusions",e,sorted)
+ return getinclusions("badinclusions",e,sorted)
end
local b_collapser=lpegpatterns.b_collapser
local m_collapser=lpegpatterns.m_collapser
@@ -15254,194 +18826,194 @@ local b_stripper=lpegpatterns.b_stripper
local m_stripper=lpegpatterns.m_stripper
local e_stripper=lpegpatterns.e_stripper
local function stripelement(e,nolines,anywhere)
- local edt=e.dt
- if edt then
- local n=#edt
- if n==0 then
- return e
- elseif anywhere then
- local t={}
- local m=0
- for e=1,n do
- local str=edt[e]
- if type(str)~="string" then
- m=m+1
- t[m]=str
- elseif str~="" then
- if nolines then
- str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
- else
- str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
- end
- if str~="" then
- m=m+1
- t[m]=str
- end
- end
- end
- e.dt=t
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==0 then
+ return e
+ elseif anywhere then
+ local t={}
+ local m=0
+ for e=1,n do
+ local str=edt[e]
+ if type(str)~="string" then
+ m=m+1
+ t[m]=str
+ elseif str~="" then
+ if nolines then
+ str=lpegmatch((n==1 and b_collapser) or (n==m and e_collapser) or m_collapser,str)
+ else
+ str=lpegmatch((n==1 and b_stripper) or (n==m and e_stripper) or m_stripper,str)
+ end
+ if str~="" then
+ m=m+1
+ t[m]=str
+ end
+ end
+ end
+ e.dt=t
+ else
+ local str=edt[1]
+ if type(str)=="string" then
+ if str~="" then
+ str=lpegmatch(nolines and b_collapser or b_stripper,str)
+ end
+ if str=="" then
+ remove(edt,1)
+ n=n-1
else
- local str=edt[1]
- if type(str)=="string" then
- if str~="" then
- str=lpegmatch(nolines and b_collapser or b_stripper,str)
- end
- if str=="" then
- remove(edt,1)
- n=n-1
- else
- edt[1]=str
- end
- end
- if n>0 then
- str=edt[n]
- if type(str)=="string" then
- if str=="" then
- remove(edt)
- else
- str=lpegmatch(nolines and e_collapser or e_stripper,str)
- if str=="" then
- remove(edt)
- else
- edt[n]=str
- end
- end
- end
+ edt[1]=str
+ end
+ end
+ if n>0 then
+ str=edt[n]
+ if type(str)=="string" then
+ if str=="" then
+ remove(edt)
+ else
+ str=lpegmatch(nolines and e_collapser or e_stripper,str)
+ if str=="" then
+ remove(edt)
+ else
+ edt[n]=str
end
+ end
end
+ end
end
- return e
+ end
+ return e
end
xml.stripelement=stripelement
function xml.strip(root,pattern,nolines,anywhere)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for i=1,#collected do
- stripelement(collected[i],nolines,anywhere)
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for i=1,#collected do
+ stripelement(collected[i],nolines,anywhere)
end
+ end
end
local function renamespace(root,oldspace,newspace)
- local ndt=#root.dt
- for i=1,ndt or 0 do
- local e=root[i]
- if type(e)=="table" then
- if e.ns==oldspace then
- e.ns=newspace
- if e.rn then
- e.rn=newspace
- end
- end
- local edt=e.dt
- if edt then
- renamespace(edt,oldspace,newspace)
- end
+ local ndt=#root.dt
+ for i=1,ndt or 0 do
+ local e=root[i]
+ if type(e)=="table" then
+ if e.ns==oldspace then
+ e.ns=newspace
+ if e.rn then
+ e.rn=newspace
end
+ end
+ local edt=e.dt
+ if edt then
+ renamespace(edt,oldspace,newspace)
+ end
end
+ end
end
xml.renamespace=renamespace
function xml.remaptag(root,pattern,newtg)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].tg=newtg
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].tg=newtg
end
+ end
end
function xml.remapnamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- collected[c].ns=newns
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ collected[c].ns=newns
end
+ end
end
function xml.checknamespace(root,pattern,newns)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- if (not e.rn or e.rn=="") and e.ns=="" then
- e.rn=newns
- end
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ if (not e.rn or e.rn=="") and e.ns=="" then
+ e.rn=newns
+ end
end
+ end
end
function xml.remapname(root,pattern,newtg,newns,newrn)
- local collected=xmlapplylpath(root,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- e.tg,e.ns,e.rn=newtg,newns,newrn
- end
+ local collected=xmlapplylpath(root,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ e.tg,e.ns,e.rn=newtg,newns,newrn
end
+ end
end
function xml.cdatatotext(e)
- local dt=e.dt
- if #dt==1 then
- local first=dt[1]
- if first.tg=="@cd@" then
- e.dt=first.dt
- end
- else
+ local dt=e.dt
+ if #dt==1 then
+ local first=dt[1]
+ if first.tg=="@cd@" then
+ e.dt=first.dt
end
+ else
+ end
end
function xml.texttocdata(e)
- local dt=e.dt
- local s=xml.tostring(dt)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(dt)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
function xml.elementtocdata(e)
- local dt=e.dt
- local s=xml.tostring(e)
- e.tg="@cd@"
- e.special=true
- e.ns=""
- e.rn=""
- e.dt={ s }
- e.at=nil
+ local dt=e.dt
+ local s=xml.tostring(e)
+ e.tg="@cd@"
+ e.special=true
+ e.ns=""
+ e.rn=""
+ e.dt={ s }
+ e.at=nil
end
xml.builtinentities=table.tohash { "amp","quot","apos","lt","gt" }
local entities=characters and characters.entities or nil
local builtinentities=xml.builtinentities
function xml.addentitiesdoctype(root,option)
- if not entities then
- require("char-ent")
- entities=characters.entities
- end
- if entities and root and root.tg=="@rt@" and root.statistics then
- local list={}
- local hexify=option=="hexadecimal"
- for k,v in table.sortedhash(root.statistics.entities.names) do
- if not builtinentities[k] then
- local e=entities[k]
- if not e then
- e=format("[%s]",k)
- elseif hexify then
- e=format("&#%05X;",utfbyte(k))
- end
- list[#list+1]=format(" <!ENTITY %s %q >",k,e)
- end
- end
- local dt=root.dt
- local n=dt[1].tg=="@pi@" and 2 or 1
- if #list>0 then
- insert(dt,n,{ "\n" })
- insert(dt,n,{
- tg="@dt@",
- dt={ format("Something [\n%s\n] ",concat(list)) },
- ns="",
- special=true,
- })
- insert(dt,n,{ "\n\n" })
- else
- end
+ if not entities then
+ require("char-ent")
+ entities=characters.entities
+ end
+ if entities and root and root.tg=="@rt@" and root.statistics then
+ local list={}
+ local hexify=option=="hexadecimal"
+ for k,v in table.sortedhash(root.statistics.entities.names) do
+ if not builtinentities[k] then
+ local e=entities[k]
+ if not e then
+ e=format("[%s]",k)
+ elseif hexify then
+ e=format("&#%05X;",utfbyte(k))
+ end
+ list[#list+1]=format(" <!ENTITY %s %q >",k,e)
+ end
end
+ local dt=root.dt
+ local n=dt[1].tg=="@pi@" and 2 or 1
+ if #list>0 then
+ insert(dt,n,{ "\n" })
+ insert(dt,n,{
+ tg="@dt@",
+ dt={ format("Something [\n%s\n] ",concat(list)) },
+ ns="",
+ special=true,
+ })
+ insert(dt,n,{ "\n\n" })
+ else
+ end
+ end
end
xml.all=xml.each
xml.insert=xml.insertafter
@@ -15451,239 +19023,241 @@ xml.before=xml.insertbefore
xml.process=xml.each
xml.obsolete=xml.obsolete or {}
local obsolete=xml.obsolete
-xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
-xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
-xml.delete_element=xml.delete obsolete.delete_element=xml.delete
-xml.replace_element=xml.replace obsolete.replace_element=xml.replace
-xml.each_element=xml.each obsolete.each_element=xml.each
-xml.process_elements=xml.process obsolete.process_elements=xml.process
-xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
-xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
-xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
-xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
-xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
-xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
-xml.inject_element=xml.inject obsolete.inject_element=xml.inject
-xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
-xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
-xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
+xml.strip_whitespace=xml.strip obsolete.strip_whitespace=xml.strip
+xml.collect_elements=xml.collect obsolete.collect_elements=xml.collect
+xml.delete_element=xml.delete obsolete.delete_element=xml.delete
+xml.replace_element=xml.replace obsolete.replace_element=xml.replace
+xml.each_element=xml.each obsolete.each_element=xml.each
+xml.process_elements=xml.process obsolete.process_elements=xml.process
+xml.insert_element_after=xml.insertafter obsolete.insert_element_after=xml.insertafter
+xml.insert_element_before=xml.insertbefore obsolete.insert_element_before=xml.insertbefore
+xml.inject_element_after=xml.injectafter obsolete.inject_element_after=xml.injectafter
+xml.inject_element_before=xml.injectbefore obsolete.inject_element_before=xml.injectbefore
+xml.process_attributes=xml.processattributes obsolete.process_attributes=xml.processattributes
+xml.collect_texts=xml.collecttexts obsolete.collect_texts=xml.collecttexts
+xml.inject_element=xml.inject obsolete.inject_element=xml.inject
+xml.remap_tag=xml.remaptag obsolete.remap_tag=xml.remaptag
+xml.remap_name=xml.remapname obsolete.remap_name=xml.remapname
+xml.remap_namespace=xml.remapnamespace obsolete.remap_namespace=xml.remapnamespace
function xml.cdata(e)
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
end
- return ""
+ end
+ return ""
end
function xml.finalizers.xml.cdata(collected)
- if collected then
- local e=collected[1]
- if e then
- local dt=e.dt
- if dt and #dt==1 then
- local first=dt[1]
- return first.tg=="@cd@" and first.dt[1] or ""
- end
- end
+ if collected then
+ local e=collected[1]
+ if e then
+ local dt=e.dt
+ if dt and #dt==1 then
+ local first=dt[1]
+ return first.tg=="@cd@" and first.dt[1] or ""
+ end
end
- return ""
+ end
+ return ""
end
function xml.insertcomment(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.insertcdata(e,str,n)
- insert(e.dt,n or 1,{
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- })
+ insert(e.dt,n or 1,{
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ })
end
function xml.setcomment(e,str,n)
- e.dt={ {
- tg="@cm@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cm@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.setcdata(e,str)
- e.dt={ {
- tg="@cd@",
- ns="",
- special=true,
- at={},
- dt={ str },
- } }
+ e.dt={ {
+ tg="@cd@",
+ ns="",
+ special=true,
+ at={},
+ dt={ str },
+ } }
end
function xml.separate(x,pattern)
- local collected=xmlapplylpath(x,pattern)
- if collected then
- for c=1,#collected do
- local e=collected[c]
- local d=e.dt
- if d==x then
- report_xml("warning: xml.separate changes root")
- x=d
- end
- local t,n={ "\n" },1
- local i,nd=1,#d
- while i<=nd do
- while i<=nd do
- local di=d[i]
- if type(di)=="string" then
- if di=="\n" or find(di,"^%s+$") then
- i=i+1
- else
- d[i]=strip(di)
- break
- end
- else
- break
- end
- end
- if i>nd then
- break
- end
- t[n+1]="\n"
- t[n+2]=d[i]
- t[n+3]="\n"
- n=n+3
- i=i+1
+ local collected=xmlapplylpath(x,pattern)
+ if collected then
+ for c=1,#collected do
+ local e=collected[c]
+ local d=e.dt
+ if d==x then
+ report_xml("warning: xml.separate changes root")
+ x=d
+ end
+ local t={ "\n" }
+ local n=1
+ local i=1
+ local nd=#d
+ while i<=nd do
+ while i<=nd do
+ local di=d[i]
+ if type(di)=="string" then
+ if di=="\n" or find(di,"^%s+$") then
+ i=i+1
+ else
+ d[i]=strip(di)
+ break
end
- t[n+1]="\n"
- setmetatable(t,getmetatable(d))
- e.dt=t
+ else
+ break
+ end
+ end
+ if i>nd then
+ break
end
+ t[n+1]="\n"
+ t[n+2]=d[i]
+ t[n+3]="\n"
+ n=n+3
+ i=i+1
+ end
+ t[n+1]="\n"
+ setmetatable(t,getmetatable(d))
+ e.dt=t
end
- return x
+ end
+ return x
end
local helpers=xml.helpers or {}
xml.helpers=helpers
local function normal(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)=="string" and str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)=="string" and str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
local function recurse(e,action)
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local str=edt[i]
- if type(str)~="string" then
- recurse(str,action)
- elseif str~="" then
- edt[i]=action(str)
- end
- end
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local str=edt[i]
+ if type(str)~="string" then
+ recurse(str,action)
+ elseif str~="" then
+ edt[i]=action(str)
+ end
end
+ end
end
function helpers.recursetext(collected,action,recursive)
- if recursive then
- for i=1,#collected do
- recurse(collected[i],action)
- end
- else
- for i=1,#collected do
- normal(collected[i],action)
- end
+ if recursive then
+ for i=1,#collected do
+ recurse(collected[i],action)
end
+ else
+ for i=1,#collected do
+ normal(collected[i],action)
+ end
+ end
end
local specials={
- ["@rt@"]="root",
- ["@pi@"]="instruction",
- ["@cm@"]="comment",
- ["@dt@"]="declaration",
- ["@cd@"]="cdata",
+ ["@rt@"]="root",
+ ["@pi@"]="instruction",
+ ["@cm@"]="comment",
+ ["@dt@"]="declaration",
+ ["@cd@"]="cdata",
}
local function convert(x,strip,flat)
- local ns=x.ns
- local tg=x.tg
- local at=x.at
- local dt=x.dt
- local node=flat and {
- [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
- } or {
- _namespace=ns~="" and ns or nil,
- _tag=not x.special and tg or nil,
- _type=specials[tg] or "_element",
- }
- if at then
- for k,v in next,at do
- node[k]=v
- end
- end
- local n=0
- for i=1,#dt do
- local di=dt[i]
- if type(di)=="table" then
- if flat and di.special then
- else
- di=convert(di,strip,flat)
- if di then
- n=n+1
- node[n]=di
- end
- end
- elseif strip then
- di=lpegmatch(strip,di)
- if di~="" then
- n=n+1
- node[n]=di
- end
- else
- n=n+1
- node[n]=di
+ local ns=x.ns
+ local tg=x.tg
+ local at=x.at
+ local dt=x.dt
+ local node=flat and {
+ [0]=(not x.special and (ns~="" and ns..":"..tg or tg)) or nil,
+ } or {
+ _namespace=ns~="" and ns or nil,
+ _tag=not x.special and tg or nil,
+ _type=specials[tg] or "_element",
+ }
+ if at then
+ for k,v in next,at do
+ node[k]=v
+ end
+ end
+ local n=0
+ for i=1,#dt do
+ local di=dt[i]
+ if type(di)=="table" then
+ if flat and di.special then
+ else
+ di=convert(di,strip,flat)
+ if di then
+ n=n+1
+ node[n]=di
end
+ end
+ elseif strip then
+ di=lpegmatch(strip,di)
+ if di~="" then
+ n=n+1
+ node[n]=di
+ end
+ else
+ n=n+1
+ node[n]=di
end
- if next(node) then
- return node
- end
+ end
+ if next(node) then
+ return node
+ end
end
function xml.totable(x,strip,flat)
- if type(x)=="table" then
- if strip then
- strip=striplinepatterns[strip]
- end
- return convert(x,strip,flat)
+ if type(x)=="table" then
+ if strip then
+ strip=striplinepatterns[strip]
end
+ return convert(x,strip,flat)
+ end
end
function xml.rename(e,namespace,name,attributes)
- if type(e)~="table" or not e.tg then
- return
- end
- if type(name)=="table" then
- attributes=name
- name=namespace
- namespace=""
- elseif type(name)~="string" then
- attributes={}
- name=namespace
- namespace=""
- end
- if type(attributes)~="table" then
- attributes={}
- end
- e.ns=namespace
- e.rn=namespace
- e.tg=name
- e.at=attributes
+ if type(e)~="table" or not e.tg then
+ return
+ end
+ if type(name)=="table" then
+ attributes=name
+ name=namespace
+ namespace=""
+ elseif type(name)~="string" then
+ attributes={}
+ name=namespace
+ namespace=""
+ end
+ if type(attributes)~="table" then
+ attributes={}
+ end
+ e.ns=namespace
+ e.rn=namespace
+ e.tg=name
+ e.at=attributes
end
@@ -15693,14 +19267,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
--- original size: 11096, stripped down to: 8243
+-- original size: 11096, stripped down to: 7702
if not modules then modules={} end modules ['lxml-xml']={
- version=1.001,
- comment="this module is the basis for the lxml-* ones",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ comment="this module is the basis for the lxml-* ones",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local tonumber,next=tonumber,next
local concat=table.concat
@@ -15712,241 +19286,241 @@ local xmltostring=xml.tostring
local xmlserialize=xml.serialize
local xmlcollected=xml.collected
local xmlnewhandlers=xml.newhandlers
-local reparsedentity=xml.reparsedentitylpeg
+local reparsedentity=xml.reparsedentitylpeg
local unescapedentity=xml.unescapedentitylpeg
local parsedentity=reparsedentity
local function first(collected)
- return collected and collected[1]
+ return collected and collected[1]
end
local function last(collected)
- return collected and collected[#collected]
+ return collected and collected[#collected]
end
local function all(collected)
- return collected
+ return collected
end
local reverse=table.reversed
local function attribute(collected,name)
- if collected and #collected>0 then
- local at=collected[1].at
- return at and at[name]
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ return at and at[name]
+ end
end
local function att(id,name)
- local at=id.at
- return at and at[name]
+ local at=id.at
+ return at and at[name]
end
local function count(collected)
- return collected and #collected or 0
+ return collected and #collected or 0
end
local function position(collected,n)
- if not collected then
- return 0
- end
- local nc=#collected
- if nc==0 then
- return 0
- end
- n=tonumber(n) or 0
- if n<0 then
- return collected[nc+n+1]
- elseif n>0 then
- return collected[n]
- else
- return collected[1].mi or 0
- end
+ if not collected then
+ return 0
+ end
+ local nc=#collected
+ if nc==0 then
+ return 0
+ end
+ n=tonumber(n) or 0
+ if n<0 then
+ return collected[nc+n+1]
+ elseif n>0 then
+ return collected[n]
+ else
+ return collected[1].mi or 0
+ end
end
local function match(collected)
- return collected and #collected>0 and collected[1].mi or 0
+ return collected and #collected>0 and collected[1].mi or 0
end
local function index(collected)
- return collected and #collected>0 and collected[1].ni or 0
+ return collected and #collected>0 and collected[1].ni or 0
end
local function attributes(collected,arguments)
- if collected and #collected>0 then
- local at=collected[1].at
- if arguments then
- return at[arguments]
- elseif next(at) then
- return at
- end
+ if collected and #collected>0 then
+ local at=collected[1].at
+ if arguments then
+ return at[arguments]
+ elseif next(at) then
+ return at
end
+ end
end
local function chainattribute(collected,arguments)
- if collected and #collected>0 then
- local e=collected[1]
- while e do
- local at=e.at
- if at then
- local a=at[arguments]
- if a then
- return a
- end
- else
- break
- end
- e=e.__p__
+ if collected and #collected>0 then
+ local e=collected[1]
+ while e do
+ local at=e.at
+ if at then
+ local a=at[arguments]
+ if a then
+ return a
end
+ else
+ break
+ end
+ e=e.__p__
end
- return ""
+ end
+ return ""
end
local function raw(collected)
- if collected and #collected>0 then
- local e=collected[1] or collected
- return e and xmltostring(e) or ""
- else
- return ""
- end
+ if collected and #collected>0 then
+ local e=collected[1] or collected
+ return e and xmltostring(e) or ""
+ else
+ return ""
+ end
end
local xmltexthandler=xmlnewhandlers {
- name="string",
- initialize=function()
- result={}
- return result
- end,
- finalize=function()
- return concat(result)
- end,
- handle=function(...)
- result[#result+1]=concat {... }
- end,
- escape=false,
+ name="string",
+ initialize=function()
+ result={}
+ return result
+ end,
+ finalize=function()
+ return concat(result)
+ end,
+ handle=function(...)
+ result[#result+1]=concat {... }
+ end,
+ escape=false,
}
local function xmltotext(root)
- local dt=root.dt
- if not dt then
- return ""
- end
- local nt=#dt
- if nt==0 then
- return ""
- elseif nt==1 and type(dt[1])=="string" then
- return dt[1]
- else
- return xmlserialize(root,xmltexthandler) or ""
- end
+ local dt=root.dt
+ if not dt then
+ return ""
+ end
+ local nt=#dt
+ if nt==0 then
+ return ""
+ elseif nt==1 and type(dt[1])=="string" then
+ return dt[1]
+ else
+ return xmlserialize(root,xmltexthandler) or ""
+ end
end
function xml.serializetotext(root)
- return root and xmlserialize(root,xmltexthandler) or ""
+ return root and xmlserialize(root,xmltexthandler) or ""
end
local function text(collected)
- if collected then
- local e=collected[1] or collected
- return e and xmltotext(e) or ""
- else
- return ""
- end
+ if collected then
+ local e=collected[1] or collected
+ return e and xmltotext(e) or ""
+ else
+ return ""
+ end
end
local function texts(collected)
- if not collected then
- return {}
- end
- local nc=#collected
- if nc==0 then
- return {}
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- if e and e.dt then
- n=n+1
- t[n]=e.dt
- end
- end
- return t
+ if not collected then
+ return {}
+ end
+ local nc=#collected
+ if nc==0 then
+ return {}
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ if e and e.dt then
+ n=n+1
+ t[n]=e.dt
+ end
+ end
+ return t
end
local function tag(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- return c and c.tg
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ return c and c.tg
end
local function name(collected,n)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local c
- if n==0 or not n then
- c=collected[1]
- elseif n>1 then
- c=collected[n]
- else
- c=collected[nc-n+1]
- end
- if not c then
- elseif c.ns=="" then
- return c.tg
- else
- return c.ns..":"..c.tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local c
+ if n==0 or not n then
+ c=collected[1]
+ elseif n>1 then
+ c=collected[n]
+ else
+ c=collected[nc-n+1]
+ end
+ if not c then
+ elseif c.ns=="" then
+ return c.tg
+ else
+ return c.ns..":"..c.tg
+ end
end
local function tags(collected,nonamespace)
- if not collected then
- return
- end
- local nc=#collected
- if nc==0 then
- return
- end
- local t,n={},0
- for c=1,nc do
- local e=collected[c]
- local ns,tg=e.ns,e.tg
- n=n+1
- if nonamespace or ns=="" then
- t[n]=tg
- else
- t[n]=ns..":"..tg
- end
+ if not collected then
+ return
+ end
+ local nc=#collected
+ if nc==0 then
+ return
+ end
+ local t,n={},0
+ for c=1,nc do
+ local e=collected[c]
+ local ns,tg=e.ns,e.tg
+ n=n+1
+ if nonamespace or ns=="" then
+ t[n]=tg
+ else
+ t[n]=ns..":"..tg
end
- return t
+ end
+ return t
end
local function empty(collected,spacesonly)
- if not collected then
- return true
- end
- local nc=#collected
- if nc==0 then
- return true
- end
- for c=1,nc do
- local e=collected[c]
- if e then
- local edt=e.dt
- if edt then
- local n=#edt
- if n==1 then
- local edk=edt[1]
- local typ=type(edk)
- if typ=="table" then
- return false
- elseif edk~="" then
- return false
- elseif spacesonly and not find(edk,"%S") then
- return false
- end
- elseif n>1 then
- return false
- end
- end
+ if not collected then
+ return true
+ end
+ local nc=#collected
+ if nc==0 then
+ return true
+ end
+ for c=1,nc do
+ local e=collected[c]
+ if e then
+ local edt=e.dt
+ if edt then
+ local n=#edt
+ if n==1 then
+ local edk=edt[1]
+ local typ=type(edk)
+ if typ=="table" then
+ return false
+ elseif edk~="" then
+ return false
+ elseif spacesonly and not find(edk,"%S") then
+ return false
+ end
+ elseif n>1 then
+ return false
end
+ end
end
- return true
+ end
+ return true
end
finalizers.first=first
finalizers.last=last
@@ -15969,124 +19543,124 @@ finalizers.name=name
finalizers.tags=tags
finalizers.empty=empty
function xml.first(id,pattern)
- return first(xmlfilter(id,pattern))
+ return first(xmlfilter(id,pattern))
end
function xml.last(id,pattern)
- return last(xmlfilter(id,pattern))
+ return last(xmlfilter(id,pattern))
end
function xml.count(id,pattern)
- return count(xmlfilter(id,pattern))
+ return count(xmlfilter(id,pattern))
end
function xml.attribute(id,pattern,a,default)
- return attribute(xmlfilter(id,pattern),a,default)
+ return attribute(xmlfilter(id,pattern),a,default)
end
function xml.raw(id,pattern)
- if pattern then
- return raw(xmlfilter(id,pattern))
- else
- return raw(id)
- end
+ if pattern then
+ return raw(xmlfilter(id,pattern))
+ else
+ return raw(id)
+ end
end
function xml.text(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- return collected and #collected>0 and xmltotext(collected[1]) or ""
- elseif id then
- return xmltotext(id) or ""
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ return collected and #collected>0 and xmltotext(collected[1]) or ""
+ elseif id then
+ return xmltotext(id) or ""
+ else
+ return ""
+ end
end
function xml.pure(id,pattern)
- if pattern then
- local collected=xmlfilter(id,pattern)
- if collected and #collected>0 then
- parsedentity=unescapedentity
- local s=collected and #collected>0 and xmltotext(collected[1]) or ""
- parsedentity=reparsedentity
- return s
- else
- return ""
- end
+ if pattern then
+ local collected=xmlfilter(id,pattern)
+ if collected and #collected>0 then
+ parsedentity=unescapedentity
+ local s=collected and #collected>0 and xmltotext(collected[1]) or ""
+ parsedentity=reparsedentity
+ return s
else
- parsedentity=unescapedentity
- local s=xmltotext(id) or ""
- parsedentity=reparsedentity
- return s
+ return ""
end
+ else
+ parsedentity=unescapedentity
+ local s=xmltotext(id) or ""
+ parsedentity=reparsedentity
+ return s
+ end
end
xml.content=text
function xml.position(id,pattern,n)
- return position(xmlfilter(id,pattern),n)
+ return position(xmlfilter(id,pattern),n)
end
function xml.match(id,pattern)
- return match(xmlfilter(id,pattern))
+ return match(xmlfilter(id,pattern))
end
function xml.empty(id,pattern,spacesonly)
- return empty(xmlfilter(id,pattern),spacesonly)
+ return empty(xmlfilter(id,pattern),spacesonly)
end
xml.all=xml.filter
xml.index=xml.position
xml.found=xml.filter
local function totable(x)
- local t={}
- for e in xmlcollected(x[1] or x,"/*") do
- t[e.tg]=xmltostring(e.dt) or ""
- end
- return next(t) and t or nil
+ local t={}
+ for e in xmlcollected(x[1] or x,"/*") do
+ t[e.tg]=xmltostring(e.dt) or ""
+ end
+ return next(t) and t or nil
end
xml.table=totable
finalizers.table=totable
local function textonly(e,t)
- if e then
- local edt=e.dt
- if edt then
- for i=1,#edt do
- local e=edt[i]
- if type(e)=="table" then
- textonly(e,t)
- else
- t[#t+1]=e
- end
- end
+ if e then
+ local edt=e.dt
+ if edt then
+ for i=1,#edt do
+ local e=edt[i]
+ if type(e)=="table" then
+ textonly(e,t)
+ else
+ t[#t+1]=e
end
+ end
end
- return t
+ end
+ return t
end
function xml.textonly(e)
- return concat(textonly(e,{}))
+ return concat(textonly(e,{}))
end
function finalizers.lowerall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=lower(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[lower(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=lower(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[lower(k)]=v
end
+ e.at=t
+ end
end
+ end
end
function finalizers.upperall(collected)
- for c=1,#collected do
- local e=collected[c]
- if not e.special then
- e.tg=upper(e.tg)
- local eat=e.at
- if eat then
- local t={}
- for k,v in next,eat do
- t[upper(k)]=v
- end
- e.at=t
- end
+ for c=1,#collected do
+ local e=collected[c]
+ if not e.special then
+ e.tg=upper(e.tg)
+ local eat=e.at
+ if eat then
+ local t={}
+ for k,v in next,eat do
+ t[upper(k)]=v
end
+ e.at=t
+ end
end
+ end
end
@@ -16096,14 +19670,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["trac-xml"] = package.loaded["trac-xml"] or true
--- original size: 6407, stripped down to: 4965
+-- original size: 6407, stripped down to: 4640
if not modules then modules={} end modules ['trac-xml']={
- version=1.001,
- comment="companion to trac-log.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 trac-log.mkiv",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local formatters=string.formatters
local reporters=logs.reporters
@@ -16112,152 +19686,152 @@ local xmlcollected=xml.collected
local xmltext=xml.text
local xmlfirst=xml.first
local function showhelp(specification,...)
- local root=xml.convert(specification.helpinfo or "")
- if not root then
- return
- end
- local xs=xml.gethandlers("string")
- xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
- xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
- local wantedcategories=select("#",...)==0 and true or table.tohash {... }
- local nofcategories=xml.count(root,"/application/flags/category")
- local report=specification.report
- for category in xmlcollected(root,"/application/flags/category") do
- local categoryname=category.at.name or ""
- if wantedcategories==true or wantedcategories[categoryname] then
- if nofcategories>1 then
- report("%s options:",categoryname)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for flag in xmlcollected(subcategory,"/flag") do
- local name=flag.at.name
- local value=flag.at.value
- local short=xmltext(xmlfirst(flag,"/short"))
- if value then
- report("--%-20s %s",formatters["%s=%s"](name,value),short)
- else
- report("--%-20s %s",name,short)
- end
- end
- report()
- end
- end
- end
- for category in xmlcollected(root,"/application/examples/category") do
- local title=xmltext(xmlfirst(category,"/title"))
- if title and title~="" then
- report()
- report(title)
- report()
- end
- for subcategory in xmlcollected(category,"/subcategory") do
- for example in xmlcollected(subcategory,"/example") do
- local command=xmltext(xmlfirst(example,"/command"))
- local comment=xmltext(xmlfirst(example,"/comment"))
- report(command)
- end
- report()
- end
- end
- for comment in xmlcollected(root,"/application/comments/comment") do
- local comment=xmltext(comment)
+ local root=xml.convert(specification.helpinfo or "")
+ if not root then
+ return
+ end
+ local xs=xml.gethandlers("string")
+ xml.sethandlersfunction(xs,"short",function(e,handler) xmlserialize(e.dt,handler) end)
+ xml.sethandlersfunction(xs,"ref",function(e,handler) handler.handle("--"..e.at.name) end)
+ local wantedcategories=select("#",...)==0 and true or table.tohash {... }
+ local nofcategories=xml.count(root,"/application/flags/category")
+ local report=specification.report
+ for category in xmlcollected(root,"/application/flags/category") do
+ local categoryname=category.at.name or ""
+ if wantedcategories==true or wantedcategories[categoryname] then
+ if nofcategories>1 then
+ report("%s options:",categoryname)
report()
- report(comment)
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for flag in xmlcollected(subcategory,"/flag") do
+ local name=flag.at.name
+ local value=flag.at.value
+ local short=xmltext(xmlfirst(flag,"/short"))
+ if value then
+ report("--%-20s %s",formatters["%s=%s"](name,value),short)
+ else
+ report("--%-20s %s",name,short)
+ end
+ end
report()
+ end
+ end
+ end
+ for category in xmlcollected(root,"/application/examples/category") do
+ local title=xmltext(xmlfirst(category,"/title"))
+ if title and title~="" then
+ report()
+ report(title)
+ report()
+ end
+ for subcategory in xmlcollected(category,"/subcategory") do
+ for example in xmlcollected(subcategory,"/example") do
+ local command=xmltext(xmlfirst(example,"/command"))
+ local comment=xmltext(xmlfirst(example,"/comment"))
+ report(command)
+ end
+ report()
end
+ end
+ for comment in xmlcollected(root,"/application/comments/comment") do
+ local comment=xmltext(comment)
+ report()
+ report(comment)
+ report()
+ end
end
local reporthelp=reporters.help
local exporthelp=reporters.export
local function xmlfound(t)
- local helpinfo=t.helpinfo
- if type(helpinfo)=="table" then
- return false
+ local helpinfo=t.helpinfo
+ if type(helpinfo)=="table" then
+ return false
+ end
+ if type(helpinfo)~="string" then
+ helpinfo="Warning: no helpinfo found."
+ t.helpinfo=helpinfo
+ return false
+ end
+ if string.find(helpinfo,".xml$") then
+ local ownscript=environment.ownscript
+ local helpdata=false
+ if ownscript then
+ local helpfile=file.join(file.pathpart(ownscript),helpinfo)
+ helpdata=io.loaddata(helpfile)
+ if helpdata=="" then
+ helpdata=false
+ end
end
- if type(helpinfo)~="string" then
- helpinfo="Warning: no helpinfo found."
- t.helpinfo=helpinfo
- return false
+ if not helpdata then
+ local helpfile=resolvers.findfile(helpinfo,"tex")
+ helpdata=helpfile and io.loaddata(helpfile)
end
- if string.find(helpinfo,".xml$") then
- local ownscript=environment.ownscript
- local helpdata=false
- if ownscript then
- local helpfile=file.join(file.pathpart(ownscript),helpinfo)
- helpdata=io.loaddata(helpfile)
- if helpdata=="" then
- helpdata=false
- end
- end
- if not helpdata then
- local helpfile=resolvers.findfile(helpinfo,"tex")
- helpdata=helpfile and io.loaddata(helpfile)
- end
- if helpdata and helpdata~="" then
- helpinfo=helpdata
- else
- helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
- end
+ if helpdata and helpdata~="" then
+ helpinfo=helpdata
+ else
+ helpinfo=formatters["Warning: help file %a is not found."](helpinfo)
end
- t.helpinfo=helpinfo
- return string.find(t.helpinfo,"^<%?xml") and true or false
+ end
+ t.helpinfo=helpinfo
+ return string.find(t.helpinfo,"^<%?xml") and true or false
end
function reporters.help(t,...)
- if xmlfound(t) then
- showhelp(t,...)
- else
- reporthelp(t,...)
- end
+ if xmlfound(t) then
+ showhelp(t,...)
+ else
+ reporthelp(t,...)
+ end
end
function reporters.export(t,methods,filename)
- if not xmlfound(t) then
- return exporthelp(t)
- end
- if not methods or methods=="" then
- methods=environment.arguments["exporthelp"]
- end
- if not filename or filename=="" then
- filename=environment.files[1]
- end
- dofile(resolvers.findfile("trac-exp.lua","tex"))
- local exporters=logs.exporters
- if not exporters or not methods then
- return exporthelp(t)
- end
- if methods=="all" then
- methods=table.keys(exporters)
- elseif type(methods)=="string" then
- methods=utilities.parsers.settings_to_array(methods)
- else
- return exporthelp(t)
- end
- if type(filename)~="string" or filename=="" then
- filename=false
- elseif file.pathpart(filename)=="" then
- t.report("export file %a will not be saved on the current path (safeguard)",filename)
- return
- end
- for i=1,#methods do
- local method=methods[i]
- local exporter=exporters[method]
- if exporter then
- local result=exporter(t,method)
- if result and result~="" then
- if filename then
- local fullname=file.replacesuffix(filename,method)
- t.report("saving export in %a",fullname)
- dir.mkdirs(file.pathpart(fullname))
- io.savedata(fullname,result)
- else
- reporters.lines(t,result)
- end
- else
- t.report("no output from exporter %a",method)
- end
+ if not xmlfound(t) then
+ return exporthelp(t)
+ end
+ if not methods or methods=="" then
+ methods=environment.arguments["exporthelp"]
+ end
+ if not filename or filename=="" then
+ filename=environment.files[1]
+ end
+ dofile(resolvers.findfile("trac-exp.lua","tex"))
+ local exporters=logs.exporters
+ if not exporters or not methods then
+ return exporthelp(t)
+ end
+ if methods=="all" then
+ methods=table.keys(exporters)
+ elseif type(methods)=="string" then
+ methods=utilities.parsers.settings_to_array(methods)
+ else
+ return exporthelp(t)
+ end
+ if type(filename)~="string" or filename=="" then
+ filename=false
+ elseif file.pathpart(filename)=="" then
+ t.report("export file %a will not be saved on the current path (safeguard)",filename)
+ return
+ end
+ for i=1,#methods do
+ local method=methods[i]
+ local exporter=exporters[method]
+ if exporter then
+ local result=exporter(t,method)
+ if result and result~="" then
+ if filename then
+ local fullname=file.replacesuffix(filename,method)
+ t.report("saving export in %a",fullname)
+ dir.mkdirs(file.pathpart(fullname))
+ io.savedata(fullname,result)
else
- t.report("unknown exporter %a",method)
+ reporters.lines(t,result)
end
+ else
+ t.report("no output from exporter %a",method)
+ end
+ else
+ t.report("unknown exporter %a",method)
end
+ end
end
@@ -16267,149 +19841,149 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-ini"] = package.loaded["data-ini"] or true
--- original size: 11099, stripped down to: 7516
+-- original size: 11099, stripped down to: 7152
if not modules then modules={} end modules ['data-ini']={
- 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,getmetatable,rawset=next,type,getmetatable,rawset
local gsub,find,gmatch,char=string.gsub,string.find,string.gmatch,string.char
local filedirname,filebasename,filejoin=file.dirname,file.basename,file.join
local ostype,osname,osuname,ossetenv,osgetenv=os.type,os.name,os.uname,os.setenv,os.getenv
local P,S,R,C,Cs,Cc,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers.register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
local report_initialization=logs.reporter("resolvers","initialization")
resolvers=resolvers or {}
local resolvers=resolvers
texconfig.kpse_init=false
texconfig.shell_escape='t'
if not (environment and environment.default_texmfcnf) and kpse and kpse.default_texmfcnf then
- local default_texmfcnf=kpse.default_texmfcnf()
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
- default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
- default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
- environment.default_texmfcnf=default_texmfcnf
+ local default_texmfcnf=kpse.default_texmfcnf()
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOLOC","selfautoloc:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTODIR","selfautodir:")
+ default_texmfcnf=gsub(default_texmfcnf,"$SELFAUTOPARENT","selfautoparent:")
+ default_texmfcnf=gsub(default_texmfcnf,"$HOME","home:")
+ environment.default_texmfcnf=default_texmfcnf
end
kpse={ original=kpse }
setmetatable(kpse,{
- __index=function(kp,name)
- report_initialization("fatal error: kpse library is accessed (key: %s)",name)
- os.exit()
- end
+ __index=function(kp,name)
+ report_initialization("fatal error: kpse library is accessed (key: %s)",name)
+ os.exit()
+ end
} )
do
- local osfontdir=osgetenv("OSFONTDIR")
- if osfontdir and osfontdir~="" then
- elseif osname=="windows" then
- ossetenv("OSFONTDIR","c:/windows/fonts//")
- elseif osname=="macosx" then
- ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
- end
+ local osfontdir=osgetenv("OSFONTDIR")
+ if osfontdir and osfontdir~="" then
+ elseif osname=="windows" then
+ ossetenv("OSFONTDIR","c:/windows/fonts//")
+ elseif osname=="macosx" then
+ ossetenv("OSFONTDIR","$HOME/Library/Fonts//;/Library/Fonts//;/System/Library/Fonts//")
+ end
end
do
- local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
- if not homedir or homedir=="" then
- homedir=char(127)
- end
- homedir=file.collapsepath(homedir)
- ossetenv("HOME",homedir)
- ossetenv("USERPROFILE",homedir)
- environment.homedir=homedir
+ local homedir=osgetenv(ostype=="windows" and 'USERPROFILE' or 'HOME') or ''
+ if not homedir or homedir=="" then
+ homedir=char(127)
+ end
+ homedir=file.collapsepath(homedir)
+ ossetenv("HOME",homedir)
+ ossetenv("USERPROFILE",homedir)
+ environment.homedir=homedir
end
do
- local args=environment.originalarguments or arg
- if not environment.ownmain then
- environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
- end
- local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
- local ownpath=environment.ownpath or os.selfdir
- ownbin=file.collapsepath(ownbin)
- ownpath=file.collapsepath(ownpath)
- if not ownpath or ownpath=="" or ownpath=="unset" then
- ownpath=args[-1] or arg[-1]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- if not ownpath or ownpath=="" then
- ownpath=args[-0] or arg[-0]
- ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
- end
- local binary=ownbin
- if not ownpath or ownpath=="" then
- ownpath=ownpath and filedirname(binary)
- end
- if not ownpath or ownpath=="" then
- if os.binsuffix~="" then
- binary=file.replacesuffix(binary,os.binsuffix)
- end
- local path=osgetenv("PATH")
- if path then
- for p in gmatch(path,"[^"..io.pathseparator.."]+") do
- local b=filejoin(p,binary)
- if lfs.isfile(b) then
- local olddir=lfs.currentdir()
- if lfs.chdir(p) then
- local pp=lfs.currentdir()
- if trace_locating and p~=pp then
- report_initialization("following symlink %a to %a",p,pp)
- end
- ownpath=pp
- lfs.chdir(olddir)
- else
- if trace_locating then
- report_initialization("unable to check path %a",p)
- end
- ownpath=p
- end
- break
- end
- end
+ local args=environment.originalarguments or arg
+ if not environment.ownmain then
+ environment.ownmain=status and string.match(string.lower(status.banner),"this is ([%a]+)") or "luatex"
+ end
+ local ownbin=environment.ownbin or args[-2] or arg[-2] or args[-1] or arg[-1] or arg[0] or "luatex"
+ local ownpath=environment.ownpath or os.selfdir
+ ownbin=file.collapsepath(ownbin)
+ ownpath=file.collapsepath(ownpath)
+ if not ownpath or ownpath=="" or ownpath=="unset" then
+ ownpath=args[-1] or arg[-1]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ if not ownpath or ownpath=="" then
+ ownpath=args[-0] or arg[-0]
+ ownpath=ownpath and filedirname(gsub(ownpath,"\\","/"))
+ end
+ local binary=ownbin
+ if not ownpath or ownpath=="" then
+ ownpath=ownpath and filedirname(binary)
+ end
+ if not ownpath or ownpath=="" then
+ if os.binsuffix~="" then
+ binary=file.replacesuffix(binary,os.binsuffix)
+ end
+ local path=osgetenv("PATH")
+ if path then
+ for p in gmatch(path,"[^"..io.pathseparator.."]+") do
+ local b=filejoin(p,binary)
+ if lfs.isfile(b) then
+ local olddir=lfs.currentdir()
+ if lfs.chdir(p) then
+ local pp=lfs.currentdir()
+ if trace_locating and p~=pp then
+ report_initialization("following symlink %a to %a",p,pp)
+ end
+ ownpath=pp
+ lfs.chdir(olddir)
+ else
+ if trace_locating then
+ report_initialization("unable to check path %a",p)
+ end
+ ownpath=p
end
+ break
+ end
end
- if not ownpath or ownpath=="" then
- ownpath="."
- report_initialization("forcing fallback to ownpath %a",ownpath)
- elseif trace_locating then
- report_initialization("using ownpath %a",ownpath)
- end
+ end
end
- environment.ownbin=ownbin
- environment.ownpath=ownpath
+ if not ownpath or ownpath=="" then
+ ownpath="."
+ report_initialization("forcing fallback to ownpath %a",ownpath)
+ elseif trace_locating then
+ report_initialization("using ownpath %a",ownpath)
+ end
+ end
+ environment.ownbin=ownbin
+ environment.ownpath=ownpath
end
resolvers.ownpath=environment.ownpath
function resolvers.getownpath()
- return environment.ownpath
+ return environment.ownpath
end
do
- local ownpath=environment.ownpath or dir.current()
- if ownpath then
- ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
- ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
- ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
- else
- report_initialization("error: unable to locate ownpath")
- os.exit()
- end
-end
-local texos=environment.texos or osgetenv("TEXOS")
+ local ownpath=environment.ownpath or dir.current()
+ if ownpath then
+ ossetenv('SELFAUTOLOC',file.collapsepath(ownpath))
+ ossetenv('SELFAUTODIR',file.collapsepath(ownpath.."/.."))
+ ossetenv('SELFAUTOPARENT',file.collapsepath(ownpath.."/../.."))
+ else
+ report_initialization("error: unable to locate ownpath")
+ os.exit()
+ end
+end
+local texos=environment.texos or osgetenv("TEXOS")
local texmfos=environment.texmfos or osgetenv('SELFAUTODIR')
if not texos or texos=="" then
- texos=file.basename(texmfos)
+ texos=file.basename(texmfos)
end
ossetenv('TEXMFOS',texmfos)
-ossetenv('TEXOS',texos)
-ossetenv('SELFAUTOSYSTEM',os.platform)
+ossetenv('TEXOS',texos)
+ossetenv('SELFAUTOSYSTEM',os.platform)
environment.texos=texos
environment.texmfos=texmfos
local texroot=environment.texroot or osgetenv("TEXROOT")
if not texroot or texroot=="" then
- texroot=osgetenv('SELFAUTOPARENT')
- ossetenv('TEXROOT',texroot)
+ texroot=osgetenv('SELFAUTOPARENT')
+ ossetenv('TEXROOT',texroot)
end
environment.texroot=file.collapsepath(texroot)
local prefixes=utilities.storage.allocate()
@@ -16418,30 +19992,30 @@ local resolved={}
local abstract={}
local dynamic={}
function resolvers.resetresolve(str)
- resolved,abstract={},{}
+ resolved,abstract={},{}
end
function resolvers.allprefixes(separator)
- local all=table.sortedkeys(prefixes)
- if separator then
- for i=1,#all do
- all[i]=all[i]..":"
- end
+ local all=table.sortedkeys(prefixes)
+ if separator then
+ for i=1,#all do
+ all[i]=all[i]..":"
end
- return all
+ end
+ return all
end
local function _resolve_(method,target)
- local action=prefixes[method]
- if action then
- return action(target)
- else
- return method..":"..target
- end
+ local action=prefixes[method]
+ if action then
+ return action(target)
+ else
+ return method..":"..target
+ end
end
function resolvers.unresolve(str)
- return abstract[str] or str
+ return abstract[str] or str
end
function resolvers.setdynamic(str)
- dynamic[str]=true
+ dynamic[str]=true
end
local pattern=Cs((C(R("az")^2)*P(":")*C((1-S(" \"\';,"))^1)/_resolve_+P(1))^0)
local prefix=C(R("az")^2)*P(":")
@@ -16450,65 +20024,65 @@ local notarget=(#S(";,")+P(-1))*Cc("")
local p_resolve=Cs(((prefix*(target+notarget))/_resolve_+P(1))^0)
local p_simple=prefix*P(-1)
local function resolve(str)
- if type(str)=="table" then
- local res={}
- for i=1,#str do
- res[i]=resolve(str[i])
- end
- return res
- end
- local res=resolved[str]
- if res then
- return res
+ if type(str)=="table" then
+ local res={}
+ for i=1,#str do
+ res[i]=resolve(str[i])
end
- local simple=lpegmatch(p_simple,str)
- local action=prefixes[simple]
- if action then
- local res=action(res)
- if not dynamic[simple] then
- resolved[simple]=res
- abstract[res]=simple
- end
- return res
+ return res
+ end
+ local res=resolved[str]
+ if res then
+ return res
+ end
+ local simple=lpegmatch(p_simple,str)
+ local action=prefixes[simple]
+ if action then
+ local res=action(res)
+ if not dynamic[simple] then
+ resolved[simple]=res
+ abstract[res]=simple
end
- res=lpegmatch(p_resolve,str)
- resolved[str]=res
- abstract[res]=str
return res
+ end
+ res=lpegmatch(p_resolve,str)
+ resolved[str]=res
+ abstract[res]=str
+ return res
end
resolvers.resolve=resolve
if type(osuname)=="function" then
- for k,v in next,osuname() do
- if not prefixes[k] then
- prefixes[k]=function() return v end
- end
+ for k,v in next,osuname() do
+ if not prefixes[k] then
+ prefixes[k]=function() return v end
end
+ end
end
if ostype=="unix" then
- local pattern
- local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
- local colon=P(":")
- for k,v in table.sortedpairs(prefixes) do
- if p then
- p=P(k)+p
- else
- p=P(k)
- end
- end
- pattern=Cs((p*colon+colon/";"+P(1))^0)
- end
- makepattern()
- table.setmetatablenewindex(prefixes,makepattern)
- function resolvers.repath(str)
- return lpegmatch(pattern,str)
+ local pattern
+ local function makepattern(t,k,v)
+ if t then
+ rawset(t,k,v)
+ end
+ local colon=P(":")
+ for k,v in table.sortedpairs(prefixes) do
+ if p then
+ p=P(k)+p
+ else
+ p=P(k)
+ end
end
+ pattern=Cs((p*colon+colon/";"+P(1))^0)
+ end
+ makepattern()
+ table.setmetatablenewindex(prefixes,makepattern)
+ function resolvers.repath(str)
+ return lpegmatch(pattern,str)
+ end
else
- function resolvers.repath(str)
- return str
- end
+ function resolvers.repath(str)
+ return str
+ end
end
@@ -16518,14 +20092,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-exp"] = package.loaded["data-exp"] or true
--- original size: 18105, stripped down to: 11207
+-- original size: 18105, stripped down to: 10389
if not modules then modules={} end modules ['data-exp']={
- 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 format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub
local concat,sort=table.concat,table.sort
@@ -16535,21 +20109,21 @@ local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S
local type,next=type,next
local isdir=lfs.isdir
local collapsepath,joinpath,basename=file.collapsepath,file.join,file.basename
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_globbing=true trackers.register("resolvers.globbing",function(v) trace_globbing=v end)
local report_expansions=logs.reporter("resolvers","expansions")
local report_globbing=logs.reporter("resolvers","globbing")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
local function f_both(a,b)
- local t,n={},0
- for sb in gmatch(b,"[^,]+") do
- for sa in gmatch(a,"[^,]+") do
- n=n+1;t[n]=sa..sb
- end
+ local t,n={},0
+ for sb in gmatch(b,"[^,]+") do
+ for sa in gmatch(a,"[^,]+") do
+ n=n+1;t[n]=sa..sb
end
- return concat(t,",")
+ end
+ return concat(t,",")
end
local comma=P(",")
local nocomma=(1-comma)^1
@@ -16559,7 +20133,7 @@ local after=Cs((Carg(1)*nocomma+docomma)^0)
local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0)
local function f_first (a,b) return lpegmatch(after,b,1,a) end
local function f_second(a,b) return lpegmatch(before,a,1,b) end
-local function f_both (a,b) return lpegmatch(both,b,1,a) end
+local function f_both (a,b) return lpegmatch(both,b,1,a) end
local left=P("{")
local right=P("}")
local var=P((1-S("{}" ))^0)
@@ -16572,141 +20146,141 @@ local l_rest=Cs((left*var*(left/"")*var*(right/"")*var*right+other )^0 )
local stripper_1=lpeg.stripper ("{}@")
local replacer_1=lpeg.replacer { { ",}",",@}" },{ "{,","{@," },}
local function splitpathexpr(str,newlist,validate)
- if trace_expansions then
- report_expansions("expanding variable %a",str)
- end
- local t,ok,done=newlist or {},false,false
- local n=#t
- str=lpegmatch(replacer_1,str)
+ if trace_expansions then
+ report_expansions("expanding variable %a",str)
+ end
+ local t,ok,done=newlist or {},false,false
+ local n=#t
+ str=lpegmatch(replacer_1,str)
+ repeat
+ local old=str
repeat
- local old=str
- repeat
- local old=str
- str=lpegmatch(l_first,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_second,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_both,str)
- until old==str
- repeat
- local old=str
- str=lpegmatch(l_rest,str)
- until old==str
- until old==str
- str=lpegmatch(stripper_1,str)
- if validate then
- for s in gmatch(str,"[^,]+") do
- s=validate(s)
- if s then
- n=n+1
- t[n]=s
- end
- end
- else
- for s in gmatch(str,"[^,]+") do
- n=n+1
- t[n]=s
- end
+ local old=str
+ str=lpegmatch(l_first,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_second,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_both,str)
+ until old==str
+ repeat
+ local old=str
+ str=lpegmatch(l_rest,str)
+ until old==str
+ until old==str
+ str=lpegmatch(stripper_1,str)
+ if validate then
+ for s in gmatch(str,"[^,]+") do
+ s=validate(s)
+ if s then
+ n=n+1
+ t[n]=s
+ end
end
- if trace_expansions then
- for k=1,#t do
- report_expansions("% 4i: %s",k,t[k])
- end
+ else
+ for s in gmatch(str,"[^,]+") do
+ n=n+1
+ t[n]=s
end
- return t
+ end
+ if trace_expansions then
+ for k=1,#t do
+ report_expansions("% 4i: %s",k,t[k])
+ end
+ end
+ return t
end
local function validate(s)
- s=collapsepath(s)
- return s~="" and not find(s,"^!*unset/*$") and s
+ s=collapsepath(s)
+ return s~="" and not find(s,"^!*unset/*$") and s
end
resolvers.validatedpath=validate
function resolvers.expandedpathfromlist(pathlist)
- local newlist={}
- for k=1,#pathlist do
- splitpathexpr(pathlist[k],newlist,validate)
- end
- return newlist
+ local newlist={}
+ for k=1,#pathlist do
+ splitpathexpr(pathlist[k],newlist,validate)
+ end
+ return newlist
end
local usedhomedir=nil
-local donegation=(P("!")/"" )^0
+local donegation=(P("!")/"" )^0
local doslashes=(P("\\")/"/"+1)^0
local function expandedhome()
- if not usedhomedir then
- usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
- if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
- if trace_expansions then
- report_expansions("no home dir set, ignoring dependent path using current path")
- end
- usedhomedir="."
- end
+ if not usedhomedir then
+ usedhomedir=lpegmatch(Cs(donegation*doslashes),environment.homedir or "")
+ if usedhomedir=="~" or usedhomedir=="" or not isdir(usedhomedir) then
+ if trace_expansions then
+ report_expansions("no home dir set, ignoring dependent path using current path")
+ end
+ usedhomedir="."
end
- return usedhomedir
+ end
+ return usedhomedir
end
local dohome=((P("~")+P("$HOME")+P("%HOME%"))/expandedhome)^0
local cleanup=Cs(donegation*dohome*doslashes)
resolvers.cleanpath=function(str)
- return str and lpegmatch(cleanup,str) or ""
+ return str and lpegmatch(cleanup,str) or ""
end
local expandhome=P("~")/"$HOME"
local dodouble=P('"')/""*(expandhome+(1-P('"')))^0*P('"')/""
local dosingle=P("'")/""*(expandhome+(1-P("'")))^0*P("'")/""
-local dostring=(expandhome+1 )^0
+local dostring=(expandhome+1 )^0
local stripper=Cs(
- lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
+ lpegpatterns.unspacer*(dosingle+dodouble+dostring)*lpegpatterns.unspacer
)
function resolvers.checkedvariable(str)
- return type(str)=="string" and lpegmatch(stripper,str) or str
+ return type(str)=="string" and lpegmatch(stripper,str) or str
end
local cache={}
local splitter=lpeg.tsplitat(";")
local backslashswapper=lpeg.replacer("\\","/")
local function splitconfigurationpath(str)
- if str then
- local found=cache[str]
- if not found then
- if str=="" then
- found={}
- else
- local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
- found={}
- local noffound=0
- for i=1,#split do
- local s=split[i]
- if not find(s,"^{*unset}*") then
- noffound=noffound+1
- found[noffound]=s
- end
- end
- if trace_expansions then
- report_expansions("splitting path specification %a",str)
- for k=1,noffound do
- report_expansions("% 4i: %s",k,found[k])
- end
- end
- cache[str]=found
- end
+ if str then
+ local found=cache[str]
+ if not found then
+ if str=="" then
+ found={}
+ else
+ local split=lpegmatch(splitter,lpegmatch(backslashswapper,str))
+ found={}
+ local noffound=0
+ for i=1,#split do
+ local s=split[i]
+ if not find(s,"^{*unset}*") then
+ noffound=noffound+1
+ found[noffound]=s
+ end
end
- return found
+ if trace_expansions then
+ report_expansions("splitting path specification %a",str)
+ for k=1,noffound do
+ report_expansions("% 4i: %s",k,found[k])
+ end
+ end
+ cache[str]=found
+ end
end
+ return found
+ end
end
resolvers.splitconfigurationpath=splitconfigurationpath
function resolvers.splitpath(str)
- if type(str)=='table' then
- return str
- else
- return splitconfigurationpath(str)
- end
+ if type(str)=='table' then
+ return str
+ else
+ return splitconfigurationpath(str)
+ end
end
function resolvers.joinpath(str)
- if type(str)=='table' then
- return joinpath(str)
- else
- return str
- end
+ if type(str)=='table' then
+ return joinpath(str)
+ else
+ return str
+ end
end
local attributes,directory=lfs.attributes,lfs.dir
local weird=P(".")^1+lpeg.anywhere(S("~`!#$%^&*()={}[]:;\"\'||<>,?\n\r\t"))
@@ -16719,201 +20293,201 @@ local fullcache={}
local nofsharedscans=0
local addcasecraptoo=true
local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant)
- local full=path=="" and spec or (spec..path..'/')
- local dirlist={}
- local nofdirs=0
- local pattern=tolerant and lessweird or weird
- local filelist={}
- local noffiles=0
- for name in directory(full) do
- if not lpegmatch(pattern,name) then
- local mode=attributes(full..name,"mode")
- if mode=="file" then
- n=n+1
- noffiles=noffiles+1
- filelist[noffiles]=name
- elseif mode=="directory" then
- m=m+1
- nofdirs=nofdirs+1
- if path~="" then
- dirlist[nofdirs]=path.."/"..name
- else
- dirlist[nofdirs]=name
- end
- end
+ local full=path=="" and spec or (spec..path..'/')
+ local dirlist={}
+ local nofdirs=0
+ local pattern=tolerant and lessweird or weird
+ local filelist={}
+ local noffiles=0
+ for name in directory(full) do
+ if not lpegmatch(pattern,name) then
+ local mode=attributes(full..name,"mode")
+ if mode=="file" then
+ n=n+1
+ noffiles=noffiles+1
+ filelist[noffiles]=name
+ elseif mode=="directory" then
+ m=m+1
+ nofdirs=nofdirs+1
+ if path~="" then
+ dirlist[nofdirs]=path.."/"..name
+ else
+ dirlist[nofdirs]=name
end
+ end
end
- if noffiles>0 then
- sort(filelist)
- for i=1,noffiles do
- local name=filelist[i]
- local lower=lower(name)
- local paths=files[lower]
- if paths then
- if onlyone then
- else
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- if addcasecraptoo then
- local paths=files[name]
- if not paths then
- files[name]=path
- elseif type(paths)=="string" then
- files[name]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- end
- if type(paths)=="string" then
- files[lower]={ paths,path }
- else
- paths[#paths+1]=path
- end
- end
- else
- files[lower]=path
- if name~=lower then
- local rl=remap[lower]
- if not rl then
- remap[lower]=name
- r=r+1
- elseif trace_globbing and rl~=name then
- report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
- end
- end
+ end
+ if noffiles>0 then
+ sort(filelist)
+ for i=1,noffiles do
+ local name=filelist[i]
+ local lower=lower(name)
+ local paths=files[lower]
+ if paths then
+ if onlyone then
+ else
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
+ if addcasecraptoo then
+ local paths=files[name]
+ if not paths then
+ files[name]=path
+ elseif type(paths)=="string" then
+ files[name]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
+ end
+ if type(paths)=="string" then
+ files[lower]={ paths,path }
+ else
+ paths[#paths+1]=path
+ end
end
- end
- if nofdirs>0 then
- sort(dirlist)
- for i=1,nofdirs do
- files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
+ else
+ files[lower]=path
+ if name~=lower then
+ local rl=remap[lower]
+ if not rl then
+ remap[lower]=name
+ r=r+1
+ elseif trace_globbing and rl~=name then
+ report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl)
+ end
end
+ end
+ end
+ end
+ if nofdirs>0 then
+ sort(dirlist)
+ for i=1,nofdirs do
+ files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant)
end
- scancache[sub(full,1,-2)]=files
- return files,remap,n,m,r
+ end
+ scancache[sub(full,1,-2)]=files
+ return files,remap,n,m,r
end
function resolvers.scanfiles(path,branch,usecache,onlyonce,tolerant)
- local realpath=resolveprefix(path)
- if usecache then
- local content=fullcache[realpath]
- if content then
- if trace_locating then
- report_expansions("using cached scan of path %a, branch %a",path,branch or path)
- end
- nofsharedscans=nofsharedscans+1
- return content
- end
- end
- statistics.starttiming(timer)
+ local realpath=resolveprefix(path)
+ if usecache then
+ local content=fullcache[realpath]
+ if content then
+ if trace_locating then
+ report_expansions("using cached scan of path %a, branch %a",path,branch or path)
+ end
+ nofsharedscans=nofsharedscans+1
+ return content
+ end
+ end
+ statistics.starttiming(timer)
+ if trace_locating then
+ report_expansions("scanning path %a, branch %a",path,branch or path)
+ end
+ local content
+ if isdir(realpath) then
+ local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
+ content={
+ metadata={
+ path=path,
+ files=n,
+ directories=m,
+ remappings=r,
+ },
+ files=files,
+ remap=remap,
+ }
if trace_locating then
- report_expansions("scanning path %a, branch %a",path,branch or path)
+ report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
end
- local content
- if isdir(realpath) then
- local files,remap,n,m,r=scan({},{},realpath..'/',"",0,0,0,onlyonce,tolerant)
- content={
- metadata={
- path=path,
- files=n,
- directories=m,
- remappings=r,
- },
- files=files,
- remap=remap,
- }
- if trace_locating then
- report_expansions("%s files found on %s directories with %s uppercase remappings",n,m,r)
- end
- else
- content={
- metadata={
- path=path,
- files=0,
- directories=0,
- remappings=0,
- },
- files={},
- remap={},
- }
- if trace_locating then
- report_expansions("invalid path %a",realpath)
- end
- end
- if usecache then
- scanned[#scanned+1]=realpath
- fullcache[realpath]=content
+ else
+ content={
+ metadata={
+ path=path,
+ files=0,
+ directories=0,
+ remappings=0,
+ },
+ files={},
+ remap={},
+ }
+ if trace_locating then
+ report_expansions("invalid path %a",realpath)
end
- nofscans=nofscans+1
- statistics.stoptiming(timer)
- return content
+ end
+ if usecache then
+ scanned[#scanned+1]=realpath
+ fullcache[realpath]=content
+ end
+ nofscans=nofscans+1
+ statistics.stoptiming(timer)
+ return content
end
function resolvers.simplescanfiles(path,branch,usecache)
- return resolvers.scanfiles(path,branch,usecache,true,true)
+ return resolvers.scanfiles(path,branch,usecache,true,true)
end
function resolvers.scandata()
- table.sort(scanned)
- return {
- n=nofscans,
- shared=nofsharedscans,
- time=statistics.elapsedtime(timer),
- paths=scanned,
- }
+ table.sort(scanned)
+ return {
+ n=nofscans,
+ shared=nofsharedscans,
+ time=statistics.elapsedtime(timer),
+ paths=scanned,
+ }
end
function resolvers.get_from_content(content,path,name)
- if not content then
- return
- end
- local files=content.files
- if not files then
- return
- end
- local remap=content.remap
- if not remap then
- return
- end
- if name then
- local used=lower(name)
- return path,remap[used] or used
- else
- local name=path
- local used=lower(name)
- local path=files[used]
- if path then
- return path,remap[used] or used
- end
- end
+ if not content then
+ return
+ end
+ local files=content.files
+ if not files then
+ return
+ end
+ local remap=content.remap
+ if not remap then
+ return
+ end
+ if name then
+ local used=lower(name)
+ return path,remap[used] or used
+ else
+ local name=path
+ local used=lower(name)
+ local path=files[used]
+ if path then
+ return path,remap[used] or used
+ end
+ end
end
local nothing=function() end
function resolvers.filtered_from_content(content,pattern)
- if content and type(pattern)=="string" then
- local pattern=lower(pattern)
- local files=content.files
- local remap=content.remap
- if files and remap then
- local f=sortedkeys(files)
- local n=#f
- local i=0
- local function iterator()
- while i<n do
- i=i+1
- local k=f[i]
- if find(k,pattern) then
- return files[k],remap and remap[k] or k
- end
- end
- end
- return iterator
+ if content and type(pattern)=="string" then
+ local pattern=lower(pattern)
+ local files=content.files
+ local remap=content.remap
+ if files and remap then
+ local f=sortedkeys(files)
+ local n=#f
+ local i=0
+ local function iterator()
+ while i<n do
+ i=i+1
+ local k=f[i]
+ if find(k,pattern) then
+ return files[k],remap and remap[k] or k
+ end
end
+ end
+ return iterator
end
- return nothing
+ end
+ return nothing
end
@@ -16923,14 +20497,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-env"] = package.loaded["data-env"] or true
--- original size: 9360, stripped down to: 6903
+-- original size: 9360, stripped down to: 6312
if not modules then modules={} end modules ['data-env']={
- 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 lower,gsub=string.lower,string.gsub
local next=next
@@ -16950,255 +20524,255 @@ resolvers.suffixmap=suffixmap
resolvers.usertypes=usertypes
local luasuffixes=utilities.lua.suffixes
local relations=allocate {
- core={
- ofm={
- names={ "ofm","omega font metric","omega font metrics" },
- variable='OFMFONTS',
- suffixes={ 'ofm','tfm' },
- },
- ovf={
- names={ "ovf","omega virtual font","omega virtual fonts" },
- variable='OVFFONTS',
- suffixes={ 'ovf','vf' },
- },
- tfm={
- names={ "tfm","tex font metric","tex font metrics" },
- variable='TFMFONTS',
- suffixes={ 'tfm' },
- },
- vf={
- names={ "vf","virtual font","virtual fonts" },
- variable='VFFONTS',
- suffixes={ 'vf' },
- },
- otf={
- names={ "otf","opentype","opentype font","opentype fonts"},
- variable='OPENTYPEFONTS',
- suffixes={ 'otf' },
- },
- ttf={
- names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
- variable='TTFONTS',
- suffixes={ 'ttf','ttc','dfont' },
- },
- afm={
- names={ "afm","adobe font metric","adobe font metrics" },
- variable="AFMFONTS",
- suffixes={ "afm" },
- },
- pfb={
- names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
- variable='T1FONTS',
- suffixes={ 'pfb','pfa' },
- },
- fea={
- names={ "fea","font feature","font features","font feature file","font feature files" },
- variable='FONTFEATURES',
- suffixes={ 'fea' },
- },
- cid={
- names={ "cid","cid map","cid maps","cid file","cid files" },
- variable='FONTCIDMAPS',
- suffixes={ 'cid','cidmap' },
- },
- fmt={
- names={ "fmt","format","tex format" },
- variable='TEXFORMATS',
- suffixes={ 'fmt' },
- },
- mem={
- names={ 'mem',"metapost format" },
- variable='MPMEMS',
- suffixes={ 'mem' },
- },
- mp={
- names={ "mp" },
- variable='MPINPUTS',
- suffixes={ 'mp','mpvi','mpiv','mpii' },
- usertype=true,
- },
- tex={
- names={ "tex" },
- variable='TEXINPUTS',
- suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
- usertype=true,
- },
- icc={
- names={ "icc","icc profile","icc profiles" },
- variable='ICCPROFILES',
- suffixes={ 'icc' },
- },
- texmfscripts={
- names={ "texmfscript","texmfscripts","script","scripts" },
- variable='TEXMFSCRIPTS',
- suffixes={ 'lua','rb','pl','py' },
- },
- lua={
- names={ "lua" },
- variable='LUAINPUTS',
- suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
- usertype=true,
- },
- lib={
- names={ "lib" },
- variable='CLUAINPUTS',
- suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
- },
- bib={
- names={ 'bib' },
- variable='BIBINPUTS',
- suffixes={ 'bib' },
- usertype=true,
- },
- bst={
- names={ 'bst' },
- variable='BSTINPUTS',
- suffixes={ 'bst' },
- usertype=true,
- },
- fontconfig={
- names={ 'fontconfig','fontconfig file','fontconfig files' },
- variable='FONTCONFIG_PATH',
- },
- pk={
- names={ "pk" },
- variable='PKFONTS',
- suffixes={ 'pk' },
- },
+ core={
+ ofm={
+ names={ "ofm","omega font metric","omega font metrics" },
+ variable='OFMFONTS',
+ suffixes={ 'ofm','tfm' },
+ },
+ ovf={
+ names={ "ovf","omega virtual font","omega virtual fonts" },
+ variable='OVFFONTS',
+ suffixes={ 'ovf','vf' },
+ },
+ tfm={
+ names={ "tfm","tex font metric","tex font metrics" },
+ variable='TFMFONTS',
+ suffixes={ 'tfm' },
+ },
+ vf={
+ names={ "vf","virtual font","virtual fonts" },
+ variable='VFFONTS',
+ suffixes={ 'vf' },
+ },
+ otf={
+ names={ "otf","opentype","opentype font","opentype fonts"},
+ variable='OPENTYPEFONTS',
+ suffixes={ 'otf' },
+ },
+ ttf={
+ names={ "ttf","truetype","truetype font","truetype fonts","truetype collection","truetype collections","truetype dictionary","truetype dictionaries" },
+ variable='TTFONTS',
+ suffixes={ 'ttf','ttc','dfont' },
+ },
+ afm={
+ names={ "afm","adobe font metric","adobe font metrics" },
+ variable="AFMFONTS",
+ suffixes={ "afm" },
+ },
+ pfb={
+ names={ "pfb","type1","type 1","type1 font","type 1 font","type1 fonts","type 1 fonts" },
+ variable='T1FONTS',
+ suffixes={ 'pfb','pfa' },
+ },
+ fea={
+ names={ "fea","font feature","font features","font feature file","font feature files" },
+ variable='FONTFEATURES',
+ suffixes={ 'fea' },
+ },
+ cid={
+ names={ "cid","cid map","cid maps","cid file","cid files" },
+ variable='FONTCIDMAPS',
+ suffixes={ 'cid','cidmap' },
+ },
+ fmt={
+ names={ "fmt","format","tex format" },
+ variable='TEXFORMATS',
+ suffixes={ 'fmt' },
+ },
+ mem={
+ names={ 'mem',"metapost format" },
+ variable='MPMEMS',
+ suffixes={ 'mem' },
+ },
+ mp={
+ names={ "mp" },
+ variable='MPINPUTS',
+ suffixes={ 'mp','mpvi','mpiv','mpii' },
+ usertype=true,
+ },
+ tex={
+ names={ "tex" },
+ variable='TEXINPUTS',
+ suffixes={ "tex","mkvi","mkiv","mkii","cld","lfg","xml" },
+ usertype=true,
+ },
+ icc={
+ names={ "icc","icc profile","icc profiles" },
+ variable='ICCPROFILES',
+ suffixes={ 'icc' },
+ },
+ texmfscripts={
+ names={ "texmfscript","texmfscripts","script","scripts" },
+ variable='TEXMFSCRIPTS',
+ suffixes={ 'lua','rb','pl','py' },
+ },
+ lua={
+ names={ "lua" },
+ variable='LUAINPUTS',
+ suffixes={ luasuffixes.lua,luasuffixes.luc,luasuffixes.tma,luasuffixes.tmc },
+ usertype=true,
},
- obsolete={
- enc={
- names={ "enc","enc files","enc file","encoding files","encoding file" },
- variable='ENCFONTS',
- suffixes={ 'enc' },
- },
- map={
- names={ "map","map files","map file" },
- variable='TEXFONTMAPS',
- suffixes={ 'map' },
- },
- lig={
- names={ "lig files","lig file","ligature file","ligature files" },
- variable='LIGFONTS',
- suffixes={ 'lig' },
- },
- opl={
- names={ "opl" },
- variable='OPLFONTS',
- suffixes={ 'opl' },
- },
- ovp={
- names={ "ovp" },
- variable='OVPFONTS',
- suffixes={ 'ovp' },
- },
+ lib={
+ names={ "lib" },
+ variable='CLUAINPUTS',
+ suffixes=os.libsuffix and { os.libsuffix } or { 'dll','so' },
},
- kpse={
- base={
- names={ 'base',"metafont format" },
- variable='MFBASES',
- suffixes={ 'base','bas' },
- },
- cmap={
- names={ 'cmap','cmap files','cmap file' },
- variable='CMAPFONTS',
- suffixes={ 'cmap' },
- },
- cnf={
- names={ 'cnf' },
- suffixes={ 'cnf' },
- },
- web={
- names={ 'web' },
- suffixes={ 'web','ch' }
- },
- cweb={
- names={ 'cweb' },
- suffixes={ 'w','web','ch' },
- },
- gf={
- names={ 'gf' },
- suffixes={ '<resolution>gf' },
- },
- mf={
- names={ 'mf' },
- variable='MFINPUTS',
- suffixes={ 'mf' },
- },
- mft={
- names={ 'mft' },
- suffixes={ 'mft' },
- },
- pk={
- names={ 'pk' },
- suffixes={ '<resolution>pk' },
- },
+ bib={
+ names={ 'bib' },
+ variable='BIBINPUTS',
+ suffixes={ 'bib' },
+ usertype=true,
},
+ bst={
+ names={ 'bst' },
+ variable='BSTINPUTS',
+ suffixes={ 'bst' },
+ usertype=true,
+ },
+ fontconfig={
+ names={ 'fontconfig','fontconfig file','fontconfig files' },
+ variable='FONTCONFIG_PATH',
+ },
+ pk={
+ names={ "pk" },
+ variable='PKFONTS',
+ suffixes={ 'pk' },
+ },
+ },
+ obsolete={
+ enc={
+ names={ "enc","enc files","enc file","encoding files","encoding file" },
+ variable='ENCFONTS',
+ suffixes={ 'enc' },
+ },
+ map={
+ names={ "map","map files","map file" },
+ variable='TEXFONTMAPS',
+ suffixes={ 'map' },
+ },
+ lig={
+ names={ "lig files","lig file","ligature file","ligature files" },
+ variable='LIGFONTS',
+ suffixes={ 'lig' },
+ },
+ opl={
+ names={ "opl" },
+ variable='OPLFONTS',
+ suffixes={ 'opl' },
+ },
+ ovp={
+ names={ "ovp" },
+ variable='OVPFONTS',
+ suffixes={ 'ovp' },
+ },
+ },
+ kpse={
+ base={
+ names={ 'base',"metafont format" },
+ variable='MFBASES',
+ suffixes={ 'base','bas' },
+ },
+ cmap={
+ names={ 'cmap','cmap files','cmap file' },
+ variable='CMAPFONTS',
+ suffixes={ 'cmap' },
+ },
+ cnf={
+ names={ 'cnf' },
+ suffixes={ 'cnf' },
+ },
+ web={
+ names={ 'web' },
+ suffixes={ 'web','ch' }
+ },
+ cweb={
+ names={ 'cweb' },
+ suffixes={ 'w','web','ch' },
+ },
+ gf={
+ names={ 'gf' },
+ suffixes={ '<resolution>gf' },
+ },
+ mf={
+ names={ 'mf' },
+ variable='MFINPUTS',
+ suffixes={ 'mf' },
+ },
+ mft={
+ names={ 'mft' },
+ suffixes={ 'mft' },
+ },
+ pk={
+ names={ 'pk' },
+ suffixes={ '<resolution>pk' },
+ },
+ },
}
resolvers.relations=relations
function resolvers.updaterelations()
- for category,categories in next,relations do
- for name,relation in next,categories do
- local rn=relation.names
- local rv=relation.variable
- if rn and rv then
- local rs=relation.suffixes
- local ru=relation.usertype
- for i=1,#rn do
- local rni=lower(gsub(rn[i]," ",""))
- formats[rni]=rv
- if rs then
- suffixes[rni]=rs
- for i=1,#rs do
- local rsi=rs[i]
- suffixmap[rsi]=rni
- end
- end
- end
- if ru then
- usertypes[name]=true
- end
+ for category,categories in next,relations do
+ for name,relation in next,categories do
+ local rn=relation.names
+ local rv=relation.variable
+ if rn and rv then
+ local rs=relation.suffixes
+ local ru=relation.usertype
+ for i=1,#rn do
+ local rni=lower(gsub(rn[i]," ",""))
+ formats[rni]=rv
+ if rs then
+ suffixes[rni]=rs
+ for i=1,#rs do
+ local rsi=rs[i]
+ suffixmap[rsi]=rni
end
+ end
+ end
+ if ru then
+ usertypes[name]=true
end
+ end
end
+ end
end
resolvers.updaterelations()
local function simplified(t,k)
- return k and rawget(t,lower(gsub(k," ",""))) or nil
+ return k and rawget(t,lower(gsub(k," ",""))) or nil
end
setmetatableindex(formats,simplified)
setmetatableindex(suffixes,simplified)
setmetatableindex(suffixmap,simplified)
function resolvers.suffixofformat(str)
- local s=suffixes[str]
- return s and s[1] or ""
+ local s=suffixes[str]
+ return s and s[1] or ""
end
function resolvers.suffixofformat(str)
- return suffixes[str] or {}
+ return suffixes[str] or {}
end
for name,format in next,formats do
- dangerous[name]=true
+ dangerous[name]=true
end
dangerous.tex=nil
function resolvers.formatofvariable(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.formatofsuffix(str)
- return suffixmap[suffixonly(str)] or 'tex'
+ return suffixmap[suffixonly(str)] or 'tex'
end
function resolvers.variableofformat(str)
- return formats[str] or ''
+ return formats[str] or ''
end
function resolvers.variableofformatorsuffix(str)
- local v=formats[str]
- if v then
- return v
- end
- v=suffixmap[suffixonly(str)]
- if v then
- return formats[v]
- end
- return ''
+ local v=formats[str]
+ if v then
+ return v
+ end
+ v=suffixmap[suffixonly(str)]
+ if v then
+ return formats[v]
+ end
+ return ''
end
@@ -17208,14 +20782,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16116, stripped down to: 11459
+-- original size: 16116, stripped down to: 10782
if not modules then modules={} end modules ['data-tmp']={
- 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,concat=string.format,string.lower,string.gsub,table.concat
local concat=table.concat
@@ -17223,19 +20797,19 @@ local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile
local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable
local formatters=string.formatters
local next,type=next,type
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
-local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end)
local report_caches=logs.reporter("resolvers","caches")
local report_resolvers=logs.reporter("resolvers","caching")
local resolvers=resolvers
local cleanpath=resolvers.cleanpath
-local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
-local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
+local directive_cleanup=false directives.register("system.compile.cleanup",function(v) directive_cleanup=v end)
+local directive_strip=false directives.register("system.compile.strip",function(v) directive_strip=v end)
local compile=utilities.lua.compile
function utilities.lua.compile(luafile,lucfile,cleanup,strip)
- if cleanup==nil then cleanup=directive_cleanup end
- if strip==nil then strip=directive_strip end
- return compile(luafile,lucfile,cleanup,strip)
+ if cleanup==nil then cleanup=directive_cleanup end
+ if strip==nil then strip=directive_strip end
+ return compile(luafile,lucfile,cleanup,strip)
end
caches=caches or {}
local caches=caches
@@ -17250,324 +20824,324 @@ caches.relocate=false
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local writable,readables,usedreadables=nil,{},{}
local function identify()
- local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- cachepath=file.collapsepath(cachepath)
- local valid=isdir(cachepath)
- if valid then
- if is_readable(cachepath) then
- readables[#readables+1]=cachepath
- if not writable and is_writable(cachepath) then
- writable=cachepath
- end
- end
- elseif not writable and caches.force then
- local cacheparent=file.dirname(cachepath)
- if is_writable(cacheparent) and true then
- if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
- mkdirs(cachepath)
- if isdir(cachepath) and is_writable(cachepath) then
- report_caches("path %a created",cachepath)
- writable=cachepath
- readables[#readables+1]=cachepath
- end
- end
- end
- end
+ local texmfcaches=resolvers.cleanpathlist("TEXMFCACHE")
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ cachepath=file.collapsepath(cachepath)
+ local valid=isdir(cachepath)
+ if valid then
+ if is_readable(cachepath) then
+ readables[#readables+1]=cachepath
+ if not writable and is_writable(cachepath) then
+ writable=cachepath
end
- end
- end
- local texmfcaches=caches.defaults
- if texmfcaches then
- for k=1,#texmfcaches do
- local cachepath=texmfcaches[k]
- cachepath=resolvers.expansion(cachepath)
- if cachepath~="" then
- cachepath=resolvers.resolve(cachepath)
- cachepath=resolvers.cleanpath(cachepath)
- local valid=isdir(cachepath)
- if valid and is_readable(cachepath) then
- if not writable and is_writable(cachepath) then
- readables[#readables+1]=cachepath
- writable=cachepath
- break
- end
- end
+ end
+ elseif not writable and caches.force then
+ local cacheparent=file.dirname(cachepath)
+ if is_writable(cacheparent) and true then
+ if not caches.ask or io.ask(format("\nShould I create the cache path %s?",cachepath),"no",{ "yes","no" })=="yes" then
+ mkdirs(cachepath)
+ if isdir(cachepath) and is_writable(cachepath) then
+ report_caches("path %a created",cachepath)
+ writable=cachepath
+ readables[#readables+1]=cachepath
+ end
end
+ end
end
+ end
end
- if not writable then
- report_caches("fatal error: there is no valid writable cache path defined")
- os.exit()
- elseif #readables==0 then
- report_caches("fatal error: there is no valid readable cache path defined")
- os.exit()
- end
- writable=dir.expandname(resolvers.cleanpath(writable))
- local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
- if tree then
- caches.tree=tree
- writable=mkdirs(writable,base,more,tree)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more,tree)
- end
- else
- writable=mkdirs(writable,base,more)
- for i=1,#readables do
- readables[i]=file.join(readables[i],base,more)
+ end
+ local texmfcaches=caches.defaults
+ if texmfcaches then
+ for k=1,#texmfcaches do
+ local cachepath=texmfcaches[k]
+ cachepath=resolvers.expansion(cachepath)
+ if cachepath~="" then
+ cachepath=resolvers.resolve(cachepath)
+ cachepath=resolvers.cleanpath(cachepath)
+ local valid=isdir(cachepath)
+ if valid and is_readable(cachepath) then
+ if not writable and is_writable(cachepath) then
+ readables[#readables+1]=cachepath
+ writable=cachepath
+ break
+ end
end
+ end
end
- if trace_cache then
- for i=1,#readables do
- report_caches("using readable path %a (order %s)",readables[i],i)
- end
- report_caches("using writable path %a",writable)
+ end
+ if not writable then
+ report_caches("fatal error: there is no valid writable cache path defined")
+ os.exit()
+ elseif #readables==0 then
+ report_caches("fatal error: there is no valid readable cache path defined")
+ os.exit()
+ end
+ writable=dir.expandname(resolvers.cleanpath(writable))
+ local base,more,tree=caches.base,caches.more,caches.tree or caches.treehash()
+ if tree then
+ caches.tree=tree
+ writable=mkdirs(writable,base,more,tree)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more,tree)
end
- identify=function()
- return writable,readables
+ else
+ writable=mkdirs(writable,base,more)
+ for i=1,#readables do
+ readables[i]=file.join(readables[i],base,more)
end
+ end
+ if trace_cache then
+ for i=1,#readables do
+ report_caches("using readable path %a (order %s)",readables[i],i)
+ end
+ report_caches("using writable path %a",writable)
+ end
+ identify=function()
return writable,readables
+ end
+ return writable,readables
end
function caches.usedpaths(separator)
- local writable,readables=identify()
- if #readables>1 then
- local result={}
- local done={}
- for i=1,#readables do
- local readable=readables[i]
- if readable==writable then
- done[readable]=true
- result[#result+1]=formatters["readable+writable: %a"](readable)
- elseif usedreadables[i] then
- done[readable]=true
- result[#result+1]=formatters["readable: %a"](readable)
- end
- end
- if not done[writable] then
- result[#result+1]=formatters["writable: %a"](writable)
- end
- return concat(result,separator or " | ")
- else
- return writable or "?"
+ local writable,readables=identify()
+ if #readables>1 then
+ local result={}
+ local done={}
+ for i=1,#readables do
+ local readable=readables[i]
+ if readable==writable then
+ done[readable]=true
+ result[#result+1]=formatters["readable+writable: %a"](readable)
+ elseif usedreadables[i] then
+ done[readable]=true
+ result[#result+1]=formatters["readable: %a"](readable)
+ end
end
+ if not done[writable] then
+ result[#result+1]=formatters["writable: %a"](writable)
+ end
+ return concat(result,separator or " | ")
+ else
+ return writable or "?"
+ end
end
function caches.configfiles()
- return concat(resolvers.configurationfiles(),";")
+ return concat(resolvers.configurationfiles(),";")
end
function caches.hashed(tree)
- tree=gsub(tree,"[\\/]+$","")
- tree=lower(tree)
- local hash=md5.hex(tree)
- if trace_cache or trace_locating then
- report_caches("hashing tree %a, hash %a",tree,hash)
- end
- return hash
+ tree=gsub(tree,"[\\/]+$","")
+ tree=lower(tree)
+ local hash=md5.hex(tree)
+ if trace_cache or trace_locating then
+ report_caches("hashing tree %a, hash %a",tree,hash)
+ end
+ return hash
end
function caches.treehash()
- local tree=caches.configfiles()
- if not tree or tree=="" then
- return false
- else
- return caches.hashed(tree)
- end
+ local tree=caches.configfiles()
+ if not tree or tree=="" then
+ return false
+ else
+ return caches.hashed(tree)
+ end
end
local r_cache,w_cache={},{}
local function getreadablepaths(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=r_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done={}
- for i=1,#readables do
- done[i]=file.join(readables[i],...)
- end
- else
- done=readables
- end
- r_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=r_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done={}
+ for i=1,#readables do
+ done[i]=file.join(readables[i],...)
+ end
+ else
+ done=readables
end
- return done
+ r_cache[hash]=done
+ end
+ return done
end
local function getwritablepath(...)
- local tags={... }
- local hash=concat(tags,"/")
- local done=w_cache[hash]
- if not done then
- local writable,readables=identify()
- if #tags>0 then
- done=mkdirs(writable,...)
- else
- done=writable
- end
- w_cache[hash]=done
+ local tags={... }
+ local hash=concat(tags,"/")
+ local done=w_cache[hash]
+ if not done then
+ local writable,readables=identify()
+ if #tags>0 then
+ done=mkdirs(writable,...)
+ else
+ done=writable
end
- return done
+ w_cache[hash]=done
+ end
+ return done
end
caches.getreadablepaths=getreadablepaths
caches.getwritablepath=getwritablepath
function caches.getfirstreadablefile(filename,...)
- local fullname,path=caches.setfirstwritablefile(filename,...)
+ local fullname,path=caches.setfirstwritablefile(filename,...)
+ if is_readable(fullname) then
+ return fullname,path
+ end
+ local rd=getreadablepaths(...)
+ for i=1,#rd do
+ local path=rd[i]
+ local fullname=file.join(path,filename)
if is_readable(fullname) then
- return fullname,path
- end
- local rd=getreadablepaths(...)
- for i=1,#rd do
- local path=rd[i]
- local fullname=file.join(path,filename)
- if is_readable(fullname) then
- usedreadables[i]=true
- return fullname,path
- end
+ usedreadables[i]=true
+ return fullname,path
end
- return fullname,path
+ end
+ return fullname,path
end
function caches.setfirstwritablefile(filename,...)
- local wr=getwritablepath(...)
- local fullname=file.join(wr,filename)
- return fullname,wr
+ local wr=getwritablepath(...)
+ local fullname=file.join(wr,filename)
+ return fullname,wr
end
function caches.define(category,subcategory)
- return function()
- return getwritablepath(category,subcategory)
- end
+ return function()
+ return getwritablepath(category,subcategory)
+ end
end
function caches.setluanames(path,name)
- return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
+ return format("%s/%s.%s",path,name,luasuffixes.tma),format("%s/%s.%s",path,name,luasuffixes.tmc)
end
function caches.loaddata(readables,name,writable)
- if type(readables)=="string" then
- readables={ readables }
+ if type(readables)=="string" then
+ readables={ readables }
+ end
+ for i=1,#readables do
+ local path=readables[i]
+ local loader=false
+ local tmaname,tmcname=caches.setluanames(path,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader and isfile(tmaname) then
+ local tmacrap,tmcname=caches.setluanames(writable,name)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ utilities.lua.compile(tmaname,tmcname)
+ if isfile(tmcname) then
+ loader=loadfile(tmcname)
+ end
+ if not loader then
+ loader=loadfile(tmaname)
+ end
end
- for i=1,#readables do
- local path=readables[i]
- local loader=false
- local tmaname,tmcname=caches.setluanames(path,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader and isfile(tmaname) then
- local tmacrap,tmcname=caches.setluanames(writable,name)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- utilities.lua.compile(tmaname,tmcname)
- if isfile(tmcname) then
- loader=loadfile(tmcname)
- end
- if not loader then
- loader=loadfile(tmaname)
- end
- end
- if loader then
- loader=loader()
- collectgarbage("step")
- return loader
- end
+ if loader then
+ loader=loader()
+ collectgarbage("step")
+ return loader
end
- return false
+ end
+ return false
end
function caches.is_writable(filepath,filename)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- return is_writable(tmaname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ return is_writable(tmaname)
end
local saveoptions={ compact=true }
function caches.savedata(filepath,filename,data,raw)
- local tmaname,tmcname=caches.setluanames(filepath,filename)
- data.cache_uuid=os.uuid()
- if caches.direct then
- file.savedata(tmaname,table.serialize(data,true,saveoptions))
- else
- table.tofile(tmaname,data,true,saveoptions)
- end
- utilities.lua.compile(tmaname,tmcname)
+ local tmaname,tmcname=caches.setluanames(filepath,filename)
+ data.cache_uuid=os.uuid()
+ if caches.direct then
+ file.savedata(tmaname,table.serialize(data,true,saveoptions))
+ else
+ table.tofile(tmaname,data,true,saveoptions)
+ end
+ utilities.lua.compile(tmaname,tmcname)
end
local content_state={}
function caches.contentstate()
- return content_state or {}
+ return content_state or {}
end
function caches.loadcontent(cachename,dataname,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
- if blob then
- local data=blob()
- if data and data.content then
- if data.type==dataname then
- if data.version==resolvers.cacheversion then
- content_state[#content_state+1]=data.uuid
- if trace_locating then
- report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
- end
- return data.content
- else
- report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
- end
- else
- report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
- end
- elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.getfirstreadablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local blob=loadfile(addsuffix(filename,luasuffixes.luc)) or loadfile(addsuffix(filename,luasuffixes.lua))
+ if blob then
+ local data=blob()
+ if data and data.content then
+ if data.type==dataname then
+ if data.version==resolvers.cacheversion then
+ content_state[#content_state+1]=data.uuid
+ if trace_locating then
+ report_resolvers("loading %a for %a from %a",dataname,cachename,filename)
+ end
+ return data.content
+ else
+ report_resolvers("skipping %a for %a from %a (version mismatch)",dataname,cachename,filename)
end
+ else
+ report_resolvers("skipping %a for %a from %a (datatype mismatch)",dataname,cachename,filename)
+ end
elseif trace_locating then
- report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ report_resolvers("skipping %a for %a from %a (no content)",dataname,cachename,filename)
end
+ elseif trace_locating then
+ report_resolvers("skipping %a for %a from %a (invalid file)",dataname,cachename,filename)
+ end
end
function caches.collapsecontent(content)
- for k,v in next,content do
- if type(v)=="table" and #v==1 then
- content[k]=v[1]
- end
+ for k,v in next,content do
+ if type(v)=="table" and #v==1 then
+ content[k]=v[1]
end
+ end
end
function caches.savecontent(cachename,dataname,content,filename)
- if not filename then
- local name=caches.hashed(cachename)
- local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
- filename=file.join(path,name)
- end
- local luaname=addsuffix(filename,luasuffixes.lua)
- local lucname=addsuffix(filename,luasuffixes.luc)
+ if not filename then
+ local name=caches.hashed(cachename)
+ local full,path=caches.setfirstwritablefile(addsuffix(name,luasuffixes.lua),"trees")
+ filename=file.join(path,name)
+ end
+ local luaname=addsuffix(filename,luasuffixes.lua)
+ local lucname=addsuffix(filename,luasuffixes.luc)
+ if trace_locating then
+ report_resolvers("preparing %a for %a",dataname,cachename)
+ end
+ local data={
+ type=dataname,
+ root=cachename,
+ version=resolvers.cacheversion,
+ date=os.date("%Y-%m-%d"),
+ time=os.date("%H:%M:%S"),
+ content=content,
+ uuid=os.uuid(),
+ }
+ local ok=io.savedata(luaname,table.serialize(data,true))
+ if ok then
if trace_locating then
- report_resolvers("preparing %a for %a",dataname,cachename)
- end
- local data={
- type=dataname,
- root=cachename,
- version=resolvers.cacheversion,
- date=os.date("%Y-%m-%d"),
- time=os.date("%H:%M:%S"),
- content=content,
- uuid=os.uuid(),
- }
- local ok=io.savedata(luaname,table.serialize(data,true))
- if ok then
- if trace_locating then
- report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
- end
- if utilities.lua.compile(luaname,lucname) then
- if trace_locating then
- report_resolvers("%a compiled to %a",dataname,lucname)
- end
- return true
- else
- if trace_locating then
- report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
- end
- os.remove(lucname)
- end
- elseif trace_locating then
- report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ report_resolvers("category %a, cachename %a saved in %a",dataname,cachename,luaname)
+ end
+ if utilities.lua.compile(luaname,lucname) then
+ if trace_locating then
+ report_resolvers("%a compiled to %a",dataname,lucname)
+ end
+ return true
+ else
+ if trace_locating then
+ report_resolvers("compiling failed for %a, deleting file %a",dataname,lucname)
+ end
+ os.remove(lucname)
end
+ elseif trace_locating then
+ report_resolvers("unable to save %a in %a (access error)",dataname,luaname)
+ end
end
@@ -17577,14 +21151,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-met"] = package.loaded["data-met"] or true
--- original size: 5310, stripped down to: 3980
+-- original size: 5310, stripped down to: 3784
if not modules then modules={} end modules ['data-met']={
- 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 find,format=string.find,string.format
local sequenced=table.sequenced
@@ -17598,86 +21172,86 @@ local allocate=utilities.storage.allocate
local resolvers=resolvers
local registered={}
local function splitmethod(filename)
- if not filename then
- return { scheme="unknown",original=filename }
- end
- if type(filename)=="table" then
- return filename
- end
- filename=file.collapsepath(filename,".")
- if not find(filename,"://",1,true) then
- return { scheme="file",path=filename,original=filename,filename=filename }
- end
- local specification=url.hashed(filename)
- if not specification.scheme or specification.scheme=="" then
- return { scheme="file",path=filename,original=filename,filename=filename }
- else
- return specification
- end
+ if not filename then
+ return { scheme="unknown",original=filename }
+ end
+ if type(filename)=="table" then
+ return filename
+ end
+ filename=file.collapsepath(filename,".")
+ if not find(filename,"://",1,true) then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ end
+ local specification=url.hashed(filename)
+ if not specification.scheme or specification.scheme=="" then
+ return { scheme="file",path=filename,original=filename,filename=filename }
+ else
+ return specification
+ end
end
resolvers.splitmethod=splitmethod
local function methodhandler(what,first,...)
- local method=registered[what]
- if method then
- local how,namespace=method.how,method.namespace
- if how=="uri" or how=="url" then
- local specification=splitmethod(first)
- local scheme=specification.scheme
- local resolver=namespace and namespace[scheme]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
- end
- return resolver(specification,...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
- end
- return resolver(specification,...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
- end
- end
- elseif how=="tag" then
- local resolver=namespace and namespace[first]
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,first)
- end
- return resolver(...)
- else
- resolver=namespace.default or namespace.file
- if resolver then
- if trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
- end
- return resolver(...)
- elseif trace_methods then
- report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
- end
- end
+ local method=registered[what]
+ if method then
+ local how,namespace=method.how,method.namespace
+ if how=="uri" or how=="url" then
+ local specification=splitmethod(first)
+ local scheme=specification.scheme
+ local resolver=namespace and namespace[scheme]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,scheme,first)
+ end
+ return resolver(specification,...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"default",first)
+ end
+ return resolver(specification,...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, handler %a, argument %a",what,how,"unset")
end
- else
- report_methods("resolving, invalid method %a")
+ end
+ elseif how=="tag" then
+ local resolver=namespace and namespace[first]
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,first)
+ end
+ return resolver(...)
+ else
+ resolver=namespace.default or namespace.file
+ if resolver then
+ if trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"default")
+ end
+ return resolver(...)
+ elseif trace_methods then
+ report_methods("resolving, method %a, how %a, tag %a",what,how,"unset")
+ end
+ end
end
+ else
+ report_methods("resolving, invalid method %a")
+ end
end
resolvers.methodhandler=methodhandler
function resolvers.registermethod(name,namespace,how)
- registered[name]={ how=how or "tag",namespace=namespace }
- namespace["byscheme"]=function(scheme,filename,...)
- if scheme=="file" then
- return methodhandler(name,filename,...)
- else
- return methodhandler(name,addurlscheme(filename,scheme),...)
- end
+ registered[name]={ how=how or "tag",namespace=namespace }
+ namespace["byscheme"]=function(scheme,filename,...)
+ if scheme=="file" then
+ return methodhandler(name,filename,...)
+ else
+ return methodhandler(name,addurlscheme(filename,scheme),...)
end
+ end
end
-local concatinators=allocate { notfound=file.join }
-local locators=allocate { notfound=function() end }
-local hashers=allocate { notfound=function() end }
-local generators=allocate { notfound=function() end }
+local concatinators=allocate { notfound=file.join }
+local locators=allocate { notfound=function() end }
+local hashers=allocate { notfound=function() end }
+local generators=allocate { notfound=function() end }
resolvers.concatinators=concatinators
resolvers.locators=locators
resolvers.hashers=hashers
@@ -17695,17 +21269,17 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-res"] = package.loaded["data-res"] or true
--- original size: 68263, stripped down to: 47789
+-- original size: 68195, stripped down to: 43680
if not modules then modules={} end modules ['data-res']={
- 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 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
local P,S,R,C,Cc,Cs,Ct,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cc,lpeg.Cs,lpeg.Ct,lpeg.Carg
@@ -17727,11 +21301,11 @@ local isfile=lfs.isfile
local isdir=lfs.isdir
local setmetatableindex=table.setmetatableindex
local luasuffixes=utilities.lua.suffixes
-local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
-local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
-local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
-local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
-local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
+local trace_locating=false trackers .register("resolvers.locating",function(v) trace_locating=v end)
+local trace_detail=false trackers .register("resolvers.details",function(v) trace_detail=v end)
+local trace_expansions=false trackers .register("resolvers.expansions",function(v) trace_expansions=v end)
+local trace_paths=false trackers .register("resolvers.paths",function(v) trace_paths=v end)
+local resolve_otherwise=true directives.register("resolvers.otherwise",function(v) resolve_otherwise=v end)
local report_resolving=logs.reporter("resolvers","resolving")
local resolvers=resolvers
local expandedpathfromlist=resolvers.expandedpathfromlist
@@ -17752,15 +21326,15 @@ resolvers.luacnfname="texmfcnf.lua"
resolvers.luacnffallback="contextcnf.lua"
resolvers.luacnfstate="unknown"
if environment.default_texmfcnf then
- resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
+ resolvers.luacnfspec="home:texmf/web2c;"..environment.default_texmfcnf
else
- resolvers.luacnfspec=concat ({
- "home:texmf/web2c",
- "selfautoparent:/texmf-local/web2c",
- "selfautoparent:/texmf-context/web2c",
- "selfautoparent:/texmf-dist/web2c",
- "selfautoparent:/texmf/web2c",
- },";")
+ resolvers.luacnfspec=concat ({
+ "home:texmf/web2c",
+ "selfautoparent:/texmf-local/web2c",
+ "selfautoparent:/texmf-context/web2c",
+ "selfautoparent:/texmf-dist/web2c",
+ "selfautoparent:/texmf/web2c",
+ },";")
end
local unset_variable="unset"
local formats=resolvers.formats
@@ -17771,24 +21345,24 @@ local suffixmap=resolvers.suffixmap
resolvers.defaultsuffixes={ "tex" }
local instance=nil
function resolvers.setenv(key,value,raw)
- if instance then
- instance.environment[key]=value
- ossetenv(key,raw and value or resolveprefix(value))
- end
+ if instance then
+ instance.environment[key]=value
+ ossetenv(key,raw and value or resolveprefix(value))
+ end
end
local function getenv(key)
- local value=rawget(instance.environment,key)
- if value and value~="" then
- return value
- else
- local e=osgetenv(key)
- return e~=nil and e~="" and checkedvariable(e) or ""
- end
+ local value=rawget(instance.environment,key)
+ if value and value~="" then
+ return value
+ else
+ local e=osgetenv(key)
+ return e~=nil and e~="" and checkedvariable(e) or ""
+ end
end
resolvers.getenv=getenv
resolvers.env=getenv
local function resolvevariable(k)
- return instance.expansions[k]
+ return instance.expansions[k]
end
local dollarstripper=lpeg.stripper("$")
local inhibitstripper=P("!")^0*Cs(P(1)^0)
@@ -17802,1506 +21376,1506 @@ local somevariable=R("az","AZ","09","__","--")^1/resolvevariable
local variable=(P("$")/"")*(somevariable+(P("{")/"")*somevariable*(P("}")/""))
local variableresolver=Cs((variable+P(1))^0)
local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
+ return lpegmatch(variableexpander,var) or var
end
function resolvers.reset()
- if trace_locating then
- report_resolving("creating instance")
- end
- local environment={}
- local variables={}
- local expansions={}
- local order={}
- instance={
- environment=environment,
- variables=variables,
- expansions=expansions,
- order=order,
- files={},
- setups={},
- found={},
- foundintrees={},
- hashes={},
- hashed={},
- pathlists=false,
- specification={},
- lists={},
- data={},
- fakepaths={},
- remember=true,
- diskcache=true,
- renewcache=false,
- renewtree=false,
- loaderror=false,
- savelists=true,
- pattern=nil,
- force_suffixes=true,
- pathstack={},
- }
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v=order[i][k]
- if v~=nil then
- t[k]=v
- return v
- end
- end
- if v==nil then
- v=""
- end
- t[k]=v
- return v
- end)
- setmetatableindex(environment,function(t,k)
- local v=osgetenv(k)
- if v==nil then
- v=variables[k]
- end
- if v~=nil then
- v=checkedvariable(v) or ""
- end
- v=resolvers.repath(v)
- t[k]=v
- return v
- end)
- setmetatableindex(expansions,function(t,k)
- local v=environment[k]
- if type(v)=="string" then
- v=lpegmatch(variableresolver,v)
- v=lpegmatch(variablecleaner,v)
- end
+ if trace_locating then
+ report_resolving("creating instance")
+ end
+ local environment={}
+ local variables={}
+ local expansions={}
+ local order={}
+ instance={
+ environment=environment,
+ variables=variables,
+ expansions=expansions,
+ order=order,
+ files={},
+ setups={},
+ found={},
+ foundintrees={},
+ hashes={},
+ hashed={},
+ pathlists=false,
+ specification={},
+ lists={},
+ data={},
+ fakepaths={},
+ remember=true,
+ diskcache=true,
+ renewcache=false,
+ renewtree=false,
+ loaderror=false,
+ savelists=true,
+ pattern=nil,
+ force_suffixes=true,
+ pathstack={},
+ }
+ setmetatableindex(variables,function(t,k)
+ local v
+ for i=1,#order do
+ v=order[i][k]
+ if v~=nil then
t[k]=v
return v
- end)
+ end
+ end
+ if v==nil then
+ v=""
+ end
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(environment,function(t,k)
+ local v=osgetenv(k)
+ if v==nil then
+ v=variables[k]
+ end
+ if v~=nil then
+ v=checkedvariable(v) or ""
+ end
+ v=resolvers.repath(v)
+ t[k]=v
+ return v
+ end)
+ setmetatableindex(expansions,function(t,k)
+ local v=environment[k]
+ if type(v)=="string" then
+ v=lpegmatch(variableresolver,v)
+ v=lpegmatch(variablecleaner,v)
+ end
+ t[k]=v
+ return v
+ end)
end
function resolvers.initialized()
- return instance~=nil
+ return instance~=nil
end
local function reset_hashes()
- instance.lists={}
- instance.pathlists=false
- instance.found={}
+ instance.lists={}
+ instance.pathlists=false
+ instance.found={}
end
local function reset_caches()
- instance.lists={}
- instance.pathlists=false
+ instance.lists={}
+ instance.pathlists=false
end
local slash=P("/")
local pathexpressionpattern=Cs (
- Cc("^")*(
- Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+ Cc("^")*(
+ Cc("%")*S(".-")+slash^2*P(-1)/"/.*"
+slash^2/"/"+(1-slash)*P(-1)*Cc("/")+P(1)
- )^1*Cc("$")
+ )^1*Cc("$")
)
local cache={}
local function makepathexpression(str)
- if str=="." then
- return "^%./$"
- else
- local c=cache[str]
- if not c then
- c=lpegmatch(pathexpressionpattern,str)
- cache[str]=c
- end
- return c
+ if str=="." then
+ return "^%./$"
+ else
+ local c=cache[str]
+ if not c then
+ c=lpegmatch(pathexpressionpattern,str)
+ cache[str]=c
end
+ return c
+ end
end
local function reportcriticalvariables(cnfspec)
- if trace_locating then
- for i=1,#resolvers.criticalvars do
- local k=resolvers.criticalvars[i]
- local v=resolvers.getenv(k) or "unknown"
- report_resolving("variable %a set to %a",k,v)
- end
- report_resolving()
- if cnfspec then
- report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
- end
- report_resolving()
+ if trace_locating then
+ for i=1,#resolvers.criticalvars do
+ local k=resolvers.criticalvars[i]
+ local v=resolvers.getenv(k) or "unknown"
+ report_resolving("variable %a set to %a",k,v)
+ end
+ report_resolving()
+ if cnfspec then
+ report_resolving("using configuration specification %a",type(cnfspec)=="table" and concat(cnfspec,",") or cnfspec)
end
- reportcriticalvariables=function() end
+ report_resolving()
+ end
+ reportcriticalvariables=function() end
end
local function identify_configuration_files()
- local specification=instance.specification
- if #specification==0 then
- local cnfspec=getenv("TEXMFCNF")
- if cnfspec=="" then
- cnfspec=resolvers.luacnfspec
- resolvers.luacnfstate="default"
- else
- resolvers.luacnfstate="environment"
- end
- reportcriticalvariables(cnfspec)
- local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
- local function locatecnf(luacnfname,kind)
- for i=1,#cnfpaths do
- local filepath=cnfpaths[i]
- local filename=collapsepath(filejoin(filepath,luacnfname))
- local realname=resolveprefix(filename)
- if trace_locating then
- local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
- local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
- report_resolving("looking for %s %a on %s path %a from specification %a",
- kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
- end
- if isfile(realname) then
- specification[#specification+1]=filename
- if trace_locating then
- report_resolving("found %s configuration file %a",kind,realname)
- end
- end
- end
- end
- locatecnf(resolvers.luacnfname,"regular")
- if #specification==0 then
- locatecnf(resolvers.luacnffallback,"fallback")
- end
+ local specification=instance.specification
+ if #specification==0 then
+ local cnfspec=getenv("TEXMFCNF")
+ if cnfspec=="" then
+ cnfspec=resolvers.luacnfspec
+ resolvers.luacnfstate="default"
+ else
+ resolvers.luacnfstate="environment"
+ end
+ reportcriticalvariables(cnfspec)
+ local cnfpaths=expandedpathfromlist(resolvers.splitpath(cnfspec))
+ local function locatecnf(luacnfname,kind)
+ for i=1,#cnfpaths do
+ local filepath=cnfpaths[i]
+ local filename=collapsepath(filejoin(filepath,luacnfname))
+ local realname=resolveprefix(filename)
if trace_locating then
- report_resolving()
+ local fullpath=gsub(resolveprefix(collapsepath(filepath)),"//","/")
+ local weirdpath=find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true)
+ report_resolving("looking for %s %a on %s path %a from specification %a",
+ kind,luacnfname,weirdpath and "weird" or "given",fullpath,filepath)
+ end
+ if isfile(realname) then
+ specification[#specification+1]=filename
+ if trace_locating then
+ report_resolving("found %s configuration file %a",kind,realname)
+ end
end
- elseif trace_locating then
- report_resolving("configuration files already identified")
+ end
+ end
+ locatecnf(resolvers.luacnfname,"regular")
+ if #specification==0 then
+ locatecnf(resolvers.luacnffallback,"fallback")
+ end
+ if trace_locating then
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("configuration files already identified")
+ end
end
local function load_configuration_files()
- local specification=instance.specification
- if #specification>0 then
- local luacnfname=resolvers.luacnfname
- for i=1,#specification do
- local filename=specification[i]
- local pathname=filedirname(filename)
- local filename=filejoin(pathname,luacnfname)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local setups=instance.setups
- local data=blob()
- local parent=data and data.parent
- if parent then
- local filename=filejoin(pathname,parent)
- local realname=resolveprefix(filename)
- local blob=loadfile(realname)
- if blob then
- local parentdata=blob()
- if parentdata then
- report_resolving("loading configuration file %a",filename)
- data=table.merged(parentdata,data)
- end
- end
- end
- data=data and data.content
- if data then
- if trace_locating then
- report_resolving("loading configuration file %a",filename)
- report_resolving()
- end
- local variables=data.variables or {}
- local warning=false
- for k,v in next,data do
- local variant=type(v)
- if variant=="table" then
- initializesetter(filename,k,v)
- elseif variables[k]==nil then
- if trace_locating and not warning then
- report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
- k,resolveprefix(filename))
- warning=true
- end
- variables[k]=v
- end
- end
- setups[pathname]=variables
- if resolvers.luacnfstate=="default" then
- local cnfspec=variables["TEXMFCNF"]
- if cnfspec then
- if trace_locating then
- report_resolving("reloading configuration due to TEXMF redefinition")
- end
- resolvers.setenv("TEXMFCNF",cnfspec)
- instance.specification={}
- identify_configuration_files()
- load_configuration_files()
- resolvers.luacnfstate="configuration"
- break
- end
- end
- else
- if trace_locating then
- report_resolving("skipping configuration file %a (no content)",filename)
- end
- setups[pathname]={}
- instance.loaderror=true
- end
- elseif trace_locating then
- report_resolving("skipping configuration file %a (no valid format)",filename)
+ local specification=instance.specification
+ if #specification>0 then
+ local luacnfname=resolvers.luacnfname
+ for i=1,#specification do
+ local filename=specification[i]
+ local pathname=filedirname(filename)
+ local filename=filejoin(pathname,luacnfname)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local setups=instance.setups
+ local data=blob()
+ local parent=data and data.parent
+ if parent then
+ local filename=filejoin(pathname,parent)
+ local realname=resolveprefix(filename)
+ local blob=loadfile(realname)
+ if blob then
+ local parentdata=blob()
+ if parentdata then
+ report_resolving("loading configuration file %a",filename)
+ data=table.merged(parentdata,data)
end
- instance.order[#instance.order+1]=instance.setups[pathname]
- if instance.loaderror then
- break
+ end
+ end
+ data=data and data.content
+ if data then
+ if trace_locating then
+ report_resolving("loading configuration file %a",filename)
+ report_resolving()
+ end
+ local variables=data.variables or {}
+ local warning=false
+ for k,v in next,data do
+ local variant=type(v)
+ if variant=="table" then
+ initializesetter(filename,k,v)
+ elseif variables[k]==nil then
+ if trace_locating and not warning then
+ report_resolving("variables like %a in configuration file %a should move to the 'variables' subtable",
+ k,resolveprefix(filename))
+ warning=true
+ end
+ variables[k]=v
+ end
+ end
+ setups[pathname]=variables
+ if resolvers.luacnfstate=="default" then
+ local cnfspec=variables["TEXMFCNF"]
+ if cnfspec then
+ if trace_locating then
+ report_resolving("reloading configuration due to TEXMF redefinition")
+ end
+ resolvers.setenv("TEXMFCNF",cnfspec)
+ instance.specification={}
+ identify_configuration_files()
+ load_configuration_files()
+ resolvers.luacnfstate="configuration"
+ break
end
+ end
+ else
+ if trace_locating then
+ report_resolving("skipping configuration file %a (no content)",filename)
+ end
+ setups[pathname]={}
+ instance.loaderror=true
end
- elseif trace_locating then
- report_resolving("warning: no lua configuration files found")
+ elseif trace_locating then
+ report_resolving("skipping configuration file %a (no valid format)",filename)
+ end
+ instance.order[#instance.order+1]=instance.setups[pathname]
+ if instance.loaderror then
+ break
+ end
end
+ elseif trace_locating then
+ report_resolving("warning: no lua configuration files found")
+ end
end
function resolvers.configurationfiles()
- return instance.specification or {}
+ return instance.specification or {}
end
local function load_file_databases()
- instance.loaderror=false
- instance.files={}
- if not instance.renewcache then
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- resolvers.hashers.byscheme(hash.type,hash.name)
- if instance.loaderror then break end
- end
+ instance.loaderror=false
+ instance.files={}
+ if not instance.renewcache then
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ resolvers.hashers.byscheme(hash.type,hash.name)
+ if instance.loaderror then break end
end
+ end
end
local function locate_file_databases()
- local texmfpaths=resolvers.expandedpathlist("TEXMF")
- if #texmfpaths>0 then
- for i=1,#texmfpaths do
- local path=collapsepath(texmfpaths[i])
- path=gsub(path,"/+$","")
- local stripped=lpegmatch(inhibitstripper,path)
- if stripped~="" then
- local runtime=stripped==path
- path=cleanpath(path)
- local spec=resolvers.splitmethod(stripped)
- if runtime and (spec.noscheme or spec.scheme=="file") then
- stripped="tree:///"..stripped
- elseif spec.scheme=="cache" or spec.scheme=="file" then
- stripped=spec.path
- end
- if trace_locating then
- if runtime then
- report_resolving("locating list of %a (runtime) (%s)",path,stripped)
- else
- report_resolving("locating list of %a (cached)",path)
- end
- end
- methodhandler('locators',stripped)
- end
+ local texmfpaths=resolvers.expandedpathlist("TEXMF")
+ if #texmfpaths>0 then
+ for i=1,#texmfpaths do
+ local path=collapsepath(texmfpaths[i])
+ path=gsub(path,"/+$","")
+ local stripped=lpegmatch(inhibitstripper,path)
+ if stripped~="" then
+ local runtime=stripped==path
+ path=cleanpath(path)
+ local spec=resolvers.splitmethod(stripped)
+ if runtime and (spec.noscheme or spec.scheme=="file") then
+ stripped="tree:///"..stripped
+ elseif spec.scheme=="cache" or spec.scheme=="file" then
+ stripped=spec.path
end
if trace_locating then
- report_resolving()
+ if runtime then
+ report_resolving("locating list of %a (runtime) (%s)",path,stripped)
+ else
+ report_resolving("locating list of %a (cached)",path)
+ end
end
- elseif trace_locating then
- report_resolving("no texmf paths are defined (using TEXMF)")
- end
-end
-local function generate_file_databases()
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- methodhandler('generators',hash.name)
+ methodhandler('locators',stripped)
+ end
end
if trace_locating then
- report_resolving()
+ report_resolving()
end
+ elseif trace_locating then
+ report_resolving("no texmf paths are defined (using TEXMF)")
+ end
+end
+local function generate_file_databases()
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ methodhandler('generators',hash.name)
+ end
+ if trace_locating then
+ report_resolving()
+ end
end
local function save_file_databases()
- for i=1,#instance.hashes do
- local hash=instance.hashes[i]
- local cachename=hash.name
- if hash.cache then
- local content=instance.files[cachename]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",cachename)
- end
- caches.savecontent(cachename,"files",content)
- elseif trace_locating then
- report_resolving("not saving runtime tree %a",cachename)
- end
+ for i=1,#instance.hashes do
+ local hash=instance.hashes[i]
+ local cachename=hash.name
+ if hash.cache then
+ local content=instance.files[cachename]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",cachename)
+ end
+ caches.savecontent(cachename,"files",content)
+ elseif trace_locating then
+ report_resolving("not saving runtime tree %a",cachename)
end
+ end
end
function resolvers.renew(hashname)
- if hashname and hashname~="" then
- local expanded=resolvers.expansion(hashname) or ""
- if expanded~="" then
- if trace_locating then
- report_resolving("identifying tree %a from %a",expanded,hashname)
- end
- hashname=expanded
- else
- if trace_locating then
- report_resolving("identifying tree %a",hashname)
- end
- end
- local realpath=resolveprefix(hashname)
- if isdir(realpath) then
- if trace_locating then
- report_resolving("using path %a",realpath)
- end
- methodhandler('generators',hashname)
- local content=instance.files[hashname]
- caches.collapsecontent(content)
- if trace_locating then
- report_resolving("saving tree %a",hashname)
- end
- caches.savecontent(hashname,"files",content)
- else
- report_resolving("invalid path %a",realpath)
- end
+ if hashname and hashname~="" then
+ local expanded=resolvers.expansion(hashname) or ""
+ if expanded~="" then
+ if trace_locating then
+ report_resolving("identifying tree %a from %a",expanded,hashname)
+ end
+ hashname=expanded
+ else
+ if trace_locating then
+ report_resolving("identifying tree %a",hashname)
+ end
end
+ local realpath=resolveprefix(hashname)
+ if isdir(realpath) then
+ if trace_locating then
+ report_resolving("using path %a",realpath)
+ end
+ methodhandler('generators',hashname)
+ local content=instance.files[hashname]
+ caches.collapsecontent(content)
+ if trace_locating then
+ report_resolving("saving tree %a",hashname)
+ end
+ caches.savecontent(hashname,"files",content)
+ else
+ report_resolving("invalid path %a",realpath)
+ end
+ end
end
local function load_databases()
- locate_file_databases()
- if instance.diskcache and not instance.renewcache then
- load_file_databases()
- if instance.loaderror then
- generate_file_databases()
- save_file_databases()
- end
- else
- generate_file_databases()
- if instance.renewcache then
- save_file_databases()
- end
+ locate_file_databases()
+ if instance.diskcache and not instance.renewcache then
+ load_file_databases()
+ if instance.loaderror then
+ generate_file_databases()
+ save_file_databases()
+ end
+ else
+ generate_file_databases()
+ if instance.renewcache then
+ save_file_databases()
end
+ end
end
function resolvers.appendhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a appended",name)
- end
- insert(instance.hashes,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a appended",name)
end
+ insert(instance.hashes,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.prependhash(type,name,cache)
- if not instance.hashed[name] then
- if trace_locating then
- report_resolving("hash %a prepended",name)
- end
- insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
- instance.hashed[name]=cache
+ if not instance.hashed[name] then
+ if trace_locating then
+ report_resolving("hash %a prepended",name)
end
+ insert(instance.hashes,1,{ type=type,name=name,cache=cache } )
+ instance.hashed[name]=cache
+ end
end
function resolvers.extendtexmfvariable(specification)
- local t=resolvers.splitpath(getenv("TEXMF"))
- insert(t,1,specification)
- local newspec=concat(t,",")
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"]=newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"]=newspec
- else
- end
- reset_hashes()
+ local t=resolvers.splitpath(getenv("TEXMF"))
+ insert(t,1,specification)
+ local newspec=concat(t,",")
+ if instance.environment["TEXMF"] then
+ instance.environment["TEXMF"]=newspec
+ elseif instance.variables["TEXMF"] then
+ instance.variables["TEXMF"]=newspec
+ else
+ end
+ reset_hashes()
end
function resolvers.splitexpansions()
- local ie=instance.expansions
- for k,v in next,ie do
- local t,tn,h,p={},0,{},splitconfigurationpath(v)
- for kk=1,#p do
- local vv=p[kk]
- if vv~="" and not h[vv] then
- tn=tn+1
- t[tn]=vv
- h[vv]=true
- end
- end
- if #t>1 then
- ie[k]=t
- else
- ie[k]=t[1]
- end
+ local ie=instance.expansions
+ for k,v in next,ie do
+ local t,tn,h,p={},0,{},splitconfigurationpath(v)
+ for kk=1,#p do
+ local vv=p[kk]
+ if vv~="" and not h[vv] then
+ tn=tn+1
+ t[tn]=vv
+ h[vv]=true
+ end
end
+ if #t>1 then
+ ie[k]=t
+ else
+ ie[k]=t[1]
+ end
+ end
end
function resolvers.datastate()
- return caches.contentstate()
+ return caches.contentstate()
end
function resolvers.variable(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.variables[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.variables[name]
+ return result~=nil and result or ""
end
function resolvers.expansion(name)
- local name=name and lpegmatch(dollarstripper,name)
- local result=name and instance.expansions[name]
- return result~=nil and result or ""
+ local name=name and lpegmatch(dollarstripper,name)
+ local result=name and instance.expansions[name]
+ return result~=nil and result or ""
end
function resolvers.unexpandedpathlist(str)
- local pth=resolvers.variable(str)
- local lst=resolvers.splitpath(pth)
- return expandedpathfromlist(lst)
+ local pth=resolvers.variable(str)
+ local lst=resolvers.splitpath(pth)
+ return expandedpathfromlist(lst)
end
function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+ return joinpath(resolvers.unexpandedpathlist(str))
end
function resolvers.pushpath(name)
- local pathstack=instance.pathstack
- local lastpath=pathstack[#pathstack]
- local pluspath=filedirname(name)
- if lastpath then
- lastpath=collapsepath(filejoin(lastpath,pluspath))
- else
- lastpath=collapsepath(pluspath)
- end
- insert(pathstack,lastpath)
- if trace_paths then
- report_resolving("pushing path %a",lastpath)
- end
+ local pathstack=instance.pathstack
+ local lastpath=pathstack[#pathstack]
+ local pluspath=filedirname(name)
+ if lastpath then
+ lastpath=collapsepath(filejoin(lastpath,pluspath))
+ else
+ lastpath=collapsepath(pluspath)
+ end
+ insert(pathstack,lastpath)
+ if trace_paths then
+ report_resolving("pushing path %a",lastpath)
+ end
end
function resolvers.poppath()
- local pathstack=instance.pathstack
- if trace_paths and #pathstack>0 then
- report_resolving("popping path %a",pathstack[#pathstack])
- end
- remove(pathstack)
+ local pathstack=instance.pathstack
+ if trace_paths and #pathstack>0 then
+ report_resolving("popping path %a",pathstack[#pathstack])
+ end
+ remove(pathstack)
end
function resolvers.stackpath()
- local pathstack=instance.pathstack
- local currentpath=pathstack[#pathstack]
- return currentpath~="" and currentpath or nil
+ local pathstack=instance.pathstack
+ local currentpath=pathstack[#pathstack]
+ return currentpath~="" and currentpath or nil
end
local done={}
function resolvers.resetextrapaths()
- local ep=instance.extra_paths
- if not ep then
- done={}
- instance.extra_paths={}
- elseif #ep>0 then
- done={}
- reset_caches()
- end
+ local ep=instance.extra_paths
+ if not ep then
+ done={}
+ instance.extra_paths={}
+ elseif #ep>0 then
+ done={}
+ reset_caches()
+ end
end
function resolvers.getextrapaths()
- return instance.extra_paths or {}
+ return instance.extra_paths or {}
end
function resolvers.registerextrapath(paths,subpaths)
- if not subpaths or subpaths=="" then
- if not paths or path=="" then
- return
- elseif done[paths] then
- return
- end
- end
- local paths=settings_to_array(paths)
- local subpaths=settings_to_array(subpaths)
- local ep=instance.extra_paths or {}
- local oldn=#ep
- local newn=oldn
- local nofpaths=#paths
- local nofsubpaths=#subpaths
- if nofpaths>0 then
- if nofsubpaths>0 then
- for i=1,nofpaths do
- local p=paths[i]
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=p.."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
- end
- else
- for i=1,nofpaths do
- local p=paths[i]
- if not done[p] then
- newn=newn+1
- ep[newn]=cleanpath(p)
- done[p]=true
- end
- end
+ if not subpaths or subpaths=="" then
+ if not paths or path=="" then
+ return
+ elseif done[paths] then
+ return
+ end
+ end
+ local paths=settings_to_array(paths)
+ local subpaths=settings_to_array(subpaths)
+ local ep=instance.extra_paths or {}
+ local oldn=#ep
+ local newn=oldn
+ local nofpaths=#paths
+ local nofsubpaths=#subpaths
+ if nofpaths>0 then
+ if nofsubpaths>0 then
+ for i=1,nofpaths do
+ local p=paths[i]
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=p.."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
end
- elseif nofsubpaths>0 then
- for i=1,oldn do
- for j=1,nofsubpaths do
- local s=subpaths[j]
- local ps=ep[i].."/"..s
- if not done[ps] then
- newn=newn+1
- ep[newn]=cleanpath(ps)
- done[ps]=true
- end
- end
+ end
+ else
+ for i=1,nofpaths do
+ local p=paths[i]
+ if not done[p] then
+ newn=newn+1
+ ep[newn]=cleanpath(p)
+ done[p]=true
end
+ end
end
- if newn>0 then
- instance.extra_paths=ep
- end
- if newn~=oldn then
- reset_caches()
+ elseif nofsubpaths>0 then
+ for i=1,oldn do
+ for j=1,nofsubpaths do
+ local s=subpaths[j]
+ local ps=ep[i].."/"..s
+ if not done[ps] then
+ newn=newn+1
+ ep[newn]=cleanpath(ps)
+ done[ps]=true
+ end
+ end
end
+ end
+ if newn>0 then
+ instance.extra_paths=ep
+ end
+ if newn~=oldn then
+ reset_caches()
+ end
end
function resolvers.pushextrapath(path)
- local paths=settings_to_array(path)
- if instance.extra_stack then
- insert(instance.extra_stack,1,paths)
- else
- instance.extra_stack={ paths }
- end
- reset_caches()
+ local paths=settings_to_array(path)
+ if instance.extra_stack then
+ insert(instance.extra_stack,1,paths)
+ else
+ instance.extra_stack={ paths }
+ end
+ reset_caches()
end
function resolvers.popextrapath()
- if instance.extra_stack then
- reset_caches()
- return remove(instance.extra_stack,1)
- end
+ if instance.extra_stack then
+ reset_caches()
+ return remove(instance.extra_stack,1)
+ end
end
local function made_list(instance,list,extra_too)
- local done={}
- local new={}
- local newn=0
- local function add(p)
- for k=1,#p do
- local v=p[k]
- if not done[v] then
- done[v]=true
- newn=newn+1
- new[newn]=v
- end
- end
+ local done={}
+ local new={}
+ local newn=0
+ local function add(p)
+ for k=1,#p do
+ local v=p[k]
+ if not done[v] then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ end
end
- for k=1,#list do
- local v=list[k]
- if done[v] then
- elseif find(v,"^[%.%/]$") then
- done[v]=true
- newn=newn+1
- new[newn]=v
- else
- break
- end
+ end
+ for k=1,#list do
+ local v=list[k]
+ if done[v] then
+ elseif find(v,"^[%.%/]$") then
+ done[v]=true
+ newn=newn+1
+ new[newn]=v
+ else
+ break
+ end
+ end
+ if extra_too then
+ local es=instance.extra_stack
+ if es and #es>0 then
+ for k=1,#es do
+ add(es[k])
+ end
end
- if extra_too then
- local es=instance.extra_stack
- if es and #es>0 then
- for k=1,#es do
- add(es[k])
- end
- end
- local ep=instance.extra_paths
- if ep and #ep>0 then
- add(ep)
- end
+ local ep=instance.extra_paths
+ if ep and #ep>0 then
+ add(ep)
end
- add(list)
- return new
+ end
+ add(list)
+ return new
end
function resolvers.cleanpathlist(str)
- local t=resolvers.expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i]=collapsepath(cleanpath(t[i]))
- end
+ local t=resolvers.expandedpathlist(str)
+ if t then
+ for i=1,#t do
+ t[i]=collapsepath(cleanpath(t[i]))
end
- return t
+ end
+ return t
end
function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
+ return joinpath(resolvers.expandedpathlist(str))
end
function resolvers.expandedpathlist(str,extra_too)
- if not str then
- return {}
- elseif instance.savelists then
- str=lpegmatch(dollarstripper,str)
- local lists=instance.lists
- local lst=lists[str]
- if not lst then
- local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
- lst=expandedpathfromlist(l)
- lists[str]=lst
- end
- return lst
- else
- local lst=resolvers.splitpath(resolvers.expansion(str))
- return made_list(instance,expandedpathfromlist(lst),extra_too)
+ if not str then
+ return {}
+ elseif instance.savelists then
+ str=lpegmatch(dollarstripper,str)
+ local lists=instance.lists
+ local lst=lists[str]
+ if not lst then
+ local l=made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+ lst=expandedpathfromlist(l)
+ lists[str]=lst
end
+ return lst
+ else
+ local lst=resolvers.splitpath(resolvers.expansion(str))
+ return made_list(instance,expandedpathfromlist(lst),extra_too)
+ end
end
function resolvers.expandedpathlistfromvariable(str)
- str=lpegmatch(dollarstripper,str)
- local tmp=resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp~="" and tmp or str)
+ str=lpegmatch(dollarstripper,str)
+ local tmp=resolvers.variableofformatorsuffix(str)
+ return resolvers.expandedpathlist(tmp~="" and tmp or str)
end
function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+ return joinpath(resolvers.expandedpathlistfromvariable(str))
end
function resolvers.cleanedpathlist(v)
- local t=resolvers.expandedpathlist(v)
- for i=1,#t do
- t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
- end
- return t
+ local t=resolvers.expandedpathlist(v)
+ for i=1,#t do
+ t[i]=resolvers.resolve(resolvers.cleanpath(t[i]))
+ end
+ return t
end
function resolvers.expandbraces(str)
- local pth=expandedpathfromlist(resolvers.splitpath(str))
- return joinpath(pth)
+ local pth=expandedpathfromlist(resolvers.splitpath(str))
+ return joinpath(pth)
end
function resolvers.registerfilehash(name,content,someerror)
- if content then
- instance.files[name]=content
- else
- instance.files[name]={}
- if somerror==true then
- instance.loaderror=someerror
- end
+ if content then
+ instance.files[name]=content
+ else
+ instance.files[name]={}
+ if somerror==true then
+ instance.loaderror=someerror
end
+ end
end
function resolvers.getfilehashes()
- return instance and instance.files or {}
+ return instance and instance.files or {}
end
function resolvers.gethashes()
- return instance and instance.hashes or {}
+ return instance and instance.hashes or {}
end
function resolvers.renewcache()
- if instance then
- instance.renewcache=true
- end
+ if instance then
+ instance.renewcache=true
+ end
end
local function isreadable(name)
- local readable=isfile(name)
- if trace_detail then
- if readable then
- report_resolving("file %a is readable",name)
- else
- report_resolving("file %a is not readable",name)
- end
+ local readable=isfile(name)
+ if trace_detail then
+ if readable then
+ report_resolving("file %a is readable",name)
+ else
+ report_resolving("file %a is not readable",name)
end
- return readable
+ end
+ return readable
end
local function collect_files(names)
- local filelist={}
- local noffiles=0
- local function check(hash,root,pathname,path,basename,name)
- if not pathname or find(path,pathname) then
- local variant=hash.type
- local search=filejoin(root,path,name)
- local result=methodhandler('concatinators',variant,root,path,name)
- if trace_detail then
- report_resolving("match: variant %a, search %a, result %a",variant,search,result)
- end
- noffiles=noffiles+1
- filelist[noffiles]={ variant,search,result }
- end
+ local filelist={}
+ local noffiles=0
+ local function check(hash,root,pathname,path,basename,name)
+ if not pathname or find(path,pathname) then
+ local variant=hash.type
+ local search=filejoin(root,path,name)
+ local result=methodhandler('concatinators',variant,root,path,name)
+ if trace_detail then
+ report_resolving("match: variant %a, search %a, result %a",variant,search,result)
+ end
+ noffiles=noffiles+1
+ filelist[noffiles]={ variant,search,result }
end
- for k=1,#names do
- local filename=names[k]
+ end
+ for k=1,#names do
+ local filename=names[k]
+ if trace_detail then
+ report_resolving("checking name %a",filename)
+ end
+ local basename=filebasename(filename)
+ local pathname=filedirname(filename)
+ if pathname=="" or find(pathname,"^%.") then
+ pathname=false
+ else
+ pathname=gsub(pathname,"%*",".*")
+ pathname="/"..pathname.."$"
+ end
+ local hashes=instance.hashes
+ for h=1,#hashes do
+ local hash=hashes[h]
+ local hashname=hash.name
+ local content=hashname and instance.files[hashname]
+ if content then
if trace_detail then
- report_resolving("checking name %a",filename)
+ report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
end
- local basename=filebasename(filename)
- local pathname=filedirname(filename)
- if pathname=="" or find(pathname,"^%.") then
- pathname=false
- else
- pathname=gsub(pathname,"%*",".*")
- pathname="/"..pathname.."$"
- end
- local hashes=instance.hashes
- for h=1,#hashes do
- local hash=hashes[h]
- local hashname=hash.name
- local content=hashname and instance.files[hashname]
- if content then
- if trace_detail then
- report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
- end
- local path,name=lookup(content,basename)
- if path then
- local metadata=content.metadata
- local realroot=metadata and metadata.path or hashname
- if type(path)=="string" then
- check(hash,realroot,pathname,path,basename,name)
- else
- for i=1,#path do
- check(hash,realroot,pathname,path[i],basename,name)
- end
- end
- end
- elseif trace_locating then
- report_resolving("no match in %a (%s)",hashname,basename)
+ local path,name=lookup(content,basename)
+ if path then
+ local metadata=content.metadata
+ local realroot=metadata and metadata.path or hashname
+ if type(path)=="string" then
+ check(hash,realroot,pathname,path,basename,name)
+ else
+ for i=1,#path do
+ check(hash,realroot,pathname,path[i],basename,name)
end
+ end
end
+ elseif trace_locating then
+ report_resolving("no match in %a (%s)",hashname,basename)
+ end
end
- return noffiles>0 and filelist or nil
+ end
+ return noffiles>0 and filelist or nil
end
local fit={}
function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname)
- local foundintrees=instance.foundintrees
- if usedmethod=="direct" and filename==foundname and fit[foundname] then
- else
- local collapsed=collapsepath(foundname,true)
- local t={
- filename=filename,
- format=format~="" and format or nil,
- filetype=filetype~="" and filetype or nil,
- usedmethod=usedmethod,
- foundname=foundname,
- fullname=collapsed,
- }
- fit[foundname]=t
- foundintrees[#foundintrees+1]=t
- end
+ local foundintrees=instance.foundintrees
+ if usedmethod=="direct" and filename==foundname and fit[foundname] then
+ else
+ local collapsed=collapsepath(foundname,true)
+ local t={
+ filename=filename,
+ format=format~="" and format or nil,
+ filetype=filetype~="" and filetype or nil,
+ usedmethod=usedmethod,
+ foundname=foundname,
+ fullname=collapsed,
+ }
+ fit[foundname]=t
+ foundintrees[#foundintrees+1]=t
+ end
end
function resolvers.foundintrees()
- return instance.foundintrees or {}
+ return instance.foundintrees or {}
end
function resolvers.foundintree(fullname)
- local f=fit[fullname]
- return f and f.usedmethod=="database"
+ local f=fit[fullname]
+ return f and f.usedmethod=="database"
end
local function can_be_dir(name)
- local fakepaths=instance.fakepaths
- if not fakepaths[name] then
- if isdir(name) then
- fakepaths[name]=1
- else
- fakepaths[name]=2
- end
+ local fakepaths=instance.fakepaths
+ if not fakepaths[name] then
+ if isdir(name) then
+ fakepaths[name]=1
+ else
+ fakepaths[name]=2
end
- return fakepaths[name]==1
+ end
+ return fakepaths[name]==1
end
local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype=''
- local filesuffix=suffixonly(filename)
- local wantedfiles={}
- wantedfiles[#wantedfiles+1]=filename
- if askedformat=="" then
- if filesuffix=="" or not suffixmap[filesuffix] then
- local defaultsuffixes=resolvers.defaultsuffixes
- local formatofsuffix=resolvers.formatofsuffix
- for i=1,#defaultsuffixes do
- local forcedname=filename..'.'..defaultsuffixes[i]
- wantedfiles[#wantedfiles+1]=forcedname
- filetype=formatofsuffix(forcedname)
- if trace_locating then
- report_resolving("forcing filetype %a",filetype)
- end
- end
- else
- filetype=resolvers.formatofsuffix(filename)
- if trace_locating then
- report_resolving("using suffix based filetype %a",filetype)
- end
+ local filetype=''
+ local filesuffix=suffixonly(filename)
+ local wantedfiles={}
+ wantedfiles[#wantedfiles+1]=filename
+ if askedformat=="" then
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local defaultsuffixes=resolvers.defaultsuffixes
+ local formatofsuffix=resolvers.formatofsuffix
+ for i=1,#defaultsuffixes do
+ local forcedname=filename..'.'..defaultsuffixes[i]
+ wantedfiles[#wantedfiles+1]=forcedname
+ filetype=formatofsuffix(forcedname)
+ if trace_locating then
+ report_resolving("forcing filetype %a",filetype)
end
+ end
else
- if filesuffix=="" or not suffixmap[filesuffix] then
- local format_suffixes=suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
- end
- end
- end
- filetype=askedformat
- if trace_locating then
- report_resolving("using given filetype %a",filetype)
+ filetype=resolvers.formatofsuffix(filename)
+ if trace_locating then
+ report_resolving("using suffix based filetype %a",filetype)
+ end
+ end
+ else
+ if filesuffix=="" or not suffixmap[filesuffix] then
+ local format_suffixes=suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ wantedfiles[#wantedfiles+1]=filename.."."..format_suffixes[i]
end
+ end
end
- return filetype,wantedfiles
+ filetype=askedformat
+ if trace_locating then
+ report_resolving("using given filetype %a",filetype)
+ end
+ end
+ return filetype,wantedfiles
end
local function find_direct(filename,allresults)
- if not dangerous[askedformat] and isreadable(filename) then
- if trace_detail then
- report_resolving("file %a found directly",filename)
- end
- return "direct",{ filename }
+ if not dangerous[askedformat] and isreadable(filename) then
+ if trace_detail then
+ report_resolving("file %a found directly",filename)
end
+ return "direct",{ filename }
+ end
end
local function find_wildcard(filename,allresults)
- if find(filename,'*',1,true) then
- if trace_locating then
- report_resolving("checking wildcard %a",filename)
- end
- local result=resolvers.findwildcardfiles(filename)
- if result then
- return "wildcard",result
- end
- end
-end
-local function find_qualified(filename,allresults,askedformat,alsostripped)
- if not is_qualified_path(filename) then
- return
- end
+ if find(filename,'*',1,true) then
if trace_locating then
- report_resolving("checking qualified name %a",filename)
+ report_resolving("checking wildcard %a",filename)
end
- if isreadable(filename) then
- if trace_detail then
- report_resolving("qualified file %a found",filename)
- end
- return "qualified",{ filename }
+ local result=resolvers.findwildcardfiles(filename)
+ if result then
+ return "wildcard",result
end
+ end
+end
+local function find_qualified(filename,allresults,askedformat,alsostripped)
+ if not is_qualified_path(filename) then
+ return
+ end
+ if trace_locating then
+ report_resolving("checking qualified name %a",filename)
+ end
+ if isreadable(filename) then
if trace_detail then
- report_resolving("locating qualified file %a",filename)
- end
- local forcedname,suffix="",suffixonly(filename)
- if suffix=="" then
- local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
- if format_suffixes then
- for i=1,#format_suffixes do
- local s=format_suffixes[i]
- forcedname=filename.."."..s
- if isreadable(forcedname) then
- if trace_locating then
- report_resolving("no suffix, forcing format filetype %a",s)
- end
- return "qualified",{ forcedname }
- end
- end
+ report_resolving("qualified file %a found",filename)
+ end
+ return "qualified",{ filename }
+ end
+ if trace_detail then
+ report_resolving("locating qualified file %a",filename)
+ end
+ local forcedname,suffix="",suffixonly(filename)
+ if suffix=="" then
+ local format_suffixes=askedformat=="" and resolvers.defaultsuffixes or suffixes[askedformat]
+ if format_suffixes then
+ for i=1,#format_suffixes do
+ local s=format_suffixes[i]
+ forcedname=filename.."."..s
+ if isreadable(forcedname) then
+ if trace_locating then
+ report_resolving("no suffix, forcing format filetype %a",s)
+ end
+ return "qualified",{ forcedname }
end
+ end
end
- if alsostripped and suffix and suffix~="" then
- local basename=filebasename(filename)
- local pattern=lpegmatch(preparetreepattern,filename)
- local savedformat=askedformat
- local format=savedformat or ""
- if format=="" then
- askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if alsostripped and suffix and suffix~="" then
+ local basename=filebasename(filename)
+ local pattern=lpegmatch(preparetreepattern,filename)
+ local savedformat=askedformat
+ local format=savedformat or ""
+ if format=="" then
+ askedformat=resolvers.formatofsuffix(suffix)
+ end
+ if not format then
+ askedformat="othertextfiles"
+ end
+ if basename~=filename then
+ local resolved=collect_instance_files(basename,askedformat,allresults)
+ if #resolved==0 then
+ local lowered=lower(basename)
+ if filename~=lowered then
+ resolved=collect_instance_files(lowered,askedformat,allresults)
end
- if not format then
- askedformat="othertextfiles"
+ end
+ resolvers.format=savedformat
+ if #resolved>0 then
+ local result={}
+ for r=1,#resolved do
+ local rr=resolved[r]
+ if find(rr,pattern) then
+ result[#result+1]=rr
+ end
end
- if basename~=filename then
- local resolved=collect_instance_files(basename,askedformat,allresults)
- if #resolved==0 then
- local lowered=lower(basename)
- if filename~=lowered then
- resolved=collect_instance_files(lowered,askedformat,allresults)
- end
- end
- resolvers.format=savedformat
- if #resolved>0 then
- local result={}
- for r=1,#resolved do
- local rr=resolved[r]
- if find(rr,pattern) then
- result[#result+1]=rr
- end
- end
- if #result>0 then
- return "qualified",result
- end
- end
+ if #result>0 then
+ return "qualified",result
end
+ end
end
+ end
end
local function check_subpath(fname)
- if isreadable(fname) then
- if trace_detail then
- report_resolving("found %a by deep scanning",fname)
- end
- return fname
+ if isreadable(fname) then
+ if trace_detail then
+ report_resolving("found %a by deep scanning",fname)
end
+ return fname
+ end
end
local function makepathlist(list,filetype)
- local typespec=resolvers.variableofformat(filetype)
- local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
- local entry={}
- if pathlist and #pathlist>0 then
- for k=1,#pathlist do
- local path=pathlist[k]
- local prescanned=find(path,'^!!')
- local resursive=find(path,'//$')
- local pathname=lpegmatch(inhibitstripper,path)
- local expression=makepathexpression(pathname)
- local barename=gsub(pathname,"/+$","")
- barename=resolveprefix(barename)
- local scheme=url.hasscheme(barename)
- local schemename=gsub(barename,"%.%*$",'')
- entry[k]={
- path=path,
- pathname=pathname,
- prescanned=prescanned,
- recursive=recursive,
- expression=expression,
- barename=barename,
- scheme=scheme,
- schemename=schemename,
- }
- end
- entry.typespec=typespec
- list[filetype]=entry
- else
- list[filetype]=false
- end
- return entry
+ local typespec=resolvers.variableofformat(filetype)
+ local pathlist=resolvers.expandedpathlist(typespec,filetype and usertypes[filetype])
+ local entry={}
+ if pathlist and #pathlist>0 then
+ for k=1,#pathlist do
+ local path=pathlist[k]
+ local prescanned=find(path,'^!!')
+ local resursive=find(path,'//$')
+ local pathname=lpegmatch(inhibitstripper,path)
+ local expression=makepathexpression(pathname)
+ local barename=gsub(pathname,"/+$","")
+ barename=resolveprefix(barename)
+ local scheme=url.hasscheme(barename)
+ local schemename=gsub(barename,"%.%*$",'')
+ entry[k]={
+ path=path,
+ pathname=pathname,
+ prescanned=prescanned,
+ recursive=recursive,
+ expression=expression,
+ barename=barename,
+ scheme=scheme,
+ schemename=schemename,
+ }
+ end
+ entry.typespec=typespec
+ list[filetype]=entry
+ else
+ list[filetype]=false
+ end
+ return entry
end
local function find_intree(filename,filetype,wantedfiles,allresults)
- local pathlists=instance.pathlists
- if not pathlists then
- pathlists=setmetatableindex({},makepathlist)
- instance.pathlists=pathlists
- end
- local pathlist=pathlists[filetype]
- if pathlist then
- local method="intree"
- local filelist=collect_files(wantedfiles)
- local dirlist={}
- local result={}
- if filelist then
- for i=1,#filelist do
- dirlist[i]=filedirname(filelist[i][3]).."/"
+ local pathlists=instance.pathlists
+ if not pathlists then
+ pathlists=setmetatableindex({},makepathlist)
+ instance.pathlists=pathlists
+ end
+ local pathlist=pathlists[filetype]
+ if pathlist then
+ local method="intree"
+ local filelist=collect_files(wantedfiles)
+ local dirlist={}
+ local result={}
+ if filelist then
+ for i=1,#filelist do
+ dirlist[i]=filedirname(filelist[i][3]).."/"
+ end
+ end
+ if trace_detail then
+ report_resolving("checking filename %a in tree",filename)
+ end
+ for k=1,#pathlist do
+ local entry=pathlist[k]
+ local path=entry.path
+ local pathname=entry.pathname
+ local done=false
+ if filelist then
+ local expression=entry.expression
+ if trace_detail then
+ report_resolving("using pattern %a for path %a",expression,pathname)
+ end
+ for k=1,#filelist do
+ local fl=filelist[k]
+ local f=fl[2]
+ local d=dirlist[k]
+ if find(d,expression) or find(resolveprefix(d),expression) then
+ result[#result+1]=resolveprefix(fl[3])
+ done=true
+ if allresults then
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
+ end
+ else
+ if trace_detail then
+ report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
+ end
+ break
end
+ elseif trace_detail then
+ report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ end
end
- if trace_detail then
- report_resolving("checking filename %a in tree",filename)
- end
- for k=1,#pathlist do
- local entry=pathlist[k]
- local path=entry.path
- local pathname=entry.pathname
- local done=false
- if filelist then
- local expression=entry.expression
+ end
+ if done then
+ method="database"
+ else
+ method="filesystem"
+ local scheme=entry.scheme
+ if not scheme or scheme=="file" then
+ local pname=entry.schemename
+ if not find(pname,"*",1,true) then
+ if can_be_dir(pname) then
+ if not done and not entry.prescanned then
if trace_detail then
- report_resolving("using pattern %a for path %a",expression,pathname)
- end
- for k=1,#filelist do
- local fl=filelist[k]
- local f=fl[2]
- local d=dirlist[k]
- if find(d,expression) or find(resolveprefix(d),expression) then
- result[#result+1]=resolveprefix(fl[3])
- done=true
- if allresults then
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, continue scanning",expression,f,d)
- end
- else
- if trace_detail then
- report_resolving("match to %a in hash for file %a and path %a, quit scanning",expression,f,d)
- end
- break
- end
- elseif trace_detail then
- report_resolving("no match to %a in hash for file %a and path %a",expression,f,d)
+ report_resolving("quick root scan for %a",pname)
+ end
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local fname=check_subpath(filejoin(pname,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
- end
- end
- if done then
- method="database"
- else
- method="filesystem"
- local scheme=entry.scheme
- if not scheme or scheme=="file" then
- local pname=entry.schemename
- if not find(pname,"*",1,true) then
- if can_be_dir(pname) then
- if not done and not entry.prescanned then
- if trace_detail then
- report_resolving("quick root scan for %a",pname)
- end
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local fname=check_subpath(filejoin(pname,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- if not done and entry.recursive then
- if trace_detail then
- report_resolving("scanning filesystem for %a",pname)
- end
- local files=resolvers.simplescanfiles(pname,false,true)
- for k=1,#wantedfiles do
- local w=wantedfiles[k]
- local subpath=files[w]
- if not subpath or subpath=="" then
- elseif type(subpath)=="string" then
- local fname=check_subpath(filejoin(pname,subpath,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- else
- for i=1,#subpath do
- local sp=subpath[i]
- if sp=="" then
- else
- local fname=check_subpath(filejoin(pname,sp,w))
- if fname then
- result[#result+1]=fname
- done=true
- if not allresults then
- break
- end
- end
- end
- end
- if done and not allresults then
- break
- end
- end
- end
- end
- end
+ end
+ end
+ if not done and entry.recursive then
+ if trace_detail then
+ report_resolving("scanning filesystem for %a",pname)
+ end
+ local files=resolvers.simplescanfiles(pname,false,true)
+ for k=1,#wantedfiles do
+ local w=wantedfiles[k]
+ local subpath=files[w]
+ if not subpath or subpath=="" then
+ elseif type(subpath)=="string" then
+ local fname=check_subpath(filejoin(pname,subpath,w))
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
+ break
end
+ end
else
- end
- else
- for k=1,#wantedfiles do
- local pname=entry.barename
- local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
- if fname then
+ for i=1,#subpath do
+ local sp=subpath[i]
+ if sp=="" then
+ else
+ local fname=check_subpath(filejoin(pname,sp,w))
+ if fname then
result[#result+1]=fname
done=true
if not allresults then
- break
+ break
end
+ end
end
+ end
+ if done and not allresults then
+ break
+ end
end
+ end
end
+ end
end
- if done and not allresults then
+ else
+ end
+ else
+ for k=1,#wantedfiles do
+ local pname=entry.barename
+ local fname=methodhandler('finders',pname.."/"..wantedfiles[k])
+ if fname then
+ result[#result+1]=fname
+ done=true
+ if not allresults then
break
+ end
end
+ end
end
- if #result>0 then
- return method,result
- end
+ end
+ if done and not allresults then
+ break
+ end
+ end
+ if #result>0 then
+ return method,result
end
+ end
end
local function find_onpath(filename,filetype,wantedfiles,allresults)
- if trace_detail then
- report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
- end
- local result={}
- for k=1,#wantedfiles do
- local fname=wantedfiles[k]
- if fname and isreadable(fname) then
- filename=fname
- result[#result+1]=filejoin('.',fname)
- if not allresults then
- break
- end
- end
- end
- if #result>0 then
- return "onpath",result
+ if trace_detail then
+ report_resolving("checking filename %a, filetype %a, wanted files %a",filename,filetype,concat(wantedfiles," | "))
+ end
+ local result={}
+ for k=1,#wantedfiles do
+ local fname=wantedfiles[k]
+ if fname and isreadable(fname) then
+ filename=fname
+ result[#result+1]=filejoin('.',fname)
+ if not allresults then
+ break
+ end
end
+ end
+ if #result>0 then
+ return "onpath",result
+ end
end
local function find_otherwise(filename,filetype,wantedfiles,allresults)
- local filelist=collect_files(wantedfiles)
- local fl=filelist and filelist[1]
- if fl then
- return "otherwise",{ resolveprefix(fl[3]) }
- end
+ local filelist=collect_files(wantedfiles)
+ local fl=filelist and filelist[1]
+ if fl then
+ return "otherwise",{ resolveprefix(fl[3]) }
+ end
end
collect_instance_files=function(filename,askedformat,allresults)
- if not filename or filename=="" then
- return {}
- end
- askedformat=askedformat or ""
- filename=collapsepath(filename,".")
- filename=gsub(filename,"^%./",getcurrentdir().."/")
- if allresults then
- local filetype,wantedfiles=find_analyze(filename,askedformat)
- local results={
- { find_direct (filename,true) },
- { find_wildcard (filename,true) },
- { find_qualified(filename,true,askedformat) },
- { find_intree (filename,filetype,wantedfiles,true) },
- { find_onpath (filename,filetype,wantedfiles,true) },
- { find_otherwise(filename,filetype,wantedfiles,true) },
- }
- local result,status,done={},{},{}
- for k,r in next,results do
- local method,list=r[1],r[2]
- if method and list then
- for i=1,#list do
- local c=collapsepath(list[i])
- if not done[c] then
- result[#result+1]=c
- done[c]=true
- end
- status[#status+1]=formatters["%-10s: %s"](method,c)
- end
- end
- end
- if trace_detail then
- report_resolving("lookup status: %s",table.serialize(status,filename))
+ if not filename or filename=="" then
+ return {}
+ end
+ askedformat=askedformat or ""
+ filename=collapsepath(filename,".")
+ filename=gsub(filename,"^%./",getcurrentdir().."/")
+ if allresults then
+ local filetype,wantedfiles=find_analyze(filename,askedformat)
+ local results={
+ { find_direct (filename,true) },
+ { find_wildcard (filename,true) },
+ { find_qualified(filename,true,askedformat) },
+ { find_intree (filename,filetype,wantedfiles,true) },
+ { find_onpath (filename,filetype,wantedfiles,true) },
+ { find_otherwise(filename,filetype,wantedfiles,true) },
+ }
+ local result,status,done={},{},{}
+ for k,r in next,results do
+ local method,list=r[1],r[2]
+ if method and list then
+ for i=1,#list do
+ local c=collapsepath(list[i])
+ if not done[c] then
+ result[#result+1]=c
+ done[c]=true
+ end
+ status[#status+1]=formatters["%-10s: %s"](method,c)
end
- return result,status
- else
- local method,result,stamp,filetype,wantedfiles
- if instance.remember then
- if askedformat=="" then
- stamp=formatters["%s::%s"](suffixonly(filename),filename)
- else
- stamp=formatters["%s::%s"](askedformat,filename)
- end
- result=stamp and instance.found[stamp]
- if result then
- if trace_locating then
- report_resolving("remembered file %a",filename)
- end
- return result
- end
+ end
+ end
+ if trace_detail then
+ report_resolving("lookup status: %s",table.serialize(status,filename))
+ end
+ return result,status
+ else
+ local method,result,stamp,filetype,wantedfiles
+ if instance.remember then
+ if askedformat=="" then
+ stamp=formatters["%s::%s"](suffixonly(filename),filename)
+ else
+ stamp=formatters["%s::%s"](askedformat,filename)
+ end
+ result=stamp and instance.found[stamp]
+ if result then
+ if trace_locating then
+ report_resolving("remembered file %a",filename)
end
- method,result=find_direct(filename)
+ return result
+ end
+ end
+ method,result=find_direct(filename)
+ if not result then
+ method,result=find_wildcard(filename)
+ if not result then
+ method,result=find_qualified(filename,false,askedformat)
if not result then
- method,result=find_wildcard(filename)
- if not result then
- method,result=find_qualified(filename,false,askedformat)
- if not result then
- filetype,wantedfiles=find_analyze(filename,askedformat)
- method,result=find_intree(filename,filetype,wantedfiles)
- if not result then
- method,result=find_onpath(filename,filetype,wantedfiles)
- if resolve_otherwise and not result then
- method,result=find_otherwise(filename,filetype,wantedfiles)
- end
- end
- end
- end
- end
- if result and #result>0 then
- local foundname=collapsepath(result[1])
- resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
- result={ foundname }
- else
- result={}
- end
- if stamp then
- if trace_locating then
- report_resolving("remembering file %a using hash %a",filename,stamp)
+ filetype,wantedfiles=find_analyze(filename,askedformat)
+ method,result=find_intree(filename,filetype,wantedfiles)
+ if not result then
+ method,result=find_onpath(filename,filetype,wantedfiles)
+ if resolve_otherwise and not result then
+ method,result=find_otherwise(filename,filetype,wantedfiles)
end
- instance.found[stamp]=result
+ end
end
- return result
+ end
+ end
+ if result and #result>0 then
+ local foundname=collapsepath(result[1])
+ resolvers.registerintrees(filename,askedformat,filetype,method,foundname)
+ result={ foundname }
+ else
+ result={}
end
+ if stamp then
+ if trace_locating then
+ report_resolving("remembering file %a using hash %a",filename,stamp)
+ end
+ instance.found[stamp]=result
+ end
+ return result
+ end
end
local function findfiles(filename,filetype,allresults)
- if not filename or filename=="" then
- return {}
- end
- local result,status=collect_instance_files(filename,filetype or "",allresults)
- if not result or #result==0 then
- local lowered=lower(filename)
- if filename~=lowered then
- result,status=collect_instance_files(lowered,filetype or "",allresults)
- end
+ if not filename or filename=="" then
+ return {}
+ end
+ local result,status=collect_instance_files(filename,filetype or "",allresults)
+ if not result or #result==0 then
+ local lowered=lower(filename)
+ if filename~=lowered then
+ result,status=collect_instance_files(lowered,filetype or "",allresults)
end
- return result or {},status
+ end
+ return result or {},status
end
function resolvers.findfiles(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,true)
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,true)
+ end
end
function resolvers.findfile(filename,filetype)
- if not filename or filename=="" then
- return ""
- else
- return findfiles(filename,filetype,false)[1] or ""
- end
+ if not filename or filename=="" then
+ return ""
+ else
+ return findfiles(filename,filetype,false)[1] or ""
+ end
end
function resolvers.findpath(filename,filetype)
- return filedirname(findfiles(filename,filetype,false)[1] or "")
+ return filedirname(findfiles(filename,filetype,false)[1] or "")
end
local function findgivenfiles(filename,allresults)
- local base=filebasename(filename)
- local result={}
- local hashes=instance.hashes
- local function okay(hash,path,name)
- local found=methodhandler('concatinators',hash.type,hash.name,path,name)
- if found and found~="" then
- result[#result+1]=resolveprefix(found)
- return not allresults
- end
- end
- for k=1,#hashes do
- local hash=hashes[k]
- local content=instance.files[hash.name]
- if content then
- local path,name=lookup(content,base)
- if not path then
- elseif type(path)=="string" then
- if okay(hash,path,name) then
- return result
- end
- else
- for i=1,#path do
- if okay(hash,path[i],name) then
- return result
- end
- end
- end
+ local base=filebasename(filename)
+ local result={}
+ local hashes=instance.hashes
+ local function okay(hash,path,name)
+ local found=methodhandler('concatinators',hash.type,hash.name,path,name)
+ if found and found~="" then
+ result[#result+1]=resolveprefix(found)
+ return not allresults
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local content=instance.files[hash.name]
+ if content then
+ local path,name=lookup(content,base)
+ if not path then
+ elseif type(path)=="string" then
+ if okay(hash,path,name) then
+ return result
+ end
+ else
+ for i=1,#path do
+ if okay(hash,path[i],name) then
+ return result
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findgivenfiles(filename)
- return findgivenfiles(filename,true)
+ return findgivenfiles(filename,true)
end
function resolvers.findgivenfile(filename)
- return findgivenfiles(filename,false)[1] or ""
+ return findgivenfiles(filename,false)[1] or ""
end
local makewildcard=Cs(
- (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
+ (P("^")^0*P("/")*P(-1)+P(-1))/".*"+(P("^")^0*P("/")/"")^0*(P("*")/".*"+P("-")/"%%-"+P(".")/"%%."+P("?")/"."+P("\\")/"/"+P(1))^0
)
function resolvers.wildcardpattern(pattern)
- return lpegmatch(makewildcard,pattern) or pattern
+ return lpegmatch(makewildcard,pattern) or pattern
end
local function findwildcardfiles(filename,allresults,result)
- local result=result or {}
- local base=filebasename(filename)
- local dirn=filedirname(filename)
- local path=lower(lpegmatch(makewildcard,dirn) or dirn)
- local name=lower(lpegmatch(makewildcard,base) or base)
- local files=instance.files
- if find(name,"*",1,true) then
- local hashes=instance.hashes
- local function okay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
- end
+ local result=result or {}
+ local base=filebasename(filename)
+ local dirn=filedirname(filename)
+ local path=lower(lpegmatch(makewildcard,dirn) or dirn)
+ local name=lower(lpegmatch(makewildcard,base) or base)
+ local files=instance.files
+ if find(name,"*",1,true) then
+ local hashes=instance.hashes
+ local function okay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
end
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- for found,base in filtered(files[hashname],name) do
- if type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
- end
+ end
+ end
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ for found,base in filtered(files[hashname],name) do
+ if type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
end
- end
- else
- local function okayokay(found,path,base,hashname,hashtype)
- if find(found,path) then
- local full=methodhandler('concatinators',hashtype,hashname,found,base)
- if full and full~="" then
- result[#result+1]=resolveprefix(full)
- return not allresults
- end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
+ end
end
+ end
end
- local hashes=instance.hashes
- for k=1,#hashes do
- local hash=hashes[k]
- local hashname=hash.name
- local hashtype=hash.type
- if hashname and hashtype then
- local found,base=lookup(content,base)
- if not found then
- elseif type(found)=='string' then
- if okay(found,path,base,hashname,hashtype) then
- break
- end
- else
- for i=1,#found do
- if okay(found[i],path,base,hashname,hashtype) then
- break
- end
- end
- end
+ end
+ end
+ else
+ local function okayokay(found,path,base,hashname,hashtype)
+ if find(found,path) then
+ local full=methodhandler('concatinators',hashtype,hashname,found,base)
+ if full and full~="" then
+ result[#result+1]=resolveprefix(full)
+ return not allresults
+ end
+ end
+ end
+ local hashes=instance.hashes
+ for k=1,#hashes do
+ local hash=hashes[k]
+ local hashname=hash.name
+ local hashtype=hash.type
+ if hashname and hashtype then
+ local found,base=lookup(content,base)
+ if not found then
+ elseif type(found)=='string' then
+ if okay(found,path,base,hashname,hashtype) then
+ break
+ end
+ else
+ for i=1,#found do
+ if okay(found[i],path,base,hashname,hashtype) then
+ break
end
+ end
end
+ end
end
- return result
+ end
+ return result
end
function resolvers.findwildcardfiles(filename,result)
- return findwildcardfiles(filename,true,result)
+ return findwildcardfiles(filename,true,result)
end
function resolvers.findwildcardfile(filename)
- return findwildcardfiles(filename,false)[1] or ""
+ return findwildcardfiles(filename,false)[1] or ""
end
function resolvers.automount()
end
function resolvers.starttiming()
- statistics.starttiming(instance)
+ statistics.starttiming(instance)
end
function resolvers.stoptiming()
- statistics.stoptiming(instance)
+ statistics.stoptiming(instance)
end
function resolvers.load(option)
- resolvers.starttiming()
- identify_configuration_files()
- load_configuration_files()
- if option~="nofiles" then
- load_databases()
- resolvers.automount()
- end
- resolvers.stoptiming()
- local files=instance.files
- return files and next(files) and true
+ resolvers.starttiming()
+ identify_configuration_files()
+ load_configuration_files()
+ if option~="nofiles" then
+ load_databases()
+ resolvers.automount()
+ end
+ resolvers.stoptiming()
+ local files=instance.files
+ return files and next(files) and true
end
function resolvers.loadtime()
- return statistics.elapsedtime(instance)
+ return statistics.elapsedtime(instance)
end
local function report(str)
- if trace_locating then
- report_resolving(str)
- else
- print(str)
- end
+ if trace_locating then
+ report_resolving(str)
+ else
+ print(str)
+ end
end
function resolvers.dowithfilesandreport(command,files,...)
- if files and #files>0 then
- if trace_locating then
- report('')
- end
- if type(files)=="string" then
- files={ files }
- end
- for f=1,#files do
- local file=files[f]
- local result=command(file,...)
- if type(result)=='string' then
- report(result)
- else
- for i=1,#result do
- report(result[i])
- end
- end
+ if files and #files>0 then
+ if trace_locating then
+ report('')
+ end
+ if type(files)=="string" then
+ files={ files }
+ end
+ for f=1,#files do
+ local file=files[f]
+ local result=command(file,...)
+ if type(result)=='string' then
+ report(result)
+ else
+ for i=1,#result do
+ report(result[i])
end
+ end
end
+ end
end
-function resolvers.showpath(str)
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+function resolvers.showpath(str)
+ return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
end
function resolvers.registerfile(files,name,path)
- if files[name] then
- if type(files[name])=='string' then
- files[name]={ files[name],path }
- else
- files[name]=path
- end
+ if files[name] then
+ if type(files[name])=='string' then
+ files[name]={ files[name],path }
else
- files[name]=path
+ files[name]=path
end
+ else
+ files[name]=path
+ end
end
function resolvers.dowithpath(name,func)
- local pathlist=resolvers.expandedpathlist(name)
- for i=1,#pathlist do
- func("^"..cleanpath(pathlist[i]))
- end
+ local pathlist=resolvers.expandedpathlist(name)
+ for i=1,#pathlist do
+ func("^"..cleanpath(pathlist[i]))
+ end
end
function resolvers.dowithvariable(name,func)
- func(expandedvariable(name))
+ func(expandedvariable(name))
end
function resolvers.locateformat(name)
- local engine=environment.ownmain or "luatex"
- local barename=removesuffix(name)
- local fullname=addsuffix(barename,"fmt")
- local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
- if fmtname=="" then
- fmtname=resolvers.findfile(fullname)
- fmtname=cleanpath(fmtname)
- end
- if fmtname~="" then
- local barename=removesuffix(fmtname)
- local luaname=addsuffix(barename,luasuffixes.lua)
- local lucname=addsuffix(barename,luasuffixes.luc)
- local luiname=addsuffix(barename,luasuffixes.lui)
- if isfile(luiname) then
- return barename,luiname
- elseif isfile(lucname) then
- return barename,lucname
- elseif isfile(luaname) then
- return barename,luaname
- end
- end
- return nil,nil
+ local engine=environment.ownmain or "luatex"
+ local barename=removesuffix(name)
+ local fullname=addsuffix(barename,"fmt")
+ local fmtname=caches.getfirstreadablefile(fullname,"formats",engine) or ""
+ if fmtname=="" then
+ fmtname=resolvers.findfile(fullname)
+ fmtname=cleanpath(fmtname)
+ end
+ if fmtname~="" then
+ local barename=removesuffix(fmtname)
+ local luaname=addsuffix(barename,luasuffixes.lua)
+ local lucname=addsuffix(barename,luasuffixes.luc)
+ local luiname=addsuffix(barename,luasuffixes.lui)
+ if isfile(luiname) then
+ return barename,luiname
+ elseif isfile(lucname) then
+ return barename,lucname
+ elseif isfile(luaname) then
+ return barename,luaname
+ end
+ end
+ return nil,nil
end
function resolvers.booleanvariable(str,default)
- local b=resolvers.expansion(str)
- if b=="" then
- return default
- else
- b=toboolean(b)
- return (b==nil and default) or b
- end
+ local b=resolvers.expansion(str)
+ if b=="" then
+ return default
+ else
+ b=toboolean(b)
+ return (b==nil and default) or b
+ end
end
function resolvers.dowithfilesintree(pattern,handle,before,after)
- local hashes=instance.hashes
- for i=1,#hashes do
- local hash=hashes[i]
- local blobtype=hash.type
- local blobpath=hash.name
- if blobtype and blobpath then
- local total=0
- local checked=0
- local done=0
- if before then
- before(blobtype,blobpath,pattern)
- end
- for path,name in filtered(instance.files[blobpath],pattern) do
- if type(path)=="string" then
- checked=checked+1
- if handle(blobtype,blobpath,path,name) then
- done=done+1
- end
- else
- checked=checked+#path
- for i=1,#path do
- if handle(blobtype,blobpath,path[i],name) then
- done=done+1
- end
- end
- end
- end
- if after then
- after(blobtype,blobpath,pattern,total,checked,done)
+ local hashes=instance.hashes
+ for i=1,#hashes do
+ local hash=hashes[i]
+ local blobtype=hash.type
+ local blobpath=hash.name
+ if blobtype and blobpath then
+ local total=0
+ local checked=0
+ local done=0
+ if before then
+ before(blobtype,blobpath,pattern)
+ end
+ for path,name in filtered(instance.files[blobpath],pattern) do
+ if type(path)=="string" then
+ checked=checked+1
+ if handle(blobtype,blobpath,path,name) then
+ done=done+1
+ end
+ else
+ checked=checked+#path
+ for i=1,#path do
+ if handle(blobtype,blobpath,path[i],name) then
+ done=done+1
end
+ end
end
+ end
+ if after then
+ after(blobtype,blobpath,pattern,checked,done)
+ end
end
+ end
end
local obsolete=resolvers.obsolete or {}
resolvers.obsolete=obsolete
-resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
-resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
+resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile
+resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles
function resolvers.knownvariables(pattern)
- if instance then
- local environment=instance.environment
- local variables=instance.variables
- local expansions=instance.expansions
- local order=instance.order
- local pattern=upper(pattern or "")
- local result={}
- for i=1,#order do
- for key in next,order[i] do
- if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
- result[key]={
- environment=rawget(environment,key),
- variable=key,
- expansion=expansions[key],
- resolved=resolveprefix(expansions[key]),
- }
- end
- end
+ if instance then
+ local environment=instance.environment
+ local variables=instance.variables
+ local expansions=instance.expansions
+ local order=instance.order
+ local pattern=upper(pattern or "")
+ local result={}
+ for i=1,#order do
+ for key in next,order[i] do
+ if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then
+ result[key]={
+ environment=rawget(environment,key),
+ variable=key,
+ expansion=expansions[key],
+ resolved=resolveprefix(expansions[key]),
+ }
end
- return result
- else
- return {}
+ end
end
+ return result
+ else
+ return {}
+ end
end
@@ -19311,14 +22885,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-pre"] = package.loaded["data-pre"] or true
--- original size: 4090, stripped down to: 3059
+-- original size: 4854, stripped down to: 2889
if not modules then modules={} end modules ['data-pre']={
- 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 resolvers=resolvers
local prefixes=resolvers.prefixes
@@ -19331,64 +22905,64 @@ local dirname=file.dirname
local joinpath=file.join
local isfile=lfs.isfile
prefixes.environment=function(str)
- return cleanpath(expansion(str))
+ return cleanpath(expansion(str))
end
local function relative(str,n)
- if not isfile(str) then
- local pstr="./"..str
+ if not isfile(str) then
+ local pstr="./"..str
+ if isfile(pstr) then
+ str=pstr
+ else
+ local p="../"
+ for i=1,n or 2 do
+ local pstr=p..str
if isfile(pstr) then
- str=pstr
+ str=pstr
+ break
else
- local p="../"
- for i=1,n or 2 do
- local pstr=p..str
- if isfile(pstr) then
- str=pstr
- break
- else
- p=p.."../"
- end
- end
+ p=p.."../"
end
+ end
end
- return cleanpath(str)
+ end
+ return cleanpath(str)
end
local function locate(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(fullname~="" and fullname or str)
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(fullname~="" and fullname or str)
end
prefixes.relative=relative
prefixes.locate=locate
prefixes.auto=function(str)
- local fullname=relative(str)
- if not isfile(fullname) then
- fullname=locate(str)
- end
- return fullname
+ local fullname=relative(str)
+ if not isfile(fullname) then
+ fullname=locate(str)
+ end
+ return fullname
end
prefixes.filename=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(basename((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(basename((fullname~="" and fullname) or str))
end
prefixes.pathname=function(str)
- local fullname=findgivenfile(str) or ""
- return cleanpath(dirname((fullname~="" and fullname) or str))
+ local fullname=findgivenfile(str) or ""
+ return cleanpath(dirname((fullname~="" and fullname) or str))
end
prefixes.selfautoloc=function(str)
- local pth=getenv('SELFAUTOLOC')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOLOC')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautoparent=function(str)
- local pth=getenv('SELFAUTOPARENT')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTOPARENT')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.selfautodir=function(str)
- local pth=getenv('SELFAUTODIR')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('SELFAUTODIR')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.home=function(str)
- local pth=getenv('HOME')
- return cleanpath(str and joinpath(pth,str) or pth)
+ local pth=getenv('HOME')
+ return cleanpath(str and joinpath(pth,str) or pth)
end
prefixes.env=prefixes.environment
prefixes.rel=prefixes.relative
@@ -19398,24 +22972,24 @@ prefixes.full=prefixes.locate
prefixes.file=prefixes.filename
prefixes.path=prefixes.pathname
local function toppath()
- local inputstack=resolvers.inputstack
- if not inputstack then
- return "."
- end
- local pathname=dirname(inputstack[#inputstack] or "")
- if pathname=="" then
- return "."
- else
- return pathname
- end
+ local inputstack=resolvers.inputstack
+ if not inputstack then
+ return "."
+ end
+ local pathname=dirname(inputstack[#inputstack] or "")
+ if pathname=="" then
+ return "."
+ else
+ return pathname
+ end
end
local function jobpath()
- local path=resolvers.stackpath()
- if not path or path=="" then
- return "."
- else
- return path
- end
+ local path=resolvers.stackpath()
+ if not path or path=="" then
+ return "."
+ else
+ return path
+ end
end
resolvers.toppath=toppath
resolvers.jobpath=jobpath
@@ -19423,8 +22997,6 @@ prefixes.toppath=function(str) return cleanpath(joinpath(toppath(),str)) end
prefixes.jobpath=function(str) return cleanpath(joinpath(jobpath(),str)) end
resolvers.setdynamic("toppath")
resolvers.setdynamic("jobpath")
-prefixes.jobfile=prefixes.jobpath
-resolvers.setdynamic("jobfile")
end -- of closure
@@ -19433,14 +23005,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-inp"] = package.loaded["data-inp"] or true
--- original size: 910, stripped down to: 823
+-- original size: 910, stripped down to: 818
if not modules then modules={} end modules ['data-inp']={
- 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 allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -19463,14 +23035,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-out"] = package.loaded["data-out"] or true
--- original size: 530, stripped down to: 475
+-- original size: 530, stripped down to: 470
if not modules then modules={} end modules ['data-out']={
- 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 allocate=utilities.storage.allocate
local resolvers=resolvers
@@ -19486,16 +23058,16 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-fil"] = package.loaded["data-fil"] or true
--- original size: 3863, stripped down to: 3310
+-- original size: 3863, stripped down to: 3170
if not modules then modules={} end modules ['data-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 trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_files=logs.reporter("resolvers","files")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -19503,88 +23075,88 @@ local finders,openers,loaders,savers=resolvers.finders,resolvers.openers,resolve
local locators,hashers,generators,concatinators=resolvers.locators,resolvers.hashers,resolvers.generators,resolvers.concatinators
local checkgarbage=utilities.garbagecollector and utilities.garbagecollector.check
function locators.file(specification)
- local filename=specification.filename
- local realname=resolveprefix(filename)
- if realname and realname~='' and lfs.isdir(realname) then
- if trace_locating then
- report_files("file locator %a found as %a",filename,realname)
- end
- resolvers.appendhash('file',filename,true)
- elseif trace_locating then
- report_files("file locator %a not found",filename)
+ local filename=specification.filename
+ local realname=resolveprefix(filename)
+ if realname and realname~='' and lfs.isdir(realname) then
+ if trace_locating then
+ report_files("file locator %a found as %a",filename,realname)
end
+ resolvers.appendhash('file',filename,true)
+ elseif trace_locating then
+ report_files("file locator %a not found",filename)
+ end
end
function hashers.file(specification)
- local pathname=specification.filename
- local content=caches.loadcontent(pathname,'files')
- resolvers.registerfilehash(pathname,content,content==nil)
+ local pathname=specification.filename
+ local content=caches.loadcontent(pathname,'files')
+ resolvers.registerfilehash(pathname,content,content==nil)
end
function generators.file(specification)
- local pathname=specification.filename
- local content=resolvers.scanfiles(pathname,false,true)
- resolvers.registerfilehash(pathname,content,true)
+ local pathname=specification.filename
+ local content=resolvers.scanfiles(pathname,false,true)
+ resolvers.registerfilehash(pathname,content,true)
end
concatinators.file=file.join
function finders.file(specification,filetype)
- local filename=specification.filename
- local foundname=resolvers.findfile(filename,filetype)
- if foundname and foundname~="" then
- if trace_locating then
- report_files("file finder: %a found",filename)
- end
- return foundname
- else
- if trace_locating then
- report_files("file finder: %a not found",filename)
- end
- return finders.notfound()
+ local filename=specification.filename
+ local foundname=resolvers.findfile(filename,filetype)
+ if foundname and foundname~="" then
+ if trace_locating then
+ report_files("file finder: %a found",filename)
+ end
+ return foundname
+ else
+ if trace_locating then
+ report_files("file finder: %a not found",filename)
end
+ return finders.notfound()
+ end
end
function openers.helpers.textopener(tag,filename,f)
- return {
- reader=function() return f:read () end,
- close=function() logs.show_close(filename) return f:close() end,
- }
+ return {
+ reader=function() return f:read () end,
+ close=function() logs.show_close(filename) return f:close() end,
+ }
end
function openers.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"r")
- if f then
- if trace_locating then
- report_files("file opener: %a opened",filename)
- end
- return openers.helpers.textopener("file",filename,f)
- end
- end
- if trace_locating then
- report_files("file opener: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"r")
+ if f then
+ if trace_locating then
+ report_files("file opener: %a opened",filename)
+ end
+ return openers.helpers.textopener("file",filename,f)
end
- return openers.notfound()
+ end
+ if trace_locating then
+ report_files("file opener: %a not found",filename)
+ end
+ return openers.notfound()
end
function loaders.file(specification,filetype)
- local filename=specification.filename
- if filename and filename~="" then
- local f=io.open(filename,"rb")
- if f then
- logs.show_load(filename)
- if trace_locating then
- report_files("file loader: %a loaded",filename)
- end
- local s=f:read("*a")
- if checkgarbage then
- checkgarbage(#s)
- end
- f:close()
- if s then
- return true,s,#s
- end
- end
- end
- if trace_locating then
- report_files("file loader: %a not found",filename)
+ local filename=specification.filename
+ if filename and filename~="" then
+ local f=io.open(filename,"rb")
+ if f then
+ logs.show_load(filename)
+ if trace_locating then
+ report_files("file loader: %a loaded",filename)
+ end
+ local s=f:read("*a")
+ if checkgarbage then
+ checkgarbage(#s)
+ end
+ f:close()
+ if s then
+ return true,s,#s
+ end
end
- return loaders.notfound()
+ end
+ if trace_locating then
+ report_files("file loader: %a not found",filename)
+ end
+ return loaders.notfound()
end
@@ -19594,116 +23166,116 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-con"] = package.loaded["data-con"] or true
--- original size: 5029, stripped down to: 3607
+-- original size: 5029, stripped down to: 3432
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
- return stored
+ 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
+ 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
+ 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
- return data
+ 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
@@ -19713,97 +23285,101 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-use"] = package.loaded["data-use"] or true
--- original size: 4272, stripped down to: 3289
+-- original size: 4434, stripped down to: 3180
if not modules then modules={} end modules ['data-use']={
- 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 format,lower,gsub,find=string.format,string.lower,string.gsub,string.find
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_mounts=logs.reporter("resolvers","mounts")
local resolvers=resolvers
resolvers.automounted=resolvers.automounted or {}
function resolvers.automount(usecache)
- local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
- if (not mountpaths or #mountpaths==0) and usecache then
- mountpaths=caches.getreadablepaths("mount")
- end
- if mountpaths and #mountpaths>0 then
- resolvers.starttiming()
- for k=1,#mountpaths do
- local root=mountpaths[k]
- local f=io.open(root.."/url.tmi")
- if f then
- for line in f:lines() do
- if line then
- if find(line,"^[%%#%-]") then
- elseif find(line,"^zip://") then
- if trace_locating then
- report_mounts("mounting %a",line)
- end
- table.insert(resolvers.automounted,line)
- resolvers.usezipfile(line)
- end
- end
- end
- f:close()
+ local mountpaths=resolvers.cleanpathlist(resolvers.expansion('TEXMFMOUNT'))
+ if (not mountpaths or #mountpaths==0) and usecache then
+ mountpaths=caches.getreadablepaths("mount")
+ end
+ if mountpaths and #mountpaths>0 then
+ resolvers.starttiming()
+ for k=1,#mountpaths do
+ local root=mountpaths[k]
+ local f=io.open(root.."/url.tmi")
+ if f then
+ for line in f:lines() do
+ if line then
+ if find(line,"^[%%#%-]") then
+ elseif find(line,"^zip://") then
+ if trace_locating then
+ report_mounts("mounting %a",line)
+ end
+ table.insert(resolvers.automounted,line)
+ resolvers.usezipfile(line)
end
+ end
end
- resolvers.stoptiming()
+ f:close()
+ end
end
+ resolvers.stoptiming()
+ end
end
statistics.register("used config file",function() return caches.configfiles() end)
statistics.register("used cache path",function() return caches.usedpaths() end)
function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner)
- local enginebanner=status.banner
- if formatbanner and enginebanner and sourcefile then
- local luvname=file.replacesuffix(texname,"luv")
- local luvdata={
- enginebanner=enginebanner,
- formatbanner=formatbanner,
- sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
- sourcefile=sourcefile,
- luaversion=LUAVERSION,
- }
- io.savedata(luvname,table.serialize(luvdata,true))
- lua.registerfinalizer(function()
- logs.report("format banner","%s",banner)
- logs.newline()
- end)
- end
+ local enginebanner=status.banner
+ if formatbanner and enginebanner and sourcefile then
+ local luvname=file.replacesuffix(texname,"luv")
+ local luvdata={
+ enginebanner=enginebanner,
+ formatbanner=formatbanner,
+ sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"),
+ sourcefile=sourcefile,
+ luaversion=LUAVERSION,
+ }
+ io.savedata(luvname,table.serialize(luvdata,true))
+ lua.registerfinalizer(function()
+ 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
end
function statistics.checkfmtstatus(texname)
- local enginebanner=status.banner
- if enginebanner and texname then
- local luvname=file.replacesuffix(texname,"luv")
- if lfs.isfile(luvname) then
- local luv=dofile(luvname)
- if luv and luv.sourcefile then
- local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
- local luvbanner=luv.enginebanner or "?"
- if luvbanner~=enginebanner then
- return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
- end
- local luvhash=luv.sourcehash or "?"
- if luvhash~=sourcehash then
- return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
- end
- local luvluaversion=luv.luaversion or 0
- if luvluaversion~=LUAVERSION then
- return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
- end
- else
- return "invalid status file"
- end
- else
- return "missing status file"
- end
+ local enginebanner=status.banner
+ if enginebanner and texname then
+ local luvname=file.replacesuffix(texname,"luv")
+ if lfs.isfile(luvname) then
+ local luv=dofile(luvname)
+ if luv and luv.sourcefile then
+ local sourcehash=md5.hex(io.loaddata(resolvers.findfile(luv.sourcefile)) or "unknown")
+ local luvbanner=luv.enginebanner or "?"
+ if luvbanner~=enginebanner then
+ return format("engine mismatch (luv: %s <> bin: %s)",luvbanner,enginebanner)
+ end
+ local luvhash=luv.sourcehash or "?"
+ if luvhash~=sourcehash then
+ return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash)
+ end
+ local luvluaversion=luv.luaversion or 0
+ if luvluaversion~=LUAVERSION then
+ return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION)
+ end
+ else
+ return "invalid status file"
+ end
+ else
+ return "missing status file"
end
- return true
+ end
+ return true
end
@@ -19813,233 +23389,233 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-zip"] = package.loaded["data-zip"] or true
--- original size: 8716, stripped down to: 6795
+-- original size: 8700, stripped down to: 6313
if not modules then modules={} end modules ['data-zip']={
- 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 format,find,match=string.format,string.find,string.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_zip=logs.reporter("resolvers","zip")
local resolvers=resolvers
zip=zip or {}
local zip=zip
-zip.archives=zip.archives or {}
-local archives=zip.archives
-zip.registeredfiles=zip.registeredfiles or {}
-local registeredfiles=zip.registeredfiles
+local archives=zip.archives or {}
+zip.archives=archives
+local registeredfiles=zip.registeredfiles or {}
+zip.registeredfiles=registeredfiles
local function validzip(str)
- if not find(str,"^zip://") then
- return "zip:///"..str
- else
- return str
- end
+ if not find(str,"^zip://") then
+ return "zip:///"..str
+ else
+ return str
+ end
end
function zip.openarchive(name)
- if not name or name=="" then
- return nil
- else
- local arch=archives[name]
- if not arch then
- local full=resolvers.findfile(name) or ""
- arch=full~="" and zip.open(full) or false
- archives[name]=arch
- end
- return arch
+ if not name or name=="" then
+ return nil
+ else
+ local arch=archives[name]
+ if not arch then
+ local full=resolvers.findfile(name) or ""
+ arch=full~="" and zip.open(full) or false
+ archives[name]=arch
end
+ return arch
+ end
end
function zip.closearchive(name)
- if not name or (name=="" and archives[name]) then
- zip.close(archives[name])
- archives[name]=nil
- end
+ if not name or (name=="" and archives[name]) then
+ zip.close(archives[name])
+ archives[name]=nil
+ end
end
function resolvers.locators.zip(specification)
- local archive=specification.filename
- local zipfile=archive and archive~="" and zip.openarchive(archive)
- if trace_locating then
- if zipfile then
- report_zip("locator: archive %a found",archive)
- else
- report_zip("locator: archive %a not found",archive)
- end
+ local archive=specification.filename
+ local zipfile=archive and archive~="" and zip.openarchive(archive)
+ if trace_locating then
+ if zipfile then
+ report_zip("locator: archive %a found",archive)
+ else
+ report_zip("locator: archive %a not found",archive)
end
+ end
end
function resolvers.hashers.zip(specification)
- local archive=specification.filename
- if trace_locating then
- report_zip("loading file %a",archive)
- end
- resolvers.usezipfile(specification.original)
+ local archive=specification.filename
+ if trace_locating then
+ report_zip("loading file %a",archive)
+ end
+ resolvers.usezipfile(specification.original)
end
function resolvers.concatinators.zip(zipfile,path,name)
- if not path or path=="" then
- return format('%s?name=%s',zipfile,name)
- else
- return format('%s?name=%s/%s',zipfile,path,name)
- end
+ if not path or path=="" then
+ return format('%s?name=%s',zipfile,name)
+ else
+ return format('%s?name=%s/%s',zipfile,path,name)
+ end
end
function resolvers.finders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("finder: archive %a found",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- dfile=zfile:close()
- if trace_locating then
- report_zip("finder: file %a found",queryname)
- end
- return specification.original
- elseif trace_locating then
- report_zip("finder: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("finder: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("finder: archive %a found",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ dfile:close()
+ if trace_locating then
+ report_zip("finder: file %a found",queryname)
+ end
+ return specification.original
+ elseif trace_locating then
+ report_zip("finder: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("finder: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("finder: %a not found",original)
- end
- return resolvers.finders.notfound()
+ end
+ if trace_locating then
+ report_zip("finder: %a not found",original)
+ end
+ return resolvers.finders.notfound()
end
function resolvers.openers.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("opener; archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- if trace_locating then
- report_zip("opener: file %a found",queryname)
- end
- return resolvers.openers.helpers.textopener('zip',original,dfile)
- elseif trace_locating then
- report_zip("opener: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("opener: unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("opener; archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ if trace_locating then
+ report_zip("opener: file %a found",queryname)
+ end
+ return resolvers.openers.helpers.textopener('zip',original,dfile)
+ elseif trace_locating then
+ report_zip("opener: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("opener: unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("opener: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("opener: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.loaders.zip(specification)
- local original=specification.original
- local archive=specification.filename
- if archive then
- local query=url.query(specification.query)
- local queryname=query.name
- if queryname then
- local zfile=zip.openarchive(archive)
- if zfile then
- if trace_locating then
- report_zip("loader: archive %a opened",archive)
- end
- local dfile=zfile:open(queryname)
- if dfile then
- logs.show_load(original)
- if trace_locating then
- report_zip("loader; file %a loaded",original)
- end
- local s=dfile:read("*all")
- dfile:close()
- return true,s,#s
- elseif trace_locating then
- report_zip("loader: file %a not found",queryname)
- end
- elseif trace_locating then
- report_zip("loader; unknown archive %a",archive)
- end
+ local original=specification.original
+ local archive=specification.filename
+ if archive then
+ local query=url.query(specification.query)
+ local queryname=query.name
+ if queryname then
+ local zfile=zip.openarchive(archive)
+ if zfile then
+ if trace_locating then
+ report_zip("loader: archive %a opened",archive)
end
+ local dfile=zfile:open(queryname)
+ if dfile then
+ logs.show_load(original)
+ if trace_locating then
+ report_zip("loader; file %a loaded",original)
+ end
+ local s=dfile:read("*all")
+ dfile:close()
+ return true,s,#s
+ elseif trace_locating then
+ report_zip("loader: file %a not found",queryname)
+ end
+ elseif trace_locating then
+ report_zip("loader; unknown archive %a",archive)
+ end
end
- if trace_locating then
- report_zip("loader: %a not found",original)
- end
- return resolvers.openers.notfound()
+ end
+ if trace_locating then
+ report_zip("loader: %a not found",original)
+ end
+ return resolvers.openers.notfound()
end
function resolvers.usezipfile(archive)
- local specification=resolvers.splitmethod(archive)
- local archive=specification.filename
- if archive and not registeredfiles[archive] then
- local z=zip.openarchive(archive)
- if z then
- local tree=url.query(specification.query).tree or ""
- if trace_locating then
- report_zip("registering: archive %a",archive)
- end
- resolvers.starttiming()
- resolvers.prependhash('zip',archive)
- resolvers.extendtexmfvariable(archive)
- registeredfiles[archive]=z
- resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
- resolvers.stoptiming()
- elseif trace_locating then
- report_zip("registering: unknown archive %a",archive)
- end
+ local specification=resolvers.splitmethod(archive)
+ local archive=specification.filename
+ if archive and not registeredfiles[archive] then
+ local z=zip.openarchive(archive)
+ if z then
+ local tree=url.query(specification.query).tree or ""
+ if trace_locating then
+ report_zip("registering: archive %a",archive)
+ end
+ resolvers.starttiming()
+ resolvers.prependhash('zip',archive)
+ resolvers.extendtexmfvariable(archive)
+ registeredfiles[archive]=z
+ resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree))
+ resolvers.stoptiming()
elseif trace_locating then
- report_zip("registering: archive %a not found",archive)
+ report_zip("registering: unknown archive %a",archive)
end
+ elseif trace_locating then
+ report_zip("registering: archive %a not found",archive)
+ end
end
function resolvers.registerzipfile(z,tree)
- local names={}
- local files={}
- local remap={}
- local n=0
- local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
- local register=resolvers.registerfile
- if trace_locating then
- report_zip("registering: using filter %a",filter)
- end
- for i in z:files() do
- local filename=i.filename
- local path,name=match(filename,filter)
- if not path then
- n=n+1
- register(names,filename,"")
- local usedname=lower(filename)
- files[usedname]=""
- if usedname~=filename then
- remap[usedname]=filename
- end
- elseif name and name~="" then
- n=n+1
- register(names,name,path)
- local usedname=lower(name)
- files[usedname]=path
- if usedname~=name then
- remap[usedname]=name
- end
- else
- end
+ local names={}
+ local files={}
+ local remap={}
+ local n=0
+ local filter=tree=="" and "^(.+)/(.-)$" or format("^%s/(.+)/(.-)$",tree)
+ local register=resolvers.registerfile
+ if trace_locating then
+ report_zip("registering: using filter %a",filter)
+ end
+ for i in z:files() do
+ local filename=i.filename
+ local path,name=match(filename,filter)
+ if not path then
+ n=n+1
+ register(names,filename,"")
+ local usedname=lower(filename)
+ files[usedname]=""
+ if usedname~=filename then
+ remap[usedname]=filename
+ end
+ elseif name and name~="" then
+ n=n+1
+ register(names,name,path)
+ local usedname=lower(name)
+ files[usedname]=path
+ if usedname~=name then
+ remap[usedname]=name
+ end
+ else
end
- report_zip("registering: %s files registered",n)
- return {
- files=files,
- remap=remap,
- }
+ end
+ report_zip("registering: %s files registered",n)
+ return {
+ files=files,
+ remap=remap,
+ }
end
@@ -20049,20 +23625,20 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tre"] = package.loaded["data-tre"] or true
--- original size: 8479, stripped down to: 5580
+-- original size: 8478, stripped down to: 5223
if not modules then modules={} end modules ['data-tre']={
- 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 find,gsub,lower=string.find,string.gsub,string.lower
-local basename,dirname,joinname=file.basename,file.dirname,file .join
+local basename,dirname,joinname=file.basename,file.dirname,file .join
local globdir,isdir,isfile=dir.glob,lfs.isdir,lfs.isfile
local P,lpegmatch=lpeg.P,lpeg.match
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local report_trees=logs.reporter("resolvers","trees")
local resolvers=resolvers
local resolveprefix=resolvers.resolve
@@ -20071,165 +23647,167 @@ local lookup=resolvers.get_from_content
local collectors={}
local found={}
function resolvers.finders.tree(specification)
- local spec=specification.filename
- local okay=found[spec]
- if okay==nil then
- if spec~="" then
- local path=dirname(spec)
- local name=basename(spec)
- if path=="" then
- path="."
- end
- local names=collectors[path]
- if not names then
- local pattern=find(path,"/%*+$") and path or (path.."/*")
- names=globdir(pattern)
- collectors[path]=names
- end
- local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
- for i=1,#names do
- local fullname=names[i]
- if find(fullname,pattern) then
- found[spec]=fullname
- return fullname
- end
- end
- local pattern=lower(pattern)
- for i=1,#names do
- local fullname=lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
- found[spec]=fullname
- return fullname
- else
- break
- end
- end
- end
+ local spec=specification.filename
+ local okay=found[spec]
+ if okay==nil then
+ if spec~="" then
+ local path=dirname(spec)
+ local name=basename(spec)
+ if path=="" then
+ path="."
+ end
+ local names=collectors[path]
+ if not names then
+ local pattern=find(path,"/%*+$") and path or (path.."/*")
+ names=globdir(pattern)
+ collectors[path]=names
+ end
+ local pattern="/"..gsub(name,"([%.%-%+])","%%%1").."$"
+ for i=1,#names do
+ local fullname=names[i]
+ if find(fullname,pattern) then
+ found[spec]=fullname
+ return fullname
+ end
+ end
+ local pattern=lower(pattern)
+ for i=1,#names do
+ local fullname=lower(names[i])
+ if find(fullname,pattern) then
+ if isfile(fullname) then
+ found[spec]=fullname
+ return fullname
+ else
+ break
+ end
end
- okay=notfound()
- found[spec]=okay
+ end
end
- return okay
+ okay=notfound()
+ found[spec]=okay
+ end
+ return okay
end
function resolvers.locators.tree(specification)
- local name=specification.filename
- local realname=resolveprefix(name)
- if realname and realname~='' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
- end
- resolvers.appendhash('tree',name,false)
- elseif trace_locating then
- report_trees("locator %a not found",name)
+ local name=specification.filename
+ local realname=resolveprefix(name)
+ if realname and realname~='' and isdir(realname) then
+ if trace_locating then
+ report_trees("locator %a found",realname)
end
+ resolvers.appendhash('tree',name,false)
+ elseif trace_locating then
+ report_trees("locator %a not found",name)
+ end
end
function resolvers.hashers.tree(specification)
- local name=specification.filename
- report_trees("analyzing %a",name)
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+ local name=specification.filename
+ if trace_locating then
+ report_trees("analyzing %a",name)
+ end
+ resolvers.methodhandler("hashers",name)
+ resolvers.generators.file(specification)
end
local collectors={}
local splitter=lpeg.splitat("/**/")
local stripper=lpeg.replacer { [P("/")*P("*")^1*P(-1)]="" }
table.setmetatableindex(collectors,function(t,k)
- local rootname=lpegmatch(stripper,k)
- local dataname=joinname(rootname,"dirlist")
- local content=caches.loadcontent(dataname,"files",dataname)
- if not content then
- content=resolvers.scanfiles(rootname,nil,nil,false,true)
- caches.savecontent(dataname,"files",content,dataname)
- end
- t[k]=content
- return content
+ local rootname=lpegmatch(stripper,k)
+ local dataname=joinname(rootname,"dirlist")
+ local content=caches.loadcontent(dataname,"files",dataname)
+ if not content then
+ content=resolvers.scanfiles(rootname,nil,nil,false,true)
+ caches.savecontent(dataname,"files",content,dataname)
+ end
+ t[k]=content
+ return content
end)
local function checked(root,p,n)
- if p then
- if type(p)=="table" then
- for i=1,#p do
- local fullname=joinname(root,p[i],n)
- if isfile(fullname) then
- return fullname
- end
- end
- else
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
+ if p then
+ if type(p)=="table" then
+ for i=1,#p do
+ local fullname=joinname(root,p[i],n)
+ if isfile(fullname) then
+ return fullname
end
+ end
+ else
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- return notfound()
+ end
+ return notfound()
end
local function resolve(specification)
- local filename=specification.filename
- if filename~="" then
- local root,rest=lpegmatch(splitter,filename)
- if root and rest then
- local path,name=dirname(rest),basename(rest)
- if name~=rest then
- local content=collectors[root]
- local p,n=lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern=".*/"..path.."$"
- local istable=type(p)=="table"
- if istable then
- for i=1,#p do
- local pi=p[i]
- if pi==path or find(pi,pattern) then
- local fullname=joinname(root,pi,n)
- if isfile(fullname) then
- return fullname
- end
- end
- end
- elseif p==path or find(p,pattern) then
- local fullname=joinname(root,p,n)
- if isfile(fullname) then
- return fullname
- end
- end
- local queries=specification.queries
- if queries and queries.option=="fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
+ local filename=specification.filename
+ if filename~="" then
+ local root,rest=lpegmatch(splitter,filename)
+ if root and rest then
+ local path,name=dirname(rest),basename(rest)
+ if name~=rest then
+ local content=collectors[root]
+ local p,n=lookup(content,name)
+ if not p then
+ return notfound()
+ end
+ local pattern=".*/"..path.."$"
+ local istable=type(p)=="table"
+ if istable then
+ for i=1,#p do
+ local pi=p[i]
+ if pi==path or find(pi,pattern) then
+ local fullname=joinname(root,pi,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
+ end
+ elseif p==path or find(p,pattern) then
+ local fullname=joinname(root,p,n)
+ if isfile(fullname) then
+ return fullname
+ end
end
- local path,name=dirname(filename),basename(filename)
- local root=lpegmatch(stripper,path)
- local content=collectors[path]
- local p,n=lookup(content,name)
- if p then
- return checked(root,p,n)
+ local queries=specification.queries
+ if queries and queries.option=="fileonly" then
+ return checked(root,p,n)
+ else
+ return notfound()
end
+ end
end
- return notfound()
+ local path,name=dirname(filename),basename(filename)
+ local root=lpegmatch(stripper,path)
+ local content=collectors[path]
+ local p,n=lookup(content,name)
+ if p then
+ return checked(root,p,n)
+ end
+ end
+ return notfound()
end
-resolvers.finders .dirlist=resolve
-resolvers.locators .dirlist=resolvers.locators .tree
-resolvers.hashers .dirlist=resolvers.hashers .tree
+resolvers.finders .dirlist=resolve
+resolvers.locators .dirlist=resolvers.locators .tree
+resolvers.hashers .dirlist=resolvers.hashers .tree
resolvers.generators.dirlist=resolvers.generators.file
-resolvers.openers .dirlist=resolvers.openers .file
-resolvers.loaders .dirlist=resolvers.loaders .file
+resolvers.openers .dirlist=resolvers.openers .file
+resolvers.loaders .dirlist=resolvers.loaders .file
function resolvers.finders.dirfile(specification)
- local queries=specification.queries
- if queries then
- queries.option="fileonly"
- else
- specification.queries={ option="fileonly" }
- end
- return resolve(specification)
-end
-resolvers.locators .dirfile=resolvers.locators .dirlist
-resolvers.hashers .dirfile=resolvers.hashers .dirlist
+ local queries=specification.queries
+ if queries then
+ queries.option="fileonly"
+ else
+ specification.queries={ option="fileonly" }
+ end
+ return resolve(specification)
+end
+resolvers.locators .dirfile=resolvers.locators .dirlist
+resolvers.hashers .dirfile=resolvers.hashers .dirlist
resolvers.generators.dirfile=resolvers.generators.dirlist
-resolvers.openers .dirfile=resolvers.openers .dirlist
-resolvers.loaders .dirfile=resolvers.loaders .dirlist
+resolvers.openers .dirfile=resolvers.openers .dirlist
+resolvers.loaders .dirfile=resolvers.loaders .dirlist
end -- of closure
@@ -20238,19 +23816,19 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-sch"] = package.loaded["data-sch"] or true
--- original size: 6753, stripped down to: 5511
+-- original size: 6753, stripped down to: 5268
if not modules then modules={} end modules ['data-sch']={
- 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 load,tonumber=load,tonumber
local gsub,concat,format=string.gsub,table.concat,string.format
local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders
-local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
+local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end)
local report_schemes=logs.reporter("resolvers","schemes")
local http=require("socket.http")
local ltn12=require("ltn12")
@@ -20263,27 +23841,27 @@ schemes.cleaners=cleaners
local threshold=24*60*60
directives.register("schemes.threshold",function(v) threshold=tonumber(v) or threshold end)
function cleaners.none(specification)
- return specification.original
+ return specification.original
end
function cleaners.strip(specification)
- local path,name=file.splitbase(specification.original)
- if path=="" then
- return (gsub(name,"[^%a%d%.]+","-"))
- else
- return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
- end
+ local path,name=file.splitbase(specification.original)
+ if path=="" then
+ return (gsub(name,"[^%a%d%.]+","-"))
+ else
+ return (gsub((gsub(path,"%.","-").."-"..name),"[^%a%d%.]+","-"))
+ end
end
function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
+ return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
end
local cleaner=cleaners.strip
directives.register("schemes.cleanmethod",function(v) cleaner=cleaners[v] or cleaners.strip end)
function resolvers.schemes.cleanname(specification)
- local hash=cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %a to %a",specification.original,hash)
- end
- return hash
+ local hash=cleaner(specification)
+ if trace_schemes then
+ report_schemes("hashing %a to %a",specification.original,hash)
+ end
+ return hash
end
local cached={}
local loaded={}
@@ -20291,139 +23869,139 @@ local reused={}
local thresholds={}
local handlers={}
local runner=sandbox.registerrunner {
- name="curl resolver",
- method="execute",
- program="curl",
- template="--silent --insecure --create-dirs --output %cachename% %original%",
- checkers={
- cachename="cache",
- original="url",
- }
+ name="curl resolver",
+ method="execute",
+ program="curl",
+ template="--silent --insecure --create-dirs --output %cachename% %original%",
+ checkers={
+ cachename="cache",
+ original="url",
+ }
}
local function fetch(specification)
- local original=specification.original
- local scheme=specification.scheme
- local cleanname=schemes.cleanname(specification)
- local cachename=caches.setfirstwritablefile(cleanname,"schemes")
- if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
- cached[original]=cachename
- local handler=handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
- end
- logs.flush()
- runner {
- original=original,
- cachename=cachename,
- }
- end
- end
- if io.exists(cachename) then
- cached[original]=cachename
- if trace_schemes then
- report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
- end
- else
- cached[original]=""
- if trace_schemes then
- report_schemes("using missing %a, protocol %a",original,scheme)
- end
+ local original=specification.original
+ local scheme=specification.scheme
+ local cleanname=schemes.cleanname(specification)
+ local cachename=caches.setfirstwritablefile(cleanname,"schemes")
+ if not cached[original] then
+ statistics.starttiming(schemes)
+ if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification)>(thresholds[protocol] or threshold)) then
+ cached[original]=cachename
+ local handler=handlers[scheme]
+ if handler then
+ if trace_schemes then
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"built-in")
end
- loaded[scheme]=loaded[scheme]+1
- statistics.stoptiming(schemes)
- else
+ logs.flush()
+ handler(specification,cachename)
+ else
if trace_schemes then
- report_schemes("reusing %a, protocol %a",original,scheme)
+ report_schemes("fetching %a, protocol %a, method %a",original,scheme,"curl")
end
- reused[scheme]=reused[scheme]+1
+ logs.flush()
+ runner {
+ original=original,
+ cachename=cachename,
+ }
+ end
+ end
+ if io.exists(cachename) then
+ cached[original]=cachename
+ if trace_schemes then
+ report_schemes("using cached %a, protocol %a, cachename %a",original,scheme,cachename)
+ end
+ else
+ cached[original]=""
+ if trace_schemes then
+ report_schemes("using missing %a, protocol %a",original,scheme)
+ end
end
- return cached[original]
+ loaded[scheme]=loaded[scheme]+1
+ statistics.stoptiming(schemes)
+ else
+ if trace_schemes then
+ report_schemes("reusing %a, protocol %a",original,scheme)
+ end
+ reused[scheme]=reused[scheme]+1
+ end
+ return cached[original]
end
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",fetch(specification),filetype)
end
local opener=openers.file
local loader=loaders.file
local function install(scheme,handler,newthreshold)
- handlers [scheme]=handler
- loaded [scheme]=0
- reused [scheme]=0
- finders [scheme]=finder
- openers [scheme]=opener
- loaders [scheme]=loader
- thresholds[scheme]=newthreshold or threshold
+ handlers [scheme]=handler
+ loaded [scheme]=0
+ reused [scheme]=0
+ finders [scheme]=finder
+ openers [scheme]=opener
+ loaders [scheme]=loader
+ thresholds[scheme]=newthreshold or threshold
end
schemes.install=install
local function http_handler(specification,cachename)
- local tempname=cachename..".tmp"
- local f=io.open(tempname,"wb")
- local status,message=http.request {
- url=specification.original,
- sink=ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
+ local tempname=cachename..".tmp"
+ local f=io.open(tempname,"wb")
+ local status,message=http.request {
+ url=specification.original,
+ sink=ltn12.sink.file(f)
+ }
+ if not status then
+ os.remove(tempname)
+ else
+ os.remove(cachename)
+ os.rename(tempname,cachename)
+ end
+ return cachename
end
install('http',http_handler)
install('https')
install('ftp')
statistics.register("scheme handling time",function()
- local l,r,nl,nr={},{},0,0
- for k,v in table.sortedhash(loaded) do
- if v>0 then
- nl=nl+1
- l[nl]=k..":"..v
- end
- end
- for k,v in table.sortedhash(reused) do
- if v>0 then
- nr=nr+1
- r[nr]=k..":"..v
- end
- end
- local n=nl+nr
- if n>0 then
- l=nl>0 and concat(l) or "none"
- r=nr>0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes),n,threshold,l,r)
- else
- return nil
- end
+ local l,r,nl,nr={},{},0,0
+ for k,v in table.sortedhash(loaded) do
+ if v>0 then
+ nl=nl+1
+ l[nl]=k..":"..v
+ end
+ end
+ for k,v in table.sortedhash(reused) do
+ if v>0 then
+ nr=nr+1
+ r[nr]=k..":"..v
+ end
+ end
+ local n=nl+nr
+ if n>0 then
+ l=nl>0 and concat(l) or "none"
+ r=nr>0 and concat(r) or "none"
+ return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
+ statistics.elapsedtime(schemes),n,threshold,l,r)
+ else
+ return nil
+ end
end)
local httprequest=http.request
local toquery=url.toquery
local function fetchstring(url,data)
- local q=data and toquery(data)
- if q then
- url=url.."?"..q
- end
- local reply=httprequest(url)
- return reply
+ local q=data and toquery(data)
+ if q then
+ url=url.."?"..q
+ end
+ local reply=httprequest(url)
+ return reply
end
schemes.fetchstring=fetchstring
function schemes.fetchtable(url,data)
- local reply=fetchstring(url,data)
- if reply then
- local s=load("return "..reply)
- if s then
- return s()
- end
+ local reply=fetchstring(url,data)
+ if reply then
+ local s=load("return "..reply)
+ if s then
+ return s()
end
+ end
end
@@ -20433,14 +24011,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lua"] = package.loaded["data-lua"] or true
--- original size: 4207, stripped down to: 3137
+-- original size: 4207, stripped down to: 3041
if not modules then modules={} end modules ['data-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 package,lpeg=package,lpeg
local gsub=string.gsub
@@ -20459,20 +24037,20 @@ helpers.report=logs.reporter("resolvers","libraries")
trackers.register("resolvers.libraries",function(v) helpers.trace=v end)
trackers.register("resolvers.locating",function(v) helpers.trace=v end)
helpers.sequence={
- "already loaded",
- "preload table",
- "lua variable format",
- "lib variable format",
- "lua extra list",
- "lib extra list",
- "path specification",
- "cpath specification",
- "all in one fallback",
- "not loaded",
+ "already loaded",
+ "preload table",
+ "lua variable format",
+ "lib variable format",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
}
local pattern=Cs(P("!")^0/""*(P("/")*P(-1)/"/"+P("/")^1/"/"+1)^0)
function helpers.cleanpath(path)
- return resolveprefix(lpegmatch(pattern,path))
+ return resolveprefix(lpegmatch(pattern,path))
end
local loadedaslib=helpers.loadedaslib
local registerpath=helpers.registerpath
@@ -20480,56 +24058,56 @@ local lualibfile=helpers.lualibfile
local luaformatpaths
local libformatpaths
local function getluaformatpaths()
- if not luaformatpaths then
- luaformatpaths={}
- for i=1,#luaformats do
- registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
- end
+ if not luaformatpaths then
+ luaformatpaths={}
+ for i=1,#luaformats do
+ registerpath("lua format","lua",luaformatpaths,resolvers.expandedpathlistfromvariable(luaformats[i]))
end
- return luaformatpaths
+ end
+ return luaformatpaths
end
local function getlibformatpaths()
- if not libformatpaths then
- libformatpaths={}
- for i=1,#libformats do
- registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
- end
+ if not libformatpaths then
+ libformatpaths={}
+ for i=1,#libformats do
+ registerpath("lib format","lib",libformatpaths,resolvers.expandedpathlistfromvariable(libformats[i]))
end
- return libformatpaths
+ end
+ return libformatpaths
end
local function loadedbyformat(name,rawname,suffixes,islib,what)
- local trace=helpers.trace
- local report=helpers.report
- for i=1,#suffixes do
- local format=suffixes[i]
- local resolved=resolvers.findfile(name,format) or ""
- if trace then
- report("%s format, identifying %a using format %a",what,name,format)
- end
- if resolved~="" then
- if trace then
- report("%s format, %a found on %a",what,name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
- end
- end
+ local trace=helpers.trace
+ local report=helpers.report
+ for i=1,#suffixes do
+ local format=suffixes[i]
+ local resolved=resolvers.findfile(name,format) or ""
+ if trace then
+ report("%s format, identifying %a using format %a",what,name,format)
+ end
+ if resolved~="" then
+ if trace then
+ report("%s format, %a found on %a",what,name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
+ end
end
+ end
end
helpers.loadedbyformat=loadedbyformat
methods["lua variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lua",#getluaformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),"lua"),name,luasuffixes,false,"lua")
end
methods["lib variable format"]=function(name)
- if helpers.trace then
- helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
- end
- return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
+ if helpers.trace then
+ helpers.report("%s format, checking %s paths","lib",#getlibformatpaths())
+ end
+ return loadedbyformat(addsuffix(lualibfile(name),os.libsuffix),name,libsuffixes,true,"lib")
end
resolvers.loadlualib=require
@@ -20540,64 +24118,64 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-aux"] = package.loaded["data-aux"] or true
--- original size: 2438, stripped down to: 2003
+-- original size: 2452, stripped down to: 1877
if not modules then modules={} end modules ['data-aux']={
- 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 find=string.find
local type,next=type,next
-local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
+local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end)
local resolvers=resolvers
local report_scripts=logs.reporter("resolvers","scripts")
function resolvers.updatescript(oldname,newname)
- local scriptpath="context/lua"
- newname=file.addsuffix(newname,"lua")
- local oldscript=resolvers.cleanpath(oldname)
+ local scriptpath="context/lua"
+ newname=file.addsuffix(newname,"lua")
+ local oldscript=resolvers.cleanpath(oldname)
+ if trace_locating then
+ report_scripts("to be replaced old script %a",oldscript)
+ end
+ local newscripts=resolvers.findfiles(newname) or {}
+ if #newscripts==0 then
if trace_locating then
- report_scripts("to be replaced old script %a",oldscript)
+ report_scripts("unable to locate new script")
end
- local newscripts=resolvers.findfiles(newname) or {}
- if #newscripts==0 then
+ else
+ for i=1,#newscripts do
+ local newscript=resolvers.cleanpath(newscripts[i])
+ if trace_locating then
+ report_scripts("checking new script %a",newscript)
+ end
+ if oldscript==newscript then
if trace_locating then
- report_scripts("unable to locate new script")
+ report_scripts("old and new script are the same")
end
- else
- for i=1,#newscripts do
- local newscript=resolvers.cleanpath(newscripts[i])
- if trace_locating then
- report_scripts("checking new script %a",newscript)
- end
- if oldscript==newscript then
- if trace_locating then
- report_scripts("old and new script are the same")
- end
- elseif not find(newscript,scriptpath,1,true) then
- if trace_locating then
- report_scripts("new script should come from %a",scriptpath)
- end
- elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
- if trace_locating then
- report_scripts("invalid new script name")
- end
- else
- local newdata=io.loaddata(newscript)
- if newdata then
- if trace_locating then
- report_scripts("old script content replaced by new content")
- end
- io.savedata(oldscript,newdata)
- break
- elseif trace_locating then
- report_scripts("unable to load new script")
- end
- end
+ elseif not find(newscript,scriptpath,1,true) then
+ if trace_locating then
+ report_scripts("new script should come from %a",scriptpath)
end
+ elseif not (find(oldscript,file.removesuffix(newname).."$") or find(oldscript,newname.."$")) then
+ if trace_locating then
+ report_scripts("invalid new script name")
+ end
+ else
+ local newdata=io.loaddata(newscript)
+ if newdata then
+ if trace_locating then
+ report_scripts("old script content replaced by new content: %s",oldscript)
+ end
+ io.savedata(oldscript,newdata)
+ break
+ elseif trace_locating then
+ report_scripts("unable to load new script")
+ end
+ end
end
+ end
end
@@ -20607,53 +24185,53 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmf"] = package.loaded["data-tmf"] or true
--- original size: 2601, stripped down to: 1627
+-- original size: 2601, stripped down to: 1549
if not modules then modules={} end modules ['data-tmf']={
- 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 resolvers=resolvers
local report_tds=logs.reporter("resolvers","tds")
function resolvers.load_tree(tree,resolve)
- if type(tree)=="string" and tree~="" then
- local getenv,setenv=resolvers.getenv,resolvers.setenv
- local texos="texmf-"..os.platform
- local oldroot=environment.texroot
- local newroot=file.collapsepath(tree)
- local newtree=file.join(newroot,texos)
- local newpath=file.join(newtree,"bin")
- if not lfs.isdir(newtree) then
- report_tds("no %a under tree %a",texos,tree)
- os.exit()
- end
- if not lfs.isdir(newpath) then
- report_tds("no '%s/bin' under tree %a",texos,tree)
- os.exit()
- end
- local texmfos=newtree
- environment.texroot=newroot
- environment.texos=texos
- environment.texmfos=texmfos
- if resolve then
- resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
- end
- setenv('SELFAUTOPARENT',newroot)
- setenv('SELFAUTODIR',newtree)
- setenv('SELFAUTOLOC',newpath)
- setenv('TEXROOT',newroot)
- setenv('TEXOS',texos)
- setenv('TEXMFOS',texmfos)
- setenv('TEXMFCNF',resolvers.luacnfspec,true)
- setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
- report_tds("changing from root %a to %a",oldroot,newroot)
- report_tds("prepending %a to PATH",newpath)
- report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
- report_tds()
- end
+ if type(tree)=="string" and tree~="" then
+ local getenv,setenv=resolvers.getenv,resolvers.setenv
+ local texos="texmf-"..os.platform
+ local oldroot=environment.texroot
+ local newroot=file.collapsepath(tree)
+ local newtree=file.join(newroot,texos)
+ local newpath=file.join(newtree,"bin")
+ if not lfs.isdir(newtree) then
+ report_tds("no %a under tree %a",texos,tree)
+ os.exit()
+ end
+ if not lfs.isdir(newpath) then
+ report_tds("no '%s/bin' under tree %a",texos,tree)
+ os.exit()
+ end
+ local texmfos=newtree
+ environment.texroot=newroot
+ environment.texos=texos
+ environment.texmfos=texmfos
+ if resolve then
+ resolvers.luacnfspec=resolvers.resolve(resolvers.luacnfspec)
+ end
+ setenv('SELFAUTOPARENT',newroot)
+ setenv('SELFAUTODIR',newtree)
+ setenv('SELFAUTOLOC',newpath)
+ setenv('TEXROOT',newroot)
+ setenv('TEXOS',texos)
+ setenv('TEXMFOS',texmfos)
+ setenv('TEXMFCNF',resolvers.luacnfspec,true)
+ setenv('PATH',newpath..io.pathseparator..getenv('PATH'))
+ report_tds("changing from root %a to %a",oldroot,newroot)
+ report_tds("prepending %a to PATH",newpath)
+ report_tds("setting TEXMFCNF to %a",resolvers.luacnfspec)
+ report_tds()
+ end
end
@@ -20663,14 +24241,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-lst"] = package.loaded["data-lst"] or true
--- original size: 1823, stripped down to: 1591
+-- original size: 1823, stripped down to: 1542
if not modules then modules={} end modules ['data-lst']={
- 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=type
local concat,sortedhash=table.concat,table.sortedhash
@@ -20681,37 +24259,37 @@ local resolveprefix=resolvers.resolve
local report_lists=logs.reporter("resolvers","lists")
local report_resolved=logs.reporter("system","resolved")
local function tabstr(str)
- if type(str)=='table' then
- return concat(str," | ")
- else
- return str
- end
+ if type(str)=='table' then
+ return concat(str," | ")
+ else
+ return str
+ end
end
function listers.variables(pattern)
- local result=resolvers.knownvariables(pattern)
- for key,value in sortedhash(result) do
- report_lists(key)
- report_lists(" env: %s",tabstr(value.environment or "unset"))
- report_lists(" var: %s",tabstr(value.variable or "unset"))
- report_lists(" exp: %s",tabstr(value.expansion or "unset"))
- report_lists(" res: %s",tabstr(value.resolved or "unset"))
- end
+ local result=resolvers.knownvariables(pattern)
+ for key,value in sortedhash(result) do
+ report_lists(key)
+ report_lists(" env: %s",tabstr(value.environment or "unset"))
+ report_lists(" var: %s",tabstr(value.variable or "unset"))
+ report_lists(" exp: %s",tabstr(value.expansion or "unset"))
+ report_lists(" res: %s",tabstr(value.resolved or "unset"))
+ end
end
function listers.configurations()
- local configurations=resolvers.configurationfiles()
- for i=1,#configurations do
- report_resolved("file : %s",resolveprefix(configurations[i]))
- end
- report_resolved("")
- local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
- for i=1,#list do
- local li=resolveprefix(list[i])
- if lfs.isdir(li) then
- report_resolved("path - %s",li)
- else
- report_resolved("path + %s",li)
- end
+ local configurations=resolvers.configurationfiles()
+ for i=1,#configurations do
+ report_resolved("file : %s",resolveprefix(configurations[i]))
+ end
+ report_resolved("")
+ local list=resolvers.expandedpathfromlist(resolvers.splitpath(resolvers.luacnfspec))
+ for i=1,#list do
+ local li=resolveprefix(list[i])
+ if lfs.isdir(li) then
+ report_resolved("path - %s",li)
+ else
+ report_resolved("path + %s",li)
end
+ end
end
@@ -20721,14 +24299,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-lib"] = package.loaded["util-lib"] or true
--- original size: 14943, stripped down to: 8305
+-- original size: 16094, stripped down to: 8443
if not modules then modules={} end modules ['util-lib']={
- 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=type
local next=next
@@ -20748,256 +24326,291 @@ local qualifiedpath=file.is_qualified_path
local isfile=lfs.isfile
local done=false
local function locate(required,version,trace,report,action)
- if type(required)~="string" then
- report("provide a proper library name")
- return
- end
- if trace then
- report("requiring library %a with version %a",required,version or "any")
- end
- local found_library=nil
- local required_full=gsub(required,"%.","/")
- local required_path=pathpart(required_full)
- local required_base=nameonly(required_full)
- if qualifiedpath(required) then
- if isfile(addsuffix(required,os.libsuffix)) then
- if trace then
- report("qualified name %a found",required)
- end
- found_library=required
- else
- if trace then
- report("qualified name %a not found",required)
- end
- end
+ if type(required)~="string" then
+ report("provide a proper library name")
+ return
+ end
+ if trace then
+ report("requiring library %a with version %a",required,version or "any")
+ end
+ local found_library=nil
+ local required_full=gsub(required,"%.","/")
+ local required_path=pathpart(required_full)
+ local required_base=nameonly(required_full)
+ if qualifiedpath(required) then
+ if isfile(addsuffix(required,os.libsuffix)) then
+ if trace then
+ report("qualified name %a found",required)
+ end
+ found_library=required
else
- local required_name=required_base.."."..os.libsuffix
- local version=type(version)=="string" and version~="" and version or false
- local engine="luatex"
- if trace and not done then
- local list=expandpaths("lib")
- for i=1,#list do
- report("tds path %i: %s",i,list[i])
- end
+ if trace then
+ report("qualified name %a not found",required)
+ end
+ end
+ else
+ local required_name=required_base.."."..os.libsuffix
+ local version=type(version)=="string" and version~="" and version or false
+ local engine="luatex"
+ if trace and not done then
+ local list=expandpaths("lib")
+ for i=1,#list do
+ report("tds path %i: %s",i,list[i])
+ end
+ end
+ local function found(locate,asked_library,how,...)
+ if trace then
+ report("checking %s: %a",how,asked_library)
+ end
+ return locate(asked_library,...)
+ end
+ local function check(locate,...)
+ local found=nil
+ if version then
+ local asked_library=joinfile(required_path,version,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function found(locate,asked_library,how,...)
- if trace then
- report("checking %s: %a",how,asked_library)
- end
- return locate(asked_library,...)
- end
- local function check(locate,...)
- local found=nil
- if version then
- local asked_library=joinfile(required_path,version,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- if not found or found=="" then
- local asked_library=joinfile(required_path,required_name)
- if trace then
- report("checking %s: %a","with version",asked_library)
- end
- found=locate(asked_library,...)
- end
- return found and found~="" and found or false
+ found=locate(asked_library,...)
+ end
+ if not found or found=="" then
+ local asked_library=joinfile(required_path,required_name)
+ if trace then
+ report("checking %s: %a","with version",asked_library)
end
- local function attempt(checkpattern)
- if trace then
- report("checking tds lib paths strictly")
- end
- local found=findfile and check(findfile,"lib")
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- if trace then
- report("checking tds lib paths with wildcard")
- end
- local asked_library=joinfile(required_path,".*",required_name)
- if trace then
- report("checking %s: %a","latest version",asked_library)
- end
- local list=findfiles(asked_library,"lib",true)
- if list and #list>0 then
- sort(list)
- local found=list[#list]
- if found and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- if trace then
- report("checking lib paths")
- end
- package.extralibpath(environment.ownpath)
- local paths=package.libpaths()
- local pattern="/[^/]+%."..os.libsuffix.."$"
- for i=1,#paths do
- required_path=gsub(paths[i],pattern,"")
- local found=check(lfs.isfound)
- if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
- return found
- end
- end
- return false
+ found=locate(asked_library,...)
+ end
+ return found and found~="" and found or false
+ end
+ local function attempt(checkpattern)
+ if trace then
+ report("checking tds lib paths strictly")
+ end
+ local found=findfile and check(findfile,"lib")
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
+ end
+ if trace then
+ report("checking tds lib paths with wildcard")
+ end
+ local asked_library=joinfile(required_path,".*",required_name)
+ if trace then
+ report("checking %s: %a","latest version",asked_library)
+ end
+ local list=findfiles(asked_library,"lib",true)
+ if list and #list>0 then
+ sort(list)
+ local found=list[#list]
+ if found and (not checkpattern or find(found,checkpattern)) then
+ return found
end
- if engine then
- if trace then
- report("attemp 1, engine %a",engine)
- end
- found_library=attempt("/"..engine.."/")
- if not found_library then
- if trace then
- report("attemp 2, no engine",asked_library)
- end
- found_library=attempt()
- end
- else
- found_library=attempt()
+ end
+ if trace then
+ report("checking lib paths")
+ end
+ package.extralibpath(environment.ownpath)
+ local paths=package.libpaths()
+ local pattern="/[^/]+%."..os.libsuffix.."$"
+ for i=1,#paths do
+ required_path=gsub(paths[i],pattern,"")
+ local found=check(lfs.isfound)
+ if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then
+ return found
end
+ end
+ return false
end
- if not found_library then
+ if engine then
+ if trace then
+ report("attemp 1, engine %a",engine)
+ end
+ found_library=attempt("/"..engine.."/")
+ if not found_library then
if trace then
- report("not found: %a",required)
+ report("attemp 2, no engine",asked_library)
end
- library=false
+ found_library=attempt()
+ end
else
- if trace then
- report("found: %a",found_library)
- end
- local result,message=action(found_library,required_base)
- if result then
- library=result
- else
- library=false
- report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
- end
+ found_library=attempt()
end
+ end
+ if not found_library then
if trace then
- if not library then
- report("unknown library: %a",required)
- else
- report("stored library: %a",required)
- end
+ report("not found: %a",required)
end
- return library
+ library=false
+ else
+ if trace then
+ report("found: %a",found_library)
+ end
+ local result,message=action(found_library,required_base)
+ if result then
+ library=result
+ else
+ library=false
+ report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library")
+ end
+ end
+ if trace then
+ if not library then
+ report("unknown library: %a",required)
+ else
+ report("stored library: %a",required)
+ end
+ end
+ return library or nil
end
do
- local report_swiglib=logs.reporter("swiglib")
- local trace_swiglib=false
- local savedrequire=require
- local loadedlibs={}
- local loadlib=package.loadlib
- local pushdir=dir.push
- local popdir=dir.pop
- trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
- function requireswiglib(required,version)
- local library=loadedlibs[library]
- if library==nil then
- local trace_swiglib=trace_swiglib or package.helpers.trace
- library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
- pushdir(pathpart(name))
- local opener="luaopen_"..base
- if trace_swiglib then
- report_swiglib("opening: %a with %a",name,opener)
- end
- local library,message=loadlib(name,opener)
- local libtype=type(library)
- if libtype=="function" then
- library=library()
- else
- report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
- library=false
- end
- popdir()
- return library
- end)
- loadedlibs[required]=library or false
+ local report_swiglib=logs.reporter("swiglib")
+ local trace_swiglib=false
+ local savedrequire=require
+ local loadedlibs={}
+ local loadlib=package.loadlib
+ local pushdir=dir.push
+ local popdir=dir.pop
+ trackers.register("resolvers.swiglib",function(v) trace_swiglib=v end)
+ function requireswiglib(required,version)
+ local library=loadedlibs[library]
+ if library==nil then
+ local trace_swiglib=trace_swiglib or package.helpers.trace
+ library=locate(required,version,trace_swiglib,report_swiglib,function(name,base)
+ pushdir(pathpart(name))
+ local opener="luaopen_"..base
+ if trace_swiglib then
+ report_swiglib("opening: %a with %a",name,opener)
+ end
+ local library,message=loadlib(name,opener)
+ local libtype=type(library)
+ if libtype=="function" then
+ library=library()
+ else
+ report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library")
+ library=false
end
+ popdir()
return library
+ end)
+ loadedlibs[required]=library or false
end
- function require(name,version)
- if find(name,"^swiglib%.") then
- return requireswiglib(name,version)
- else
- return savedrequire(name)
- end
+ return library
+ end
+ function require(name,version)
+ if find(name,"^swiglib%.") then
+ return requireswiglib(name,version)
+ else
+ return savedrequire(name)
+ end
+ end
+ local swiglibs={}
+ local initializer="core"
+ function swiglib(name,version)
+ local library=swiglibs[name]
+ if not library then
+ statistics.starttiming(swiglibs)
+ if trace_swiglib then
+ report_swiglib("loading %a",name)
+ end
+ if not find(name,"%."..initializer.."$") then
+ fullname="swiglib."..name.."."..initializer
+ else
+ fullname="swiglib."..name
+ end
+ library=requireswiglib(fullname,version)
+ swiglibs[name]=library
+ statistics.stoptiming(swiglibs)
end
- local swiglibs={}
- local initializer="core"
- function swiglib(name,version)
- local library=swiglibs[name]
- if not library then
- statistics.starttiming(swiglibs)
- if trace_swiglib then
- report_swiglib("loading %a",name)
- end
- if not find(name,"%."..initializer.."$") then
- fullname="swiglib."..name.."."..initializer
- else
- fullname="swiglib."..name
- end
- library=requireswiglib(fullname,version)
- swiglibs[name]=library
- statistics.stoptiming(swiglibs)
- end
- return library
+ return library
+ end
+ statistics.register("used swiglibs",function()
+ if next(swiglibs) then
+ return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
end
- statistics.register("used swiglibs",function()
- if next(swiglibs) then
- return string.format("%s, initial load time %s seconds",table.concat(table.sortedkeys(swiglibs)," "),statistics.elapsedtime(swiglibs))
- end
- end)
+ end)
end
if FFISUPPORTED and ffi and ffi.load then
- local report_ffilib=logs.reporter("ffilib")
- local trace_ffilib=false
- local savedffiload=ffi.load
- trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
- local loaded={}
- local function locateindeed(name)
- 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
- l=library
- else
- l=false
- end
- loaded[name]=l
- elseif trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
+ local report_ffilib=logs.reporter("ffilib")
+ local trace_ffilib=false
+ local savedffiload=ffi.load
+ trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end)
+ local loaded={}
+ local function locateindeed(name)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l==nil 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
+ loaded[name]=l
+ elseif trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
end
- function ffilib(name,version)
- name=removesuffix(name)
- local l=loaded[name]
- if l~=nil then
- if trace_ffilib then
- report_ffilib("reusing already loaded %a",name)
- end
- return l
- elseif version=="system" then
- return locateindeed(name)
- else
- return locate(name,version,trace_ffilib,report_ffilib,locateindeed)
+ 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
- function ffi.load(name)
- local library=ffilib(name)
+ return { required }
+ end
+ function ffilib(name,version)
+ name=removesuffix(name)
+ local l=loaded[name]
+ if l~=nil then
+ if trace_ffilib then
+ report_ffilib("reusing already loaded %a",name)
+ end
+ return l
+ 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
+ return library
end
- if trace_ffilib then
- report_ffilib("trying to load %a using normal loader",name)
+ end
+ else
+ for i=1,#list do
+ local library=locate(list[i],version,trace_ffilib,report_ffilib,locateindeed)
+ if type(library)=="userdata" then
+ return library
end
- return savedffiload(name)
+ end
end
+ end
+ function ffi.load(name)
+ 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
+ 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
@@ -21007,13 +24620,13 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-sta"] = package.loaded["luat-sta"] or true
--- original size: 5703, stripped down to: 2507
+-- original size: 5703, stripped down to: 2321
if not modules then modules={} end modules ['luat-sta']={
- version=1.001,
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
+ version=1.001,
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local gmatch,match=string.gmatch,string.match
local type=type
@@ -21026,81 +24639,81 @@ local hash=states.hash
states.tag=states.tag or ""
states.filename=states.filename or ""
function states.save(filename,tag)
- tag=tag or states.tag
- filename=file.addsuffix(filename or states.filename,'lus')
- io.savedata(filename,
- "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
- )
+ tag=tag or states.tag
+ filename=file.addsuffix(filename or states.filename,'lus')
+ io.savedata(filename,
+ "-- generator : luat-sta.lua\n".."-- state tag : "..tag.."\n\n"..table.serialize(data[tag or states.tag] or {},true)
+ )
end
function states.load(filename,tag)
- states.filename=filename
- states.tag=tag or "whatever"
- states.filename=file.addsuffix(states.filename,'lus')
- data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
+ states.filename=filename
+ states.tag=tag or "whatever"
+ states.filename=file.addsuffix(states.filename,'lus')
+ data[states.tag],hash[states.tag]=(io.exists(filename) and dofile(filename)) or {},{}
end
local function set_by_tag(tag,key,value,default,persistent)
- local d,h=data[tag],hash[tag]
- if d then
- if type(d)=="table" then
- local dkey,hkey=key,key
- local pre,post=match(key,"(.+)%.([^%.]+)$")
- if pre and post then
- for k in gmatch(pre,"[^%.]+") do
- local dk=d[k]
- if not dk then
- dk={}
- d[k]=dk
- elseif type(dk)=="string" then
- break
- end
- d=dk
- end
- dkey,hkey=post,key
- end
- if value==nil then
- value=default
- elseif value==false then
- elseif persistent then
- value=value or d[dkey] or default
- else
- value=value or default
- end
- d[dkey],h[hkey]=value,value
- elseif type(d)=="string" then
- data[tag],hash[tag]=value,value
+ local d,h=data[tag],hash[tag]
+ if d then
+ if type(d)=="table" then
+ local dkey,hkey=key,key
+ local pre,post=match(key,"(.+)%.([^%.]+)$")
+ if pre and post then
+ for k in gmatch(pre,"[^%.]+") do
+ local dk=d[k]
+ if not dk then
+ dk={}
+ d[k]=dk
+ elseif type(dk)=="string" then
+ break
+ end
+ d=dk
end
+ dkey,hkey=post,key
+ end
+ if value==nil then
+ value=default
+ elseif value==false then
+ elseif persistent then
+ value=value or d[dkey] or default
+ else
+ value=value or default
+ end
+ d[dkey],h[hkey]=value,value
+ elseif type(d)=="string" then
+ data[tag],hash[tag]=value,value
end
+ end
end
local function get_by_tag(tag,key,default)
- local h=hash[tag]
- if h and h[key] then
- return h[key]
- else
- local d=data[tag]
- if d then
- for k in gmatch(key,"[^%.]+") do
- local dk=d[k]
- if dk~=nil then
- d=dk
- else
- return default
- end
- end
- if d==false then
- return false
- else
- return d or default
- end
+ local h=hash[tag]
+ if h and h[key] then
+ return h[key]
+ else
+ local d=data[tag]
+ if d then
+ for k in gmatch(key,"[^%.]+") do
+ local dk=d[k]
+ if dk~=nil then
+ d=dk
+ else
+ return default
end
+ end
+ if d==false then
+ return false
+ else
+ return d or default
+ end
end
+ end
end
states.set_by_tag=set_by_tag
states.get_by_tag=get_by_tag
function states.set(key,value,default,persistent)
- set_by_tag(states.tag,key,value,default,persistent)
+ set_by_tag(states.tag,key,value,default,persistent)
end
function states.get(key,default)
- return get_by_tag(states.tag,key,default)
+ return get_by_tag(states.tag,key,default)
end
@@ -21110,14 +24723,14 @@ do -- create closure to overcome 200 locals limit
package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true
--- original size: 9268, stripped down to: 7401
+-- original size: 9418, stripped down to: 7087
if not modules then modules={} end modules ['luat-fmt']={
- version=1.001,
- comment="companion to mtxrun",
- 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 mtxrun",
+ author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright="PRAGMA ADE / ConTeXt Development Team",
+ license="see context related readme files"
}
local format=string.format
local concat=table.concat
@@ -21125,229 +24738,232 @@ local quoted=string.quoted
local luasuffixes=utilities.lua.suffixes
local report_format=logs.reporter("resolvers","formats")
local function primaryflags()
- local arguments=environment.arguments
- local flags={}
- if arguments.silent then
- flags[#flags+1]="--interaction=batchmode"
- end
- if arguments.jit then
- flags[#flags+1]="--jiton"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local flags={}
+ if arguments.silent then
+ flags[#flags+1]="--interaction=batchmode"
+ end
+ return concat(flags," ")
end
local function secondaryflags()
- local arguments=environment.arguments
- local trackers=arguments.trackers
- local directives=arguments.directives
- local flags={}
- if trackers and trackers~="" then
- flags[#flags+1]="--c:trackers="..quoted(trackers)
- end
- if directives and directives~="" then
- flags[#flags+1]="--c:directives="..quoted(directives)
- end
- if arguments.silent then
- flags[#flags+1]="--c:silent"
- end
- if arguments.errors then
- flags[#flags+1]="--c:errors"
- end
- if arguments.jit then
- flags[#flags+1]="--c:jiton"
- end
- if arguments.ansi then
- flags[#flags+1]="--c:ansi"
- end
- return concat(flags," ")
+ local arguments=environment.arguments
+ local trackers=arguments.trackers
+ local directives=arguments.directives
+ local flags={}
+ if trackers and trackers~="" then
+ flags[#flags+1]="--c:trackers="..quoted(trackers)
+ end
+ if directives and directives~="" then
+ flags[#flags+1]="--c:directives="..quoted(directives)
+ end
+ if arguments.silent then
+ flags[#flags+1]="--c:silent"
+ end
+ if arguments.errors then
+ flags[#flags+1]="--c:errors"
+ end
+ if arguments.jit then
+ flags[#flags+1]="--c:jiton"
+ end
+ 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
local template=[[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]]
local checkers={
- primaryflags="string",
- secondaryflags="string",
- luafile="readable",
- texfile="readable",
- redirect="string",
- dump="string",
+ primaryflags="string",
+ secondaryflags="string",
+ luafile="readable",
+ texfile="readable",
+ redirect="string",
+ dump="string",
}
local runners={
- luatex=sandbox.registerrunner {
- name="make luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="make luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="make luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="make luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.make_format(name,arguments)
- local engine=environment.ownmain or "luatex"
- local silent=environment.arguments.silent
- local errors=environment.arguments.errors
- local olddir=dir.current()
- local path=caches.getwritablepath("formats",engine) or ""
- if path~="" then
- lfs.chdir(path)
- end
- report_format("using format path %a",dir.current())
- local texsourcename=file.addsuffix(name,"mkiv")
- local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- if fulltexsourcename=="" then
- texsourcename=file.addsuffix(name,"tex")
- fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
- end
- if fulltexsourcename=="" then
- report_format("no tex source file with name %a (mkiv or tex)",name)
- lfs.chdir(olddir)
- return
- else
- report_format("using tex source file %a",fulltexsourcename)
- end
- local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
- local specificationname=file.replacesuffix(fulltexsourcename,"lus")
- local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- if fullspecificationname=="" then
- specificationname=file.join(texsourcepath,"context.lus")
- fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
- end
- if fullspecificationname=="" then
- report_format("unknown stub specification %a",specificationname)
- lfs.chdir(olddir)
- return
- end
- local specificationpath=file.dirname(fullspecificationname)
- local usedluastub=nil
- local usedlualibs=dofile(fullspecificationname)
- if type(usedlualibs)=="string" then
- usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
- elseif type(usedlualibs)=="table" then
- report_format("using stub specification %a",fullspecificationname)
- local texbasename=file.basename(name)
- local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
- local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
- report_format("creating initialization file %a",luastubname)
- utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
- if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
- report_format("using compiled initialization file %a",lucstubname)
- usedluastub=lucstubname
- else
- report_format("using uncompiled initialization file %a",luastubname)
- usedluastub=luastubname
- end
- else
- report_format("invalid stub specification %a",fullspecificationname)
- lfs.chdir(olddir)
- return
- end
- local specification={
- primaryflags=primaryflags(),
- secondaryflags=secondaryflags(),
- luafile=quoted(usedluastub),
- texfile=quoted(fulltexsourcename),
- dump=os.platform=="unix" and "\\\\dump" or "\\dump",
- }
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
- elseif silent then
- statistics.starttiming()
- specification.redirect="> temp.log"
- local result=runner(specification)
- local runtime=statistics.stoptiming()
- if result~=0 then
- print(format("%s silent make > fatal error when making format %q",engine,name))
- else
- print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
- end
- os.remove("temp.log")
- else
- runner(specification)
- end
- local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
- local mp=dir.glob(pattern)
- if mp then
- for i=1,#mp do
- local name=mp[i]
- report_format("removing related mplib format %a",file.basename(name))
- os.remove(name)
- end
- end
+ local engine=environment.ownmain or "luatex"
+ local silent=environment.arguments.silent
+ local errors=environment.arguments.errors
+ local olddir=dir.current()
+ local path=caches.getwritablepath("formats",engine) or ""
+ if path~="" then
+ lfs.chdir(path)
+ end
+ report_format("using format path %a",dir.current())
+ local texsourcename=file.addsuffix(name,"mkiv")
+ local fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ if fulltexsourcename=="" then
+ texsourcename=file.addsuffix(name,"tex")
+ fulltexsourcename=resolvers.findfile(texsourcename,"tex") or ""
+ end
+ if fulltexsourcename=="" then
+ report_format("no tex source file with name %a (mkiv or tex)",name)
+ lfs.chdir(olddir)
+ return
+ else
+ report_format("using tex source file %a",fulltexsourcename)
+ end
+ local texsourcepath=dir.expandname(file.dirname(fulltexsourcename))
+ local specificationname=file.replacesuffix(fulltexsourcename,"lus")
+ local fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ if fullspecificationname=="" then
+ specificationname=file.join(texsourcepath,"context.lus")
+ fullspecificationname=resolvers.findfile(specificationname,"tex") or ""
+ end
+ if fullspecificationname=="" then
+ report_format("unknown stub specification %a",specificationname)
+ lfs.chdir(olddir)
+ return
+ end
+ local specificationpath=file.dirname(fullspecificationname)
+ local usedluastub=nil
+ local usedlualibs=dofile(fullspecificationname)
+ if type(usedlualibs)=="string" then
+ usedluastub=file.join(file.dirname(fullspecificationname),usedlualibs)
+ elseif type(usedlualibs)=="table" then
+ report_format("using stub specification %a",fullspecificationname)
+ local texbasename=file.basename(name)
+ local luastubname=file.addsuffix(texbasename,luasuffixes.lua)
+ local lucstubname=file.addsuffix(texbasename,luasuffixes.luc)
+ report_format("creating initialization file %a",luastubname)
+ utilities.merger.selfcreate(usedlualibs,specificationpath,luastubname)
+ if utilities.lua.compile(luastubname,lucstubname) and lfs.isfile(lucstubname) then
+ report_format("using compiled initialization file %a",lucstubname)
+ usedluastub=lucstubname
+ else
+ report_format("using uncompiled initialization file %a",luastubname)
+ usedluastub=luastubname
+ end
+ else
+ report_format("invalid stub specification %a",fullspecificationname)
lfs.chdir(olddir)
+ return
+ end
+ local specification={
+ primaryflags=primaryflags(),
+ secondaryflags=secondaryflags(),
+ luafile=quoted(usedluastub),
+ texfile=quoted(fulltexsourcename),
+ dump=os.platform=="unix" and "\\\\dump" or "\\dump",
+ }
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be generated, no runner available for engine %a",name,engine)
+ elseif silent then
+ statistics.starttiming()
+ specification.redirect="> temp.log"
+ local result=runner(specification)
+ local runtime=statistics.stoptiming()
+ if result~=0 then
+ print(format("%s silent make > fatal error when making format %q",engine,name))
+ else
+ print(format("%s silent make > format %q made in %.3f seconds",engine,name,runtime))
+ end
+ os.remove("temp.log")
+ else
+ runner(specification)
+ end
+ local pattern=file.removesuffix(file.basename(usedluastub)).."-*.mem"
+ local mp=dir.glob(pattern)
+ if mp then
+ for i=1,#mp do
+ local name=mp[i]
+ report_format("removing related mplib format %a",file.basename(name))
+ os.remove(name)
+ end
+ end
+ lfs.chdir(olddir)
end
local template=[[%flags% --fmt=%fmtfile% --lua=%luafile% %texfile% %more%]]
local checkers={
- flags="string",
- more="string",
- fmtfile="readable",
- luafile="readable",
- texfile="readable",
+ flags="string",
+ more="string",
+ fmtfile="readable",
+ luafile="readable",
+ texfile="readable",
}
local runners={
- luatex=sandbox.registerrunner {
- name="run luatex format",
- program="luatex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
- luajittex=sandbox.registerrunner {
- name="run luajittex format",
- program="luajittex",
- template=template,
- checkers=checkers,
- reporter=report_format,
- },
+ luatex=sandbox.registerrunner {
+ name="run luatex format",
+ program="luatex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
+ luajittex=sandbox.registerrunner {
+ name="run luajittex format",
+ program="luajittex",
+ template=template,
+ checkers=checkers,
+ reporter=report_format,
+ },
}
function environment.run_format(name,data,more)
- if name and name~="" then
- local engine=environment.ownmain or "luatex"
- local barename=file.removesuffix(name)
- local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
- if fmtname=="" then
- fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
- end
- fmtname=resolvers.cleanpath(fmtname)
- if fmtname=="" then
- report_format("no format with name %a",name)
+ if name and name~="" then
+ local engine=environment.ownmain or "luatex"
+ local barename=file.removesuffix(name)
+ local fmtname=caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats",engine)
+ if fmtname=="" then
+ fmtname=resolvers.findfile(file.addsuffix(barename,"fmt")) or ""
+ end
+ fmtname=resolvers.cleanpath(fmtname)
+ if fmtname=="" then
+ report_format("no format with name %a",name)
+ else
+ local barename=file.removesuffix(name)
+ local luaname=file.addsuffix(barename,"luc")
+ if not lfs.isfile(luaname) then
+ luaname=file.addsuffix(barename,"lua")
+ end
+ if not lfs.isfile(luaname) then
+ report_format("using format name %a",fmtname)
+ report_format("no luc/lua file with name %a",barename)
+ else
+ local runner=runners[engine]
+ if not runner then
+ report_format("format %a cannot be run, no runner available for engine %a",name,engine)
else
- local barename=file.removesuffix(name)
- local luaname=file.addsuffix(barename,"luc")
- if not lfs.isfile(luaname) then
- luaname=file.addsuffix(barename,"lua")
- end
- if not lfs.isfile(luaname) then
- report_format("using format name %a",fmtname)
- report_format("no luc/lua file with name %a",barename)
- else
- local runner=runners[engine]
- if not runner then
- report_format("format %a cannot be run, no runner available for engine %a",name,engine)
- else
- runner {
- flags=primaryflags(),
- fmtfile=quoted(barename),
- luafile=quoted(luaname),
- texfile=quoted(data),
- more=more,
- }
- end
- end
+ runner {
+ flags=primaryflags(),
+ fmtfile=quoted(barename),
+ luafile=quoted(luaname),
+ texfile=quoted(data),
+ more=more,
+ }
end
+ end
end
+ end
end
end -- of closure
--- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
+-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 877962
--- stripped bytes : 317771
+-- original bytes : 994864
+-- stripped bytes : 395007
-- end library merge
@@ -21370,6 +24986,7 @@ local owntree = environment and environment.ownpath or ownpath
local ownlibs = { -- order can be made better
+ 'l-bit32.lua',
'l-lua.lua',
'l-macro.lua',
'l-sandbox.lua',
@@ -21385,6 +25002,7 @@ local ownlibs = { -- order can be made better
'l-file.lua',
'l-gzip.lua',
'l-md5.lua',
+ 'l-sha.lua',
'l-url.lua',
'l-dir.lua',
'l-boolean.lua',
@@ -21399,6 +25017,19 @@ local ownlibs = { -- order can be made better
'util-prs.lua',
'util-fmt.lua',
+ 'util-soc-imp-reset.lua',
+ 'util-soc-imp-socket.lua',
+ 'util-soc-imp-copas.lua',
+ 'util-soc-imp-ltn12.lua',
+ -- 'util-soc-imp-mbox.lua',
+ 'util-soc-imp-mime.lua',
+ 'util-soc-imp-url.lua',
+ 'util-soc-imp-headers.lua',
+ 'util-soc-imp-tp.lua',
+ 'util-soc-imp-http.lua',
+ 'util-soc-imp-ftp.lua',
+ 'util-soc-imp-smtp.lua',
+
'trac-set.lua',
'trac-log.lua',
'trac-inf.lua', -- was before trac-set
@@ -21601,9 +25232,7 @@ local helpinfo = [[
<flag name="locate"><short>locate given filename in database (default) or system (<ref name="first"/> <ref name="all"/> <ref name="detail"/>)</short></flag>
</subcategory>
<subcategory>
- <flag name="autotree"><short>use texmf tree cf. env texmfstart_tree or texmfstarttree</short></flag>
<flag name="tree" value="pathtotree"><short>use given texmf tree (default file: setuptex.tmf)</short></flag>
- <flag name="environment" value="name"><short>use given (tmf) environment file</short></flag>
<flag name="path" value="runpath"><short>go to given path before execution</short></flag>
<flag name="ifchanged" value="filename"><short>only execute when given file has changed (md checksum)</short></flag>
<flag name="iftouched" value="old,new"><short>only execute when given file has changed (time stamp)</short></flag>
@@ -21623,7 +25252,7 @@ local helpinfo = [[
</subcategory>
<subcategory>
<flag name="edit"><short>launch editor with found file</short></flag>
- <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>)</short></flag>
+ <flag name="launch"><short>launch files like manuals, assumes os support (<ref name="all"/>,<ref name="list"/>)</short></flag>
</subcategory>
<subcategory>
<flag name="timedrun"><short>run a script and time its run</short></flag>
@@ -22022,9 +25651,9 @@ function resolvers.launch(str)
end
function runners.launch_file(filename)
- trackers.enable("resolvers.locating")
local allresults = environment.arguments["all"]
- local pattern = environment.arguments["pattern"]
+ local pattern = environment.arguments["pattern"]
+ local listonly = environment.arguments["list"]
if not pattern or pattern == "" then
pattern = filename
end
@@ -22039,14 +25668,32 @@ function runners.launch_file(filename)
t = resolvers.findfiles("*/" .. pattern .. "*",nil,allresults)
end
if t and #t > 0 then
- if allresults then
- for _, v in pairs(t) do
- report("launching %s", v)
- resolvers.launch(v)
+ for i=1,#t do
+ local name = t[i]
+ if listonly then
+ report("% 3i: %-30s %s",i,file.basename(name),file.dirname(name))
+ else
+ report("launching: %s",name)
+ resolvers.launch(name)
+ if not allresults then
+ break
+ end
+ end
+ end
+ if listonly then
+ io.write("\n")
+ io.write("\n[select number]\n\n>> ")
+ local answer = tonumber(io.read())
+ if answer then
+ io.write("\n")
+ local name = t[answer]
+ if name then
+ report("launching: %s",name)
+ resolvers.launch(name)
+ else
+ report("invalid number")
+ end
end
- else
- report("launching %s", t[1])
- resolvers.launch(t[1])
end
else
report("no match for %s", pattern)
@@ -22166,12 +25813,9 @@ function runners.execute_ctx_script(filename,...)
dofile(fullname)
local savename = environment.arguments['save']
if savename then
- local save_list = runners.save_list
- if save_list and next(save_list) then
- if type(savename) ~= "string" then savename = file.basename(fullname) end
- savename = file.replacesuffix(savename,"cfg")
- runners.save_script_session(savename,save_list)
- end
+ if type(savename) ~= "string" then savename = file.basename(fullname) end
+ savename = file.replacesuffix(savename,"cfg")
+ runners.save_script_session(savename,save_list)
end
return true
end
@@ -22188,22 +25832,22 @@ function runners.execute_ctx_script(filename,...)
local scriptbase = match(scriptname,".*mtx%-([^%-]-)%.lua")
if scriptbase then
local data = io.loaddata(scriptname)
-local application = match(data,"local application.-=.-(%{.-%})")
-if application then
- application = loadstring("return " .. application)
- if application then
- application = application()
- local banner = application.banner
- if banner then
- local description, version = match(banner,"^(.-) ([%d.]+)$")
- if description then
- valid[#valid+1] = { scriptbase, version, description }
- else
- valid[#valid+1] = { scriptbase, "", banner }
- end
- end
- end
-end
+ local application = match(data,"local application.-=.-(%{.-%})")
+ if application then
+ application = loadstring("return " .. application)
+ if application then
+ application = application()
+ local banner = application.banner
+ if banner then
+ local description, version = match(banner,"^(.-) ([%d.]+)$")
+ if description then
+ valid[#valid+1] = { scriptbase, version, description }
+ else
+ valid[#valid+1] = { scriptbase, "", banner }
+ end
+ end
+ end
+ end
end
end
if #valid > 0 then
@@ -22243,7 +25887,7 @@ function runners.timedrun(filename) -- just for me
end
function runners.timed(action)
- statistics.timed(action)
+ statistics.timed(action,true)
end
function runners.associate(filename)
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 <jobname.tui>:
@@ -1176,7 +1176,7 @@
\def\defineregister
{\dodoubleargument\dodefineregister}
-
+
\def\registerlengte{\utilityregisterlength}
\def\utilityregisterlength{0}
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.</p>
-- 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 <l n='context'/> end a private attri
accessible too, so a private attribute can have a public appearance.</p>
--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
@@ -1760,6 +1804,25 @@ 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
local function resolve(di,element,n,fulltag)
@@ -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 = { "<btxdata>"}
+ for dataset, used in sortedhash(tagsindatasets) do
+ t[#t+1] = publications.converttoxml(dataset,true,false,true,false,true,true)
+ end
+ t[#t+1] = "</btxdata>"
+ 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['<c n="%s">%s</c>']
+ local f_spacing = formatters['<c p="%s">%s</c>']
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] = "<?xml version='1.0' standalone='yes'?>" .. "\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</%s>",currentdepth,top)
+ report_export("%w</%s>",currentdepth,tree.tg)
else
- report_export("</%s>",top)
+ report_export("</%s>",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<!-- start content with length %s -->",currentdepth,#content)
+ report_export("%w<!-- start content with length %s -->",currentdepth,utflen(content))
report_export("%w%s",currentdepth,(gsub(content,"\n","\\n")))
report_export("%w<!-- stop content -->",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<!-- possible paragraph mixup at %C case %i -->",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<!-- processing glyph %C tagged %a) -->",currentdepth,c,last)
+ report_export("%w<!-- processing glyph %C tagged %a -->",currentdepth,c,last)
end
else
if trace_export then
- report_export("%w<!-- processing glyph %C tagged %a) -->",currentdepth,c,at)
+ report_export("%w<!-- processing glyph %C tagged %a -->",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<!-- processing space glyph %U tagged %a case 1 -->",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<!-- processing space glyph %U tagged %a case 1 -->",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<!-- processing space glyph %U tagged %a case 2 -->",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<!-- processing space glyph %U tagged %a case 2 -->",currentdepth,ca,last)
+ end
end
+ -- if somespace[currentcontent[nofcurrentcontent]] then
+ -- if trace_export then
+ -- report_export("%w<!-- removing space -->",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<!-- removing space -->",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<!-- processing image tagged %a",currentdepth,last)
- end
- last = nil
- currentparagraph = nil
- else
- -- we need to determine an end-of-line
- local list = getlist(n)
- if list then
+ 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
- collectresults(list,n,at)
- end
- end
- elseif id == kern_code then
- local kern = getkern(n)
- if kern > 0 then
- local limit = threshold
- if p and getid(p) == glyph_code then
- limit = fontquads[getfont(p)] / 4
+ 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<!-- processing image tagged %a",currentdepth,last)
+ end
+ last = nil
+ currentparagraph = nil
+ else
+ -- we need to determine an end-of-line
+ local list = getlist(n)
+ if list then
+ -- todo: no par checking needed in math
+ local at = getattr(n,a_tagged) or pat
+ collectresults(list,n,at)
+ end
end
- if kern > limit then
- if last and not somespace[currentcontent[nofcurrentcontent]] then
- local a = getattr(n,a_tagged) or pat
- if a == last then
- if not somespace[currentcontent[nofcurrentcontent]] then
+ elseif id == kern_code then
+ local kern = getkern(n)
+ if kern > 0 then
+ local limit = threshold
+ if p then
+ local c, f = isglyph(p)
+ if c then
+ limit = fontquads[f] / 4
+ end
+ end
+ if kern > limit then
+ if last and not somespace[currentcontent[nofcurrentcontent]] then
+ local a = getattr(n,a_tagged) or pat
+ if a == last then
+ if not somespace[currentcontent[nofcurrentcontent]] then
+ if trace_export then
+ report_export("%w<!-- injecting spacing 8 (kern %p) -->",currentdepth,kern)
+ end
+ nofcurrentcontent = nofcurrentcontent + 1
+ currentcontent[nofcurrentcontent] = " "
+ end
+ elseif a then
+ -- e.g LOGO<space>LOGO
+ if trace_export then
+ report_export("%w<!-- processing kern, threshold %p, tag %s => %s -->",currentdepth,limit,last,a)
+ end
+ last = a
+ pushcontent()
if trace_export then
- report_export("%w<!-- injecting spacing 8 (kern %p) -->",currentdepth,kern)
+ report_export("%w<!-- injecting spacing 9 (kern %p) -->",currentdepth,kern)
end
nofcurrentcontent = nofcurrentcontent + 1
currentcontent[nofcurrentcontent] = " "
+ currentnesting = taglist[last]
+ pushentry(currentnesting)
+ currentattribute = last
end
- elseif a then
- -- e.g LOGO<space>LOGO
- if trace_export then
- report_export("%w<!-- processing kern, threshold %p, tag %s => %s -->",currentdepth,limit,last,a)
- end
- last = a
- pushcontent()
- if trace_export then
- report_export("%w<!-- injecting spacing 9 (kern %p) -->",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<!-- processing anchor tagged %a",currentdepth,last)
+ end
+ last = nil
+ currentparagraph = nil
+ end
+ elseif not localparagraph and id == localpar_code and subtype == 0 then
+ localparagraph = getattr(n,a_taggedpar)
end
+ p = n
+ pid = id
+ end
+ if maybewrong then
+ showmaybe(maybewrong)
end
- p = n
end
-end
-function nodes.handlers.export(head) -- hooks into the page builder
- starttiming(treehash)
- if trace_export then
- report_export("%w<!-- start flushing page -->",currentdepth)
+ function nodes.handlers.export(head) -- hooks into the page builder
+ starttiming(treehash)
+ if trace_export then
+ report_export("%w<!-- start flushing page -->",currentdepth)
+ end
+ -- continueexport()
+ restart = true
+ collectresults(head)
+ if trace_export then
+ report_export("%w<!-- stop flushing page -->",currentdepth)
+ end
+ stoptiming(treehash)
+ return head
end
- -- continueexport()
- restart = true
- collectresults(tonut(head))
- if trace_export then
- report_export("%w<!-- stop flushing page -->",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] = "<extradata>"
+ for name, action in sortedhash(extradata) do
+ t[#t+1] = action()
+ end
+ t[#t+1] = "</extradata>"
+ t[#t+1] = "</document>"
+ -- we use a function because otherwise we can have a bad capture index
+ result = gsub(result,"</document>",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),
+ "<!-- This export file is used for filtering runtime only! -->\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,
@@ -3880,6 +4156,12 @@ implement {
}
implement {
+ name = "settagformulacontent",
+ actions = structurestags.setformulacontent,
+ arguments = "integer",
+}
+
+implement {
name = "settagdelimitedsymbol",
actions = structurestags.settagdelimitedsymbol,
arguments = "string"
@@ -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 "<unset> (not supported yet)")
- -- report(" width : %p",width or "<unset>")
- -- report(" height: %p",height or "<unset>")
- -- report(" depth : %p",depth or "<unset>")
- -- report(" attr : %s",attr or "<unset>")
- -- report(" data : %s",data or "<unset>")
- -- 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 "<unset>")
- -- report(" view : %s",view or "<unset>")
- -- report(" zoom : %s",zoom or "<unset> (not supported)")
- -- report(" width : %p",width or "<unset>")
- -- report(" height: %p",height or "<unset>")
- -- report(" depth : %p",depth or "<unset>")
- -- 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_<k> 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_<k> 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","<<newline>>" },
- { "\r","<<par>>" },
+ { "\n", "<<newline>>" },
+ { "\r", "<<par>>" },
}
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 "<<function>>" -- argument.mode
+ end
+ return "<<token>>"
+ end
+ return "<<userdata>>"
+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.</p>
<p>Some code may move to a module in the language namespace.</p>
--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 "<unset>"
- 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("<subaction>",t)
+ local a = subactions[t]
+ if a then
+ a(t)
+ else
+ if trace_charstrings then
+ showvalue("<subaction>",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--
<p>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 <l n='luatex'/>.</p>
--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,10 +2489,23 @@ 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",
actions = adaptcontext
@@ -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.</p>
-- 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--
-<p>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.</p>
---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|<color>}
-
-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
<p>This is very experimental code!</p>
--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-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|<color>}
+
+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'] = {
<p>Not much is happening here.</p>
--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 <i> <n> RD or -| <n encrypted bytes> 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 <n> RD <n encrypted bytes> 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.</p>
-- 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 "<noname>",wd,basename)
+ report_markwidth("mark %a with width %b found in %a",d.name or "<noname>",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/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-example.mkiv
index 584ee1351..82d5b0cb0 100644
--- a/tex/context/base/mkiv/java-imp-exa.mkiv
+++ b/tex/context/base/mkiv/java-imp-example.mkiv
@@ -1,5 +1,5 @@
%D \module
-%D [ file=java-exa,
+%D [ file=java-imp-example, % was: java-exa
%D version=2002.??.??,
%D title=\CONTEXT\ JavaScript Macros,
%D subtitle=Example Support,
@@ -11,6 +11,9 @@
%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
diff --git a/tex/context/base/mkiv/java-imp-fld.mkiv b/tex/context/base/mkiv/java-imp-fields.mkiv
index cbd53fffb..5801c3216 100644
--- a/tex/context/base/mkiv/java-imp-fld.mkiv
+++ b/tex/context/base/mkiv/java-imp-fields.mkiv
@@ -1,5 +1,5 @@
%D \module
-%D [ file=java-fld,
+%D [ file=java-imp-fields, % was java-fld
%D version=1998.05.20,
%D title=\CONTEXT\ JavaScript Macros,
%D subtitle=Field Support,
@@ -26,9 +26,9 @@
%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.
+%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.
@@ -262,9 +262,28 @@ function Forget_Changes() {
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.
@@ -278,7 +297,7 @@ function Field_Name(FieldSet,i) {
function Reset_Fields(FieldSet) {
var i = 1 ;
while (true) {
- v = Field_Name(FieldSet,i) ;
+ var v = Field_Name(FieldSet,i) ;
if (!v) {
break ;
} else {
@@ -292,7 +311,7 @@ function Reset_Fields(FieldSet) {
function Set_Fields(FieldSet) {
var i = 1 ;
while (true) {
- v = Field_Name(FieldSet,i) ;
+ var v = Field_Name(FieldSet,i) ;
if (!v) {
break ;
} else {
@@ -305,7 +324,7 @@ function Set_Fields(FieldSet) {
function Set_Field(FieldSet, FieldName) {
Reset_Fields(FieldSet) ;
- v = Field_Name(FieldSet,FieldName) ;
+ var v = Field_Name(FieldSet,FieldName) ;
if (v) {
v.value = "Yes" ;
this.dirty = false ;
@@ -314,7 +333,7 @@ function Set_Field(FieldSet, FieldName) {
function Reset_Field(FieldSet, FieldName) {
Set_Fields(FieldSet) ;
- v = Field_Name(FieldSet,FieldName) ;
+ var v = Field_Name(FieldSet,FieldName) ;
if (v) {
v.value = "Off" ;
this.dirty = false ;
@@ -323,16 +342,16 @@ function Reset_Field(FieldSet, FieldName) {
function Walk_Field(FieldSet) {
var i = 1 ;
+ this.syncAnnotScan();
while (true) {
- v = Field_Name(FieldSet,i) ;
+ var v = Field_Name(FieldSet,i) ;
if (v) {
if (v.value != "Off") {
v.value = "Off" ;
- var ii = i ;
- ii++ ;
- v = Field_Name(FieldSet,ii) ;
+ v = Field_Name(FieldSet,i + 1) ;
if (! v) {
v = Field_Name(FieldSet,1) ;
+ } else {
}
if (v) {
v.value = "Yes" ;
@@ -341,6 +360,10 @@ function Walk_Field(FieldSet) {
}
i++ ;
} else {
+ v = Field_Name(FieldSet,1) ;
+ if (v) {
+ v.value = "Yes" ;
+ }
break ;
}
}
diff --git a/tex/context/base/mkiv/java-imp-rhh.mkiv b/tex/context/base/mkiv/java-imp-highlight.mkiv
index 5f057f550..b55628f4b 100644
--- a/tex/context/base/mkiv/java-imp-rhh.mkiv
+++ b/tex/context/base/mkiv/java-imp-highlight.mkiv
@@ -1,5 +1,5 @@
%D \module
-%D [ file=java-rhh,
+%D [ file=java-imp-highlightm, % was: java-rhh
%D version=2010.02.01,
%D title=\CONTEXT\ JavaScript Macros,
%D subtitle=Runtime Highlight Hack,
diff --git a/tex/context/base/mkiv/java-imp-fil.mkiv b/tex/context/base/mkiv/java-imp-print.mkiv
index 808950f28..3d5325ff0 100644
--- a/tex/context/base/mkiv/java-imp-fil.mkiv
+++ b/tex/context/base/mkiv/java-imp-print.mkiv
@@ -1,5 +1,5 @@
%D \module
-%D [ file=java-fil,
+%D [ file=java-imp-print, % was: java-fil
%D version=1998.06.01,
%D title=\CONTEXT\ JavaScript Macros,
%D subtitle=Filing and Printing,
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\startJSpreamble Auxiliary used now
+\startJSpreamble auxiliary used now
function DocumentFileName() {
var Paths = this.path.split("/") ;
diff --git a/tex/context/base/mkiv/java-imp-stp.mkiv b/tex/context/base/mkiv/java-imp-steps.mkiv
index 8ac5d58b8..3990e4d7a 100644
--- a/tex/context/base/mkiv/java-imp-stp.mkiv
+++ b/tex/context/base/mkiv/java-imp-steps.mkiv
@@ -1,5 +1,5 @@
%D \module
-%D [ file=java-stp,
+%D [ file=java-imp-steps, % was: java-stp
%D version=2004.03.15,
%D title=\CONTEXT\ JavaScript Macros,
%D subtitle=Stepping,
diff --git a/tex/context/base/mkiv/java-imp-videoplayer.mkiv b/tex/context/base/mkiv/java-imp-videoplayer.mkiv
new file mode 100644
index 000000000..beda499a7
--- /dev/null
+++ b/tex/context/base/mkiv/java-imp-videoplayer.mkiv
@@ -0,0 +1,82 @@
+%D \module
+%D [ file=java-imp-videoplayer,
+%D version=2009.12.31,
+%D title=\CONTEXT\ JavaScript Macros,
+%D subtitle=Shockwave 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 As part of the interaction manual writing this code was moved here. It's
+%D kind of obsolete as shockwave is obsolete.
+
+% using videoplayer.swf from adobe or strobemediaplayback.swf from sourceforge:
+
+\startluaparameterset[shockwave:display]
+ toolbar = true,
+ -- preview = "somefile",
+ open = "click",
+ close = "focus",
+\stopluaparameterset
+
+\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
+
+\definereference[StartShockwave] [JS(StartShockwave)]
+\definereference[StopShockwave] [JS(StopShockwave)]
+\definereference[RewindShockwave][JS(RewindShockwave)]
+\definereference[PauseShockwave] [JS(PauseShockwave)]
+
+\unprotect
+
+\doglobal \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]
+
+% \doglobal \useexternalfigure
+% [shockwave]
+% [strobemediaplayback.swf]
+% [arguments=\luaparameterset{shockwave:arguments}{src="\externalfigureparameter\v!file"},
+% resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}},
+% display=shockwave:display]
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/java-imp-vplayer.mkiv b/tex/context/base/mkiv/java-imp-vplayer.mkiv
new file mode 100644
index 000000000..4ed08cad6
--- /dev/null
+++ b/tex/context/base/mkiv/java-imp-vplayer.mkiv
@@ -0,0 +1,105 @@
+%D \module
+%D [ file=java-imp-vplayer,
+%D version=2009.12.31,
+%D title=\CONTEXT\ JavaScript Macros,
+%D subtitle=Shockwave 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 As part of the interaction manual writing this code was moved here. It's
+%D kind of obsolete as shockwave is obsolete. Anywaym, here's how it works.
+%D One can actually set all kind of properties but let's not waste time on
+%D that. Maybe some day \PDF\ will have proper native video support.
+%D
+%D \starttyping
+%D \starttext
+%D
+%D \useJSscripts[vplayer]
+%D
+%D \setupinteraction
+%D [state=start]
+%D
+%D \externalfigure
+%D [shockwave]
+%D [frame=on,
+%D width=480pt,
+%D height=270pt,
+%D %file=mathematics.mp4, % Hollie McNish, Martin Pyper & Jules Buckley (Metropole Orchestra)
+%D file=bathtub.mp4, % Jacob Collier & Becca Stevens
+%D label=foo]
+%D
+%D \goto{START} [JS(StartShockwave{foo})]
+%D \goto{REWIND}[JS(RewindShockwave{foo})]
+%D \goto{PAUSE} [JS(PauseShockwave{foo})]
+%D \goto{STOP} [JS(StopShockwave{foo})]
+%D
+%D \stoptext
+%D \stoptyping
+
+% using vplayer9.swf from ctan:
+
+\startluaparameterset[shockwave:display]
+ toolbar = true,
+ -- preview = "somefile",
+ open = "click",
+ close = "focus",
+\stopluaparameterset
+
+\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
+
+\definereference[StartShockwave] [JS(StartShockwave)]
+\definereference[StopShockwave] [JS(StopShockwave)]
+\definereference[RewindShockwave][JS(RewindShockwave)]
+\definereference[PauseShockwave] [JS(PauseShockwave)]
+
+\unprotect
+
+\doglobal \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]
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/java-ini.lua b/tex/context/base/mkiv/java-ini.lua
index 61ab15e7a..b41b065e8 100644
--- a/tex/context/base/mkiv/java-ini.lua
+++ b/tex/context/base/mkiv/java-ini.lua
@@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['java-ini'] = {
-- todo: don't flush scripts if no JS key
-local format = string.format
+local format, gsub, find = string.format, string.gsub, string.find
local concat = table.concat
local lpegmatch, P, S, C, Carg, Cc = lpeg.match, lpeg.P, lpeg.S, lpeg.C, lpeg.Carg, lpeg.Cc
@@ -69,6 +69,7 @@ local parsefunctions = (fname + any)^0
function javascripts.storecode(str)
local name, uses, script = lpegmatch(parsecode,str)
if name and name ~= "" then
+ script = gsub(script,"%s*([^\n\r]+)%s*[\n\r]+$","%1")
codes[name] = { uses, script }
end
end
@@ -123,8 +124,9 @@ function javascripts.usepreamblenow(name) -- now later
local names = settings_to_array(name)
for i=1,#names do
local somename = names[i]
- if not preambled[somename] then
- preambles[preambled[somename]][2] = "now"
+ local preamble = preambled[somename]
+ if preamble then
+ preambles[preamble][2] = "now"
if trace_javascript then
report_javascripts("used preamble %a, state %a, order %a",somename,"now","auto")
end
diff --git a/tex/context/base/mkiv/java-ini.mkiv b/tex/context/base/mkiv/java-ini.mkiv
index 25b8ba600..95c9c5220 100644
--- a/tex/context/base/mkiv/java-ini.mkiv
+++ b/tex/context/base/mkiv/java-ini.mkiv
@@ -38,7 +38,6 @@
%D \goto{calculate total}[Sum(1.5,2.3)]
%D \stoptyping
-
%D \macros
%D {startJScode}
%D
@@ -55,7 +54,7 @@
%D actually include the preamble needed.
%D
%D \starttyping
-%D \startJScode{uses} uses {later}
+%D \startJScode{uses} used {later}
%D uses = 6 ;
%D \stopJScode
%D \stoptyping
@@ -156,4 +155,18 @@
{\clf_usejavascriptscripts {#1}% two steps as this one calls tex code
\clf_usejavascriptpreamble{#2}}% so this one comes later
+\unexpanded\def\useJSpreamble
+ {\dosingleempty\java_use_preamble}
+
+\def\java_use_preamble[#1]%
+ {\clf_usejavascriptpreamble{#1}}% so this one comes later
+
+%D Here:
+
+\definefilesynonym[java-imp-fld.mkiv] [java-imp-fields.mkiv]
+\definefilesynonym[java-imp-stp.mkiv] [java-imp-steps.mkiv]
+\definefilesynonym[java-imp-fil.mkiv] [java-imp-print.mkiv]
+\definefilesynonym[java-imp-rhh.mkiv] [java-imp-highlight.mkiv]
+\definefilesynonym[java-imp-exa.mkiv] [java-imp-example.mkiv]
+
\protect \endinput
diff --git a/tex/context/base/mkiv/l-bit32.lua b/tex/context/base/mkiv/l-bit32.lua
index 5f35b8fee..25716e0a8 100644
--- a/tex/context/base/mkiv/l-bit32.lua
+++ b/tex/context/base/mkiv/l-bit32.lua
@@ -20,7 +20,7 @@ elseif utf8 then
-- lua 5.3: bitwise.lua, v 1.24 2014/12/26 17:20:53 roberto
- bit32 = load ( [[
+ load ( [[
local select = select -- instead of: arg = { ... }
bit32 = {
@@ -105,13 +105,13 @@ bit32 = {
return ((a & ~(mask << f)) | ((v & mask) << f)) & 0xFFFFFFFF
end,
}
- ]] )
+ ]] ) ()
elseif bit then
-- luajit (for now)
- bit32 = load ( [[
+ load ( [[
local band, bnot, rshift, lshift = bit.band, bit.bnot, bit.rshift, bit.lshift
bit32 = {
@@ -135,7 +135,7 @@ bit32 = {
rrotate = bit.ror,
rshift = rshift,
}
- ]] )
+ ]] ) ()
else
@@ -146,5 +146,3 @@ else
xpcall(function() local _, t = require("bit32") if t then bit32 = t end return end,function() end)
end
-
-return bit32 or false
diff --git a/tex/context/base/mkiv/l-dir.lua b/tex/context/base/mkiv/l-dir.lua
index bc691d536..b0b2c5283 100644
--- a/tex/context/base/mkiv/l-dir.lua
+++ b/tex/context/base/mkiv/l-dir.lua
@@ -75,7 +75,8 @@ function dir.current()
return (gsub(currentdir(),"\\","/"))
end
--- somewhat optimized
+-- The next one is somewhat optimized but still slow but it's a pitty that the iterator
+-- doesn't return a mode too.
local function glob_pattern_function(path,patt,recurse,action)
if isdir(path) then
@@ -89,6 +90,7 @@ local function glob_pattern_function(path,patt,recurse,action)
usedpath = path
end
local dirs
+ local nofdirs = 0
for name in walkdir(usedpath) do
if name ~= "." and name ~= ".." then
local full = path .. name
@@ -98,16 +100,18 @@ local function glob_pattern_function(path,patt,recurse,action)
action(full)
end
elseif recurse and mode == "directory" then
- if not dirs then
- dirs = { full }
+ if dirs then
+ nofdirs = nofdirs + 1
+ dirs[nofdirs] = full
else
- dirs[#dirs+1] = full
+ nofdirs = 1
+ dirs = { full }
end
end
end
end
if dirs then
- for i=1,#dirs do
+ for i=1,nofdirs do
glob_pattern_function(dirs[i],patt,recurse,action)
end
end
@@ -118,38 +122,41 @@ local function glob_pattern_table(path,patt,recurse,result)
if not result then
result = { }
end
- if isdir(path) then
- local usedpath
- if path == "/" then
- usedpath = "/."
- elseif not find(path,"/$") then
- usedpath = path .. "/."
- path = path .. "/"
- else
- usedpath = path
- end
- local dirs
- for name in walkdir(usedpath) do
- if name ~= "." and name ~= ".." then
- local full = path .. name
- local mode = attributes(full,'mode')
- if mode == 'file' then
- if not patt or find(full,patt) then
- result[#result+1] = full
- end
- elseif recurse and mode == "directory" then
- if not dirs then
- dirs = { full }
- else
- dirs[#dirs+1] = full
- end
+ local usedpath
+ if path == "/" then
+ usedpath = "/."
+ elseif not find(path,"/$") then
+ usedpath = path .. "/."
+ path = path .. "/"
+ else
+ usedpath = path
+ end
+ local dirs
+ local nofdirs = 0
+ local noffiles = #result
+ for name, a in walkdir(usedpath) do
+ if name ~= "." and name ~= ".." then
+ local full = path .. name
+ local mode = attributes(full,'mode')
+ if mode == 'file' then
+ if not patt or find(full,patt) then
+ noffiles = noffiles + 1
+ result[noffiles] = full
+ end
+ elseif recurse and mode == "directory" then
+ if dirs then
+ nofdirs = nofdirs + 1
+ dirs[nofdirs] = full
+ else
+ nofdirs = 1
+ dirs = { full }
end
end
end
- if dirs then
- for i=1,#dirs do
- glob_pattern_table(dirs[i],patt,recurse,result)
- end
+ end
+ if dirs then
+ for i=1,nofdirs do
+ glob_pattern_table(dirs[i],patt,recurse,result)
end
end
return result
@@ -160,12 +167,13 @@ local function globpattern(path,patt,recurse,method)
if patt and sub(patt,1,-3) == path then
patt = false
end
+ local okay = isdir(path)
if kind == "function" then
- return glob_pattern_function(path,patt,recurse,method)
+ return okay and glob_pattern_function(path,patt,recurse,method) or { }
elseif kind == "table" then
- return glob_pattern_table(path,patt,recurse,method)
+ return okay and glob_pattern_table(path,patt,recurse,method) or method
else
- return glob_pattern_table(path,patt,recurse,{ })
+ return okay and glob_pattern_table(path,patt,recurse,{ }) or { }
end
end
diff --git a/tex/context/base/mkiv/l-file.lua b/tex/context/base/mkiv/l-file.lua
index 5fec0040f..46b6847d3 100644
--- a/tex/context/base/mkiv/l-file.lua
+++ b/tex/context/base/mkiv/l-file.lua
@@ -69,35 +69,34 @@ local lpegmatch = lpeg.match
local getcurrentdir, attributes = lfs.currentdir, lfs.attributes
local checkedsplit = string.checkedsplit
--- local patterns = file.patterns or { }
--- file.patterns = patterns
-
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
-- better this way:
-local tricky = S("/\\") * P(-1)
+----- 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
+ -- if not lpegmatch(tricky,name) then
+ -- name = name .. "/."
+ -- 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(":")
@@ -725,3 +724,10 @@ function file.withinbase(path) -- don't go beyond root
return true
end
+-- not used in context but was in luatex once:
+
+local symlinkattributes = lfs.symlinkattributes
+
+function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
+end
diff --git a/tex/context/base/mkiv/l-lpeg.lua b/tex/context/base/mkiv/l-lpeg.lua
index a7ebd567d..51bc1d3df 100644
--- a/tex/context/base/mkiv/l-lpeg.lua
+++ b/tex/context/base/mkiv/l-lpeg.lua
@@ -202,13 +202,13 @@ 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 m_collapser = Cs( (nonwhitespace^1 + whitespace^1/" ")^0)
+local b_collapser = Cs( whitespace^0 /"" * (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 m_stripper = Cs( (nonspacer^1 + spacer^1/" ")^0)
+local b_stripper = Cs( spacer^0 /"" * (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
@@ -270,7 +270,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 -- hm is this ok
patterns.octal = patterns.oct
patterns.HEX = zero * P("X") * (digit+uppercase)^1
patterns.hex = zero * P("x") * (digit+lowercase)^1
@@ -289,10 +289,14 @@ patterns.propername = (uppercase + lowercase + underscore) * (uppercase + low
patterns.somecontent = (anything - newline - space)^1 -- (utf8char - newline - space)^1
patterns.beginline = #(1-newline)
-patterns.longtostring = Cs(whitespace^0/"" * ((patterns.quoted + nonwhitespace^1 + whitespace^1/"" * (P(-1) + Cc(" ")))^0))
+patterns.longtostring = Cs(whitespace^0/"" * ((patterns.quoted + nonwhitespace^1 + whitespace^1/"" * (endofstring + Cc(" ")))^0))
-local function anywhere(pattern) --slightly adapted from website
- return P { P(pattern) + 1 * V(1) }
+-- local function anywhere(pattern) -- slightly adapted from website
+-- return P { P(pattern) + 1 * V(1) }
+-- end
+
+function anywhere(pattern) -- faster
+ return (1-P(pattern))^0 * P(pattern)
end
lpeg.anywhere = anywhere
@@ -304,12 +308,28 @@ function lpeg.instringchecker(p)
end
end
+-- function lpeg.splitter(pattern, action)
+-- return (((1-P(pattern))^1)/action+1)^0
+-- end
+
+-- function lpeg.tsplitter(pattern, action)
+-- return Ct((((1-P(pattern))^1)/action+1)^0)
+-- end
+
function lpeg.splitter(pattern, action)
- return (((1-P(pattern))^1)/action+1)^0
+ 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)
- return Ct((((1-P(pattern))^1)/action+1)^0)
+ if action then
+ return Ct((((1-P(pattern))^1)/action+1)^0)
+ else
+ return Ct((Cs((1-P(pattern))^1)+1)^0)
+ end
end
-- probleem: separator can be lpeg and that does not hash too well, but
@@ -637,82 +657,6 @@ function lpeg.counter(pattern,action)
end
end
--- utf extensies
-
-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) -- 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)
- elseif 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 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<<c))
- #define extract(a,b) ((a>>b)&0x1))
- #define lshift(a,b) ((a<<b)&0xFFFFFFFF)
- #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<<(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
@@ -225,6 +225,15 @@ local specifications = allocate {
["variant"] = "fi",
},
{
+ ["description"] = "Estonian",
+ ["script"] = "latn",
+ ["bibliographical"] = "est",
+ ["terminological"] = "est",
+ ["context"] = "et",
+ ["opentype"] = "est",
+ ["variant"] = "et",
+ },
+ {
["description"] = "French",
["script"] = "latn",
["bibliographical"] = "fre",
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
@@ -22,19 +22,6 @@
% 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,
\c!leftsentence=\emdash,
@@ -51,6 +38,19 @@
\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,
\s!lefthyphenmin=3,
@@ -328,6 +328,22 @@
\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,
\c!leftsentence=\emdash,
@@ -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 "<unset>")
- 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 "<unset>"
+ 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("<feff") * (lpegpatterns.utf8character/cache)^1 * Cc(">"))
+
+function lpdf.tosixteen(str) -- an lpeg might be faster (no table)
+ if not str or str == "" then
+ return "<feff>" -- 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","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2001</pdfxid:GTS_PDFXVersion></rdf:Description>",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","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-1a:2003</pdfxid:GTS_PDFXVersion></rdf:Description>",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","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",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","<rdf:Description rdf:about='' xmlns:pdfxid='http://www.npes.org/pdfx/ns/id/'><pdfxid:GTS_PDFXVersion>PDF/X-4p</pdfxid:GTS_PDFXVersion></rdf:Description>",false)
insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","<xmpMM:VersionID>1</xmpMM:VersionID>",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","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>1</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",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","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>1</pdfaid:part><pdfaid:conformance>B</pdfaid:conformance></rdf:Description>",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","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>2</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",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","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>3</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",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","<rdf:Description rdf:about='' xmlns:pdfaid='http://www.aiim.org/pdfa/ns/id/'><pdfaid:part>3</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance></rdf:Description>",false)
injectxmpinfo("xml://rdf:RDF","<rdf:Description rdf:about='' xmlns:pdfuaid='http://www.aiim.org/pdfua/ns/id/'><pdfuaid:part>1</pdfuaid:part></rdf:Description>",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("<feff") * (lpeg.patterns.utf8character/cache)^1 * Cc(">"))
+
+ tosixteen = function(str) -- an lpeg might be faster (no table)
+ if not str or str == "" then
+ return "<feff>" -- 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("<feff") * (lpeg.patterns.utf8character/cache)^1 * Cc(">"))
+ local more = 0
-local function tosixteen(str) -- an lpeg might be faster (no table)
- if not str or str == "" then
- return "<feff>" -- 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 <</ActualText %s >> 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 @@
<pdfx:ConTeXt.Url/>
<pdfx:ConTeXt.Support/>
<pdfx:ConTeXt.Version/>
+ <pdfx:ConTeXt.LMTX/>
<pdfx:TeX.Support/>
<pdfx:LuaTeX.Version/>
<pdfx:LuaTeX.Functionality/>
@@ -100,40 +101,76 @@
<pdfaSchema:property>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
- <pdfaProperty:category>external</pdfaProperty:category>
- <pdfaProperty:description>Name of the ConTeXt job</pdfaProperty:description>
- <pdfaProperty:name>ConTeXt.Jobname</pdfaProperty:name>
- <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>Name of the ConTeXt job</pdfaProperty:description>
+ <pdfaProperty:name>ConTeXt.Jobname</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
</rdf:li>
<rdf:li rdf:parseType="Resource">
- <pdfaProperty:category>external</pdfaProperty:category>
- <pdfaProperty:description>Time stamp of ConTeXt version</pdfaProperty:description>
- <pdfaProperty:name>ConTeXt.Time</pdfaProperty:name>
- <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>Time stamp of ConTeXt version</pdfaProperty:description>
+ <pdfaProperty:name>ConTeXt.Time</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
</rdf:li>
<rdf:li rdf:parseType="Resource">
- <pdfaProperty:category>external</pdfaProperty:category>
- <pdfaProperty:description>ConTeXt website</pdfaProperty:description>
- <pdfaProperty:name>ConTeXt.Url</pdfaProperty:name>
- <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>ConTeXt website</pdfaProperty:description>
+ <pdfaProperty:name>ConTeXt.Url</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
</rdf:li>
<rdf:li rdf:parseType="Resource">
- <pdfaProperty:category>external</pdfaProperty:category>
- <pdfaProperty:description>ConTeXt version</pdfaProperty:description>
- <pdfaProperty:name>ConTeXt.Version</pdfaProperty:name>
- <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>ConTeXt support</pdfaProperty:description>
+ <pdfaProperty:name>ConTeXt.Support</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
</rdf:li>
<rdf:li rdf:parseType="Resource">
- <pdfaProperty:category>external</pdfaProperty:category>
- <pdfaProperty:description>Banner of pdftex or one of its successors</pdfaProperty:description>
- <pdfaProperty:name>PTEX.Fullbanner</pdfaProperty:name>
- <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>ConTeXt version</pdfaProperty:description>
+ <pdfaProperty:name>ConTeXt.Version</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
</rdf:li>
<rdf:li rdf:parseType="Resource">
- <pdfaProperty:category>external</pdfaProperty:category>
- <pdfaProperty:description>Document identifier</pdfaProperty:description>
- <pdfaProperty:name>ID</pdfaProperty:name>
- <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>ConTeXt LMTX version</pdfaProperty:description>
+ <pdfaProperty:name>ConTeXt.LMTX</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>TeX support</pdfaProperty:description>
+ <pdfaProperty:name>TeX.Support</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>LuaTeX version</pdfaProperty:description>
+ <pdfaProperty:name>LuaTeX.Version</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>LuaTeX functionality</pdfaProperty:description>
+ <pdfaProperty:name>LuaTeX.Functionality</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>LuaTeX Lua version</pdfaProperty:description>
+ <pdfaProperty:name>LuaTeX.LuaVersion</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>LuaTeX platform</pdfaProperty:description>
+ <pdfaProperty:name>LuaTeX.Platform</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>Document identifier</pdfaProperty:description>
+ <pdfaProperty:name>ID</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
</rdf:li>
</rdf:Seq>
</pdfaSchema:property>
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.
+
+-- <hex encoded> : implicit 0 appended if odd
+-- (byte encoded) : \( \) \\ escaped
+--
+-- <FE><FF> : utf16be
+--
+-- \r \r \t \b \f \( \) \\ \NNN and \<newline> : 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 : <start> <stop> <firstcode>
+-- <start> <stop> [ <firstsequence> <firstsequence> <firstsequence> ]
+-- beginbfchar : <code> <newcodes>
+
+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 @@
<pdfx:ConTeXt.Url/>
<pdfx:ConTeXt.Support/>
<pdfx:ConTeXt.Version/>
+ <pdfx:ConTeXt.LMTX/>
<pdfx:TeX.Support/>
<pdfx:LuaTeX.Version/>
<pdfx:LuaTeX.Functionality/>
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 @@
<pdfx:ConTeXt.Url/>
<pdfx:ConTeXt.Support/>
<pdfx:ConTeXt.Version/>
+ <pdfx:ConTeXt.LMTX/>
<pdfx:TeX.Support/>
<pdfx:LuaTeX.Version/>
<pdfx:LuaTeX.Functionality/>
@@ -112,14 +113,50 @@
</rdf:li>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>ConTeXt support</pdfaProperty:description>
+ <pdfaProperty:name>ConTeXt.Support</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
<pdfaProperty:description>ConTeXt version</pdfaProperty:description>
<pdfaProperty:name>ConTeXt.Version</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<pdfaProperty:category>external</pdfaProperty:category>
- <pdfaProperty:description>Banner of pdftex or one of its successors</pdfaProperty:description>
- <pdfaProperty:name>PTEX.Fullbanner</pdfaProperty:name>
+ <pdfaProperty:description>ConTeXt LMTX version</pdfaProperty:description>
+ <pdfaProperty:name>ConTeXt.LMTX</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>TeX support</pdfaProperty:description>
+ <pdfaProperty:name>TeX.Support</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>LuaTeX version</pdfaProperty:description>
+ <pdfaProperty:name>LuaTeX.Version</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>LuaTeX functionality</pdfaProperty:description>
+ <pdfaProperty:name>LuaTeX.Functionality</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>LuaTeX Lua version</pdfaProperty:description>
+ <pdfaProperty:name>LuaTeX.LuaVersion</pdfaProperty:name>
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
+ </rdf:li>
+ <rdf:li rdf:parseType="Resource">
+ <pdfaProperty:category>external</pdfaProperty:category>
+ <pdfaProperty:description>LuaTeX platform</pdfaProperty:description>
+ <pdfaProperty:name>LuaTeX.Platform</pdfaProperty:name>
<pdfaProperty:valueType>Text</pdfaProperty:valueType>
</rdf:li>
<rdf:li rdf:parseType="Resource">
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 ( [[
-<?xpacket begin="%s" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<?xpacket begin="%s" id="W5M0MpCehiHzreSzNTczkc9d"?>
%%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 <self></self>) / 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 <self></self>) / 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 <self></self>) / 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
-- <?context-directive foo ... ?>
@@ -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","<bar>%1</bar>"))
+ -- 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['<?xml version="2.0"?>\n\n<!-- formula %i -->\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,"^( *)<m:math")
+ local e = match(s,"( *)</m:math>%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,18 +1144,59 @@ 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)
if list and next(list) then
local n, t = 0, { }
@@ -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
@@ -658,6 +863,21 @@ 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
local qprint = mp.quoted
local getmacro = tokens.getters.macro
@@ -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=<string>
-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.</p>
--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"
}
---[[
-<p>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 <l n='luatex'/> node management.</p>
--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] = "<node>"
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.</p>
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 <box>
%
\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] = "<?xml version='1.0' standalone='yes'?>"
- r = r + 1 ; result[r] = "<bibtex>"
+ r = r + 1 ; result[r] = formatters["<bibtex dataset='%s'>"](current.name)
--
if nice then -- will be default
local f_entry_start = formatters[" <entry tag='%s' category='%s' index='%s'>"]
local s_entry_stop = " </entry>"
local f_field = formatters[" <field name='%s'>%s</field>"]
+ local f_cdata = formatters[" <field name='rawbibtex'><![CDATA[%s]]></field>"]
+
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] = "</bibtex>"
--
- 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
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index a2f2ee28b..8cbd7014c 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-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:<name>"
+
+\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 <crlf> {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{<box><hss><box><hss><box>}
{\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 <return> = control <space>
-\def\^^I{\ } % same for <tab>
-
-%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/mkii/syst-rtp.mkiv b/tex/context/base/mkiv/syst-rtp.mkiv
index 82c0778b4..82c0778b4 100644
--- a/tex/context/base/mkii/syst-rtp.mkiv
+++ b/tex/context/base/mkiv/syst-rtp.mkiv
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.</p>
-- 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("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;" + P('"')/"&quot;" + P(1))^0)
-patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + P(1))^0)
+patterns.xmlescape = Cs((P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;" + P('"')/"&quot;" + 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 @@
<cd:variable name='chemicals' value='chemicals'/>
<cd:variable name='chemistry' value='chemistry'/>
<cd:variable name='cite' value='cite'/>
+ <cd:variable name='closed' value='closed'/>
<cd:variable name='color' value='barevne'/>
<cd:variable name='column' value='column'/>
<cd:variable name='columns' value='sloupce'/>
@@ -421,7 +422,7 @@
<cd:variable name='positive' value='positiv'/>
<cd:variable name='postponing' value='odlozit'/>
<cd:variable name='postscript' value='postscript'/>
- <cd:variable name='precedingpage' value='followingpage'/>
+ <cd:variable name='precedingpage' value='precedingpage'/>
<cd:variable name='preference' value='nastaveni'/>
<cd:variable name='preview' value='nahled'/>
<cd:variable name='previous' value='predchozi'/>
@@ -589,6 +590,7 @@
<cd:variable name='understrike' value='understrike'/>
<cd:variable name='understrikes' value='understrikes'/>
<cd:variable name='unframed' value='unframed'/>
+ <cd:variable name='unicode' value='unicode'/>
<cd:variable name='unit' value='jednotka'/>
<cd:variable name='units' value='jednotky'/>
<cd:variable name='unknown' value='neznamy'/>
@@ -859,7 +861,7 @@
<cd:constant name='headseparator' value='headseparator'/>
<cd:constant name='headstyle' value='stylhlavicky'/>
<cd:constant name='height' value='vyska'/>
- <cd:constant name='hfactor' value='vfaktor'/>
+ <cd:constant name='hfactor' value='hfaktor'/>
<cd:constant name='hfil' value='hfil'/>
<cd:constant name='hidenumber' value='hidenumber'/>
<cd:constant name='hoffset' value='hoffset'/>
@@ -1033,6 +1035,7 @@
<cd:constant name='otherstext' value='otherstext'/>
<cd:constant name='outermargin' value='outermargin'/>
<cd:constant name='overprint' value='overprint'/>
+ <cd:constant name='ownerpassword' value='ownerpassword'/>
<cd:constant name='ownnumber' value='vlastnicislo'/>
<cd:constant name='page' value='stranka'/>
<cd:constant name='pageboundaries' value='hranicestranky'/>
@@ -1246,6 +1249,7 @@
<cd:constant name='textstyle' value='styltextu'/>
<cd:constant name='textwidth' value='sirkatextu'/>
<cd:constant name='threshold' value='threshold'/>
+ <cd:constant name='time' value='time'/>
<cd:constant name='title' value='titul'/>
<cd:constant name='titlecolor' value='barvatitulek'/>
<cd:constant name='titlecommand' value='titlecommand'/>
@@ -1274,12 +1278,14 @@
<cd:constant name='up' value='up'/>
<cd:constant name='urlalternative' value='urlalternativa'/>
<cd:constant name='urlspace' value='prostorurl'/>
+ <cd:constant name='userpassword' value='userpassword'/>
<cd:constant name='validate' value='validovat'/>
<cd:constant name='values' value='values'/>
<cd:constant name='vcommand' value='vprikaz'/>
<cd:constant name='vcompact' value='vcompact'/>
<cd:constant name='vector' value='vector'/>
<cd:constant name='veroffset' value='offsethlavicky'/>
+ <cd:constant name='vfactor' value='vfaktor'/>
<cd:constant name='vfil' value='vfil'/>
<cd:constant name='viewerprefix' value='viewerprefix'/>
<cd:constant name='voffset' value='voffset'/>
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 @@
<cd:variable name='chemicals' value='chemicals'/>
<cd:variable name='chemistry' value='chemistry'/>
<cd:variable name='cite' value='cite'/>
+ <cd:variable name='closed' value='closed'/>
<cd:variable name='color' value='farbe'/>
<cd:variable name='column' value='column'/>
<cd:variable name='columns' value='spalten'/>
@@ -421,7 +422,7 @@
<cd:variable name='positive' value='positiv'/>
<cd:variable name='postponing' value='verschieben'/>
<cd:variable name='postscript' value='postscript'/>
- <cd:variable name='precedingpage' value='followingpage'/>
+ <cd:variable name='precedingpage' value='precedingpage'/>
<cd:variable name='preference' value='einstellung'/>
<cd:variable name='preview' value='vorschau'/>
<cd:variable name='previous' value='vorig'/>
@@ -589,6 +590,7 @@
<cd:variable name='understrike' value='understrike'/>
<cd:variable name='understrikes' value='understrikes'/>
<cd:variable name='unframed' value='unframed'/>
+ <cd:variable name='unicode' value='unicode'/>
<cd:variable name='unit' value='einheit'/>
<cd:variable name='units' value='einheiten'/>
<cd:variable name='unknown' value='unbekannt'/>
@@ -1033,6 +1035,7 @@
<cd:constant name='otherstext' value='otherstext'/>
<cd:constant name='outermargin' value='outermargin'/>
<cd:constant name='overprint' value='overprint'/>
+ <cd:constant name='ownerpassword' value='ownerpassword'/>
<cd:constant name='ownnumber' value='eigenenummer'/>
<cd:constant name='page' value='seite'/>
<cd:constant name='pageboundaries' value='seitenbegrenzung'/>
@@ -1246,6 +1249,7 @@
<cd:constant name='textstyle' value='textstil'/>
<cd:constant name='textwidth' value='textbreite'/>
<cd:constant name='threshold' value='threshold'/>
+ <cd:constant name='time' value='time'/>
<cd:constant name='title' value='titel'/>
<cd:constant name='titlecolor' value='titelfarbe'/>
<cd:constant name='titlecommand' value='titlecommand'/>
@@ -1274,12 +1278,14 @@
<cd:constant name='up' value='up'/>
<cd:constant name='urlalternative' value='urlalternative'/>
<cd:constant name='urlspace' value='urlspatium'/>
+ <cd:constant name='userpassword' value='userpassword'/>
<cd:constant name='validate' value='validieren'/>
<cd:constant name='values' value='values'/>
<cd:constant name='vcommand' value='vbefehl'/>
<cd:constant name='vcompact' value='vcompact'/>
<cd:constant name='vector' value='vector'/>
<cd:constant name='veroffset' value='kopfoffset'/>
+ <cd:constant name='vfactor' value='vfaktor'/>
<cd:constant name='vfil' value='vfil'/>
<cd:constant name='viewerprefix' value='viewerprefix'/>
<cd:constant name='voffset' value='voffset'/>
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 @@
<cd:variable name='chemicals' value='chemicals'/>
<cd:variable name='chemistry' value='chemistry'/>
<cd:variable name='cite' value='cite'/>
+ <cd:variable name='closed' value='closed'/>
<cd:variable name='color' value='color'/>
<cd:variable name='column' value='column'/>
<cd:variable name='columns' value='columns'/>
@@ -421,7 +422,7 @@
<cd:variable name='positive' value='positive'/>
<cd:variable name='postponing' value='postponing'/>
<cd:variable name='postscript' value='postscript'/>
- <cd:variable name='precedingpage' value='followingpage'/>
+ <cd:variable name='precedingpage' value='precedingpage'/>
<cd:variable name='preference' value='preference'/>
<cd:variable name='preview' value='preview'/>
<cd:variable name='previous' value='previous'/>
@@ -1033,6 +1034,7 @@
<cd:constant name='otherstext' value='otherstext'/>
<cd:constant name='outermargin' value='outermargin'/>
<cd:constant name='overprint' value='overprint'/>
+ <cd:constant name='ownerpassword' value='ownerpassword'/>
<cd:constant name='ownnumber' value='ownnumber'/>
<cd:constant name='page' value='page'/>
<cd:constant name='pageboundaries' value='pageboundaries'/>
@@ -1246,6 +1248,7 @@
<cd:constant name='textstyle' value='textstyle'/>
<cd:constant name='textwidth' value='textwidth'/>
<cd:constant name='threshold' value='threshold'/>
+ <cd:constant name='time' value='time'/>
<cd:constant name='title' value='title'/>
<cd:constant name='titlecolor' value='titlecolor'/>
<cd:constant name='titlecommand' value='titlecommand'/>
@@ -1274,12 +1277,14 @@
<cd:constant name='up' value='up'/>
<cd:constant name='urlalternative' value='urlalternative'/>
<cd:constant name='urlspace' value='urlspace'/>
+ <cd:constant name='userpassword' value='userpassword'/>
<cd:constant name='validate' value='validate'/>
<cd:constant name='values' value='values'/>
<cd:constant name='vcommand' value='vcommand'/>
<cd:constant name='vcompact' value='vcompact'/>
<cd:constant name='vector' value='vector'/>
<cd:constant name='veroffset' value='veroffset'/>
+ <cd:constant name='vfactor' value='vfactor'/>
<cd:constant name='vfil' value='vfil'/>
<cd:constant name='viewerprefix' value='viewerprefix'/>
<cd:constant name='voffset' value='voffset'/>
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 @@
<cd:variable name='chemicals' value='chemicals'/>
<cd:variable name='chemistry' value='chemistry'/>
<cd:variable name='cite' value='cite'/>
+ <cd:variable name='closed' value='closed'/>
<cd:variable name='color' value='couleur'/>
<cd:variable name='column' value='colonne'/>
<cd:variable name='columns' value='colonnes'/>
@@ -421,7 +422,7 @@
<cd:variable name='positive' value='positif'/>
<cd:variable name='postponing' value='postponing'/>
<cd:variable name='postscript' value='postscript'/>
- <cd:variable name='precedingpage' value='followingpage'/>
+ <cd:variable name='precedingpage' value='precedingpage'/>
<cd:variable name='preference' value='preference'/>
<cd:variable name='preview' value='previsualisation'/>
<cd:variable name='previous' value='precedent'/>
@@ -1033,6 +1034,7 @@
<cd:constant name='otherstext' value='otherstext'/>
<cd:constant name='outermargin' value='margeexterieure'/>
<cd:constant name='overprint' value='overprint'/>
+ <cd:constant name='ownerpassword' value='ownerpassword'/>
<cd:constant name='ownnumber' value='numeroproprio'/>
<cd:constant name='page' value='page'/>
<cd:constant name='pageboundaries' value='limitespage'/>
@@ -1246,6 +1248,7 @@
<cd:constant name='textstyle' value='styletexte'/>
<cd:constant name='textwidth' value='largeurtexte'/>
<cd:constant name='threshold' value='threshold'/>
+ <cd:constant name='time' value='time'/>
<cd:constant name='title' value='titre'/>
<cd:constant name='titlecolor' value='couleurtitre'/>
<cd:constant name='titlecommand' value='titlecommand'/>
@@ -1274,12 +1277,14 @@
<cd:constant name='up' value='up'/>
<cd:constant name='urlalternative' value='alternativeurl'/>
<cd:constant name='urlspace' value='espaceurl'/>
+ <cd:constant name='userpassword' value='userpassword'/>
<cd:constant name='validate' value='valider'/>
<cd:constant name='values' value='values'/>
<cd:constant name='vcommand' value='vcommande'/>
<cd:constant name='vcompact' value='vcompact'/>
<cd:constant name='vector' value='vector'/>
<cd:constant name='veroffset' value='veroffset'/>
+ <cd:constant name='vfactor' value='vfactor'/>
<cd:constant name='vfil' value='vfil'/>
<cd:constant name='viewerprefix' value='viewerprefix'/>
<cd:constant name='voffset' value='voffset'/>
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 @@
<cd:variable name='chemicals' value='chemicals'/>
<cd:variable name='chemistry' value='chemistry'/>
<cd:variable name='cite' value='cite'/>
+ <cd:variable name='closed' value='closed'/>
<cd:variable name='color' value='colore'/>
<cd:variable name='column' value='colonna'/>
<cd:variable name='columns' value='colonne'/>
@@ -421,7 +422,7 @@
<cd:variable name='positive' value='positivo'/>
<cd:variable name='postponing' value='posporre'/>
<cd:variable name='postscript' value='postscript'/>
- <cd:variable name='precedingpage' value='followingpage'/>
+ <cd:variable name='precedingpage' value='precedingpage'/>
<cd:variable name='preference' value='preferenza'/>
<cd:variable name='preview' value='anteprima'/>
<cd:variable name='previous' value='precedente'/>
@@ -589,6 +590,7 @@
<cd:variable name='understrike' value='understrike'/>
<cd:variable name='understrikes' value='understrikes'/>
<cd:variable name='unframed' value='unframed'/>
+ <cd:variable name='unicode' value='unicode'/>
<cd:variable name='unit' value='unita'/>
<cd:variable name='units' value='unita'/>
<cd:variable name='unknown' value='ignoto'/>
@@ -1033,6 +1035,7 @@
<cd:constant name='otherstext' value='otherstext'/>
<cd:constant name='outermargin' value='margineesterno'/>
<cd:constant name='overprint' value='overprint'/>
+ <cd:constant name='ownerpassword' value='ownerpassword'/>
<cd:constant name='ownnumber' value='numeroproprio'/>
<cd:constant name='page' value='pagina'/>
<cd:constant name='pageboundaries' value='limitipagina'/>
@@ -1246,6 +1249,7 @@
<cd:constant name='textstyle' value='stiletesto'/>
<cd:constant name='textwidth' value='ampiezzatesto'/>
<cd:constant name='threshold' value='threshold'/>
+ <cd:constant name='time' value='time'/>
<cd:constant name='title' value='titolo'/>
<cd:constant name='titlecolor' value='coloretitolo'/>
<cd:constant name='titlecommand' value='titlecommand'/>
@@ -1274,12 +1278,14 @@
<cd:constant name='up' value='up'/>
<cd:constant name='urlalternative' value='alternativaurl'/>
<cd:constant name='urlspace' value='spaziourl'/>
+ <cd:constant name='userpassword' value='userpassword'/>
<cd:constant name='validate' value='verifica'/>
<cd:constant name='values' value='values'/>
<cd:constant name='vcommand' value='vcomando'/>
<cd:constant name='vcompact' value='vcompact'/>
<cd:constant name='vector' value='vector'/>
<cd:constant name='veroffset' value='veroffset'/>
+ <cd:constant name='vfactor' value='vfactor'/>
<cd:constant name='vfil' value='vfil'/>
<cd:constant name='viewerprefix' value='viewerprefix'/>
<cd:constant name='voffset' value='voffset'/>
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 @@
<cd:variable name='chemicals' value='chemicals'/>
<cd:variable name='chemistry' value='chemie'/>
<cd:variable name='cite' value='cite'/>
+ <cd:variable name='closed' value='gesloten'/>
<cd:variable name='color' value='kleur'/>
<cd:variable name='column' value='kolom'/>
<cd:variable name='columns' value='kolommen'/>
@@ -188,6 +189,7 @@
<cd:variable name='extremestretch' value='extremestretch'/>
<cd:variable name='fact' value='gegeven'/>
<cd:variable name='february' value='februari'/>
+ <cd:variable name='field' value='veld'/>
<cd:variable name='figure' value='figuur'/>
<cd:variable name='figures' value='figuren'/>
<cd:variable name='file' value='file'/>
@@ -800,7 +802,7 @@
<cd:constant name='family' value='soort'/>
<cd:constant name='features' value='features'/>
<cd:constant name='fences' value='fences'/>
- <cd:constant name='field' value='field'/>
+ <cd:constant name='field' value='veld'/>
<cd:constant name='fieldbackgroundcolor' value='veldachtergrondkleur'/>
<cd:constant name='fieldframecolor' value='veldkaderkleur'/>
<cd:constant name='fieldlayer' value='veldlaag'/>
@@ -855,6 +857,7 @@
<cd:constant name='headerstate' value='hoofdstatus'/>
<cd:constant name='headlabel' value='koplabel'/>
<cd:constant name='headnumber' value='kopnummer'/>
+ <cd:constant name='headseparator' value='kopscheider'/>
<cd:constant name='headstyle' value='kopletter'/>
<cd:constant name='height' value='hoogte'/>
<cd:constant name='hfactor' value='hfactor'/>
@@ -1031,6 +1034,7 @@
<cd:constant name='otherstext' value='otherstext'/>
<cd:constant name='outermargin' value='buitenmarge'/>
<cd:constant name='overprint' value='overprint'/>
+ <cd:constant name='ownerpassword' value='ownerpassword'/>
<cd:constant name='ownnumber' value='eigennummer'/>
<cd:constant name='page' value='pagina'/>
<cd:constant name='pageboundaries' value='paginaovergangen'/>
@@ -1081,6 +1085,7 @@
<cd:constant name='preview' value='preview'/>
<cd:constant name='previous' value='vorige'/>
<cd:constant name='previousnumber' value='vorigenummer'/>
+ <cd:constant name='print' value='print'/>
<cd:constant name='printable' value='printbaar'/>
<cd:constant name='process' value='proces'/>
<cd:constant name='profile' value='profile'/>
@@ -1166,8 +1171,10 @@
<cd:constant name='sidemethod' value='zijmethode'/>
<cd:constant name='sidespaceafter' value='zijnawit'/>
<cd:constant name='sidespacebefore' value='zijvoorwit'/>
+ <cd:constant name='sidespaceinbetween' value='zijtussenwit'/>
<cd:constant name='sidethreshold' value='sidethreshold'/>
<cd:constant name='sign' value='teken'/>
+ <cd:constant name='simplecommand' value='simpelcommando'/>
<cd:constant name='size' value='formaat'/>
<cd:constant name='slantedfeatures' value='slantedfeatures'/>
<cd:constant name='slantedfont' value='slantedfont'/>
@@ -1241,6 +1248,7 @@
<cd:constant name='textstyle' value='tekstletter'/>
<cd:constant name='textwidth' value='tekstbreedte'/>
<cd:constant name='threshold' value='threshold'/>
+ <cd:constant name='time' value='tijd'/>
<cd:constant name='title' value='titel'/>
<cd:constant name='titlecolor' value='titelkleur'/>
<cd:constant name='titlecommand' value='titelcommando'/>
@@ -1269,12 +1277,14 @@
<cd:constant name='up' value='up'/>
<cd:constant name='urlalternative' value='urlvariant'/>
<cd:constant name='urlspace' value='urlspatie'/>
+ <cd:constant name='userpassword' value='userpassword'/>
<cd:constant name='validate' value='valideer'/>
<cd:constant name='values' value='waarden'/>
<cd:constant name='vcommand' value='vcommando'/>
<cd:constant name='vcompact' value='vcomprimeer'/>
<cd:constant name='vector' value='vector'/>
<cd:constant name='veroffset' value='kopoffset'/>
+ <cd:constant name='vfactor' value='vfactor'/>
<cd:constant name='vfil' value='vfil'/>
<cd:constant name='viewerprefix' value='viewerprefix'/>
<cd:constant name='voffset' value='voffset'/>
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 @@
<cd:variable name='chemicals' value='chemicals'/>
<cd:variable name='chemistry' value='chemistry'/>
<cd:variable name='cite' value='cite'/>
+ <cd:variable name='closed' value='closed'/>
<cd:variable name='color' value='رنگ'/>
<cd:variable name='column' value='ستون'/>
<cd:variable name='columns' value='ستونها'/>
@@ -421,7 +422,7 @@
<cd:variable name='positive' value='مثبت'/>
<cd:variable name='postponing' value='تاخیر'/>
<cd:variable name='postscript' value='پست‌اسکریپت'/>
- <cd:variable name='precedingpage' value='followingpage'/>
+ <cd:variable name='precedingpage' value='precedingpage'/>
<cd:variable name='preference' value='ترجیح'/>
<cd:variable name='preview' value='پیش‌دید'/>
<cd:variable name='previous' value='قبلی'/>
@@ -1033,6 +1034,7 @@
<cd:constant name='otherstext' value='otherstext'/>
<cd:constant name='outermargin' value='حاشیه‌خارجی'/>
<cd:constant name='overprint' value='overprint'/>
+ <cd:constant name='ownerpassword' value='ownerpassword'/>
<cd:constant name='ownnumber' value='شماره‌خود'/>
<cd:constant name='page' value='صفحه'/>
<cd:constant name='pageboundaries' value='مرزهای‌صفحه'/>
@@ -1246,6 +1248,7 @@
<cd:constant name='textstyle' value='سبک‌متن'/>
<cd:constant name='textwidth' value='عرض‌متن'/>
<cd:constant name='threshold' value='threshold'/>
+ <cd:constant name='time' value='time'/>
<cd:constant name='title' value='عنوان'/>
<cd:constant name='titlecolor' value='رنگ‌عنوان'/>
<cd:constant name='titlecommand' value='فرمان‌عنوان'/>
@@ -1274,12 +1277,14 @@
<cd:constant name='up' value='up'/>
<cd:constant name='urlalternative' value='urlalternative'/>
<cd:constant name='urlspace' value='urlspace'/>
+ <cd:constant name='userpassword' value='userpassword'/>
<cd:constant name='validate' value='تاییداعتبار'/>
<cd:constant name='values' value='values'/>
<cd:constant name='vcommand' value='vcommand'/>
<cd:constant name='vcompact' value='vcompact'/>
<cd:constant name='vector' value='vector'/>
<cd:constant name='veroffset' value='آفست‌عم'/>
+ <cd:constant name='vfactor' value='vfactor'/>
<cd:constant name='vfil' value='vfil'/>
<cd:constant name='viewerprefix' value='viewerprefix'/>
<cd:constant name='voffset' value='آفست‌ع'/>
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 @@
<cd:variable name='chemicals' value='chemicals'/>
<cd:variable name='chemistry' value='chemistry'/>
<cd:variable name='cite' value='cite'/>
+ <cd:variable name='closed' value='closed'/>
<cd:variable name='color' value='culoare'/>
<cd:variable name='column' value='coloana'/>
<cd:variable name='columns' value='coloane'/>
@@ -421,7 +422,7 @@
<cd:variable name='positive' value='positiv'/>
<cd:variable name='postponing' value='postponing'/>
<cd:variable name='postscript' value='postscript'/>
- <cd:variable name='precedingpage' value='followingpage'/>
+ <cd:variable name='precedingpage' value='precedingpage'/>
<cd:variable name='preference' value='preferinta'/>
<cd:variable name='preview' value='previzualizare'/>
<cd:variable name='previous' value='precedent'/>
@@ -589,6 +590,7 @@
<cd:variable name='understrike' value='understrike'/>
<cd:variable name='understrikes' value='understrikes'/>
<cd:variable name='unframed' value='unframed'/>
+ <cd:variable name='unicode' value='unicode'/>
<cd:variable name='unit' value='unitate'/>
<cd:variable name='units' value='unitati'/>
<cd:variable name='unknown' value='necunoscut'/>
@@ -1033,6 +1035,7 @@
<cd:constant name='otherstext' value='otherstext'/>
<cd:constant name='outermargin' value='outermargin'/>
<cd:constant name='overprint' value='overprint'/>
+ <cd:constant name='ownerpassword' value='ownerpassword'/>
<cd:constant name='ownnumber' value='numarpropriu'/>
<cd:constant name='page' value='pagina'/>
<cd:constant name='pageboundaries' value='marginipagina'/>
@@ -1246,6 +1249,7 @@
<cd:constant name='textstyle' value='stiltext'/>
<cd:constant name='textwidth' value='latimetext'/>
<cd:constant name='threshold' value='threshold'/>
+ <cd:constant name='time' value='time'/>
<cd:constant name='title' value='titlu'/>
<cd:constant name='titlecolor' value='culoaretitlu'/>
<cd:constant name='titlecommand' value='titlecommand'/>
@@ -1274,12 +1278,14 @@
<cd:constant name='up' value='up'/>
<cd:constant name='urlalternative' value='urlalternativ'/>
<cd:constant name='urlspace' value='spatiuurl'/>
+ <cd:constant name='userpassword' value='userpassword'/>
<cd:constant name='validate' value='verifica'/>
<cd:constant name='values' value='values'/>
<cd:constant name='vcommand' value='comandav'/>
<cd:constant name='vcompact' value='vcompact'/>
<cd:constant name='vector' value='vector'/>
<cd:constant name='veroffset' value='veroffset'/>
+ <cd:constant name='vfactor' value='vfactor'/>
<cd:constant name='vfil' value='vfil'/>
<cd:constant name='viewerprefix' value='viewerprefix'/>
<cd:constant name='voffset' value='voffset'/>
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 @@
<cd:constant type="global"/>
<cd:constant default="yes" type="public"/>
<cd:constant type="private"/>
+ <cd:constant type="pickup"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -793,6 +794,7 @@
<cd:constant type="global"/>
<cd:constant type="public"/>
<cd:constant default="yes" type="private"/>
+ <cd:constant type="pickup"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -864,23 +866,23 @@
<cd:constant type="cd:file"/>
</cd:parameter>
<cd:parameter name="intent">
- <cd:constant type="Coated FOGRA39 (ISO 12647-2:2004)"/>
+ <cd:constant type="Coated␣FOGRA39␣(ISO␣12647-2:2004)"/>
<cd:constant type="GRACoL2006_Coated1v2.icc"/>
- <cd:constant type="ISO Coated v2 300% (ECI)"/>
- <cd:constant type="ISO Coated v2 (ECI)"/>
+ <cd:constant type="ISO␣Coated␣v2␣300%␣(ECI)"/>
+ <cd:constant type="ISO␣Coated␣v2␣(ECI)"/>
<cd:constant type="ISOnewspaper26v4"/>
<cd:constant type="ISOnewspaper26v4_gr"/>
- <cd:constant type="ISO Uncoated"/>
- <cd:constant type="ISO Uncoated Yellowish"/>
- <cd:constant type="ISO Web Coated"/>
- <cd:constant type="Japan Color 2001 Coated"/>
- <cd:constant type="Japan Color 2002 Newspaper"/>
- <cd:constant type="Japan Web Coated (Ad)"/>
- <cd:constant type="SNAP 2007"/>
+ <cd:constant type="ISO␣Uncoated"/>
+ <cd:constant type="ISO␣Uncoated␣Yellowish"/>
+ <cd:constant type="ISO␣Web␣Coated"/>
+ <cd:constant type="Japan␣Color␣2001␣Coated"/>
+ <cd:constant type="Japan␣Color␣2002␣Newspaper"/>
+ <cd:constant type="Japan␣Web␣Coated␣(Ad)"/>
+ <cd:constant type="SNAP␣2007"/>
<cd:constant type="SWOP2006_Coated3v2.icc"/>
<cd:constant type="SWOP2006_Coated5v2.icc"/>
- <cd:constant type="Uncoated FOGRA29 (ISO 12647-2:2004)"/>
- <cd:constant type="Web Coated FOGRA28 (ISO 12647-2:2004)"/>
+ <cd:constant type="Uncoated␣FOGRA29␣(ISO␣12647-2:2004)"/>
+ <cd:constant type="Web␣Coated␣FOGRA28␣(ISO␣12647-2:2004)"/>
<cd:constant type="PSR_LWC_PLUS_V2_PT"/>
<cd:constant type="PSR_LWC_STD_V2_PT"/>
<cd:constant type="PSR_SC_PLUS_V2_PT"/>
@@ -1444,9 +1446,31 @@
<cd:parameter name="after">
<cd:constant type="cd:command"/>
</cd:parameter>
+ <cd:parameter name="left">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="right">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="alternative">
+ <cd:constant default="yes" type="paragraph"/>
+ <cd:constant type="text"/>
+ </cd:parameter>
<cd:parameter name="inner">
<cd:constant type="cd:command"/>
</cd:parameter>
+ <cd:parameter name="setups">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="align">
+ <cd:constant type="left"/>
+ <cd:constant type="right"/>
+ <cd:constant type="middle"/>
+ <cd:constant type="flushleft"/>
+ <cd:constant type="flushright"/>
+ <cd:constant type="inner"/>
+ <cd:constant type="outer"/>
+ </cd:parameter>
<cd:parameter name="style">
<cd:constant type="cd:style"/>
<cd:constant type="cd:command"/>
@@ -1467,6 +1491,11 @@
<cd:constant type="-"/>
<cd:constant type="cd:name"/>
</cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:parameter name="cd:key">
+ <cd:constant type="cd:value"/>
+ </cd:parameter>
+ </cd:assignments>
</cd:arguments>
</cd:command>
<cd:command category="structure" file="strc-blk.mkiv" level="style" name="hideblocks">
@@ -1537,6 +1566,13 @@
</cd:assignments>
</cd:arguments>
</cd:command>
+ <cd:command category="structure" file="strc-blk.mkiv" level="document" name="blockuservariable">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:key"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
</cd:interface>
<cd:interface file="i-bookmark.xml">
<cd:command category="pdf" file="strc-bkm.mkiv" level="style" name="setupbookmark">
@@ -1571,6 +1607,7 @@
<cd:constant method="range" prefix="cd:section" type="cd:section"/>
<cd:constant method="range" prefix="cd:section" type="*"/>
<cd:constant method="range" prefix="cd:section" type="all"/>
+ <cd:constant type="current"/>
</cd:parameter>
<cd:parameter name="sectionblock">
<cd:constant type="yes"/>
@@ -1885,6 +1922,17 @@
<cd:content/>
</cd:arguments>
</cd:command>
+ <cd:command file="supp-box.mkiv" level="system" name="linebox">
+ <cd:arguments>
+ <cd:content/>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="supp-box.mkiv" level="system" name="shiftbox">
+ <cd:arguments>
+ <cd:dimension/>
+ <cd:content/>
+ </cd:arguments>
+ </cd:command>
<cd:command file="supp-box.mkiv" level="system" name="inlinedbox">
<cd:arguments>
<cd:content/>
@@ -2975,6 +3023,10 @@
<cd:parameter name="after">
<cd:constant type="cd:command"/>
</cd:parameter>
+ <cd:parameter name="strip">
+ <cd:constant default="yes" type="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -2993,7 +3045,7 @@
</cd:command>
<cd:command category="buffer" file="buff-ini.mkiv" level="document" name="getbuffer">
<cd:arguments>
- <cd:keywords optional="yes">
+ <cd:keywords list="yes" optional="yes">
<cd:constant type="cd:buffer"/>
</cd:keywords>
</cd:arguments>
@@ -3012,7 +3064,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command evel="document" file="buff-ini.mkiv" generated="yes" lcategory="buffer" name="buffer" type="environment" variant="instance">
+ <cd:command category="buffer" file="buff-ini.mkiv" generated="yes" level="document" name="buffer" type="environment" variant="instance">
<cd:sequence>
<cd:instance value="buffer"/>
</cd:sequence>
@@ -3740,6 +3792,13 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="characters fonts" file="char-ini.mkiv" level="style" name="textormathchars">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:character"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command category="characters" file="char-ini.mkiv" level="style" name="chardescription">
<cd:arguments>
<cd:keywords delimiters="braces">
@@ -3796,9 +3855,35 @@
</cd:arguments>
</cd:command>
<cd:command category="alignment" file="typo-tal.mkiv" level="system" name="resetcharacteralign"/>
+ <cd:command category="alignment" file="typo-tal.mkiv" level="system" name="nocharacteralign"/>
+ <cd:command category="alignment" file="typo-tal.mkiv" level="system" name="setcharacteraligndetail">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:number"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:text"/>
+ <cd:constant method="apply" prefix="number" type="cd:text"/>
+ <cd:constant method="apply" prefix="text" type="cd:text"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:dimension"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:dimension"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command category="alignment" file="typo-tal.mkiv" level="system" name="alignmentcharacter"/>
<cd:command category="alignment" file="typo-tal.mkiv" level="system" name="characteralign" type="environment">
<cd:arguments>
+ <cd:assignments list="yes">
+ <cd:inherit name="setupcharacteralign"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="alignment" file="typo-tal.mkiv" level="system" name="characteralign" type="environment" variant="argument">
+ <cd:arguments>
<cd:keywords optional="yes">
<cd:constant type="cd:text"/>
<cd:constant method="apply" prefix="number" type="cd:text"/>
@@ -3811,6 +3896,31 @@
<cd:content/>
</cd:arguments>
</cd:command>
+ <cd:command category="alignment" file="typo-tal.mkiv" level="style" name="setupcharacteralign">
+ <cd:arguments>
+ <cd:assignments list="yes">
+ <cd:parameter name="leftwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="rightwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="leftsample">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="rightsample">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="character">
+ <cd:constant type="cd:text"/>
+ <cd:constant method="apply" prefix="number" type="cd:text"/>
+ <cd:constant method="apply" prefix="text" type="cd:text"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="alignment" file="typo-tal.mkiv" level="system" name="setfirstpasscharacteralign"/>
+ <cd:command category="alignment" file="typo-tal.mkiv" level="system" name="setsecondpasscharacteralign"/>
</cd:interface>
<cd:interface file="i-characterspacing.xml">
<cd:command category="fonts" file="typo-spa.mkiv" level="style" name="definecharacterspacing">
@@ -4681,7 +4791,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="colors" file="colo-ini.mkiv" name="transparent" type="environment">
+ <cd:command category="colors" file="colo-ini.mkiv" level="style" name="transparent" type="environment">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:color"/>
@@ -4787,7 +4897,7 @@
</cd:arguments>
</cd:command>
<cd:command begin="save" category="colors" end="restore" file="colo-ini.mkiv" level="system" name="color" type="environment"/>
- <cd:command category="colors" file="colo-ini.mkiv" name="definepalet">
+ <cd:command category="colors" file="colo-ini.mkiv" level="style" name="definepalet">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:name"/>
@@ -5111,10 +5221,10 @@
<cd:constant type="no"/>
</cd:parameter>
<cd:parameter name="align">
- <cd:constant type="setupalign"/>
+ <cd:inherit type="setupalign"/>
</cd:parameter>
<cd:parameter name="tolerance">
- <cd:constant type="setuptolerance"/>
+ <cd:inherit type="setuptolerance"/>
</cd:parameter>
<cd:parameter name="blank">
<cd:inherit name="blank"/>
@@ -5147,7 +5257,7 @@
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="columns" file="page-mul.mkiv" name="columnspan" type="environment">
+ <cd:command category="columns" file="page-mul.mkiv" level="document" name="columnspan" type="environment">
<cd:arguments>
<cd:assignments list="yes" optional="yes">
<cd:inherit name="setupcolumnspan"/>
@@ -5654,6 +5764,16 @@
<cd:csname/>
</cd:arguments>
</cd:command>
+ <cd:command file="mult-aux.mkiv" level="system" name="installmacrostack">
+ <cd:arguments>
+ <cd:csname/>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="mult-aux.mkiv" level="system" name="installglobalmacrostack">
+ <cd:arguments>
+ <cd:csname/>
+ </cd:arguments>
+ </cd:command>
</cd:interface>
<cd:interface file="i-comment.xml">
<cd:command category="pdf" file="scrn-wid.mkvi" level="style" name="definecomment">
@@ -6627,6 +6747,7 @@
<cd:constant method="range" prefix="cd:section" type="cd:section"/>
<cd:constant method="range" prefix="cd:section" type="*"/>
<cd:constant method="range" prefix="cd:section" type="all"/>
+ <cd:constant type="current"/>
</cd:parameter>
<cd:parameter name="numberorder">
<cd:constant type="reverse"/>
@@ -7211,6 +7332,7 @@
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="cd:name"/>
+ <cd:constant method="range" prefix="cd:name" type="cd:number"/>
</cd:keywords>
<cd:assignments list="yes">
<cd:parameter name="before">
@@ -7458,6 +7580,7 @@
<cd:constant type="serried"/>
<cd:constant type="hanging"/>
<cd:constant type="top"/>
+ <cd:constant type="empty"/>
<cd:constant type="command"/>
<cd:constant type="cd:name"/>
</cd:parameter>
@@ -7541,6 +7664,10 @@
<cd:parameter name="headcolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="aligntitle">
+ <cd:constant default="yes" type="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -7958,6 +8085,52 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="structure" file="file-job.mkvi" level="style" name="doifelsedocumentvariable">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:key"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:false"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="file-job.mkvi" level="style" name="doifdocumentvariableelse">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:key"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:false"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="file-job.mkvi" level="style" name="doifdocumentvariable">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:key"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="file-job.mkvi" level="style" name="doifnotdocumentvariable">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:key"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
</cd:interface>
<cd:interface file="i-dummy.xml">
<cd:command file="mult-aux.mkiv" level="system" name="getdummyparameters">
@@ -8054,7 +8227,7 @@
<cd:constant type="cd:number"/>
</cd:parameter>
<cd:parameter name="rulethickness">
- <cd:constant type="cd:number"/>
+ <cd:constant type="cd:dimension"/>
</cd:parameter>
<cd:parameter name="alternative">
<cd:constant default="yes" type="normal"/>
@@ -8191,6 +8364,7 @@
<cd:constant type="serried"/>
<cd:constant type="hanging"/>
<cd:constant default="yes" type="top"/>
+ <cd:constant type="empty"/>
<cd:constant type="command"/>
<cd:constant type="cd:name"/>
</cd:parameter>
@@ -8274,6 +8448,10 @@
<cd:parameter name="headcolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="aligntitle">
+ <cd:constant default="yes" type="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<cd:inherit name="setupcounter"/>
</cd:assignments>
</cd:arguments>
@@ -9537,6 +9715,21 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="rules" file="spac-flr.mkiv" level="style" name="fillupto">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="sym"/>
+ <cd:constant type="symbol"/>
+ <cd:constant type="rule"/>
+ <cd:constant type="width"/>
+ <cd:constant type="space"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:text"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command category="rules" file="spac-flr.mkiv" level="style" name="checkedfiller">
<cd:arguments>
<cd:keywords delimiters="braces">
@@ -10099,10 +10292,10 @@
<cd:constant type="cd:dimension"/>
</cd:parameter>
<cd:parameter name="ntop">
- <cd:constant type="cd:dimension"/>
+ <cd:constant type="cd:number"/>
</cd:parameter>
<cd:parameter name="nbottom">
- <cd:constant type="cd:dimension"/>
+ <cd:constant type="cd:number"/>
</cd:parameter>
<cd:parameter name="step">
<cd:constant type="small"/>
@@ -10118,6 +10311,7 @@
<cd:constant default="yes" type="yes"/>
<cd:constant type="no"/>
</cd:parameter>
+ <cd:inherit name="setupframed"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -10131,7 +10325,7 @@
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="structure fonts counter" file="strc-flt.mkvi" level="style" name="setupfloatcaption">
+ <cd:command category="structure fonts counter" file="strc-flt.mkvi" level="style" name="setupcaption">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="cd:name"/>
@@ -10153,6 +10347,7 @@
<cd:constant type="low"/>
<cd:constant type="high"/>
<cd:constant type="grid"/>
+ <cd:constant type="lines"/>
<cd:constant type="overlay"/>
<cd:constant type="inner"/>
<cd:constant type="outer"/>
@@ -10192,6 +10387,13 @@
<cd:parameter name="distance">
<cd:constant type="cd:dimension"/>
</cd:parameter>
+ <cd:parameter name="headstyle">
+ <cd:constant type="cd:style"/>
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="headcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
<cd:parameter name="headseparator">
<cd:constant type="cd:text"/>
</cd:parameter>
@@ -10247,26 +10449,27 @@
<cd:constant type="cd:dimension"/>
</cd:parameter>
<cd:inherit name="setupcounter"/>
+ <cd:inherit name="setupframed"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="structure fonts counter" file="strc-flt.mkvi" level="style" name="setupcaption">
+ <cd:command category="structure fonts counter" file="strc-flt.mkvi" level="style" name="setupcaptions">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="cd:name"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setupfloatcaption"/>
+ <cd:inherit name="setupcaption"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="structure fonts counter" file="strc-flt.mkvi" level="style" name="setupcaptions">
+ <cd:command category="structure background" file="strc-flt.mkvi" level="style" name="setupfloatframed">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="cd:name"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setupfloatcaption"/>
+ <cd:inherit name="setupframed"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -10930,6 +11133,53 @@
<cd:content/>
</cd:arguments>
</cd:command>
+ <cd:command category="structure" file="page-ffl.mkiv" level="style" name="definefacingfloat">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupfacingfloat"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="page-ffl.mkiv" level="style" name="setupfacingfloat">
+ <cd:arguments>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:parameter name="inbetween">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="page">
+ <cd:inherit name="page"/>
+ </cd:parameter>
+ <cd:parameter name="spaceinbetween">
+ <cd:inherit name="blank"/>
+ </cd:parameter>
+ <cd:parameter name="style">
+ <cd:constant type="cd:style"/>
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:inherit name="setupframed"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="page-ffl.mkiv" level="document" name="facingfloat" type="environment">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="tabl-tsp.mkiv" level="document" name="splittext" type="environment"/>
</cd:interface>
<cd:interface file="i-fontfamily.xml">
<cd:command category="fonts" file="font-sel.mkvi" level="style" name="definefontfamily">
@@ -11201,12 +11451,20 @@
<cd:constant type="cd:number"/>
<cd:constant type="cd:name"/>
</cd:parameter>
+ <cd:parameter name="target">
+ <cd:constant type="cd:number"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
<cd:parameter name="features">
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="factor">
<cd:constant type="cd:number"/>
</cd:parameter>
+ <cd:parameter name="method">
+ <cd:constant type="lowercase"/>
+ <cd:constant type="uppercase"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -11461,7 +11719,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command ategory="fonts" clevel="style" file="font-fea.mkvi" name="subtractfeature" variant="direct">
+ <cd:command category="fonts" file="font-fea.mkvi" level="style" name="subtractfeature" variant="direct">
<cd:arguments>
<cd:keywords delimiters="braces">
<cd:constant type="cd:name"/>
@@ -11575,6 +11833,45 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="fonts conditional" file="font-fea.mkvi" level="system" name="doifelsefontfeature">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:false"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="fonts conditional" file="font-fea.mkvi" level="system" name="doiffontfeatureelse">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:false"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="fonts conditional" file="font-fea.mkvi" level="system" name="doifunknownfontfeature">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:false"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command category="fonts" file="font-fea.mkvi" level="system" name="doaddfeature">
<cd:arguments>
<cd:keywords delimiters="braces" list="yes">
@@ -12119,7 +12416,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command ategory="fonts" clevel="style" file="font-ini.mkiv" name="switchstyleonly">
+ <cd:command category="fonts" file="font-ini.mkiv" level="style" name="switchstyleonly">
<cd:arguments>
<cd:keywords>
<cd:constant type="rm"/>
@@ -13273,6 +13570,9 @@
<cd:constant type="-"/>
<cd:constant type="cd:reference"/>
</cd:keywords>
+ <cd:keywords delimiters="braces" optional="yes">
+ <cd:constant type="cd:text"/>
+ </cd:keywords>
</cd:arguments>
</cd:command>
<cd:command category="mathematics" file="strc-mat.mkiv" level="document" name="placeformula" type="environment">
@@ -13311,6 +13611,9 @@
<cd:keywords delimiters="braces">
<cd:constant type="cd:text"/>
</cd:keywords>
+ <cd:keywords delimiters="braces" optional="yes">
+ <cd:constant type="cd:text"/>
+ </cd:keywords>
</cd:arguments>
</cd:command>
<cd:command category="mathematics" file="strc-mat.mkiv" level="document" name="placesubformula">
@@ -13320,6 +13623,9 @@
<cd:constant type="-"/>
<cd:constant type="cd:reference"/>
</cd:keywords>
+ <cd:keywords delimiters="braces" optional="yes">
+ <cd:constant type="cd:text"/>
+ </cd:keywords>
</cd:arguments>
</cd:command>
<cd:command category="mathematics" file="strc-mat" level="document" name="formulanumber">
@@ -13535,21 +13841,25 @@
<cd:parameter name="topframe">
<cd:constant default="yes" type="on"/>
<cd:constant type="off"/>
+ <cd:constant type="small"/>
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="bottomframe">
<cd:constant default="yes" type="on"/>
<cd:constant type="off"/>
+ <cd:constant type="small"/>
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="leftframe">
<cd:constant default="yes" type="on"/>
<cd:constant type="off"/>
+ <cd:constant type="small"/>
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="rightframe">
<cd:constant default="yes" type="on"/>
<cd:constant type="off"/>
+ <cd:constant type="small"/>
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="region">
@@ -13566,6 +13876,8 @@
<cd:constant default="yes" type="on"/>
<cd:constant type="off"/>
<cd:constant type="overlay"/>
+ <cd:constant type="small"/>
+ <cd:constant type="closed"/>
<cd:constant type="none"/>
</cd:parameter>
<cd:parameter name="background">
@@ -13613,6 +13925,9 @@
<cd:constant default="yes" type="broad"/>
<cd:constant type="cd:dimension"/>
</cd:parameter>
+ <cd:parameter name="minheight">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
<cd:parameter name="align">
<cd:inherit name="setupalign"/>
</cd:parameter>
@@ -14055,6 +14370,17 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="background rules" level="system" name="doifelseframed">
+ <cd:arguments>
+ <cd:csname/>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:false"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
</cd:interface>
<cd:interface file="i-framedtable.xml">
<cd:command category="tables" file="tabl-frm.mkiv" level="style" name="defineframedtable">
@@ -14360,6 +14686,16 @@
<cd:constant type="no"/>
<cd:constant type="cd:number"/>
</cd:parameter>
+ <cd:parameter name="transform">
+ <cd:constant default="yes" type="auto"/>
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="userpassword">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="ownerpassword">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -14678,6 +15014,20 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="graphics" file="pack-box.mkiv" level="style" name="overlayimage">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:file"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="graphics" file="pack-box.mkiv" level="style" name="clippedoverlayimage">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:file"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
</cd:interface>
<cd:interface file="i-grid.xml">
<cd:command category="layout" file="page-grd.mkiv" level="document" name="showgrid">
@@ -14694,6 +15044,7 @@
<cd:constant default="yes" type="right"/>
<cd:constant type="left"/>
<cd:constant type="outer"/>
+ <cd:constant type="inner"/>
<cd:constant default="yes" type="columns"/>
</cd:keywords>
</cd:arguments>
@@ -14924,6 +15275,12 @@
<cd:parameter name="color">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="rulecolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="rulethickness">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -15151,6 +15508,7 @@
<cd:constant type="quotation"/>
<cd:constant type="sentence"/>
<cd:constant type="intersentence"/>
+ <cd:constant type="final"/>
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -15189,10 +15547,12 @@
<cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="thinspace"/>
<cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="negthinspace"/>
<cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="enspace"/>
+ <cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="negenspace"/>
<cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="enskip"/>
<cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="quad"/>
<cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="qquad"/>
<cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="emspace"/>
+ <cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="negemspace"/>
<cd:command category="whitespace" file="spac-hor.mkiv" level="system" name="dotfskip">
<cd:arguments>
<cd:keywords delimiters="braces">
@@ -16457,6 +16817,7 @@
<cd:constant type="paper"/>
<cd:constant type="attachment"/>
<cd:constant type="layer"/>
+ <cd:constant type="title"/>
</cd:parameter>
<cd:parameter name="copies">
<cd:constant type="cd:number"/>
@@ -17890,6 +18251,40 @@
</cd:assignments>
</cd:arguments>
</cd:command>
+ <cd:command catgeory="fonts whitespace" file="typo-pnc.mkic" level="style" name="defineperiodkerning">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupperiodkerning"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command catgeory="fonts whitespace" file="typo-pnc.mkic" level="style" name="setupperiodkerning">
+ <cd:arguments>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:parameter name="factor">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command catgeory="fonts whitespace" file="typo-pnc.mkic" level="style" name="setperiodkerning">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="reset"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command catgeory="fonts whitespace" file="typo-pnc.mkic" level="style" name="resetperiodkerning"/>
</cd:interface>
<cd:interface file="i-label.xml">
<cd:command category="structure" file="strc-lab.mkiv" level="style" name="definelabel">
@@ -17994,6 +18389,7 @@
<cd:constant type="serried"/>
<cd:constant type="hanging"/>
<cd:constant type="top"/>
+ <cd:constant type="empty"/>
<cd:constant type="command"/>
<cd:constant default="yes" type="intext"/>
<cd:constant type="cd:name"/>
@@ -18078,6 +18474,10 @@
<cd:parameter name="headcolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="aligntitle">
+ <cd:constant default="yes" type="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<cd:inherit name="setupcounter"/>
</cd:assignments>
</cd:arguments>
@@ -18361,6 +18761,9 @@
<cd:parameter name="date">
<cd:inherit name="currentdate"/>
</cd:parameter>
+ <cd:parameter name="time">
+ <cd:inherit name="currenttime"/>
+ </cd:parameter>
<cd:parameter name="patterns">
<cd:constant type="cd:file"/>
</cd:parameter>
@@ -18385,6 +18788,7 @@
</cd:parameter>
<cd:parameter name="font">
<cd:constant type="auto"/>
+ <cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="bidi">
<cd:constant type="left"/>
@@ -18517,6 +18921,13 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="language" file="lang-ini.mkiv" level="document" name="language" type="environment">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:language"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command category="language" file="lang-ini.mkiv" level="style" name="mainlanguage">
<cd:arguments>
<cd:keywords>
@@ -19120,6 +19531,7 @@
</cd:parameter>
<cd:parameter name="cropoffset">
<cd:constant type="cd:dimension"/>
+ <cd:constant type="auto"/>
</cd:parameter>
<cd:parameter name="trimoffset">
<cd:constant type="cd:dimension"/>
@@ -19313,7 +19725,7 @@
</cd:command>
<cd:command category="layout" file="page-run.mkiv" level="document" name="showmargins"/>
<cd:command category="layout" file="page-spr.mkiv" level="document" name="spread" type="environment"/>
- <cd:command category="layout conditional" file="page-lay.mkiv" level="system" name="doifelsetopofpage">
+ <cd:command category="layout conditional" file="page-ini.mkiv" level="system" name="doifelsetopofpage">
<cd:arguments>
<cd:keywords delimiters="braces">
<cd:constant type="cd:true"/>
@@ -19323,7 +19735,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="layout conditional" file="page-lay.mkiv" level="system" name="doiftopofpageelse">
+ <cd:command category="layout conditional" file="page-ini.mkiv" level="system" name="doiftopofpageelse">
<cd:arguments>
<cd:keywords delimiters="braces">
<cd:constant type="cd:true"/>
@@ -19334,6 +19746,107 @@
</cd:arguments>
</cd:command>
</cd:interface>
+ <cd:interface file="i-linefiller.xml">
+ <cd:command category="rules metapost" file="node-rul.mkiv" level="style" name="definelinefiller">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuplinefiller"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="rules metapost" file="node-rul.mkiv" level="style" name="setuplinefiller">
+ <cd:arguments>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:parameter name="location">
+ <cd:constant type="left"/>
+ <cd:constant type="right"/>
+ <cd:constant default="yes" type="both"/>
+ </cd:parameter>
+ <cd:parameter name="scope">
+ <cd:constant type="left"/>
+ <cd:constant type="right"/>
+ <cd:constant default="yes" type="local"/>
+ <cd:constant type="global"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="height">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="depth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="distance">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="threshold">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="rulethickness">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="textstyle">
+ <cd:constant type="cd:style"/>
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="textcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="align">
+ <cd:inherit name="setupalign"/>
+ </cd:parameter>
+ <cd:parameter name="mp">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="before">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="after">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="rules metapost" file="node-rul.mkiv" level="style" name="setuplinefillers">
+ <cd:arguments>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:inherit name="setuplinefiller"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="rules metapost" file="node-rul.mkiv" level="style" name="linefiller" type="environment">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="filler"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuplinefiller"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="rules metapost" file="node-rul.mkiv" level="style" name="setlinefiller">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="filler"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ </cd:interface>
<cd:interface file="i-linenumber.xml">
<cd:command category="structure" file="page-lin.mkvi" level="style" name="definelinenumbering">
<cd:arguments>
@@ -19825,7 +20338,6 @@
<cd:parameter name="width">
<cd:constant type="fit"/>
<cd:constant type="broad"/>
- <cd:constant type="auto"/>
<cd:constant type="cd:dimension"/>
</cd:parameter>
<cd:parameter name="height">
@@ -20022,6 +20534,7 @@
<cd:constant method="range" prefix="cd:section" type="cd:section"/>
<cd:constant method="range" prefix="cd:section" type="*"/>
<cd:constant method="range" prefix="cd:section" type="all"/>
+ <cd:constant type="current"/>
</cd:parameter>
<cd:parameter name="pageprefixconnector">
<cd:constant type="cd:command"/>
@@ -20152,7 +20665,7 @@
<cd:constant type="cd:list"/>
</cd:keywords>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -20162,7 +20675,55 @@
<cd:constant type="cd:list"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplist"/>
+ <cd:parameter name="criterium">
+ <cd:constant default="yes" type="local"/>
+ <cd:constant type="intro"/>
+ <cd:constant type="reference"/>
+ <cd:constant method="range" prefix="cd:sectionblock" type="reference"/>
+ <cd:constant type="all"/>
+ <cd:constant method="range" prefix="cd:sectionblock" type="all"/>
+ <cd:constant type="text"/>
+ <cd:constant method="range" prefix="cd:sectionblock" type="text"/>
+ <cd:constant type="current"/>
+ <cd:constant method="range" prefix="cd:sectionblock" type="current"/>
+ <cd:constant type="here"/>
+ <cd:constant type="previous"/>
+ <cd:constant method="range" prefix="cd:sectionblock" type="previous"/>
+ <cd:constant type="component"/>
+ <cd:constant type="cd:section"/>
+ <cd:constant method="range" prefix="cd:sectionblock" type="cd:section"/>
+ </cd:parameter>
+ <cd:parameter name="reference">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="extras">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="order">
+ <cd:constant type="command"/>
+ <cd:constant type="all"/>
+ <cd:constant type="title"/>
+ </cd:parameter>
+ <cd:parameter name="alternative">
+ <cd:constant type="a"/>
+ <cd:constant default="yes" type="b"/>
+ <cd:constant type="c"/>
+ <cd:constant type="d"/>
+ <cd:constant type="e"/>
+ <cd:constant type="f"/>
+ <cd:constant type="g"/>
+ <cd:constant type="left"/>
+ <cd:constant type="right"/>
+ <cd:constant type="top"/>
+ <cd:constant type="bottom"/>
+ <cd:constant type="command"/>
+ <cd:constant type="none"/>
+ <cd:constant type="interactive"/>
+ <cd:constant type="paragraph"/>
+ <cd:constant type="horizontal"/>
+ <cd:constant type="vertical"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -20172,7 +20733,7 @@
<cd:constant type="cd:list"/>
</cd:keywords>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -20183,7 +20744,7 @@
</cd:sequence>
<cd:arguments>
<cd:assignments list="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
<cd:instances>
@@ -20197,7 +20758,7 @@
</cd:sequence>
<cd:arguments>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
<cd:instances>
@@ -20211,7 +20772,7 @@
</cd:sequence>
<cd:arguments>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
<cd:instances>
@@ -21617,6 +22178,7 @@
<cd:parameter name="align">
<cd:constant default="yes" type="l2r"/>
<cd:constant type="r2l"/>
+ <cd:constant type="righttoleft"/>
</cd:parameter>
<cd:parameter name="bidi">
<cd:constant type="yes"/>
@@ -21692,6 +22254,17 @@
<cd:parameter name="ampersand">
<cd:constant type="normal"/>
</cd:parameter>
+ <cd:parameter name="collapsing">
+ <cd:constant type="1"/>
+ <cd:constant type="2"/>
+ <cd:constant default="yes" type="3"/>
+ <cd:constant type="none"/>
+ <cd:constant type="reset"/>
+ </cd:parameter>
+ <cd:parameter name="kernpairs">
+ <cd:constant type="yes"/>
+ <cd:constant default="yes" type="no"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -22302,6 +22875,9 @@
<cd:parameter name="method">
<cd:constant type="auto"/>
</cd:parameter>
+ <cd:parameter name="size">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
<cd:parameter name="factor">
<cd:constant type="none"/>
<cd:constant type="auto"/>
@@ -22558,6 +23134,14 @@
<cd:constant value="mathmatrix"/>
</cd:instances>
</cd:command>
+ <cd:command category="mathematics tables" file="math-ali.mkiv" generated="yes" level="document" name="mathmatrix">
+ <cd:sequence>
+ <cd:variable value="mathmatrix"/>
+ </cd:sequence>
+ <cd:arguments>
+ <cd:content/>
+ </cd:arguments>
+ </cd:command>
<cd:command category="mathematics tables" file="math-ali.mkiv" level="document" name="matrices" type="environment">
<cd:arguments>
<cd:assignments list="yes" optional="yes">
@@ -24807,6 +25391,10 @@
<cd:parameter name="headcolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="aligntitle">
+ <cd:constant default="yes" type="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<cd:inherit name="setupcounter"/>
</cd:assignments>
</cd:arguments>
@@ -25165,6 +25753,7 @@
</cd:command>
<cd:command category="structure notes" file="strc-not.mkvi" level="style" name="postponenotes"/>
<cd:command category="structure notes" file="strc-not.mkvi" level="style" name="flushnotes"/>
+ <cd:command category="structure notes" file="strc-not.mkvi" name="postponingnotes" type="environment"/>
<cd:command category="structure notes conditional" file="strc-not.mkvi" level="system" name="doifelsenoteonsamepage">
<cd:arguments>
<cd:keywords delimiters="braces">
@@ -26052,6 +26641,81 @@
</cd:arguments>
</cd:command>
</cd:interface>
+ <cd:interface file="i-pagecolumns.xml">
+ <cd:command category="structure layout" file="page-pcl.mkiv" level="style" name="definepagecolumns">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagecolumns"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure layout" file="page-pcl.mkiv" level="style" name="setuppagecolumns">
+ <cd:arguments>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:parameter name="separator">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="direction">
+ <cd:constant default="yes" type="normal"/>
+ <cd:constant type="reverse"/>
+ </cd:parameter>
+ <cd:parameter name="distance">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="n">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="maxwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="align">
+ <cd:inherit name="setupalign"/>
+ </cd:parameter>
+ <cd:parameter name="blank">
+ <cd:inherit name="blank"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="setups">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="page">
+ <cd:inherit name="page"/>
+ </cd:parameter>
+ <cd:inherit name="setupframed"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure layout" file="page-pcl.mkiv" level="document" name="pagecolumns" type="environment" variant="name">
+ <cd:arguments>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure layout" file="page-pcl.mkiv" level="document" name="pagecolumns" type="environment">
+ <cd:arguments>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagecolumns"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure layout" file="page-pcl.mkiv" generated="yes" level="document" name="pagecolumns" type="environment" variant="instance">
+ <cd:sequence>
+ <cd:instance value="pagecolumns"/>
+ </cd:sequence>
+ </cd:command>
+ </cd:interface>
<cd:interface file="i-pagecomment.xml">
<cd:command category="pdf" file="page-com.mkiv" level="style" name="setuppagecomment">
<cd:arguments>
@@ -26118,7 +26782,7 @@
</cd:command>
</cd:interface>
<cd:interface file="i-pagegrid.xml">
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="definepagegrid">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="definecolumnset">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:name"/>
@@ -26127,14 +26791,15 @@
<cd:constant type="cd:name"/>
</cd:keywords>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegrid"/>
+ <cd:inherit name="setupcolumnset"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="setuppagegrid">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="setupcolumnset">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="cd:name"/>
+ <cd:constant method="range" prefix="cd:name" type="cd:number"/>
</cd:keywords>
<cd:assignments list="yes">
<cd:parameter name="n">
@@ -26173,43 +26838,27 @@
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" generated="yes" level="document" name="pagegrid" type="environment" variant="example">
+ <cd:command category="layout" file="page-cst.mkiv" generated="yes" level="document" name="columnset" type="environment" variant="example">
<cd:sequence>
- <cd:variable value="pagegrid"/>
+ <cd:variable value="columnset"/>
</cd:sequence>
<cd:arguments>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegrid"/>
+ <cd:inherit name="setupcolumnset"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="document" name="pagegrid" type="environment">
+ <cd:command category="layout" file="page-cst.mkiv" level="document" name="columnset" type="environment">
<cd:arguments>
<cd:keywords optional="yes">
<cd:constant type="cd:name"/>
</cd:keywords>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegrid"/>
+ <cd:inherit name="setupcolumnset"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="document" name="setpagegrid">
- <cd:arguments>
- <cd:assignments list="yes" optional="yes">
- <cd:parameter name="c">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="r">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="option">
- <cd:constant default="yes" type="none"/>
- </cd:parameter>
- </cd:assignments>
- <cd:content/>
- </cd:arguments>
- </cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="definepagegridspan">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="definecolumnsetspan">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:name"/>
@@ -26218,11 +26867,11 @@
<cd:constant type="cd:name"/>
</cd:keywords>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegridspan"/>
+ <cd:inherit name="setupcolumnsetspan"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="setuppagegridspan">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="setupcolumnsetspan">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="cd:name"/>
@@ -26248,24 +26897,24 @@
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="document" name="pagegridspan" type="environment">
+ <cd:command category="layout" file="page-cst.mkiv" level="document" name="columnsetspan" type="environment">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:name"/>
</cd:keywords>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegridspan"/>
+ <cd:inherit name="setupcolumnsetspan"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="pagegridspanwidth">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="columnsetspanwidth">
<cd:arguments>
<cd:keywords delimiters="braces">
<cd:constant type="cd:number"/>
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="definepagegridarea">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="definecolumnsetarea">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:name"/>
@@ -26274,11 +26923,11 @@
<cd:constant type="cd:name"/>
</cd:keywords>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegridarea"/>
+ <cd:inherit name="setupcolumnsetarea"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="setuppagegridarea">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="setupcolumnsetarea">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="cd:name"/>
@@ -26318,7 +26967,7 @@
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="setuppagegridareatext">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="setupcolumnsetareatext">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:name"/>
@@ -26328,7 +26977,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="setuppagegridlines">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="setupcolumnsetlines">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:name"/>
@@ -26344,7 +26993,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="layout" file="page-cst.mkiv" level="style" name="setuppagegridstart">
+ <cd:command category="layout" file="page-cst.mkiv" level="style" name="setupcolumnsetstart">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:name"/>
@@ -26840,6 +27489,18 @@
</cd:command>
</cd:interface>
<cd:interface file="i-pagestate.xml">
+ <cd:command file="spac-pag.mkiv" level="system" name="signalrightpage"/>
+ <cd:command file="spac-pag.mkiv" level="system" name="doifelserightpage">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:false"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="spac-pag.mkiv" level="system" name="rightpageorder"/>
<cd:command file="core-dat.mkiv" level="system" name="definepagestate">
<cd:arguments>
<cd:keywords>
@@ -26899,19 +27560,65 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command file="core-dat.mkiv" level="system" name="pagestaterealpageorder">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:name"/>
+ <cd:constant type="cd:number"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="core-dat.mkiv" level="system" name="autopagestaterealpage">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="core-dat.mkiv" level="system" name="setautopagestaterealpageno">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="core-dat.mkiv" level="system" name="autopagestaterealpageorder">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
</cd:interface>
<cd:interface file="i-pagemarks.xml">
- <cd:command file="page-lay.mkiv" level="style" name="markpage">
+ <cd:command file="page-ini.mkiv" level="style" name="markpage">
<cd:arguments>
<cd:keywords>
<cd:constant type="cd:name"/>
</cd:keywords>
- <cd:keywords optional="yes">
+ <cd:keywords list="yes" optional="yes">
<cd:constant method="none" prefix="cd:sign" type="cd:number"/>
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="conditional" file="page-lay.mkiv" level="style" name="doifelsemarkedpage">
+ <cd:command file="page-ini.mkiv" level="style" name="markedpages">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="page-ini.mkiv" level="style" name="markpages" type="environment">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="conditional" file="page-ini.mkiv" level="style" name="doifelsemarkedpage">
<cd:arguments>
<cd:keywords delimiters="braces">
<cd:constant type="cd:name"/>
@@ -32655,6 +33362,7 @@
<cd:constant method="range" prefix="cd:section" type="cd:section"/>
<cd:constant method="range" prefix="cd:section" type="*"/>
<cd:constant method="range" prefix="cd:section" type="all"/>
+ <cd:constant type="current"/>
</cd:parameter>
<cd:parameter name="numberconversion">
<cd:constant type="cd:name"/>
@@ -32831,6 +33539,10 @@
<cd:constant type="all"/>
<cd:constant type="packed"/>
</cd:parameter>
+ <cd:parameter name="check">
+ <cd:constant default="yes" type="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<cd:parameter name="criterium">
<cd:constant type="local"/>
<cd:constant type="text"/>
@@ -32865,6 +33577,7 @@
<cd:constant method="range" prefix="cd:section" type="cd:section"/>
<cd:constant method="range" prefix="cd:section" type="*"/>
<cd:constant method="range" prefix="cd:section" type="all"/>
+ <cd:constant type="current"/>
</cd:parameter>
<cd:parameter name="pageprefixconnector">
<cd:constant type="cd:command"/>
@@ -32970,6 +33683,12 @@
<cd:parameter name="pagecolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="pageleft">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="pageright">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
<cd:parameter name="n">
<cd:constant type="cd:number"/>
</cd:parameter>
@@ -33034,6 +33753,10 @@
<cd:constant default="yes" type="no"/>
<cd:constant type="all"/>
</cd:parameter>
+ <cd:parameter name="check">
+ <cd:constant default="yes" type="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<cd:parameter name="criterium">
<cd:constant type="local"/>
<cd:constant type="text"/>
@@ -33068,6 +33791,7 @@
<cd:constant method="range" prefix="cd:section" type="cd:section"/>
<cd:constant method="range" prefix="cd:section" type="*"/>
<cd:constant method="range" prefix="cd:section" type="all"/>
+ <cd:constant type="current"/>
</cd:parameter>
<cd:parameter name="pageprefixconnector">
<cd:constant type="cd:command"/>
@@ -33173,6 +33897,12 @@
<cd:parameter name="pagecolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="pageleft">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="pageright">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
<cd:parameter name="n">
<cd:constant type="cd:number"/>
</cd:parameter>
@@ -33740,6 +34470,89 @@
</cd:arguments>
</cd:command>
</cd:interface>
+ <cd:interface file="i-ruby.xml">
+ <cd:command category="fonts" file="typo-rub.mkiv" level="style" name="defineruby">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupruby"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="fonts" file="typo-rub.mkiv" level="style" name="setupruby">
+ <cd:arguments>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:parameter name="location">
+ <cd:constant default="yes" type="top"/>
+ <cd:constant type="left"/>
+ <cd:constant type="right"/>
+ <cd:constant type="none"/>
+ </cd:parameter>
+ <cd:parameter name="align">
+ <cd:constant type="auto"/>
+ <cd:constant type="flushleft"/>
+ <cd:constant default="yes" type="middle"/>
+ <cd:constant type="flushright"/>
+ </cd:parameter>
+ <cd:parameter name="stretch">
+ <cd:constant type="yes"/>
+ <cd:constant default="yes" type="no"/>
+ </cd:parameter>
+ <cd:parameter name="hoffset">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="voffset">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="distance">
+ <cd:constant type="none"/>
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="left">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="right">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="style">
+ <cd:constant type="cd:style"/>
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="fonts" file="typo-rub.mkiv" level="document" name="ruby">
+ <cd:arguments>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:text"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:text"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="fonts" file="typo-rub.mkiv" level="document" name="ruby" type="environment">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ </cd:interface>
<cd:interface file="i-scale.xml">
<cd:command category="graphics" file="grph-trf.mkiv" level="style" name="definescale">
<cd:arguments>
@@ -33786,6 +34599,7 @@
<cd:constant type="fit"/>
<cd:constant type="broad"/>
<cd:constant type="max"/>
+ <cd:constant type="min"/>
<cd:constant type="auto"/>
<cd:constant type="default"/>
</cd:parameter>
@@ -33793,6 +34607,7 @@
<cd:constant type="fit"/>
<cd:constant type="broad"/>
<cd:constant type="max"/>
+ <cd:constant type="min"/>
<cd:constant type="auto"/>
<cd:constant type="default"/>
</cd:parameter>
@@ -33800,6 +34615,7 @@
<cd:constant type="fit"/>
<cd:constant type="broad"/>
<cd:constant type="max"/>
+ <cd:constant type="min"/>
<cd:constant type="auto"/>
<cd:constant type="default"/>
</cd:parameter>
@@ -33925,6 +34741,32 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="language" file="scrp-ini.mkvi" level="style" name="setlocalscript">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="hangul"/>
+ <cd:constant type="hanzi"/>
+ <cd:constant type="nihongo"/>
+ <cd:constant type="ethiopic"/>
+ <cd:constant type="thai"/>
+ <cd:constant type="test"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="language" file="scrp-ini.mkvi" level="style" name="setglobalscript">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="hangul"/>
+ <cd:constant type="hanzi"/>
+ <cd:constant type="nihongo"/>
+ <cd:constant type="ethiopic"/>
+ <cd:constant type="thai"/>
+ <cd:constant type="test"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command category="language" file="scrp-ini.mkvi" level="system" name="resetscript"/>
<cd:command category="language" file="scrp-ini.mkvi" name="script" type="environment">
<cd:arguments>
@@ -34026,6 +34868,7 @@
<cd:constant method="range" prefix="cd:section" type="cd:section"/>
<cd:constant method="range" prefix="cd:section" type="*"/>
<cd:constant method="range" prefix="cd:section" type="all"/>
+ <cd:constant type="current"/>
</cd:parameter>
<cd:parameter name="referenceprefix">
<cd:constant type="+"/>
@@ -34928,6 +35771,16 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command file="core-env.mkiv" level="system" name="copysetups">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command file="core-env.mkiv" level="system" name="showsetupsdefinition">
<cd:arguments>
<cd:keywords>
@@ -35688,10 +36541,7 @@
<cd:variable value="startstop"/>
</cd:sequence>
</cd:command>
- <cd:command category="structure" file="core-sys.mkiv" level="document" name="startstop" type="environment">
- <cd:sequence>
- <cd:string value="​"/>
- </cd:sequence>
+ <cd:command category="structure" file="core-sys.mkiv" level="document" name="" type="environment">
<cd:arguments>
<cd:keywords optional="yes">
<cd:constant type="cd:name"/>
@@ -35907,6 +36757,7 @@
</cd:arguments>
</cd:command>
<cd:command file="spac-ver.mkiv" level="system" name="setfontstrut"/>
+ <cd:command file="spac-ver.mkiv" level="system" name="settightstrut"/>
<cd:command file="spac-ver.mkiv" level="system" name="setcapstrut"/>
<cd:command file="spac-ver.mkiv" level="system" name="setnostrut"/>
<cd:command file="spac-ver.mkiv" level="document" name="showstruts"/>
@@ -36084,6 +36935,11 @@
<cd:keywords>
<cd:constant type="cd:name"/>
</cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:parameter name="font">
+ <cd:constant type="cd:font"/>
+ </cd:parameter>
+ </cd:assignments>
</cd:arguments>
</cd:command>
<cd:command category="symbols" file="symb-ini.mkiv" level="style" name="setupsymbolset">
@@ -37719,6 +38575,13 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command file="syst-aux.mkiv" level="system" name="firstinlist">
+ <cd:arguments>
+ <cd:keywords list="yes">
+ <cd:constant type="cd:command"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command file="syst-aux.mkiv" level="system" name="dogetcommacommandelement">
<cd:arguments>
<cd:keywords delimiters="none">
@@ -38653,7 +39516,7 @@
</cd:command>
<cd:command file="syst-aux.mkiv" level="system" name="increment" variant="argument">
<cd:arguments>
- <cd:keywords delimiters="parentheses" list="yes">
+ <cd:keywords delimiters="parenthesis" list="yes">
<cd:constant type="cd:csname"/>
<cd:constant type="cd:number"/>
</cd:keywords>
@@ -38666,7 +39529,7 @@
</cd:command>
<cd:command file="syst-aux.mkiv" level="system" name="decrement" variant="argument">
<cd:arguments>
- <cd:keywords delimiters="parentheses" list="yes">
+ <cd:keywords delimiters="parenthesis" list="yes">
<cd:constant type="cd:csname"/>
<cd:constant type="cd:number"/>
</cd:keywords>
@@ -38870,6 +39733,24 @@
<cd:delimiter name="fi"/>
</cd:arguments>
</cd:command>
+ <cd:command file="syst-aux.mkiv" level="system" name="doifelseassignmentcs">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:text"/>
+ </cd:keywords>
+ <cd:csname/>
+ <cd:csname/>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="syst-aux.mkiv" level="system" name="doifassignmentelsecs">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:text"/>
+ </cd:keywords>
+ <cd:csname/>
+ <cd:csname/>
+ </cd:arguments>
+ </cd:command>
<cd:command file="syst-aux.mkiv" level="system" name="convertargument">
<cd:arguments>
<cd:keywords delimiters="none">
@@ -41112,6 +41993,36 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command file="syst-lua.mkiv" level="system" name="expandeddoif">
+ <cd:arguments>
+ <cd:content/>
+ <cd:content/>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="syst-lua.mkiv" level="system" name="expandeddoifnot">
+ <cd:arguments>
+ <cd:content/>
+ <cd:content/>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="syst-lua.mkiv" level="system" name="expandeddoifelse">
+ <cd:arguments>
+ <cd:content/>
+ <cd:content/>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:false"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command file="syst-lua.mkiv" level="system" name="expdoifelsecommon">
<cd:arguments>
<cd:keywords delimiters="braces" list="yes">
@@ -41391,6 +42302,74 @@
<cd:constant type="grid"/>
<cd:constant type="cd:dimension"/>
</cd:parameter>
+ <cd:parameter name="blank">
+ <cd:constant type="preference"/>
+ <cd:constant type="samepage"/>
+ <cd:constant type="max"/>
+ <cd:constant type="force"/>
+ <cd:constant type="enable"/>
+ <cd:constant type="disable"/>
+ <cd:constant type="nowhite"/>
+ <cd:constant type="packed"/>
+ <cd:constant type="back"/>
+ <cd:constant type="overlay"/>
+ <cd:constant type="always"/>
+ <cd:constant type="weak"/>
+ <cd:constant type="strong"/>
+ <cd:constant type="default"/>
+ <cd:constant type="before"/>
+ <cd:constant type="inbetween"/>
+ <cd:constant type="after"/>
+ <cd:constant type="fixed"/>
+ <cd:constant type="flexible"/>
+ <cd:constant type="none"/>
+ <cd:constant type="small"/>
+ <cd:constant type="medium"/>
+ <cd:constant type="big"/>
+ <cd:constant type="line"/>
+ <cd:constant type="halfline"/>
+ <cd:constant type="quarterline"/>
+ <cd:constant type="formula"/>
+ <cd:constant type="white"/>
+ <cd:constant type="height"/>
+ <cd:constant type="depth"/>
+ <cd:constant type="standard"/>
+ <cd:constant method="factor" prefix="cd:number" type="small"/>
+ <cd:constant method="factor" prefix="cd:number" type="medium"/>
+ <cd:constant method="factor" prefix="cd:number" type="big"/>
+ <cd:constant method="factor" prefix="cd:number" type="line"/>
+ <cd:constant method="factor" prefix="cd:number" type="halfline"/>
+ <cd:constant method="factor" prefix="cd:number" type="quarterline"/>
+ <cd:constant method="factor" prefix="cd:number" type="formula"/>
+ <cd:constant method="factor" prefix="cd:number" type="white"/>
+ <cd:constant method="factor" prefix="cd:number" type="height"/>
+ <cd:constant method="factor" prefix="cd:number" type="depth"/>
+ <cd:constant method="range" prefix="category" type="cd:number"/>
+ <cd:constant method="range" prefix="order" type="cd:number"/>
+ <cd:constant method="range" prefix="penalty" type="cd:number"/>
+ <cd:constant type="cd:dimension"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="headstyle">
+ <cd:constant type="cd:style"/>
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="headcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="background">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="backgroundcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="foregroundstyle">
+ <cd:constant type="cd:style"/>
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="foregroundcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
<cd:parameter name="align">
<cd:constant type="left"/>
<cd:constant type="middle"/>
@@ -41556,7 +42535,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="xml" file="strc-tag.mkiv" name="element" type="environment">
+ <cd:command category="xml" file="strc-tag.mkiv" level="document" name="element" type="environment">
<cd:arguments>
<cd:keywords delimiters="braces">
<cd:constant type="cd:name"/>
@@ -41631,6 +42610,13 @@
</cd:assignments>
</cd:arguments>
</cd:command>
+ <cd:command category="xml" file="strc-tag.mkiv" level="style" name="ignoretagsinexport">
+ <cd:arguments>
+ <cd:keywords list="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
</cd:interface>
<cd:interface file="i-textbackground.xml">
<cd:command category="background" file="anch-bck.mkiv" level="style" name="definetextbackground">
@@ -42043,7 +43029,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -42055,7 +43041,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -42067,7 +43053,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -42079,7 +43065,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -42091,7 +43077,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -42511,6 +43497,44 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command file="toks-aux.mkiv" level="style" name="definetokenlist">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="toks-aux.mkiv" level="style" name="tokenlist" type="environment">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="toks-aux.mkiv" level="style" name="gettokenlist">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="toks-aux.mkiv" level="style" name="resettokenlist">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command file="toks-aux.mkiv" level="style" name="settokenlist">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:text"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
</cd:interface>
<cd:interface file="i-tolerance.xml">
<cd:command category="whitespace" file="spac-hor.mkiv" level="style" name="setuptolerance">
@@ -43240,6 +44264,108 @@
</cd:assignments>
</cd:arguments>
</cd:command>
+ <cd:command category="symbols" file="core-con.mkiv" level="style" name="spaceddigitsmethod"/>
+ <cd:command category="symbols" file="core-con.mkiv" level="style" name="spaceddigitssymbol"/>
+ <cd:command category="symbols" file="core-con.mkiv" level="style" name="spaceddigitsseparator"/>
+ <cd:command category="symbols" file="core-con.mkiv" level="document" name="spaceddigits">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:number"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ </cd:interface>
+ <cd:interface file="i-userdata.xml">
+ <cd:command category="structure" file="strc-usr.mkiv" level="style" name="defineuserdata">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupuserdata"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="strc-usr.mkiv" level="style" name="setupuserdata">
+ <cd:arguments>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:parameter name="before">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="after">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="align">
+ <cd:inherit name="setupalign"/>
+ </cd:parameter>
+ <cd:parameter name="setups">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="style">
+ <cd:constant type="cd:style"/>
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="alternative">
+ <cd:constant type="default"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="cd:key">
+ <cd:constant type="cd:value"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="strc-usr.mkiv" level="document" name="userdata" type="environment">
+ <cd:arguments>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:parameter name="cd:key">
+ <cd:constant type="cd:value"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="strc-usr.mkiv" level="style" name="defineuserdataalternative">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupuserdataalternative"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="strc-usr.mkiv" level="style" name="setupuserdataalternative">
+ <cd:arguments>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:parameter name="renderingsetup">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="cd:key">
+ <cd:constant type="cd:value"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="structure" file="strc-usr.mkiv" level="style" name="getuserdata"/>
+ <cd:command category="structure" file="strc-usr.mkiv" level="style" name="getinlineuserdata"/>
</cd:interface>
<cd:interface file="i-variables.xml">
<cd:command file="core-env.mkiv" level="style" name="setvariables">
@@ -44106,7 +45232,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="verbatim" file="buff-ver.mkiv" level="system conditional" name="doifelsetypingfile">
+ <cd:command category="verbatim conditional" file="buff-ver.mkiv" level="system" name="doifelsetypingfile">
<cd:arguments>
<cd:keywords delimiters="braces">
<cd:constant type="cd:file"/>
@@ -44119,7 +45245,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="verbatim" file="buff-ver.mkiv" level="system conditional" name="doiftypingfileelse">
+ <cd:command category="verbatim conditional" file="buff-ver.mkiv" level="system" name="doiftypingfileelse">
<cd:arguments>
<cd:keywords delimiters="braces">
<cd:constant type="cd:file"/>
@@ -44419,19 +45545,19 @@
<cd:arguments>
<cd:keywords optional="yes">
<cd:constant default="yes" type="makeup"/>
- <cd:constant type="all"/>
+ <cd:constant type="reset"/>
<cd:constant type="boxes"/>
- <cd:constant type="line"/>
- <cd:constant type="glyph"/>
- <cd:constant type="fontkern"/>
+ <cd:constant type="all"/>
<cd:constant type="hbox"/>
<cd:constant type="vbox"/>
<cd:constant type="vtop"/>
<cd:constant type="kern"/>
<cd:constant type="glue"/>
<cd:constant type="penalty"/>
+ <cd:constant type="fontkern"/>
<cd:constant type="strut"/>
<cd:constant type="whatsit"/>
+ <cd:constant type="glyph"/>
<cd:constant type="simple"/>
<cd:constant type="simplehbox"/>
<cd:constant type="simplevbox"/>
@@ -44440,7 +45566,11 @@
<cd:constant type="math"/>
<cd:constant type="italic"/>
<cd:constant type="origin"/>
- <cd:constant type="reset"/>
+ <cd:constant type="discretionary"/>
+ <cd:constant type="expansion"/>
+ <cd:constant type="line"/>
+ <cd:constant type="space"/>
+ <cd:constant type="depth"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -44449,6 +45579,8 @@
<cd:command file="trc-vis.mkiv" level="document" name="showglyphs"/>
<cd:command file="trc-vis.mkiv" level="document" name="showfontkerns"/>
<cd:command file="trc-vis.mkiv" level="document" name="showfontitalics"/>
+ <cd:command file="trc-vis.mkiv" level="document" name="showglyphdata"/>
+ <cd:command file="trc-vis.mkiv" level="document" name="showfontexpansion"/>
<cd:command file="trc-vis.mkiv" level="system" name="setvisualizerfont">
<cd:arguments>
<cd:keywords optional="yes">
@@ -44565,6 +45697,7 @@
<cd:constant type="enable"/>
<cd:constant type="disable"/>
<cd:constant type="nowhite"/>
+ <cd:constant type="packed"/>
<cd:constant type="back"/>
<cd:constant type="overlay"/>
<cd:constant type="always"/>
@@ -44653,6 +45786,20 @@
<cd:command category="whitespace" file="spac-ver.mkiv" level="system" name="smallskip"/>
<cd:command category="whitespace" file="spac-ver.mkiv" level="system" name="medskip"/>
<cd:command category="whitespace" file="spac-ver.mkiv" level="system" name="bigskip"/>
+ <cd:command category="whitespace" file="spac-ver.mkiv" level="system" name="checkedblank">
+ <cd:arguments>
+ <cd:keywords list="yes">
+ <cd:inherit name="blank"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="whitespace" file="spac-ver.mkiv" level="system" name="prerollblank">
+ <cd:arguments>
+ <cd:keywords list="yes">
+ <cd:inherit name="blank"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
</cd:interface>
<cd:interface file="i-whitespace.xml">
<cd:command category="whitespace" file="spac-ver.mkiv" level="style" name="setupwhitespace">
@@ -44686,7 +45833,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="whitespace" file="spac-ver.mkiv" name="unpacked" type="environment"/>
+ <cd:command category="whitespace" file="spac-ver.mkiv" level="document" name="unpacked" type="environment"/>
<cd:command category="whitespace" file="spac-ver.mkiv" level="document" name="linecorrection" type="environment">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
@@ -44695,7 +45842,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command category="whitespace" file="spac-ver.mkiv" name="locallinecorrection" type="environment">
+ <cd:command category="whitespace" file="spac-ver.mkiv" level="document" name="locallinecorrection" type="environment">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="blank"/>
@@ -44703,6 +45850,7 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="alignment" file="spac-ver.mkiv" level="system" name="forgetparskip"/>
</cd:interface>
<cd:interface file="i-xml.xml">
<cd:command category="xml" file="lxml-ini.mkiv" level="style" name="xmlmain">
@@ -45671,6 +46819,45 @@
</cd:keywords>
</cd:arguments>
</cd:command>
+ <cd:command category="xml" file="lxml-ini.mkiv" level="style" name="xmldoifatt">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:node"/>
+ </cd:keywords>
+ <cd:string/>
+ <cd:string/>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="xml" file="lxml-ini.mkiv" level="style" name="xmldoifnotatt">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:node"/>
+ </cd:keywords>
+ <cd:string/>
+ <cd:string/>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="xml" file="lxml-ini.mkiv" level="style" name="xmldoifelseatt">
+ <cd:arguments>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:node"/>
+ </cd:keywords>
+ <cd:string/>
+ <cd:string/>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:true"/>
+ </cd:keywords>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:false"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command category="xml" file="lxml-ini.mkiv" level="style" name="xmldoifselfempty">
<cd:arguments>
<cd:keywords delimiters="braces">
@@ -46057,6 +47244,25 @@
<cd:parameter name="distance">
<cd:constant type="cd:dimension"/>
</cd:parameter>
+ <cd:parameter name="aligncharacter">
+ <cd:constant type="yes"/>
+ <cd:constant default="yes" type="no"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentleftsample">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentrightsample">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentleftwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentrightwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentcharacter">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
<cd:inherit name="setupframed"/>
</cd:assignments>
</cd:arguments>
@@ -46116,6 +47322,20 @@
</cd:assignments>
</cd:arguments>
</cd:command>
+ <cd:command category="tables" file="tabl-xtb.mkvi" level="document" name="xcolumn" type="environment">
+ <cd:arguments>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupxtable"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+ <cd:command category="tables" file="tabl-xtb.mkvi" level="document" name="xcolumn" type="environment" variant="name">
+ <cd:arguments>
+ <cd:keywords optional="yes">
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
<cd:command category="tables" file="tabl-xtb.mkvi" level="document" name="xcell" type="environment">
<cd:arguments>
<cd:keywords optional="yes">
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 @@
<cd:constant type="global"/>
<cd:constant type="public" default="yes"/>
<cd:constant type="private"/>
+ <cd:constant type="pickup"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -42,6 +43,7 @@
<cd:constant type="global"/>
<cd:constant type="public"/>
<cd:constant type="private" default="yes"/>
+ <cd:constant type="pickup"/>
</cd:keywords>
</cd:arguments>
</cd:command>
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 @@
<cd:constant type="cd:file"/>
</cd:parameter>
<cd:parameter name="intent">
- <cd:constant type="Coated FOGRA39 (ISO 12647-2:2004)"/>
+ <cd:constant type="Coated&blank;FOGRA39&blank;(ISO&blank;12647-2:2004)"/>
<cd:constant type="GRACoL2006_Coated1v2.icc"/>
- <cd:constant type="ISO Coated v2 300% (ECI)"/>
- <cd:constant type="ISO Coated v2 (ECI)"/>
+ <cd:constant type="ISO&blank;Coated&blank;v2&blank;300&percnt;&blank;(ECI)"/>
+ <cd:constant type="ISO&blank;Coated&blank;v2&blank;(ECI)"/>
<cd:constant type="ISOnewspaper26v4"/>
<cd:constant type="ISOnewspaper26v4_gr"/>
- <cd:constant type="ISO Uncoated"/>
- <cd:constant type="ISO Uncoated Yellowish"/>
- <cd:constant type="ISO Web Coated"/>
- <cd:constant type="Japan Color 2001 Coated"/>
- <cd:constant type="Japan Color 2002 Newspaper"/>
- <cd:constant type="Japan Web Coated (Ad)"/>
- <cd:constant type="SNAP 2007"/>
+ <cd:constant type="ISO&blank;Uncoated"/>
+ <cd:constant type="ISO&blank;Uncoated&blank;Yellowish"/>
+ <cd:constant type="ISO&blank;Web&blank;Coated"/>
+ <cd:constant type="Japan&blank;Color&blank;2001&blank;Coated"/>
+ <cd:constant type="Japan&blank;Color&blank;2002&blank;Newspaper"/>
+ <cd:constant type="Japan&blank;Web&blank;Coated&blank;(Ad)"/>
+ <cd:constant type="SNAP&blank;2007"/>
<cd:constant type="SWOP2006_Coated3v2.icc"/>
<cd:constant type="SWOP2006_Coated5v2.icc"/>
- <cd:constant type="Uncoated FOGRA29 (ISO 12647-2:2004)"/>
- <cd:constant type="Web Coated FOGRA28 (ISO 12647-2:2004)"/>
+ <cd:constant type="Uncoated&blank;FOGRA29&blank;(ISO␣12647-2:2004)"/>
+ <cd:constant type="Web&blank;Coated&blank;FOGRA28&blank;(ISO&blank;12647-2:2004)"/>
<cd:constant type="PSR_LWC_PLUS_V2_PT"/>
<cd:constant type="PSR_LWC_STD_V2_PT"/>
<cd:constant type="PSR_SC_PLUS_V2_PT"/>
@@ -86,4 +86,4 @@
</cd:arguments>
</cd:command>
-</cd:interface>
+</cd:interface> \ 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 @@
<cd:parameter name="after">
<cd:constant type="cd:command"/>
</cd:parameter>
+ <cd:parameter name="left">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="right">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="alternative">
+ <cd:constant type="paragraph" default="yes"/>
+ <cd:constant type="text"/>
+ </cd:parameter>
<cd:parameter name="inner">
<cd:constant type="cd:command"/>
</cd:parameter>
+ <cd:parameter name="setups">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="align">
+ <cd:resolve name="value-alignsimple"/>
+ </cd:parameter>
<cd:parameter name="style">
<cd:resolve name="value-style"/>
</cd:parameter>
@@ -47,6 +63,7 @@
<cd:constant type="-"/>
<cd:constant type="cd:name"/>
</cd:keywords>
+ <cd:resolve name="assignment-userdata-list-optional"/>
</cd:arguments>
</cd:command>
@@ -103,4 +120,10 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+ <cd:command name="blockuservariable" level="document" category="structure" file="strc-blk.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-key"/>
+ </cd:arguments>
+ </cd:command>
+
+</cd:interface>
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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="linebox" level="system" file="supp-box.mkiv">
+ <cd:arguments>
+ <cd:content/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="shiftbox" level="system" file="supp-box.mkiv">
+ <cd:arguments>
+ <cd:dimension/>
+ <cd:content/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="inlinedbox" level="system" file="supp-box.mkiv">
<cd:arguments>
<cd:content/>
@@ -1128,4 +1141,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
<cd:parameter name="after">
<cd:constant type="cd:command"/>
</cd:parameter>
+ <cd:parameter name="strip">
+ <cd:constant type="yes" default="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -81,7 +85,7 @@
<cd:command name="getbuffer" level="document" category="buffer" file="buff-ini.mkiv">
<cd:arguments>
- <cd:resolve name="keyword-buffer-optional"/>
+ <cd:resolve name="keyword-buffer-list-optional"/>
</cd:arguments>
</cd:command>
@@ -97,7 +101,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="buffer" type="environment" generated="yes" variant="instance" lcategory="buffer" evel="document" file="buff-ini.mkiv">
+ <cd:command name="buffer" type="environment" generated="yes" variant="instance" category="buffer" level="document" file="buff-ini.mkiv">
<cd:sequence>
<cd:instance value="buffer"/>
</cd:sequence>
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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="textormathchars" level="style" category="characters fonts" file="char-ini.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-character"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="chardescription" level="style" category="characters" file="char-ini.mkiv">
<cd:arguments>
<cd:resolve name="argument-number"/>
@@ -141,4 +147,4 @@
<cd:command name="textplus" level="document" category="characters" file="enco-ini.mkiv"/>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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,10 +24,33 @@
<cd:command name="resetcharacteralign" level="system" category="alignment" file="typo-tal.mkiv"/>
+ <cd:command name="nocharacteralign" level="system" category="alignment" file="typo-tal.mkiv"/>
+
+ <cd:command name="setcharacteraligndetail" level="system" category="alignment" file="typo-tal.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-number"/>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:text"/>
+ <cd:constant type="cd:text" prefix="number" method="apply"/>
+ <cd:constant type="cd:text" prefix="text" method="apply"/>
+ </cd:keywords>
+ <cd:resolve name="argument-dimension"/>
+ <cd:resolve name="argument-dimension"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="alignmentcharacter" level="system" category="alignment" file="typo-tal.mkiv"/>
<cd:command name="characteralign" type="environment" category="alignment" level="system" file="typo-tal.mkiv">
<cd:arguments>
+ <cd:assignments list="yes">
+ <cd:inherit name="setupcharacteralign"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="characteralign" type="environment" variant="argument" category="alignment" level="system" file="typo-tal.mkiv">
+ <cd:arguments>
<cd:keywords optional="yes">
<cd:constant type="cd:text"/>
<cd:constant type="cd:text" prefix="number" method="apply"/>
@@ -42,4 +65,32 @@
</cd:arguments>
</cd:command>
+ <cd:command name="setupcharacteralign" level="style" category="alignment" file="typo-tal.mkiv">
+ <cd:arguments>
+ <cd:assignments list="yes">
+ <cd:parameter name="leftwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="rightwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="leftsample">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="rightsample">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="character">
+ <cd:constant type="cd:text"/>
+ <cd:constant type="cd:text" prefix="number" method="apply"/>
+ <cd:constant type="cd:text" prefix="text" method="apply"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setfirstpasscharacteralign" level="system" category="alignment" file="typo-tal.mkiv"/>
+
+ <cd:command name="setsecondpasscharacteralign" level="system" category="alignment" file="typo-tal.mkiv"/>
+
</cd:interface> \ 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 @@
</cd:arguments>
</cd:command>
- <cd:command name="transparent" type="environment" category="colors" file="colo-ini.mkiv">
+ <cd:command name="transparent" type="environment" level="style" category="colors" file="colo-ini.mkiv">
<cd:arguments>
<cd:resolve name="keyword-color"/>
</cd:arguments>
@@ -366,7 +366,7 @@
<cd:command name="color" type="environment" begin="save" end="restore" level="system" category="colors" file="colo-ini.mkiv"/>
- <cd:command name="definepalet" category="colors" file="colo-ini.mkiv">
+ <cd:command name="definepalet" level="style" category="colors" file="colo-ini.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
<cd:assignments list="yes">
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 @@
<cd:constant type="no"/>
</cd:parameter>
<cd:parameter name="align">
- <cd:constant type="setupalign"/>
+ <cd:inherit type="setupalign"/>
</cd:parameter>
<cd:parameter name="tolerance">
- <cd:constant type="setuptolerance"/>
+ <cd:inherit type="setuptolerance"/>
</cd:parameter>
<cd:parameter name="blank">
<cd:inherit name="blank"/>
@@ -73,7 +73,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="columnspan" type="environment" category="columns" file="page-mul.mkiv">
+ <cd:command name="columnspan" type="environment" level="document" category="columns" file="page-mul.mkiv">
<cd:arguments>
<cd:assignments list="yes" optional="yes">
<cd:inherit name="setupcolumnspan"/>
@@ -108,4 +108,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="installmacrostack" level="system" file="mult-aux.mkiv">
+ <cd:arguments>
+ <cd:csname/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="installglobalmacrostack" level="system" file="mult-aux.mkiv">
+ <cd:arguments>
+ <cd:csname/>
+ </cd:arguments>
+ </cd:command>
+
</cd:interface>
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 @@
</cd:keywords>
</cd:define>
+ <!-- * -->
+ <!-- \... [...] -->
+ <!-- -->
+ <!-- * SCRIPT -->
+
+ <cd:define name="keyword-script">
+ <cd:keywords>
+ <cd:constant type="hangul"/>
+ <cd:constant type="hanzi"/>
+ <cd:constant type="nihongo"/>
+ <cd:constant type="ethiopic"/>
+ <cd:constant type="thai"/>
+ <cd:constant type="test"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:define>
+
</cd:interface> \ 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 @@
<cd:constant type="cd:section" prefix="cd:section" method="range"/>
<cd:constant type="*" prefix="cd:section" method="range"/>
<cd:constant type="all" prefix="cd:section" method="range"/>
+ <cd:constant type="current"/>
</cd:define>
<!-- numbersegments = ... -->
@@ -314,6 +315,41 @@
<cd:constant type="de-AT"/>
<cd:constant type="ru-iso9"/>
<cd:constant type="ocs-scn"/>
+ <!--
+ <cd:constant type="en"/>
+ <cd:constant type="nl"/>
+ <cd:constant type="fr"/>
+ <cd:constant type="de"/>
+ <cd:constant type="deo"/>
+ <cd:constant type="fi"/>
+ <cd:constant type="sl"/>
+ <cd:constant type="ru"/>
+ <cd:constant type="uk"/>
+ <cd:constant type="be"/>
+ <cd:constant type="bg"/>
+ <cd:constant type="cu"/>
+ <cd:constant type="pl"/>
+ <cd:constant type="cz"/>
+ <cd:constant type="cs"/>
+ <cd:constant type="sk"/>
+ <cd:constant type="hr"/>
+ <cd:constant type="sr"/>
+ <cd:constant type="no"/>
+ <cd:constant type="da"/>
+ <cd:constant type="sv"/>
+ <cd:constant type="is"/>
+ <cd:constant type="gr"/>
+ <cd:constant type="la"/>
+ <cd:constant type="it"/>
+ <cd:constant type="ro"/>
+ <cd:constant type="es"/>
+ <cd:constant type="pt"/>
+ <cd:constant type="lt"/>
+ <cd:constant type="hu"/>
+ <cd:constant type="et"/>
+ <cd:constant type="kr"/>
+ <cd:constant type="jp"/>
+ -->
<cd:constant type="cd:language"/>
</cd:define>
@@ -683,4 +719,55 @@
<cd:constant type="cd:name"/>
</cd:define>
+ <!-- blank -->
+
+ <cd:define name="value-blank">
+ <cd:constant type="preference"/>
+ <cd:constant type="samepage"/>
+ <cd:constant type="max"/>
+ <cd:constant type="force"/>
+ <cd:constant type="enable"/>
+ <cd:constant type="disable"/>
+ <cd:constant type="nowhite"/>
+ <cd:constant type="packed"/>
+ <cd:constant type="back"/>
+ <cd:constant type="overlay"/>
+ <cd:constant type="always"/>
+ <cd:constant type="weak"/>
+ <cd:constant type="strong"/>
+ <cd:constant type="default"/>
+ <cd:constant type="before"/>
+ <cd:constant type="inbetween"/>
+ <cd:constant type="after"/>
+ <cd:constant type="fixed"/>
+ <cd:constant type="flexible"/>
+ <cd:constant type="none"/>
+ <cd:constant type="small"/>
+ <cd:constant type="medium"/>
+ <cd:constant type="big"/>
+ <cd:constant type="line"/>
+ <cd:constant type="halfline"/>
+ <cd:constant type="quarterline"/>
+ <cd:constant type="formula"/>
+ <cd:constant type="white"/>
+ <cd:constant type="height"/>
+ <cd:constant type="depth"/>
+ <cd:constant type="standard"/>
+ <cd:constant type="small" prefix="cd:number" method="factor"/>
+ <cd:constant type="medium" prefix="cd:number" method="factor"/>
+ <cd:constant type="big" prefix="cd:number" method="factor"/>
+ <cd:constant type="line" prefix="cd:number" method="factor"/>
+ <cd:constant type="halfline" prefix="cd:number" method="factor"/>
+ <cd:constant type="quarterline" prefix="cd:number" method="factor"/>
+ <cd:constant type="formula" prefix="cd:number" method="factor"/>
+ <cd:constant type="white" prefix="cd:number" method="factor"/>
+ <cd:constant type="height" prefix="cd:number" method="factor"/>
+ <cd:constant type="depth" prefix="cd:number" method="factor"/>
+ <cd:constant type="cd:number" prefix="category" method="range"/>
+ <cd:constant type="cd:number" prefix="order" method="range"/>
+ <cd:constant type="cd:number" prefix="penalty" method="range"/>
+ <cd:constant type="cd:dimension"/>
+ <cd:constant type="cd:name"/>
+ </cd:define>
+
</cd:interface>
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index 39538aa7b..7f468c416 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files 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 @@
<cd:interfacefile filename="i-language.xml"/>
<cd:interfacefile filename="i-layer.xml"/>
<cd:interfacefile filename="i-layout.xml"/>
+ <cd:interfacefile filename="i-linefiller.xml"/>
<cd:interfacefile filename="i-linenumber.xml"/>
<cd:interfacefile filename="i-lines.xml"/>
<cd:interfacefile filename="i-linetable.xml"/>
@@ -151,6 +152,7 @@
<cd:interfacefile filename="i-output.xml"/>
<cd:interfacefile filename="i-overlay.xml"/>
<cd:interfacefile filename="i-pagebreak.xml"/>
+ <cd:interfacefile filename="i-pagecolumns.xml"/>
<cd:interfacefile filename="i-pagecomment.xml"/>
<cd:interfacefile filename="i-pagefigure.xml"/>
<cd:interfacefile filename="i-pagegrid.xml"/>
@@ -187,6 +189,7 @@
<cd:interfacefile filename="i-renderingwindow.xml"/>
<cd:interfacefile filename="i-replacement.xml"/>
<cd:interfacefile filename="i-rotatation.xml"/>
+ <cd:interfacefile filename="i-ruby.xml"/>
<cd:interfacefile filename="i-scale.xml"/>
<cd:interfacefile filename="i-script.xml"/>
<cd:interfacefile filename="i-section.xml"/>
@@ -224,6 +227,7 @@
<cd:interfacefile filename="i-twopassdata.xml"/>
<cd:interfacefile filename="i-typography.xml"/>
<cd:interfacefile filename="i-unit.xml"/>
+ <cd:interfacefile filename="i-userdata.xml"/>
<cd:interfacefile filename="i-variables.xml"/>
<cd:interfacefile filename="i-verbatim.xml"/>
<cd:interfacefile filename="i-version.xml"/>
@@ -234,4 +238,4 @@
<cd:interfacefile filename="i-xml.xml"/>
<cd:interfacefile filename="i-xtable.xml"/>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?context-directive job ctxfile x-setups.ctx ?>
+
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands">
+
+ <cd:command name="quotedbl" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="texthash" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textdollar" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textpercent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textampersand" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="quotesingle" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textcomma" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="texthyphen" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textperiod" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textslash" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textat" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dotlessI" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dotlessJ" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textbackslash" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textasciicircum" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textunderscore" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="idotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textbraceleft" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textbar" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textbraceright" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textasciitilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="nobreakspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="exclamdown" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textcent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textsterling" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textcurrency" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textyen" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textbrokenbar" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="sectionmark" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="copyright" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ordfeminine" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="leftguillemot" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textlognot" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="softhyphen" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="registered" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textdegree" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textpm" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="twosuperior" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="threesuperior" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textmu" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="paragraphmark" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="periodcentered" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textcedilla" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="onesuperior" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ordmasculine" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="rightguillemot" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="onequarter" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="onehalf" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="threequarter" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="questiondown" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Agrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Aacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Acircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Atilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Adiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Aring" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="AEligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ccedilla" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Egrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Eacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ecircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ediaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Igrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Iacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Icircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Idiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Eth" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ntilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ograve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Oacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ocircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Otilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Odiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textmultiply" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ostroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ugrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ucircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Udiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Yacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Thorn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ssharp" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="agrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="aacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="acircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="atilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="adiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="aring" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="aeligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ccedilla" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="egrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="eacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ecircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ediaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="igrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="iacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="icircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="idiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ comment="contextname=eth" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ntilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ograve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="oacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ocircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="otilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="odiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textdiv" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ostroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ugrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ucircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="udiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="yacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="thorn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ydiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Amacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="amacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Abreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="abreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Aogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="aogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Cacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ccircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ccircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Cdotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cdotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ccaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ccaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Dcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Dstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Emacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="emacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ebreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ebreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Edotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="edotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Eogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="eogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ecaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ecaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Gcircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="gcircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Gbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="gbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Gdotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="gdotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Gcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="gcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Hcircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hcircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Hstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Itilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="itilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Imacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="imacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ibreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ibreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Iogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="iogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Idotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dotlessi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="IJligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ijligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Jcircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="jcircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Kcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="kcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="kkra" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Lacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="lacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Lcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="lcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Lcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="lcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ldotmiddle" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ldotmiddle" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Lstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="lstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Nacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="nacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ncommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ncommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ncaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ncaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="napostrophe" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Neng" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="neng" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Omacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="omacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Obreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="obreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ohungarumlaut" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ohungarumlaut" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="OEligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="oeligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Racute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="racute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Rcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="rcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Rcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="rcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Sacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="sacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Scircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="scircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Scedilla" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="scedilla" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Scaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="scaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Tcedilla" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="tcedilla" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Tcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="tcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Tstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="tstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Utilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="utilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Umacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="umacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ubreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ubreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uring" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uring" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uhungarumlaut" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uhungarumlaut" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Wcircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="wcircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ycircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ycircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ydiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Zacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="zacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Zdotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="zdotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Zcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="zcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="slong" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="bstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Bhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Chook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="chook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Dafrican" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Dhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Schwa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Fhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="fhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ghook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Istroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Khook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="khook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="lbar" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ohorn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ohorn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Phook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="phook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Thook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="thook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uhorn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uhorn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Yhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="yhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Zstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="zstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="DZcaronligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Dzcaronligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dzcaronligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="LJligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ljligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ljligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="NJligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Njligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="njligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Acaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="acaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Icaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="icaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ocaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ocaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ucaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ucaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Udiaeresismacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="udiaeresismacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Udiaeresisacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="udiaeresisacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Udiaeresiscaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="udiaeresiscaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Udiaeresisgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="udiaeresisgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Adiaeresismacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="adiaeresismacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Adotaccentmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="adotaccentmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="AEmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="aemacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Gstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="gstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Gcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="gcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Kcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="kcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Oogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="oogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Oogonekmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="oogonekmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="jcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="DZligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Dzligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dzligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Gacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="gacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ngrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ngrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Aringacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="aringacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="AEacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="aeacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ostrokeacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ostrokeacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Adoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="adoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ainvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ainvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Edoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="edoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Einvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="einvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Idoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="idoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Iinvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="iinvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Odoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="odoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Oinvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="oinvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Rdoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="rdoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Rinvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="rinvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Udoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="udoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uinvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uinvertedbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Scommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="scommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Tcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="tcommaaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Hcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dcurl" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Zhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="zhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Adotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="adotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ecedilla" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ecedilla" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Odiaeresismacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="odiaeresismacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Otildemacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="otildemacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Odotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="odotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Odotaccentmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="odotaccentmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ymacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ymacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="lcurl" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ncurl" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="tcurl" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dotlessj" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Astroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Cstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Lbar" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="bhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ccurl" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dtail" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="schwa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="schwahook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="dotlessjstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textcircumflex" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textcaron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textdotaccent" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textring" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textogonek" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="texttilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="texthungarumlaut" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textbottomdot" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textbottomcomma" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greektonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdialytikatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilontonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicrontonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilontonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotadialytikatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlpha" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekBeta" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekGamma" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekDelta" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilon" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekZeta" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEta" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekTheta" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIota" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekKappa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekLambda" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekMu" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekNu" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekXi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekPi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekRho" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekSigma" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekTau" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilon" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekPhi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekChi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekPsi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmega" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotadialytika" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilondialytika" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilontonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilondialytikatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalpha" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekbeta" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekgamma" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdelta" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilon" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekzeta" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greektheta" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiota" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekkappa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeklambda" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekmu" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeknu" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekxi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekpi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekrho" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekfinalsigma" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeksigma" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greektau" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilon" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekphi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekchi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekpsi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomega" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotadialytika" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilondiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicrontonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilontonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekthetaalt" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekphialt" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekpialt" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekkoppa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekstigma" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdigamma" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeknumkoppa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeksampi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekrhoalt" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeksigmalunate" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilonalt" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekSigmalunate" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicEgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicYO" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicDJE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicGJE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicIE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicDZE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicII" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicYI" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicJE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicLJE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicNJE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicTSHE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicKJE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicIgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicUSHRT" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicDZHE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicB" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicV" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicG" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicD" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicZH" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicZ" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicI" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicISHRT" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicK" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicL" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicM" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicN" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicO" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicP" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicR" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicS" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicT" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicU" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicF" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicH" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicC" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicCH" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicSH" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicSHCH" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicHRDSN" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicERY" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicSFTSN" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicEREV" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicYU" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicYA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillica" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicb" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicv" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicg" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicd" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillice" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliczh" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicz" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillici" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicishrt" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillick" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicl" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicm" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillico" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicp" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicr" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillics" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillict" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicu" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicf" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillich" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicc" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicch" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicsh" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicshch" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillichrdsn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicery" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicsftsn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicerev" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicyu" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicya" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicyo" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicdje" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicgje" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicie" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicdze" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicii" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicyi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicje" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliclje" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicnje" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillictshe" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillickje" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicigrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicushrt" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicdzhe" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicOMEGA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicomega" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicYAT" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicyat" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicEiotified" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliceiotified" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicLITTLEYUS" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliclittleyus" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicLITTLEYUSiotified" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliclittleyusiotified" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicBIGYUS" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicbigyus" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicBIGYUSiotified" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicbigyusiotified" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicKSI" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicksi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicPSI" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicpsi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicFITA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicfita" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicIZHITSA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicizhitsa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicIZHITSAdoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicizhitsadoublegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicUK" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicuk" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicOMEGAround" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicomegaround" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicOMEGAtitlo" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicomegatitlo" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicOT" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicot" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicKOPPA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillickoppa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicTITLO" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicPALATALIZATION" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicDASIAPNEUMATA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicPSILIPNEUMATA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicISHRTtail" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicishrttail" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicSEMISOFT" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicsemisoft" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicERtick" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicertick" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicGHEupturn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicgheupturn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicGHEstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicghestroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicGHEmidhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicghemidhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicZHEdescender" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliczhedescender" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicZDSC" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliczdsc" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicKADC" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillickadc" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicKAvertstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillickavertstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicKAstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillickastroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicKAbashkir" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillickabashkir" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicENDC" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicendc" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicENGHE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicenghe" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicPEmidhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicpemidhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicHA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicha" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicSDSC" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicsdsc" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicTEDC" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillictedc" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicYstr" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicystr" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicYstrstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicystrstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicHADC" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillichadc" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicTETSE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillictetse" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicCHEDC" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicchedc" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicCHEvertstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicchevertstroke" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicSHHA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicshha" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicCHEabkhasian" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliccheabkhasian" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicCHEDCabkhasian" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicchedcabkhasian" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicPALOCHKA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicZHEbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliczhebreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicKAhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillickahook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicELtail" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliceltail" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicENhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicenhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicENtail" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicentail" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicCHEkhakassian" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicchekhakassian" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicEMtail" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicemtail" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicAbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicabreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicAdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicadiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicAE" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicae" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicEbreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicebreve" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicSCHWA" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicschwa" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicSCHWAdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicschwadiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicZHEdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliczhediaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicZEdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrilliczediaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicDZEabkhasian" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicdzeabkhasian" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicImacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicimacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicIdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicidiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicOdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicodiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicObarred" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicobarred" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicObarreddiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicobarreddiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicEdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicediaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicUmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicumacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicUdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicudiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicUdoubleacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicudoubleacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicCHEdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicchediaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicYERUdiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="cyrillicyerudiaeresis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewAlef" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewBet" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewGimel" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewDalet" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewHe" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewVav" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewZayin" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewHet" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewTet" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewYod" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewKaffinal" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewKaf" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewLamed" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewMemfinal" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewMem" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewNunfinal" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewNun" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewSamekh" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewAyin" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewPefinal" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewPe" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewTsadifinal" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewTsadi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewQof" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewResh" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewShin" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hebrewTav" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Adotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="adotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ahook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ahook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Acircumflexacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="acircumflexacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Acircumflexgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="acircumflexgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Acircumflexhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="acircumflexhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Acircumflextilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="acircumflextilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Acircumflexdotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="acircumflexdotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Abreveacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="abreveacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Abrevegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="abrevegrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Abrevehook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="abrevehook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Abrevetilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="abrevetilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Abrevedotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="abrevedotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Edotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="edotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ehook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ehook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Etilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="etilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ecircumflexacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ecircumflexacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ecircumflexgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ecircumflexgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ecircumflexhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ecircumflexhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ecircumflextilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ecircumflextilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ecircumflexdotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ecircumflexdotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ihook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ihook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Idotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="idotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Odotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="odotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ohook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ohook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ocircumflexacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ocircumflexacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ocircumflexgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ocircumflexgrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ocircumflexhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ocircumflexhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ocircumflextilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ocircumflextilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ocircumflexdotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ocircumflexdotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ohornacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ohornacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ohorngrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ohorngrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ohornhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ohornhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ohorntilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ohorntilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ohorndotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ohorndotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Udotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="udotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uhornacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uhornacute" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uhorngrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uhorngrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uhornhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uhornhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uhorntilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uhorntilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Uhorndotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="uhorndotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ygrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ygrave" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ydotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ydotbelow" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Yhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="yhook" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="Ytilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ytilde" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphapsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphadasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphapsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphadasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphapsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphadasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphapsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphadasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphapsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphadasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphapsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphadasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphapsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphadasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphapsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphadasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilonpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilondasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilonpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilondasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilonpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilondasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilonpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilondasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilonpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilondasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilonpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilondasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketapsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketadasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketapsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketadasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketapsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketadasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketapsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketadasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtapsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtadasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtapsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtadasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtapsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtadasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtapsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtadasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotapsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotadasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotapsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotadasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotapsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotadasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotapsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotadasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotapsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotadasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotapsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotadasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotapsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotadasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotapsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotadasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicronpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicrondasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicronpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicrondasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicronpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicrondasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicronpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicrondasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicronpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicrondasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicronpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicrondasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilonpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilondasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilonpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilondasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilonpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilondasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilonpsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilondasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilondasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilondasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilondasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilondasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegapsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegadasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegapsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegadasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegapsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegadasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegapsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegadasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegapsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegadasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegapsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegadasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegapsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegadasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegapsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegadasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaoxia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilonvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekepsilonoxia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaoxia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotaoxia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicronvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomicronoxia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilonvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilonoxia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaoxia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubdasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubdasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubdasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubpsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubdasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphaiotasubpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphaiotasubdasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphaiotasubpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphaiotasubdasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphaiotasubpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphaiotasubdasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphaiotasubpsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphaiotasubdasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubdasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubdasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubdasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubpsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubdasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtaiotasubpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtaiotasubdasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtaiotasubpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtaiotasubdasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtaiotasubpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtaiotasubdasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtaiotasubpsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtaiotasubdasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubdasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubdasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubdasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubpsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubdasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegaiotasubpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegaiotasubdasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegaiotasubpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegaiotasubdasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegaiotasubpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegaiotasubdasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegaiotasubpsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegaiotasubdasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphavrachy" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphamacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasub" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubtonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekalphaiotasubperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphavrachy" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphamacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekAlphaiotasub" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekCoronis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekprosgegrammeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekpsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdialytikaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasub" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubtonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greeketaiotasubperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilonvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEpsilontonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekEtaiotasub" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekpsilivaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekpsilitonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekpsiliperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotavrachy" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotamacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotadialytikavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotadialytikatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekiotadialytikaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotavrachy" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotamacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekIotatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdasiavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdasiatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdasiaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilonvrachy" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilonmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilondialytikavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilondialytikatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekrhopsili" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekrhodasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilonperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekupsilondialytikaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilonvrachy" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilonmacron" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilonvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekUpsilontonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekRhodasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdialytikavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdialytikatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasub" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubtonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekomegaiotasubperispomeni" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicronvaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmicrontonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegavaria" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegatonos" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekOmegaiotasub" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekoxia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="greekdasia" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="enspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="emspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="threeperemspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="fourperemspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="sixperemspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="figurespace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="punctuationspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="breakablethinspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="hairspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="zerowidthspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="zwnj" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="zwj" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textminus" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="endash" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="emdash" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="texthorizontalbar" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="quoteleft" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="quoteright" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="quotesinglebase" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="quotedblleft" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="quotedblright" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="quotedblbase" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textdag" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textddag" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textbullet" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textellipsis" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="narrownobreakspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="perthousand" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="guilsingleleft" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="guilsingleright" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textfraction" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="medspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textdong" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="texteuro" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textcelsius" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textnumero" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textcircledP" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="trademark" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textounce" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textohm" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textmho" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textkelvin" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="textAngstrom" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="onethird" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="twothirds" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="onefifth" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="twofifths" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="threefifths" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="fourfifths" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="onesixth" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="fivesixths" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="oneeighth" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="threeeighths" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="fiveeighths" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="seveneighths" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanI" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanII" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanIII" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanIV" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanV" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanVI" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanVII" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanVIII" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanIX" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanX" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanXI" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanXII" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanL" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanC" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanD" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanM" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romani" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanii" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romaniii" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romaniv" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanv" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanvi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanvii" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanviii" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanix" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanx" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanxi" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanxii" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanl" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanc" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romand" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="romanm" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="carriagereturn" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ideographicspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ideographichalffillspace" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ffligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="filigature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="flligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="ffiligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="fflligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="stligature" level="document" category="characters" file="char-def.lua"/>
+
+ <cd:command name="zerowidthnobreakspace" level="document" category="characters" file="char-def.lua"/>
+
+</cd:interface> \ 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 @@
<cd:command name="setupdelimitedtext" level="style" category="language" file="typo-del.mkiv">
<cd:arguments>
- <cd:resolve name="keyword-name-list-optional"/>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ <cd:constant type="cd:number" prefix="cd:name" method="range"/>
+ </cd:keywords>
<cd:assignments list="yes">
<cd:parameter name="before">
<cd:constant type="cd:command"/>
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 @@
<cd:constant type="serried"/>
<cd:constant type="hanging"/>
<cd:constant type="top"/>
+ <cd:constant type="empty"/>
<cd:constant type="command"/>
<cd:constant type="cd:name"/>
</cd:parameter>
@@ -129,6 +130,10 @@
<cd:parameter name="headcolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="aligntitle">
+ <cd:constant type="yes" default="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<!-- end construction values -->
</cd:assignments>
</cd:arguments>
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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="doifelsedocumentvariable" level="style" category="structure" file="file-job.mkvi">
+ <cd:arguments>
+ <cd:resolve name="argument-key"/>
+ <cd:resolve name="argument-true"/>
+ <cd:resolve name="argument-false"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="doifdocumentvariableelse" level="style" category="structure" file="file-job.mkvi">
+ <cd:arguments>
+ <cd:resolve name="argument-key"/>
+ <cd:resolve name="argument-true"/>
+ <cd:resolve name="argument-false"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="doifdocumentvariable" level="style" category="structure" file="file-job.mkvi">
+ <cd:arguments>
+ <cd:resolve name="argument-key"/>
+ <cd:resolve name="argument-true"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="doifnotdocumentvariable" level="style" category="structure" file="file-job.mkvi">
+ <cd:arguments>
+ <cd:resolve name="argument-key"/>
+ <cd:resolve name="argument-true"/>
+ </cd:arguments>
+ </cd:command>
+
</cd:interface> \ 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 @@
<cd:constant type="cd:number"/>
</cd:parameter>
<cd:parameter name="rulethickness">
- <cd:constant type="cd:number"/>
+ <cd:constant type="cd:dimension"/>
</cd:parameter>
<cd:parameter name="alternative">
<cd:constant type="normal" default="yes"/>
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 @@
<cd:constant type="serried"/>
<cd:constant type="hanging"/>
<cd:constant type="top" default="yes"/>
+ <cd:constant type="empty"/>
<cd:constant type="command"/>
<cd:constant type="cd:name"/>
</cd:parameter>
@@ -175,6 +176,10 @@
<cd:parameter name="headcolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="aligntitle">
+ <cd:constant type="yes" default="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<!-- end construction values -->
<cd:inherit name="setupcounter"/>
</cd:assignments>
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 @@
</cd:arguments>
</cd:command>
-</cd:interface>
+</cd:interface> \ 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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="fillupto" level="style" category="rules" file="spac-flr.mkiv">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="sym"/>
+ <cd:constant type="symbol"/>
+ <cd:constant type="rule"/>
+ <cd:constant type="width"/>
+ <cd:constant type="space"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:resolve name="argument-text"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="checkedfiller" level="style" category="rules" file="spac-flr.mkiv">
<cd:arguments>
<cd:keywords delimiters="braces">
@@ -207,4 +221,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
</cd:arguments>
</cd:command>
-</cd:interface>
+</cd:interface> \ 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 @@
<cd:constant type="cd:dimension"/>
</cd:parameter>
<cd:parameter name="ntop">
- <cd:constant type="cd:dimension"/>
+ <cd:constant type="cd:number"/>
</cd:parameter>
<cd:parameter name="nbottom">
- <cd:constant type="cd:dimension"/>
+ <cd:constant type="cd:number"/>
</cd:parameter>
<cd:parameter name="step">
<cd:constant type="small"/>
@@ -206,6 +206,7 @@
<cd:constant type="no"/>
</cd:parameter>
<!-- end root only -->
+ <cd:inherit name="setupframed"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -231,9 +232,151 @@
</cd:arguments>
</cd:command>
+ <cd:command name="setupfloatcaption" level="style" category="structure fonts counter" file="strc-flt.mkvi">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:parameter name="suffix">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="suffixseparator">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="suffixstopper">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="location">
+ <cd:constant type="left"/>
+ <cd:constant type="right"/>
+ <cd:constant type="middle"/>
+ <cd:constant type="low"/>
+ <cd:constant type="high"/>
+ <cd:constant type="grid"/>
+ <cd:constant type="lines"/>
+ <cd:constant type="overlay"/>
+ <cd:constant type="inner"/>
+ <cd:constant type="outer"/>
+ <cd:constant type="innermargin"/>
+ <cd:constant type="outermargin"/>
+ <cd:constant type="leftmargin"/>
+ <cd:constant type="rightmargin"/>
+ <cd:constant type="lefthanging"/>
+ <cd:constant type="righthanging"/>
+ <cd:constant type="hang"/>
+ <cd:constant type="top"/>
+ <cd:constant type="bottom" default="yes"/>
+ <cd:constant type="stretch"/>
+ <cd:constant type="tolerant"/>
+ <cd:constant type="verytolerant"/>
+ <cd:constant type="none"/>
+ <cd:constant type="default"/>
+ </cd:parameter>
+ <cd:parameter name="command">
+ <cd:constant type="cd:oneargument"/>
+ </cd:parameter>
+ <cd:parameter name="numbercommand">
+ <cd:constant type="cd:oneargument"/>
+ </cd:parameter>
+ <cd:parameter name="textcommand">
+ <cd:constant type="cd:oneargument"/>
+ </cd:parameter>
+ <cd:parameter name="spacebefore">
+ <cd:inherit name="blank"/>
+ </cd:parameter>
+ <cd:parameter name="spaceinbetween">
+ <cd:inherit name="blank"/>
+ </cd:parameter>
+ <cd:parameter name="spaceafter">
+ <cd:inherit name="blank"/>
+ </cd:parameter>
+ <cd:parameter name="distance">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="headstyle">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="headcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="headseparator">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="inbetween">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="style">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="topoffset">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="bottomoffset">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="number">
+ <cd:constant type="yes" default="yes"/>
+ <cd:constant type="no"/>
+ <cd:constant type="none"/>
+ </cd:parameter>
+ <cd:parameter name="group">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="leftmargin">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="rightmargin">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="innermargin">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="outermargin">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="align">
+ <cd:inherit name="setupalign"/>
+ </cd:parameter>
+ <cd:parameter name="width">
+ <cd:constant type="fit" default="yes"/>
+ <cd:constant type="max"/>
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="minwidth">
+ <cd:constant type="fit" default="yes"/>
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="maxwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:inherit name="setupcounter"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setupcaption" level="style" category="structure fonts counter" file="strc-flt.mkvi">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:inherit name="setupfloatcaption"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setupcaptions" level="style" category="structure fonts counter" file="strc-flt.mkvi">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:inherit name="setupfloatcaption"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
-->
- <cd:command name="setupfloatcaption" level="style" category="structure fonts counter" file="strc-flt.mkvi">
+ <cd:command name="setupcaption" level="style" category="structure fonts counter" file="strc-flt.mkvi">
<cd:arguments>
<cd:resolve name="keyword-name-list-optional"/>
<cd:assignments list="yes">
@@ -253,6 +396,7 @@
<cd:constant type="low"/>
<cd:constant type="high"/>
<cd:constant type="grid"/>
+ <cd:constant type="lines"/>
<cd:constant type="overlay"/>
<cd:constant type="inner"/>
<cd:constant type="outer"/>
@@ -292,7 +436,12 @@
<cd:parameter name="distance">
<cd:constant type="cd:dimension"/>
</cd:parameter>
- <!-- headstyle headcolor headseparator -->
+ <cd:parameter name="headstyle">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="headcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
<cd:parameter name="headseparator">
<cd:constant type="cd:text"/>
</cd:parameter>
@@ -347,24 +496,39 @@
<cd:constant type="cd:dimension"/>
</cd:parameter>
<cd:inherit name="setupcounter"/>
+ <cd:inherit name="setupframed"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command name="setupcaption" level="style" category="structure fonts counter" file="strc-flt.mkvi">
+ <cd:command name="setupcaptions" level="style" category="structure fonts counter" file="strc-flt.mkvi">
<cd:arguments>
<cd:resolve name="keyword-name-list-optional"/>
<cd:assignments list="yes">
- <cd:inherit name="setupfloatcaption"/>
+ <cd:inherit name="setupcaption"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command name="setupcaptions" level="style" category="structure fonts counter" file="strc-flt.mkvi">
+ <!--
+
+ <cd:command name="definefloatframed" level="style" category="structure background" file="strc-flt.mkvi">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupfloatframed"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="setupfloatframed" level="style" category="structure background" file="strc-flt.mkvi">
<cd:arguments>
<cd:resolve name="keyword-name-list-optional"/>
<cd:assignments list="yes">
- <cd:inherit name="setupfloatcaption"/>
+ <cd:inherit name="setupframed"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -796,4 +960,46 @@
</cd:arguments>
</cd:command>
+ <cd:command name="definefacingfloat" level="style" category="structure" file="page-ffl.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupfacingfloat"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setupfacingfloat" level="style" category="structure" file="page-ffl.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:parameter name="inbetween">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="page">
+ <cd:inherit name="page"/>
+ </cd:parameter>
+ <cd:parameter name="spaceinbetween">
+ <cd:inherit name="blank"/>
+ </cd:parameter>
+ <cd:parameter name="style">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:inherit name="setupframed"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="facingfloat" type="environment" level="document" category="structure" file="page-ffl.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="splittext" type="environment" level="document" category="structure" file="tabl-tsp.mkiv"/>
+
</cd:interface>
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 @@
<cd:constant type="cd:number"/>
<cd:constant type="cd:name"/>
</cd:parameter>
+ <cd:parameter name="target">
+ <cd:constant type="cd:number"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
<cd:parameter name="features">
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="factor">
<cd:constant type="cd:number"/>
</cd:parameter>
+ <cd:parameter name="method">
+ <cd:constant type="lowercase"/>
+ <cd:constant type="uppercase"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -332,7 +340,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="subtractfeature" variant="direct" clevel="style" ategory="fonts" file="font-fea.mkvi">
+ <cd:command name="subtractfeature" variant="direct" level="style" category="fonts" file="font-fea.mkvi">
<cd:arguments>
<cd:resolve name="argument-name"/>
</cd:arguments>
@@ -421,7 +429,6 @@
<cd:resolve name="argument-false"/>
</cd:arguments>
</cd:command>
-
<cd:command name="doifcurrentfonthasfeatureelse" level="system" category="fonts conditional" file="font-fea.mkvi">
<cd:arguments>
<cd:resolve name="argument-name"/>
@@ -430,6 +437,29 @@
</cd:arguments>
</cd:command>
+ <cd:command name="doifelsefontfeature" level="system" category="fonts conditional" file="font-fea.mkvi">
+ <cd:arguments>
+ <cd:resolve name="argument-name"/>
+ <cd:resolve name="argument-true"/>
+ <cd:resolve name="argument-false"/>
+ </cd:arguments>
+ </cd:command>
+ <cd:command name="doiffontfeatureelse" level="system" category="fonts conditional" file="font-fea.mkvi">
+ <cd:arguments>
+ <cd:resolve name="argument-name"/>
+ <cd:resolve name="argument-true"/>
+ <cd:resolve name="argument-false"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="doifunknownfontfeature" level="system" category="fonts conditional" file="font-fea.mkvi">
+ <cd:arguments>
+ <cd:resolve name="argument-name"/>
+ <cd:resolve name="argument-true"/>
+ <cd:resolve name="argument-false"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="doaddfeature" level="system" category="fonts" file="font-fea.mkvi">
<cd:arguments>
<cd:resolve name="argument-name-list"/>
@@ -935,7 +965,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="switchstyleonly" clevel="style" ategory="fonts" file="font-ini.mkiv">
+ <cd:command name="switchstyleonly" level="style" category="fonts" file="font-ini.mkiv">
<cd:arguments>
<cd:keywords>
<cd:constant type="rm"/>
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 @@
<cd:command name="placeformula" level="document" category="mathematics" file="strc-mat.mkiv">
<cd:arguments>
<cd:resolve name="keyword-formulareference-list-optional"/>
+ <cd:resolve name="argument-text-optional"/>
</cd:arguments>
</cd:command>
@@ -303,12 +304,14 @@
<cd:arguments>
<cd:resolve name="keyword-formulareference-list-optional"/>
<cd:resolve name="argument-text"/>
+ <cd:resolve name="argument-text-optional"/>
</cd:arguments>
</cd:command>
<cd:command name="placesubformula" level="document" category="mathematics" file="strc-mat.mkiv">
<cd:arguments>
<cd:resolve name="keyword-formulareference-list-optional"/>
+ <cd:resolve name="argument-text-optional"/>
</cd:arguments>
</cd:command>
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 @@
<cd:parameter name="topframe">
<cd:constant type="on" default="yes"/>
<cd:constant type="off"/>
+ <cd:constant type="small"/>
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="bottomframe">
<cd:constant type="on" default="yes"/>
<cd:constant type="off"/>
+ <cd:constant type="small"/>
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="leftframe">
<cd:constant type="on" default="yes"/>
<cd:constant type="off"/>
+ <cd:constant type="small"/>
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="rightframe">
<cd:constant type="on" default="yes"/>
<cd:constant type="off"/>
+ <cd:constant type="small"/>
<cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="region">
@@ -88,6 +92,8 @@
<cd:constant type="on" default="yes"/>
<cd:constant type="off"/>
<cd:constant type="overlay"/>
+ <cd:constant type="small"/>
+ <cd:constant type="closed"/>
<cd:constant type="none"/>
</cd:parameter>
<cd:parameter name="background">
@@ -132,6 +138,9 @@
<cd:constant type="broad" default="yes"/>
<cd:constant type="cd:dimension"/>
</cd:parameter>
+ <cd:parameter name="minheight">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
<cd:parameter name="align">
<cd:inherit name="setupalign"/>
</cd:parameter>
@@ -627,4 +636,12 @@
</cd:arguments>
</cd:command>
+ <cd:command name="doifelseframed" level="system" category="background rules">
+ <cd:arguments>
+ <cd:csname/>
+ <cd:resolve name="argument-true"/>
+ <cd:resolve name="argument-false"/>
+ </cd:arguments>
+ </cd:command>
+
</cd:interface> \ 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 @@
<!-- only passed by the system: -->
<cd:constant type="cd:number"/>
</cd:parameter>
+ <cd:parameter name="transform">
+ <cd:constant type="auto" default="yes"/>
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="userpassword">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="ownerpassword">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -524,4 +534,16 @@
</cd:arguments>
</cd:command>
+ <cd:command name="overlayimage" level="style" category="graphics" file="pack-box.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-file"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="clippedoverlayimage" level="style" category="graphics" file="pack-box.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-file"/>
+ </cd:arguments>
+ </cd:command>
+
</cd:interface> \ 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 @@
<cd:constant type="right" default="yes"/>
<cd:constant type="left"/>
<cd:constant type="outer"/>
+ <cd:constant type="inner"/>
<cd:constant type="columns" default="yes"/>
</cd:keywords>
</cd:arguments>
@@ -174,6 +175,12 @@
<cd:parameter name="color">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="rulecolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="rulethickness">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -186,4 +193,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
<cd:constant type="quotation"/>
<cd:constant type="sentence"/>
<cd:constant type="intersentence"/>
+ <cd:constant type="final"/>
<cd:constant type="cd:name"/>
</cd:keywords>
</cd:arguments>
@@ -92,6 +93,8 @@
<cd:command name="enspace" level="style" category="whitespace" file="spac-hor.mkiv"/>
+ <cd:command name="negenspace" level="style" category="whitespace" file="spac-hor.mkiv"/>
+
<cd:command name="enskip" level="style" category="whitespace" file="spac-hor.mkiv"/>
<cd:command name="quad" level="style" category="whitespace" file="spac-hor.mkiv"/>
@@ -100,6 +103,8 @@
<cd:command name="emspace" level="style" category="whitespace" file="spac-hor.mkiv"/>
+ <cd:command name="negemspace" level="style" category="whitespace" file="spac-hor.mkiv"/>
+
<cd:command name="dotfskip" level="system" category="whitespace" file="spac-hor.mkiv">
<cd:arguments>
<cd:resolve name="argument-dimension"/>
@@ -162,4 +167,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
<cd:constant type="paper"/>
<cd:constant type="attachment"/>
<cd:constant type="layer"/>
+ <cd:constant type="title"/>
</cd:parameter>
<cd:parameter name="copies">
<cd:constant type="cd:number"/>
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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="defineperiodkerning" level="style" catgeory="fonts whitespace" file="typo-pnc.mkic">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupperiodkerning"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setupperiodkerning" level="style" catgeory="fonts whitespace" file="typo-pnc.mkic">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:parameter name="factor">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setperiodkerning" level="style" catgeory="fonts whitespace" file="typo-pnc.mkic">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="reset"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="resetperiodkerning" level="style" catgeory="fonts whitespace" file="typo-pnc.mkic"/>
+
</cd:interface> \ 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 @@
<cd:constant type="serried"/>
<cd:constant type="hanging"/>
<cd:constant type="top"/>
+ <cd:constant type="empty"/>
<cd:constant type="command"/>
<cd:constant type="intext" default="yes"/>
<cd:constant type="cd:name"/>
@@ -176,6 +177,10 @@
<cd:parameter name="headcolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="aligntitle">
+ <cd:constant type="yes" default="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<!-- end construction values -->
<cd:inherit name="setupcounter"/>
</cd:assignments>
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 @@
<cd:parameter name="date">
<cd:inherit name="currentdate"/>
</cd:parameter>
+ <cd:parameter name="time">
+ <cd:inherit name="currenttime"/>
+ </cd:parameter>
<cd:parameter name="patterns">
<cd:constant type="cd:file"/>
</cd:parameter>
@@ -61,6 +64,7 @@
</cd:parameter>
<cd:parameter name="font">
<cd:constant type="auto"/>
+ <cd:constant type="cd:name"/>
</cd:parameter>
<cd:parameter name="bidi">
<cd:constant type="left"/>
@@ -174,6 +178,12 @@
</cd:arguments>
</cd:command>
+ <cd:command name="language" type="environment" level="document" category="language" file="lang-ini.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-language"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="mainlanguage" level="style" category="language" file="lang-ini.mkiv">
<cd:arguments>
<cd:resolve name="keyword-language"/>
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 @@
</cd:parameter>
<cd:parameter name="cropoffset">
<cd:constant type="cd:dimension"/>
+ <cd:constant type="auto"/>
</cd:parameter>
<cd:parameter name="trimoffset">
<cd:constant type="cd:dimension"/>
@@ -367,14 +368,14 @@
<cd:command name="spread" type="environment" level="document" category="layout" file="page-spr.mkiv"/>
- <cd:command name="doifelsetopofpage" level="system" category="layout conditional" file="page-lay.mkiv">
+ <cd:command name="doifelsetopofpage" level="system" category="layout conditional" file="page-ini.mkiv">
<cd:arguments>
<cd:resolve name="argument-true"/>
<cd:resolve name="argument-false"/>
</cd:arguments>
</cd:command>
- <cd:command name="doiftopofpageelse" level="system" category="layout conditional" file="page-lay.mkiv">
+ <cd:command name="doiftopofpageelse" level="system" category="layout conditional" file="page-ini.mkiv">
<cd:arguments>
<cd:resolve name="argument-true"/>
<cd:resolve name="argument-false"/>
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?context-directive job ctxfile x-setups.ctx ?>
+
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands">
+
+ <cd:command name="definelinefiller" level="style" category="rules metapost" file="node-rul.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuplinefiller"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setuplinefiller" level="style" category="rules metapost" file="node-rul.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:parameter name="location">
+ <cd:constant type="left"/>
+ <cd:constant type="right"/>
+ <cd:constant type="both" default="yes"/>
+ </cd:parameter>
+ <cd:parameter name="scope">
+ <cd:constant type="left"/>
+ <cd:constant type="right"/>
+ <cd:constant type="local" default="yes"/>
+ <cd:constant type="global"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="height">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="depth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="distance">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="threshold">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="rulethickness">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <!-- cd:parameter name="method">
+ <cd:constant type="cd:number"/>
+ </cd:parameter -->
+ <cd:parameter name="textstyle">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="textcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="align">
+ <cd:inherit name="setupalign"/>
+ </cd:parameter>
+ <cd:parameter name="mp">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="before">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="after">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setuplinefillers" level="style" category="rules metapost" file="node-rul.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:inherit name="setuplinefiller"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="linefiller" type="environment" level="style" category="rules metapost" file="node-rul.mkiv">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="filler"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuplinefiller"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setlinefiller" level="style" category="rules metapost" file="node-rul.mkiv">
+ <cd:arguments>
+ <cd:keywords>
+ <cd:constant type="filler"/>
+ <cd:constant type="cd:name"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+
+</cd:interface>
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 @@
<cd:parameter name="width">
<cd:constant type="fit"/>
<cd:constant type="broad"/>
- <cd:constant type="auto"/>
+ <!--
+ <cd:constant type="auto"/>
+ -->
<cd:constant type="cd:dimension"/>
</cd:parameter>
<cd:parameter name="height">
@@ -386,7 +388,7 @@
<cd:resolve name="keyword-name"/>
<cd:resolve name="keyword-list-list"/>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -395,7 +397,55 @@
<cd:arguments>
<cd:resolve name="keyword-list"/>
<cd:assignments list="yes">
- <cd:inherit name="setuplist"/>
+ <cd:parameter name="criterium">
+ <cd:constant type="local" default="yes"/>
+ <cd:constant type="intro"/>
+ <cd:constant type="reference"/>
+ <cd:constant type="reference" prefix="cd:sectionblock" method="range"/>
+ <cd:constant type="all"/>
+ <cd:constant type="all" prefix="cd:sectionblock" method="range"/>
+ <cd:constant type="text"/>
+ <cd:constant type="text" prefix="cd:sectionblock" method="range"/>
+ <cd:constant type="current"/>
+ <cd:constant type="current" prefix="cd:sectionblock" method="range"/>
+ <cd:constant type="here"/>
+ <cd:constant type="previous"/>
+ <cd:constant type="previous" prefix="cd:sectionblock" method="range"/>
+ <cd:constant type="component"/>
+ <cd:constant type="cd:section"/>
+ <cd:constant type="cd:section" prefix="cd:sectionblock" method="range"/>
+ </cd:parameter>
+ <cd:parameter name="reference">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="extras">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="order">
+ <cd:constant type="command"/>
+ <cd:constant type="all"/>
+ <cd:constant type="title"/>
+ </cd:parameter>
+ <cd:parameter name="alternative">
+ <cd:constant type="a"/>
+ <cd:constant type="b" default="yes"/>
+ <cd:constant type="c"/>
+ <cd:constant type="d"/>
+ <cd:constant type="e"/>
+ <cd:constant type="f"/>
+ <cd:constant type="g"/>
+ <cd:constant type="left"/>
+ <cd:constant type="right"/>
+ <cd:constant type="top"/>
+ <cd:constant type="bottom"/>
+ <cd:constant type="command"/>
+ <cd:constant type="none"/>
+ <cd:constant type="interactive"/>
+ <cd:constant type="paragraph"/>
+ <cd:constant type="horizontal"/>
+ <cd:constant type="vertical"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -404,7 +454,7 @@
<cd:arguments>
<cd:resolve name="keyword-list"/>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -416,7 +466,7 @@
</cd:sequence>
<cd:arguments>
<cd:assignments list="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
<cd:instances>
@@ -431,7 +481,7 @@
</cd:sequence>
<cd:arguments>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
<cd:instances>
@@ -446,7 +496,7 @@
</cd:sequence>
<cd:arguments>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuplist"/>
+ <cd:inherit name="setupcombinedlist"/>
</cd:assignments>
</cd:arguments>
<cd:instances>
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 @@
<cd:parameter name="align">
<cd:constant type="l2r" default="yes"/>
<cd:constant type="r2l"/>
+ <cd:constant type="righttoleft"/>
</cd:parameter>
<cd:parameter name="bidi">
<cd:constant type="yes"/>
@@ -109,6 +110,17 @@
<cd:parameter name="ampersand">
<cd:constant type="normal"/>
</cd:parameter>
+ <cd:parameter name="collapsing">
+ <cd:constant type="1"/>
+ <cd:constant type="2"/>
+ <cd:constant type="3" default="yes"/>
+ <cd:constant type="none"/>
+ <cd:constant type="reset"/>
+ </cd:parameter>
+ <cd:parameter name="kernpairs">
+ <cd:constant type="yes"/>
+ <cd:constant type="no" default="yes"/>
+ </cd:parameter>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -499,4 +511,4 @@
</cd:arguments>
</cd:command>
-</cd:interface>
+</cd:interface> \ 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 @@
<cd:parameter name="method">
<cd:constant type="auto"/>
</cd:parameter>
+ <cd:parameter name="size">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
<cd:parameter name="factor">
<cd:constant type="none"/>
<cd:constant type="auto"/>
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 @@
-->
+ <cd:command name="mathmatrix" generated="yes" level="document" category="mathematics tables" file="math-ali.mkiv">
+ <cd:sequence>
+ <cd:variable value="mathmatrix"/>
+ </cd:sequence>
+ <cd:arguments>
+ <cd:content/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="matrices" type="environment" level="document" category="mathematics tables" file="math-ali.mkiv">
<cd:arguments>
<cd:assignments list="yes" optional="yes">
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?context-directive job ctxfile x-setups.ctx ?>
+
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands">
+
+ <cd:command name="mathhash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mathdollar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mathpercent" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mathampersand" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lparent" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rparent" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ast" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mathhyphen" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="colon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lt" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gt" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lbracket" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="backslash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rbracket" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Hat" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="grave" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lbrace" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rbrace" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="yen" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="S" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ddot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="pm" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="acute" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="P" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="centerdot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="times" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eth" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="div" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lambdabar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="hat" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="check" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="breve" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="dot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ring" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="tilde" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="widehat" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="widetilde" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="not" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Alpha" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Beta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Gamma" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Delta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Epsilon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Zeta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Eta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Theta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Iota" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Kappa" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Lambda" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Mu" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Nu" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Xi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Omicron" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Pi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Rho" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Sigma" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Tau" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Upsilon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Phi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Chi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Psi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Omega" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="alpha" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="beta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gamma" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="delta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="varepsilon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="zeta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="theta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="iota" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="kappa" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lambda" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mu" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nu" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="xi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="omicron" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="pi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rho" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="varsigma" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sigma" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="tau" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="upsilon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="varphi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="chi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="psi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="omega" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="varTheta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="phi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="varpi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="digamma" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="varkappa" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="epsilon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="backepsilon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bullet" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="prime" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="doubleprime" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="tripleprime" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="reversedprime" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="reverseddoubleprime" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="reversedtripleprime" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="quadrupleprime" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="invisibletimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="positivesign" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="negativesign" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="vec" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="dddot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigsquare" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigdiamond" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="actuarial" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="complexes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Eulerconst" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Plankconst" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Im" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ell" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="naturalnumbers" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="wp" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="primes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rationals" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Re" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="reals" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="integers" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ohm" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mho" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="turnediota" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Angstrom" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Finv" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="aleph" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="beth" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gimel" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="daleth" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Game" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sansLturned" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sansLmirrored" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Yup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="differentialD" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="differentiald" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="exponentiale" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="imaginaryi" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="imaginaryj" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="PropertyLine" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="upand" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="uparrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="downarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="updownarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nwarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="searrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="swarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftwavearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightwavearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="twoheadleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="twoheaduparrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="twoheadrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="twoheaddownarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftarrowtail" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightarrowtail" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mapsfrom" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mapsup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mapsto" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mapsdown" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="updownarrowbar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="hookleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="hookrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="looparrowleft" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="looparrowright" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftrightsquigarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nleftrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="downzigzagarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Lsh" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Rsh" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Ldsh" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Rdsh" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="linefeed" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="carriagereturn" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="curvearrowleft" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="curvearrowright" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="barovernorthwestarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="barleftarrowrightarrowbar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftharpoonup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftharpoondown" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="upharpoonleft" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightharpoonup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightharpoondown" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="downharpoonright" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="downharpoonleft" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightleftarrows" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="updownarrows" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftrightarrows" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftleftarrows" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="upuparrows" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightrightarrows" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="downdownarrows" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftrightharpoons" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightleftharpoons" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nLeftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nLeftrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nRightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Leftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Uparrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Downarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Leftrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Updownarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Nwarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Nearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Searrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Swarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Lleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Rrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftsquigarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nHuparrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nHdownarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftdasharrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="updasharrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="downdasharrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="barleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightarrowbar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftwhitearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="upwhitearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightwhitearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="downwhitearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="whitearrowupfrombar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="circleonrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="downuparrows" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightthreearrows" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nvleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nvrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nvleftrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nVleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nVrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nVleftrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftarrowtriangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightarrowtriangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftrightarrowtriangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="forall" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="complement" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="partial" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="exists" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nexists" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="emptyset" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nabla" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="in" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="prod" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="coprod" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sum" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="mp" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="dotplus" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="diagup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="diagdown" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ast" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="circ" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="propto" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="infty" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="angle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="measuredangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sphericalangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="divides" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nparallel" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="cap" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="cup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="oint" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="oiint" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="oiiint" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="intclockwise" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ointclockwise" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ointctrclockwise" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="therefore" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="because" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="colon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="squaredots" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="dotminus" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="minuscolon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="backsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="wr" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eqsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="simeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsimeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="approxnEq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="approx" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="napprox" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="approxeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="asymp" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Bumpeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="doteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="fallingdotseq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="risingdotseq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="colonequals" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="equalscolon" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eqcirc" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="circeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="wedgeeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="veeeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="stareq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="triangleq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="definedeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="measuredeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="questionedeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="equiv" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nequiv" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="geqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lneqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gneqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ll" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gg" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="between" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nasymp" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nless" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ngtr" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nleq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ngeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lesssim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gtrsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nlesssim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ngtrsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lessgtr" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gtrless" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nlessgtr" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ngtrless" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="prec" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succ" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="preccurlyeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succcurlyeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="precsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nprec" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsucc" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="subset" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="supset" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsubset" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsupset" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="subseteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="supseteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsubseteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsupseteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="subsetneq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="supsetneq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="uplus" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sqsubset" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sqsupset" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sqsubseteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sqsupseteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sqcap" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sqcup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="oplus" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ominus" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="otimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="oslash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="odot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="circledcirc" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="circledast" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="circledequals" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="circleddash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="boxplus" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="boxminus" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="boxtimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="boxdot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="vdash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="dashv" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="top" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="models" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="vDash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Vdash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Vvdash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="VDash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nvdash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nvDash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nVdash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nVDash" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="multimap" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="intercal" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="veebar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="barwedge" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigwedge" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigvee" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigcap" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigcup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="diamond" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="star" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="divideontimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ltimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rtimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leftthreetimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rightthreetimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="curlyvee" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="curlywedge" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Subset" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Supset" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="pitchfork" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lessdot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gtrdot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lesseqgtr" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gtreqless" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eqless" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eqgtr" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="curlyeqprec" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="curlyeqsucc" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="npreccurlyeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsucccurlyeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsqsubseteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nsqsupseteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sqsubsetneq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sqsupsetneq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lnsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gnsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="precnsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succnsim" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ntriangleright" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ntriangleleft" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ntrianglelefteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ntrianglerighteq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="vdots" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="cdots" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="udots" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ddots" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lceil" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rceil" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lfloor" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rfloor" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="ulcorner" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="urcorner" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="llcorner" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lrcorner" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="frown" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="smile" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lmoustache" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rmoustache" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="overbracket" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="underbracket" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="overparent" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="underparent" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="overbrace" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="underbrace" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="circledR" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="circledS" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="blacksquare" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="blacktriangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="blacktriangleright" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="triangleright" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="blacktriangledown" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="blacktriangleleft" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="triangleleft" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lozenge" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigcirc" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigstar" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="spadesuit" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="heartsuit" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="diamondsuit" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="clubsuit" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="blacklozenge" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="flat" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="natural" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="sharp" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="checkmark" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="maltese" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="llbracket" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rrbracket" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="langle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="llangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rrangle" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lgroup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rgroup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="longleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="longrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="longleftrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Longleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Longrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Longleftrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="longmapsfrom" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="longmapsto" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Longmapsfrom" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Longmapsto" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="longrightsquigarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Mapsfrom" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Mapsto" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Uuparrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="Ddownarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="dashedleftarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="dashedrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="dottedrightarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="twoheadrightarrowtail" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="nwsearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="neswarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lhooknwarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rhooknearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lhooksearrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rhookswarrow" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigodot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigoplus" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigotimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigudot" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="biguplus" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigsqcap" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigsqcup" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="bigtimes" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="amalg" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="coloncolonequals" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eqeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eqeqeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="leqslant" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="geqslant" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lessapprox" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gtrapprox" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lneq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="rneq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lnapprox" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gnapprox" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="lesseqqgtr" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="gtreqqless" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eqslantless" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="eqslantgtr" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="preceq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succeq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="precneq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succneq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="preceqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succeqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="precneqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succneqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="precapprox" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succapprox" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="precnapprox" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="succnapprox" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="subseteqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="supseteqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="subsetneqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="supsetneqq" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="backprime" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="imath" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="jmath" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="vartheta" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="varkappa" level="document" category="character mathematics" file="char-def.lua"/>
+
+ <cd:command name="varrho" level="document" category="character mathematics" file="char-def.lua"/>
+
+</cd:interface> \ 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 @@
<cd:constant type="right" prefix="cd:number" method="factor"/>
<cd:constant type="reset"/>
<cd:constant type="reverse"/>
- </cd:keywords>
+ </cd:keywords>
</cd:arguments>
</cd:command>
@@ -100,7 +100,7 @@
<cd:constant type="right" prefix="cd:number" method="factor"/>
<cd:constant type="reset"/>
<cd:constant type="reverse"/>
- </cd:keywords>
+ </cd:keywords>
</cd:arguments>
</cd:command>
@@ -118,7 +118,7 @@
<cd:constant type="right" prefix="cd:number" method="factor"/>
<cd:constant type="reset"/>
<cd:constant type="reverse"/>
- </cd:keywords>
+ </cd:keywords>
</cd:arguments>
</cd:command>
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 @@
<cd:parameter name="headcolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="aligntitle">
+ <cd:constant type="yes" default="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<!-- end construction values -->
<cd:inherit name="setupcounter"/>
</cd:assignments>
@@ -467,6 +471,8 @@
<cd:command name="flushnotes" level="style" category="structure notes" file="strc-not.mkvi"/>
+ <cd:command name="postponingnotes" type="environment" category="structure notes" file="strc-not.mkvi"/>
+
<cd:command name="doifelsenoteonsamepage" level="system" category="structure notes conditional" file="strc-not.mkvi">
<cd:arguments>
<cd:resolve name="argument-name"/>
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?context-directive job ctxfile x-setups.ctx ?>
+
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands">
+
+ <cd:command name="definepagecolumns" level="style" category="structure layout" file="page-pcl.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagecolumns"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setuppagecolumns" level="style" category="structure layout" file="page-pcl.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:parameter name="separator">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="direction">
+ <cd:constant type="normal" default="yes"/>
+ <cd:constant type="reverse"/>
+ </cd:parameter>
+ <cd:parameter name="distance">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="n">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="maxwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <!--
+ <cd:parameter name="maxheight">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="step">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ -->
+ <cd:parameter name="align">
+ <cd:inherit name="setupalign"/>
+ </cd:parameter>
+ <cd:parameter name="blank">
+ <cd:inherit name="blank"/>
+ </cd:parameter>
+ <!--
+ <cd:parameter name="profile">
+ <cd:inherit name="setprofile"/>
+ </cd:parameter>
+ -->
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="setups">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="page">
+ <cd:inherit name="page"/>
+ </cd:parameter>
+ <cd:inherit name="setupframed"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="pagecolumns" type="environment" variant="name" level="document" category="structure layout" file="page-pcl.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-optional"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="pagecolumns" type="environment" level="document" category="structure layout" file="page-pcl.mkiv">
+ <cd:arguments>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagecolumns"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="pagecolumns" type="environment" generated="yes" variant="instance" level="document" category="structure layout" file="page-pcl.mkiv">
+ <cd:sequence>
+ <cd:instance value="pagecolumns"/>
+ </cd:sequence>
+ </cd:command>
+
+</cd:interface>
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 @@
<cd:interface xmlns:cd="http://www.pragma-ade.com/commands">
- <cd:command name="definepagegrid" level="style" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="definepagegrid" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagegrid"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="definecolumnset" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
<cd:resolve name="keyword-name-optional"/>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegrid"/>
+ <cd:inherit name="setupcolumnset"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command name="setuppagegrid" level="style" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="setuppagegrid" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ <cd:constant type="cd:number" prefix="cd:name" method="range"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:parameter name="n">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="nleft">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="nright">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="width">
+ <cd:constant type="cd:dimension"/>
+ <cd:constant type="auto"/>
+ </cd:parameter>
+ <cd:parameter name="distance">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="lines">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="maxwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="maxheight">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="direction">
+ <cd:constant type="normal" default="yes"/>
+ <cd:constant type="reverse"/>
+ </cd:parameter>
+ <cd:parameter name="page">
+ <cd:inherit name="page"/>
+ </cd:parameter>
+ <cd:inherit name="setupframed"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="setupcolumnset" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
- <cd:resolve name="keyword-name-list-optional"/>
+ <cd:keywords list="yes" optional="yes">
+ <cd:constant type="cd:name"/>
+ <cd:constant type="cd:number" prefix="cd:name" method="range"/>
+ </cd:keywords>
<cd:assignments list="yes">
<cd:parameter name="n">
<cd:constant type="cd:number"/>
@@ -27,6 +92,7 @@
<cd:parameter name="nright">
<cd:constant type="cd:number"/>
</cd:parameter>
+ <!-- begin of values which can be set for each column -->
<cd:parameter name="width">
<cd:constant type="cd:dimension"/>
<cd:constant type="auto"/>
@@ -34,6 +100,7 @@
<cd:parameter name="distance">
<cd:constant type="cd:dimension"/>
</cd:parameter>
+ <!-- end of values which can be set for each column -->
<cd:parameter name="lines">
<cd:constant type="cd:number"/>
</cd:parameter>
@@ -55,57 +122,121 @@
</cd:arguments>
</cd:command>
- <cd:command name="pagegrid" type="environment" generated="yes" variant="example" level="document" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="pagegrid" type="environment" generated="yes" variant="example" level="document" category="layout" file="page-cst.mkiv">
+ <cd:sequence>
+ <cd:variable value="pagegrid"/>
+ </cd:sequence>
+ <cd:arguments>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagegrid"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="pagegrid" type="environment" level="document" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagegrid"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="columnset" type="environment" generated="yes" variant="example" level="document" category="layout" file="page-cst.mkiv">
<cd:sequence>
- <cd:variable value="pagegrid"/>
+ <cd:variable value="columnset"/>
</cd:sequence>
<cd:arguments>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegrid"/>
+ <cd:inherit name="setupcolumnset"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command name="pagegrid" type="environment" level="document" category="layout" file="page-cst.mkiv">
+ <cd:command name="columnset" type="environment" level="document" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name-optional"/>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegrid"/>
+ <cd:inherit name="setupcolumnset"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command name="setpagegrid" level="document" category="layout" file="page-cst.mkiv">
- <cd:arguments>
- <cd:assignments list="yes" optional="yes">
- <cd:parameter name="c">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="r">
- <cd:constant type="cd:number"/>
- </cd:parameter>
- <cd:parameter name="option">
- <cd:constant type="none" default="yes"/>
- <!--
+ <!--
+
+ <cd:command name="setpagegrid" level="document" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:assignments list="yes" optional="yes">
+ <cd:parameter name="c">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="r">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="option">
+ <cd:constant type="none" default="yes"/>
<cd:constant type="wide"/>
- -->
- </cd:parameter>
- </cd:assignments>
- <cd:content/>
- </cd:arguments>
- </cd:command>
+ </cd:parameter>
+ </cd:assignments>
+ <cd:content/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="definepagegridspan" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagegridspan"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
- <cd:command name="definepagegridspan" level="style" category="layout" file="page-cst.mkiv">
+ <cd:command name="definecolumnsetspan" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
<cd:resolve name="keyword-name-optional"/>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegridspan"/>
+ <cd:inherit name="setupcolumnsetspan"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command name="setuppagegridspan" level="style" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="setuppagegridspan" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:parameter name="n">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="style">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="before">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="after">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:inherit name="setupframed"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="setupcolumnsetspan" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name-list-optional"/>
<cd:assignments list="yes">
@@ -129,32 +260,111 @@
</cd:arguments>
</cd:command>
- <cd:command name="pagegridspan" type="environment" level="document" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="pagegridspan" type="environment" level="document" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagegridspan"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="columnsetspan" type="environment" level="document" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegridspan"/>
+ <cd:inherit name="setupcolumnsetspan"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command name="pagegridspanwidth" level="style" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="pagegridspanwidth" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-number"/>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="columnsetspanwidth" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="argument-number"/>
</cd:arguments>
</cd:command>
- <cd:command name="definepagegridarea" level="style" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="definepagegridarea" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setuppagegridarea"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="definecolumnsetarea" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
<cd:resolve name="keyword-name-optional"/>
<cd:assignments list="yes" optional="yes">
- <cd:inherit name="setuppagegridarea"/>
+ <cd:inherit name="setupcolumnsetarea"/>
</cd:assignments>
</cd:arguments>
</cd:command>
- <cd:command name="setuppagegridarea" level="style" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="setuppagegridarea" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:parameter name="state">
+ <cd:constant type="start"/>
+ <cd:constant type="stop" default="yes"/>
+ <cd:constant type="repeat"/>
+ </cd:parameter>
+ <cd:parameter name="x">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="y">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="nx">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="ny">
+ <cd:constant type="cd:number"/>
+ </cd:parameter>
+ <cd:parameter name="style">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="clipoffset">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="rightoffset">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:inherit name="setupframed"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="setupcolumnsetarea" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name-list-optional"/>
<cd:assignments list="yes">
@@ -192,14 +402,38 @@
</cd:arguments>
</cd:command>
- <cd:command name="setuppagegridareatext" level="style" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="setuppagegridareatext" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-text"/>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="setupcolumnsetareatext" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
<cd:resolve name="keyword-text"/>
</cd:arguments>
</cd:command>
- <cd:command name="setuppagegridlines" level="style" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="setuppagegridlines" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-number"/>
+ <cd:resolve name="keyword-number"/>
+ <cd:resolve name="keyword-number"/>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="setupcolumnsetlines" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
<cd:resolve name="keyword-number"/>
@@ -208,7 +442,20 @@
</cd:arguments>
</cd:command>
- <cd:command name="setuppagegridstart" level="style" category="layout" file="page-cst.mkiv">
+ <!--
+
+ <cd:command name="setuppagegridstart" level="style" category="layout" file="page-cst.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-number"/>
+ <cd:resolve name="keyword-number"/>
+ <cd:resolve name="keyword-number"/>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="setupcolumnsetstart" level="style" category="layout" file="page-cst.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
<cd:resolve name="keyword-number"/>
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 @@
<cd:interface xmlns:cd="http://www.pragma-ade.com/commands">
- <cd:command name="markpage" level="style" file="page-lay.mkiv">
+ <cd:command name="markpage" level="style" file="page-ini.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
- <cd:keywords optional="yes">
+ <cd:keywords list="yes" optional="yes">
<cd:constant type="cd:number" prefix="cd:sign" method="none"/>
</cd:keywords>
</cd:arguments>
</cd:command>
- <cd:command name="doifelsemarkedpage" level="style" category="conditional" file="page-lay.mkiv">
+ <cd:command name="markedpages" level="style" file="page-ini.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="markpages" type="environment" level="style" file="page-ini.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="doifelsemarkedpage" level="style" category="conditional" file="page-ini.mkiv">
<cd:arguments>
<cd:resolve name="argument-name"/>
<cd:resolve name="argument-true"/>
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 @@
<cd:interface xmlns:cd="http://www.pragma-ade.com/commands">
+ <cd:command name="signalrightpage" level="system" file="spac-pag.mkiv"/>
+
+ <cd:command name="doifelserightpage" level="system" file="spac-pag.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-true"/>
+ <cd:resolve name="argument-false"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="rightpageorder" level="system" file="spac-pag.mkiv"/>
+
<cd:command name="definepagestate" level="system" file="core-dat.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
@@ -56,4 +67,32 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+ <cd:command name="pagestaterealpageorder" level="system" file="core-dat.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-name"/>
+ <cd:keywords delimiters="braces">
+ <cd:constant type="cd:name"/>
+ <cd:constant type="cd:number"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="autopagestaterealpage" level="system" file="core-dat.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-name"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setautopagestaterealpageno" level="system" file="core-dat.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-name"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="autopagestaterealpageorder" level="system" file="core-dat.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-name"/>
+ </cd:arguments>
+ </cd:command>
+
+</cd:interface>
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index ee6712cfd..a0a875e51 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files 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 @@
<cd:constant type="all"/>
<cd:constant type="packed"/>
</cd:parameter>
+ <cd:parameter name="check">
+ <cd:constant type="yes" default="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<cd:parameter name="criterium">
<cd:constant type="local"/>
<cd:constant type="text"/>
@@ -162,6 +166,12 @@
<cd:parameter name="pagecolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="pageleft">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="pageright">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
<cd:parameter name="n">
<cd:constant type="cd:number"/>
</cd:parameter>
@@ -215,6 +225,10 @@
<cd:constant type="no" default="yes"/>
<cd:constant type="all"/>
</cd:parameter>
+ <cd:parameter name="check">
+ <cd:constant type="yes" default="yes"/>
+ <cd:constant type="no"/>
+ </cd:parameter>
<cd:parameter name="criterium">
<cd:constant type="local"/>
<cd:constant type="text"/>
@@ -328,6 +342,12 @@
<cd:parameter name="pagecolor">
<cd:constant type="cd:color"/>
</cd:parameter>
+ <cd:parameter name="pageleft">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="pageright">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
<cd:parameter name="n">
<cd:constant type="cd:number"/>
</cd:parameter>
@@ -544,7 +564,7 @@
</cd:keywords>
<cd:index list="yes"/>
</cd:arguments>
- </cd:command>
+ </cd:command>
<cd:command name="stopregister" level="document" category="structure" file="strc-reg.mkiv">
<cd:arguments>
@@ -664,4 +684,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
<cd:constant type="top" default="yes"/>
<cd:constant type="left"/>
<cd:constant type="right"/>
+ <cd:constant type="none"/>
</cd:parameter>
<cd:parameter name="align">
<cd:constant type="auto"/>
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 @@
<cd:constant type="fit"/>
<cd:constant type="broad"/>
<cd:constant type="max"/>
+ <cd:constant type="min"/>
<cd:constant type="auto"/>
<cd:constant type="default"/>
</cd:parameter>
@@ -51,6 +52,7 @@
<cd:constant type="fit"/>
<cd:constant type="broad"/>
<cd:constant type="max"/>
+ <cd:constant type="min"/>
<cd:constant type="auto"/>
<cd:constant type="default"/>
</cd:parameter>
@@ -58,6 +60,7 @@
<cd:constant type="fit"/>
<cd:constant type="broad"/>
<cd:constant type="max"/>
+ <cd:constant type="min"/>
<cd:constant type="auto"/>
<cd:constant type="default"/>
</cd:parameter>
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 @@
<cd:command name="setscript" level="style" category="language" file="scrp-ini.mkvi">
<cd:arguments>
- <cd:keywords>
- <cd:constant type="hangul"/>
- <cd:constant type="hanzi"/>
- <cd:constant type="nihongo"/>
- <cd:constant type="ethiopic"/>
- <cd:constant type="thai"/>
- <cd:constant type="test"/>
- <cd:constant type="cd:name"/>
- </cd:keywords>
+ <cd:resolve name="keyword-script"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setlocalscript" level="style" category="language" file="scrp-ini.mkvi">
+ <cd:arguments>
+ <cd:resolve name="keyword-script"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setglobalscript" level="style" category="language" file="scrp-ini.mkvi">
+ <cd:arguments>
+ <cd:resolve name="keyword-script"/>
</cd:arguments>
</cd:command>
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 @@
<cd:command name="headsetupspacing" level="system" category="structure" file="strc-ren.mkiv"/>
-</cd:interface>
+</cd:interface> \ 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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="copysetups" level="system" file="core-env.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="showsetupsdefinition" level="system" file="core-env.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
@@ -221,4 +228,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
</cd:sequence>
</cd:command>
- <cd:command name="startstop" type="environment" level="document" category="structure" file="core-sys.mkiv">
- <cd:sequence>
- <cd:string value="​"/><!-- value="zero width space -->
- </cd:sequence>
+ <!--
+
+ Variant 1: <cd:string value="zero width space"/>
+
+ <cd:command name="startstop" type="environment" level="document" category="structure" file="core-sys.mkiv">
+ <cd:sequence>
+ <cd:string value="​"/>
+ </cd:sequence>
+ <cd:arguments>
+ <cd:resolve name="keyword-name-optional"/>
+ </cd:arguments>
+ </cd:command>
+
+ Variant 2: <cd:delimiter name="stop"/>
+
+ <cd:command name="start" level="document" category="structure" file="core-sys.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:resolve name="string-content"/>
+ <cd:delimiter name="stop"/>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="" type="environment" level="document" category="structure" file="core-sys.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name-optional"/>
</cd:arguments>
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 @@
<cd:command name="setfontstrut" level="system" file="spac-ver.mkiv"/>
+ <cd:command name="settightstrut" level="system" file="spac-ver.mkiv"/>
+
<cd:command name="setcapstrut" level="system" file="spac-ver.mkiv"/>
<cd:command name="setnostrut" level="system" file="spac-ver.mkiv"/>
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 @@
<cd:command name="symbolset" type="environment" level="style" category="symbols" file="symb-ini.mkiv">
<cd:arguments>
<cd:resolve name="keyword-name"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:parameter name="font">
+ <cd:constant type="cd:font"/>
+ </cd:parameter>
+ </cd:assignments>
</cd:arguments>
</cd:command>
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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="firstinlist" level="system" file="syst-aux.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-command-list"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="dogetcommacommandelement" level="system" file="syst-aux.mkiv">
<cd:arguments>
<cd:resolve name="string-number"/>
@@ -1641,7 +1647,7 @@
<cd:command name="increment" variant="argument" level="system" file="syst-aux.mkiv">
<cd:arguments>
- <cd:keywords delimiters="parentheses" list="yes">
+ <cd:keywords delimiters="parenthesis" list="yes">
<cd:constant type="cd:csname"/>
<cd:constant type="cd:number"/>
</cd:keywords>
@@ -1656,7 +1662,7 @@
<cd:command name="decrement" variant="argument" level="system" file="syst-aux.mkiv">
<cd:arguments>
- <cd:keywords delimiters="parentheses" list="yes">
+ <cd:keywords delimiters="parenthesis" list="yes">
<cd:constant type="cd:csname"/>
<cd:constant type="cd:number"/>
</cd:keywords>
@@ -1834,6 +1840,22 @@
</cd:arguments>
</cd:command>
+ <cd:command name="doifelseassignmentcs" level="system" file="syst-aux.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-text"/>
+ <cd:csname/>
+ <cd:csname/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="doifassignmentelsecs" level="system" file="syst-aux.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-text"/>
+ <cd:csname/>
+ <cd:csname/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="convertargument" level="system" file="syst-aux.mkiv">
<cd:arguments>
<cd:resolve name="string-text"/>
@@ -3601,6 +3623,31 @@
</cd:arguments>
</cd:command>
+ <cd:command name="expandeddoif" level="system" file="syst-lua.mkiv">
+ <cd:arguments>
+ <cd:content/>
+ <cd:content/>
+ <cd:resolve name="argument-true"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="expandeddoifnot" level="system" file="syst-lua.mkiv">
+ <cd:arguments>
+ <cd:content/>
+ <cd:content/>
+ <cd:resolve name="argument-true"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="expandeddoifelse" level="system" file="syst-lua.mkiv">
+ <cd:arguments>
+ <cd:content/>
+ <cd:content/>
+ <cd:resolve name="argument-true"/>
+ <cd:resolve name="argument-false"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="expdoifelsecommon" level="system" file="syst-lua.mkiv">
<cd:arguments>
<cd:resolve name="argument-text-list"/>
@@ -3643,4 +3690,4 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
<cd:constant type="grid"/>
<cd:constant type="cd:dimension"/>
</cd:parameter>
+ <cd:parameter name="blank">
+ <cd:resolve name="value-blank"/>
+ </cd:parameter>
+ <cd:parameter name="headstyle">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="headcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="background">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="backgroundcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="foregroundstyle">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="foregroundcolor">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
<cd:parameter name="align">
<cd:constant type="left"/>
<cd:constant type="middle"/>
@@ -276,4 +297,4 @@
-->
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
</cd:arguments>
</cd:command>
- <cd:command name="element" type="environment" category="xml" file="strc-tag.mkiv">
+ <cd:command name="element" type="environment" level="document" category="xml" file="strc-tag.mkiv">
<cd:arguments>
<cd:resolve name="argument-name"/>
<cd:resolve name="assignment-userdata-list-optional"/>
@@ -72,4 +72,10 @@
</cd:arguments>
</cd:command>
-</cd:interface> \ No newline at end of file
+ <cd:command name="ignoretagsinexport" level="style" category="xml" file="strc-tag.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list"/>
+ </cd:arguments>
+ </cd:command>
+
+</cd:interface>
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 @@
</cd:arguments>
</cd:command>
+ <!--
+
+ <cd:command name="setuptop" level="style" category="layout" file="page-txt.mkvi">
+ <cd:arguments>
+ <cd:keywords optional="yes">
+ <cd:constant type="text"/>
+ <cd:constant type="margin"/>
+ <cd:constant type="edge"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:inherit name="setuplayoutelement"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setupheader" level="style" category="layout" file="page-txt.mkvi">
+ <cd:arguments>
+ <cd:keywords optional="yes">
+ <cd:constant type="text"/>
+ <cd:constant type="margin"/>
+ <cd:constant type="edge"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:inherit name="setuplayoutelement"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setuptext" level="style" category="layout" file="page-txt.mkvi">
+ <cd:arguments>
+ <cd:keywords optional="yes">
+ <cd:constant type="text"/>
+ <cd:constant type="margin"/>
+ <cd:constant type="edge"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:inherit name="setuplayoutelement"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setupfooter" level="style" category="layout" file="page-txt.mkvi">
+ <cd:arguments>
+ <cd:keywords optional="yes">
+ <cd:constant type="text"/>
+ <cd:constant type="margin"/>
+ <cd:constant type="edge"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:inherit name="setuplayoutelement"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setupbottom" level="style" category="layout" file="page-txt.mkvi">
+ <cd:arguments>
+ <cd:keywords optional="yes">
+ <cd:constant type="text"/>
+ <cd:constant type="margin"/>
+ <cd:constant type="edge"/>
+ </cd:keywords>
+ <cd:assignments list="yes">
+ <cd:inherit name="setuplayoutelement"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
<cd:command name="setuptop" level="style" category="layout" file="page-txt.mkvi">
<cd:arguments>
<cd:keywords optional="yes">
@@ -173,7 +242,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -186,7 +255,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -199,7 +268,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -212,7 +281,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
@@ -225,7 +294,7 @@
<cd:constant type="edge"/>
</cd:keywords>
<cd:assignments list="yes">
- <cd:inherit name="setuplayoutelement"/>
+ <cd:inherit name="setuplayouttext"/>
</cd:assignments>
</cd:arguments>
</cd:command>
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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="definetokenlist" level="style" file="toks-aux.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="tokenlist" type="environment" level="style" file="toks-aux.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="gettokenlist" level="style" file="toks-aux.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="resettokenlist" level="style" file="toks-aux.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="settokenlist" level="style" file="toks-aux.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="argument-text"/>
+ </cd:arguments>
+ </cd:command>
+
</cd:interface> \ 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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="spaceddigitsmethod" level="style" category="symbols" file="core-con.mkiv"/> <!-- alternative methods : 1 default, 2 and 3 only when > 4 -->
+
+ <cd:command name="spaceddigitssymbol" level="style" category="symbols" file="core-con.mkiv"/> <!-- extra splitter symbol : {,} -->
+
+ <cd:command name="spaceddigitsseparator" level="style" category="symbols" file="core-con.mkiv"/><!-- separator symbol : {\Uchar{"2008}} -->
+
+ <cd:command name="spaceddigits" level="document" category="symbols" file="core-con.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-number"/>
+ </cd:arguments>
+ </cd:command>
+
</cd:interface> \ 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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?context-directive job ctxfile x-setups.ctx ?>
+
+<cd:interface xmlns:cd="http://www.pragma-ade.com/commands">
+
+ <cd:command name="defineuserdata" level="style" category="structure" file="strc-usr.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupuserdata"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setupuserdata" level="style" category="structure" file="strc-usr.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:parameter name="before">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="after">
+ <cd:constant type="cd:command"/>
+ </cd:parameter>
+ <cd:parameter name="align">
+ <cd:inherit name="setupalign"/>
+ </cd:parameter>
+ <cd:parameter name="setups">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="style">
+ <cd:resolve name="value-style"/>
+ </cd:parameter>
+ <cd:parameter name="color">
+ <cd:constant type="cd:color"/>
+ </cd:parameter>
+ <cd:parameter name="alternative">
+ <cd:constant type="default"/>
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="cd:key">
+ <cd:constant type="cd:value"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="userdata" type="environment" level="document" category="structure" file="strc-usr.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:resolve name="assignment-userdata-list-optional"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="defineuserdataalternative" level="style" category="structure" file="strc-usr.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name"/>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupuserdataalternative"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="setupuserdataalternative" level="style" category="structure" file="strc-usr.mkiv">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-list-optional"/>
+ <cd:assignments list="yes">
+ <cd:parameter name="renderingsetup">
+ <cd:constant type="cd:name"/>
+ </cd:parameter>
+ <cd:parameter name="cd:key">
+ <cd:constant type="cd:value"/>
+ </cd:parameter>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="getuserdata" level="style" category="structure" file="strc-usr.mkiv"/>
+
+ <cd:command name="getinlineuserdata" level="style" category="structure" file="strc-usr.mkiv"/>
+
+</cd:interface>
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 @@
</cd:arguments>
</cd:command>
- <cd:command name="doifelsetypingfile" category="verbatim" level="system conditional" file="buff-ver.mkiv">
+ <cd:command name="doifelsetypingfile" category="verbatim conditional" level="system" file="buff-ver.mkiv">
<cd:arguments>
<cd:resolve name="argument-file"/>
<cd:resolve name="argument-true"/>
@@ -329,7 +329,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="doiftypingfileelse" category="verbatim" level="system conditional" file="buff-ver.mkiv">
+ <cd:command name="doiftypingfileelse" category="verbatim conditional" level="system" file="buff-ver.mkiv">
<cd:arguments>
<cd:resolve name="argument-file"/>
<cd:resolve name="argument-true"/>
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 @@
<cd:arguments>
<cd:keywords optional="yes">
<cd:constant type="makeup" default="yes"/>
- <cd:constant type="all"/>
+ <cd:constant type="reset"/>
<cd:constant type="boxes"/>
- <cd:constant type="line"/>
- <cd:constant type="glyph"/>
- <cd:constant type="fontkern"/>
+ <cd:constant type="all"/>
<cd:constant type="hbox"/>
<cd:constant type="vbox"/>
<cd:constant type="vtop"/>
<cd:constant type="kern"/>
<cd:constant type="glue"/>
<cd:constant type="penalty"/>
+ <cd:constant type="fontkern"/>
<cd:constant type="strut"/>
<cd:constant type="whatsit"/>
+ <cd:constant type="glyph"/>
<cd:constant type="simple"/>
<cd:constant type="simplehbox"/>
<cd:constant type="simplevbox"/>
@@ -133,7 +133,11 @@
<cd:constant type="math"/>
<cd:constant type="italic"/>
<cd:constant type="origin"/>
- <cd:constant type="reset"/>
+ <cd:constant type="discretionary"/>
+ <cd:constant type="expansion"/>
+ <cd:constant type="line"/>
+ <cd:constant type="space"/>
+ <cd:constant type="depth"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -148,6 +152,10 @@
<cd:command name="showfontitalics" level="document" file="trc-vis.mkiv"/>
+ <cd:command name="showglyphdata" level="document" file="trc-vis.mkiv"/>
+
+ <cd:command name="showfontexpansion" level="document" file="trc-vis.mkiv"/>
+
<cd:command name="setvisualizerfont" level="system" file="trc-vis.mkiv">
<cd:arguments>
<cd:resolve name="keyword-font-optional"/>
@@ -156,4 +164,4 @@
<cd:command name="resetvisualizers" level="system" file="trc-vis.mkiv"/>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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 @@
<cd:command name="vspacing" level="system" category="whitespace" file="spac-ver.mkiv">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
- <cd:constant type="preference"/>
- <cd:constant type="samepage"/>
- <cd:constant type="max"/>
- <cd:constant type="force"/>
- <cd:constant type="enable"/>
- <cd:constant type="disable"/>
- <cd:constant type="nowhite"/>
- <cd:constant type="packed"/>
- <cd:constant type="back"/>
- <cd:constant type="overlay"/>
- <cd:constant type="always"/>
- <cd:constant type="weak"/>
- <cd:constant type="strong"/>
- <cd:constant type="default"/>
- <cd:constant type="before"/>
- <cd:constant type="inbetween"/>
- <cd:constant type="after"/>
- <cd:constant type="fixed"/>
- <cd:constant type="flexible"/>
- <cd:constant type="none"/>
- <cd:constant type="small"/>
- <cd:constant type="medium"/>
- <cd:constant type="big"/>
- <cd:constant type="line"/>
- <cd:constant type="halfline"/>
- <cd:constant type="quarterline"/>
- <cd:constant type="formula"/>
- <cd:constant type="white"/>
- <cd:constant type="height"/>
- <cd:constant type="depth"/>
- <cd:constant type="standard"/>
- <cd:constant type="small" prefix="cd:number" method="factor"/>
- <cd:constant type="medium" prefix="cd:number" method="factor"/>
- <cd:constant type="big" prefix="cd:number" method="factor"/>
- <cd:constant type="line" prefix="cd:number" method="factor"/>
- <cd:constant type="halfline" prefix="cd:number" method="factor"/>
- <cd:constant type="quarterline" prefix="cd:number" method="factor"/>
- <cd:constant type="formula" prefix="cd:number" method="factor"/>
- <cd:constant type="white" prefix="cd:number" method="factor"/>
- <cd:constant type="height" prefix="cd:number" method="factor"/>
- <cd:constant type="depth" prefix="cd:number" method="factor"/>
- <cd:constant type="cd:number" prefix="category" method="range"/>
- <cd:constant type="cd:number" prefix="order" method="range"/>
- <cd:constant type="cd:number" prefix="penalty" method="range"/>
- <cd:constant type="cd:dimension"/>
- <cd:constant type="cd:name"/>
+ <cd:resolve name="value-blank"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -121,51 +76,7 @@
<cd:command name="blank" level="document" category="whitespace" file="spac-ver.mkiv">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
- <cd:constant type="preference"/>
- <cd:constant type="samepage"/>
- <cd:constant type="max"/>
- <cd:constant type="force"/>
- <cd:constant type="enable"/>
- <cd:constant type="disable"/>
- <cd:constant type="nowhite"/>
- <cd:constant type="back"/>
- <cd:constant type="overlay"/>
- <cd:constant type="always"/>
- <cd:constant type="weak"/>
- <cd:constant type="strong"/>
- <cd:constant type="default"/>
- <cd:constant type="before"/>
- <cd:constant type="inbetween"/>
- <cd:constant type="after"/>
- <cd:constant type="fixed"/>
- <cd:constant type="flexible"/>
- <cd:constant type="none"/>
- <cd:constant type="small"/>
- <cd:constant type="medium"/>
- <cd:constant type="big"/>
- <cd:constant type="line"/>
- <cd:constant type="halfline"/>
- <cd:constant type="quarterline"/>
- <cd:constant type="formula"/>
- <cd:constant type="white"/>
- <cd:constant type="height"/>
- <cd:constant type="depth"/>
- <cd:constant type="standard"/>
- <cd:constant type="small" prefix="cd:number" method="factor"/>
- <cd:constant type="medium" prefix="cd:number" method="factor"/>
- <cd:constant type="big" prefix="cd:number" method="factor"/>
- <cd:constant type="line" prefix="cd:number" method="factor"/>
- <cd:constant type="halfline" prefix="cd:number" method="factor"/>
- <cd:constant type="quarterline" prefix="cd:number" method="factor"/>
- <cd:constant type="formula" prefix="cd:number" method="factor"/>
- <cd:constant type="white" prefix="cd:number" method="factor"/>
- <cd:constant type="height" prefix="cd:number" method="factor"/>
- <cd:constant type="depth" prefix="cd:number" method="factor"/>
- <cd:constant type="cd:number" prefix="category" method="range"/>
- <cd:constant type="cd:number" prefix="order" method="range"/>
- <cd:constant type="cd:number" prefix="penalty" method="range"/>
- <cd:constant type="cd:dimension"/>
- <cd:constant type="cd:name"/>
+ <cd:resolve name="value-blank"/>
</cd:keywords>
</cd:arguments>
</cd:command>
@@ -213,4 +124,20 @@
<cd:command name="bigskip" level="system" category="whitespace" file="spac-ver.mkiv"/>
+ <cd:command name="checkedblank" level="system" category="whitespace" file="spac-ver.mkiv">
+ <cd:arguments>
+ <cd:keywords list="yes">
+ <cd:inherit name="blank"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="prerollblank" level="system" category="whitespace" file="spac-ver.mkiv">
+ <cd:arguments>
+ <cd:keywords list="yes">
+ <cd:inherit name="blank"/>
+ </cd:keywords>
+ </cd:arguments>
+ </cd:command>
+
</cd:interface>
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 @@
</cd:arguments>
</cd:command>
- <cd:command name="unpacked" type="environment" category="whitespace" file="spac-ver.mkiv"/>
+ <cd:command name="unpacked" type="environment" level="document" category="whitespace" file="spac-ver.mkiv"/>
<cd:command name="linecorrection" type="environment" level="document" category="whitespace" file="spac-ver.mkiv">
<cd:arguments>
@@ -50,7 +50,7 @@
</cd:arguments>
</cd:command>
- <cd:command name="locallinecorrection" type="environment" category="whitespace" file="spac-ver.mkiv">
+ <cd:command name="locallinecorrection" type="environment" level="document" category="whitespace" file="spac-ver.mkiv">
<cd:arguments>
<cd:keywords list="yes" optional="yes">
<cd:constant type="blank"/>
@@ -59,4 +59,6 @@
</cd:arguments>
</cd:command>
+ <cd:command name="forgetparskip" category="alignment" level="system" file="spac-ver.mkiv"/>
+
</cd:interface> \ 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 @@
</cd:arguments>
</cd:command>
+ <cd:command name="xmldoifatt" level="style" category="xml" file="lxml-ini.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-node"/>
+ <cd:string/>
+ <cd:string/>
+ <cd:resolve name="argument-true"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="xmldoifnotatt" level="style" category="xml" file="lxml-ini.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-node"/>
+ <cd:string/>
+ <cd:string/>
+ <cd:resolve name="argument-true"/>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="xmldoifelseatt" level="style" category="xml" file="lxml-ini.mkiv">
+ <cd:arguments>
+ <cd:resolve name="argument-node"/>
+ <cd:string/>
+ <cd:string/>
+ <cd:resolve name="argument-true"/>
+ <cd:resolve name="argument-false"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="xmldoifselfempty" level="style" category="xml" file="lxml-ini.mkiv">
<cd:arguments>
<cd:resolve name="argument-node"/>
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 @@
<cd:parameter name="distance">
<cd:constant type="cd:dimension"/>
</cd:parameter>
+ <cd:parameter name="aligncharacter">
+ <cd:constant type="yes"/>
+ <cd:constant type="no" default="yes"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentleftsample">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentrightsample">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentleftwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentrightwidth">
+ <cd:constant type="cd:dimension"/>
+ </cd:parameter>
+ <cd:parameter name="alignmentcharacter">
+ <cd:constant type="cd:text"/>
+ </cd:parameter>
<cd:inherit name="setupframed"/>
</cd:assignments>
</cd:arguments>
@@ -136,6 +155,33 @@
</cd:arguments>
</cd:command>
+ <!--
+
+ <cd:command name="xcolumn" type="environment" level="document" category="tables" file="tabl-xtb.mkvi">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-optional"/>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupxtable"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ -->
+
+ <cd:command name="xcolumn" type="environment" level="document" category="tables" file="tabl-xtb.mkvi">
+ <cd:arguments>
+ <cd:assignments list="yes" optional="yes">
+ <cd:inherit name="setupxtable"/>
+ </cd:assignments>
+ </cd:arguments>
+ </cd:command>
+
+ <cd:command name="xcolumn" type="environment" variant="name" level="document" category="tables" file="tabl-xtb.mkvi">
+ <cd:arguments>
+ <cd:resolve name="keyword-name-optional"/>
+ </cd:arguments>
+ </cd:command>
+
<cd:command name="xcell" type="environment" level="document" category="tables" file="tabl-xtb.mkvi">
<cd:arguments>
<cd:resolve name="keyword-name-optional"/>
@@ -244,4 +290,4 @@
<cd:command name="currentxtablecolumn" level="system" category="tables" file="tabl-xtb.mkvi"/>
-</cd:interface> \ No newline at end of file
+</cd:interface>
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,"<module:fonts:features:font>")
+ 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
@@ -58,39 +58,6 @@ function moduledata.fonts.shapes.showlist(specification) -- todo: ranges
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,"<module:fonts:shapes:font>")
- 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)
NC() char(id,v.shcode)
NC() char(id,v.lccode or k)
@@ -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,"<module:fonts:shapes:font>")
- 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,"<module:fonts:shapes:font>")
+ 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,"<module:fonts:shapes:font>")
- 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,"<module:fonts:features:font>")
+ 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 == "<boolean>" then
context(tostring(tk or false))
elseif not tk then
context("<unset>")
- 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 == "<scaled>" then
context("%p",tk)
- elseif v == "table" then
+ elseif v == "<table>" then
context("<table>")
- 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("<table>")
- 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 <anton@lml.bas.bg>
% 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 <anton@lml.bas.bg>
%
+% 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]: <http://www.researchgate.net/profile/Veska_Noncheva>
+%
+% [^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]: <http://www.linkedin.com/in/belogay>
+%
+% [^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,
+% <http://perso.telecom-bretagne.eu/yannisharalambous>
+%
+% 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]: <http://www.maths.manchester.ac.uk/~gb/>
+%
+% 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 <http://www.mind-print.com>
+%
+% 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]: <http://dcl.bas.bg/svetla_koeva/>
+%
+% [^11]: Коева, Светла. Правила за пренасяне на части от думите на нов
+% ред. Български език. 1999/2000, 1, 84-86
+%
+% [^12]: <http://lml.bas.bg/~stoyan/>
+%
+% 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
+% <http://bg.wiktionary.org> and <http://rechnik.chitanka.info>.
+%
+% [^13]: The author of this text.
+%
+% [^14]: <http://bg.linkedin.com/in/radostinradnev>
+%
+% [^15]: <http://bgoffice.sourceforge.net/>
+%
+% 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]: <http://mozillians.org/en-US/u/stoyan/>
+%
+% [^17]: <http://hyphenation.org>
+%
+% 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 <wl@gnu.org>
+% 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 <wl@gnu.org>
+% 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 <theppitak at gmail.com>
-%
-% 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 <theppitak at gmail.com>
+% 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 <anton@lml.bas.bg>\
% 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 <anton@lml.bas.bg>\
%\
-% 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]: <http://www.researchgate.net/profile/Veska_Noncheva>\
+% \
+% [^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]: <http://www.linkedin.com/in/belogay>\
+% \
+% [^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,\
+% <http://perso.telecom-bretagne.eu/yannisharalambous>\
+% \
+% 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]: <http://www.maths.manchester.ac.uk/~gb/>\
+% \
+% 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 <http://www.mind-print.com>\
+% \
+% 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]: <http://dcl.bas.bg/svetla_koeva/>\
+% \
+% [^11]: Коева, Светла. Правила за пренасяне на части от думите на нов\
+% ред. Български език. 1999/2000, 1, 84-86\
+% \
+% [^12]: <http://lml.bas.bg/~stoyan/>\
+% \
+% 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\
+% <http://bg.wiktionary.org> and <http://rechnik.chitanka.info>.\
+% \
+% [^13]: The author of this text.\
+% \
+% [^14]: <http://bg.linkedin.com/in/radostinradnev>\
+% \
+% [^15]: <http://bgoffice.sourceforge.net/>\
+% \
+% 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]: <http://mozillians.org/en-US/u/stoyan/>\
+% \
+% [^17]: <http://hyphenation.org>\
+% \
+% 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 <wl@gnu.org>\
+% 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 <wl@gnu.org>\
+% 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 <theppitak at gmail.com>\
-%\
-% 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 <theppitak at gmail.com>\
+% 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/third/aesop-de.tex
index 80a41f295..80a41f295 100644
--- a/tex/context/sample/common/aesop-de.tex
+++ b/tex/context/sample/third/aesop-de.tex
diff --git a/tex/context/sample/common/cervantes-es.tex b/tex/context/sample/third/cervantes-es.tex
index 153797023..153797023 100644
--- a/tex/context/sample/common/cervantes-es.tex
+++ b/tex/context/sample/third/cervantes-es.tex
diff --git a/tex/context/sample/common/khatt-ar.tex b/tex/context/sample/third/khatt-ar.tex
index c91426411..c91426411 100644
--- a/tex/context/sample/common/khatt-ar.tex
+++ b/tex/context/sample/third/khatt-ar.tex
diff --git a/tex/context/sample/common/khatt-en.tex b/tex/context/sample/third/khatt-en.tex
index 52891af25..52891af25 100644
--- a/tex/context/sample/common/khatt-en.tex
+++ b/tex/context/sample/third/khatt-en.tex
diff --git a/tex/context/sample/common/quevedo-es.tex b/tex/context/sample/third/quevedo-es.tex
index 166b0328f..166b0328f 100644
--- a/tex/context/sample/common/quevedo-es.tex
+++ b/tex/context/sample/third/quevedo-es.tex
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/context/base/mkiv/font-xtx.lua b/tex/generic/context/luatex/luatex-fonts-def.lua
index 494ac00a9..883451fb5 100644
--- a/tex/context/base/mkiv/font-xtx.lua
+++ b/tex/generic/context/luatex/luatex-fonts-def.lua
@@ -7,7 +7,6 @@ if not modules then modules = { } end modules ['luatex-fonts-def'] = {
}
if context then
- texio.write_nl("fatal error: this module is not for context")
os.exit()
end
@@ -26,7 +25,7 @@ end
-- the generic name parser (different from context!)
-local list = { }
+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
@@ -38,30 +37,34 @@ 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 P, S, R, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs
local spaces = P(" ")^0
-local namespec = (1-S("/:("))^0 -- was: (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(")") -- 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 pattern = (filename_1 + filename_2 + fontname_1 + fontname_2)
+ * subvalue^0 * crapspec^0 * options^0
-local function colonized(specification) -- xetex mode
+function fonts.definers.analyze(str,size)
+ local specification = fonts.definers.makespecification(str,nil,nil,nil,":",nil,size)
list = { }
- lpeg.match(pattern,specification.specification)
- list.crap = nil -- style not supported, maybe some day
+ lpeg.match(pattern,str)
+ list.crap = nil
if list.name then
specification.name = list.name
list.name = nil
@@ -75,12 +78,10 @@ local function colonized(specification) -- xetex mode
list.sub = nil
end
specification.features.normal = fonts.handlers.otf.features.normalize(list)
+ list = nil
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
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(" <loading (extended) adobe glyph list>")
+ 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/context/base/mkiv/font-gbn.lua b/tex/generic/context/luatex/luatex-fonts-gbn.lua
index 8f1acac65..53be41c7e 100644
--- a/tex/context/base/mkiv/font-gbn.lua
+++ b/tex/generic/context/luatex/luatex-fonts-gbn.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['font-gbn'] = {
+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",
@@ -9,7 +9,6 @@ if not modules then modules = { } end modules ['font-gbn'] = {
-- generic [base|node] mode handler
if context then
- texio.write_nl("fatal error: this module is not for context")
os.exit()
end
@@ -47,13 +46,13 @@ 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
@@ -69,15 +68,30 @@ function node.kerning(...)
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
--------- nodes.handlers.nodepass(head)
-function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
+local function 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
@@ -85,7 +99,7 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
local variants = nil
local redundant = nil
local nofused = 0
- for n in traverse_id(glyph_code,nuthead) do
+ for n in traverse_id(glyph_code,head) do
local font = getfont(n)
if font ~= prevfont then
if basefont then
@@ -122,7 +136,7 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
end
if variants then
local char = getchar(n)
- if char >= 0xFE00 and (char <= 0xFE0F or (char >= 0xE0100 and char <= 0xE01EF)) 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)
@@ -147,8 +161,8 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
for i=1,#redundant do
local r = redundant[i]
local p, n = getboth(r)
- if r == nuthead then
- nuthead = n
+ if r == head then
+ head = n
setprev(n)
else
setlink(p,n)
@@ -167,7 +181,7 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
flush_node(r)
end
end
- for d in traverse_id(disc_code,nuthead) do
+ 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
@@ -205,16 +219,16 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
local start = range[1]
local stop = range[2]
if start then
- local front = nuthead == start
+ local front = head == start
local prev, next
if stop then
next = getnext(stop)
- start, stop = ligaturing(start,stop)
- start, stop = kerning(start,stop)
+ start, stop = d_ligaturing(start,stop)
+ start, stop = d_kerning(start,stop)
else
prev = getprev(start)
- start = ligaturing(start)
- start = kerning(start)
+ start = d_ligaturing(start)
+ start = d_kerning(start)
end
if prev then
setlink(prev,start)
@@ -222,41 +236,65 @@ function nodes.handlers.nodepass(head,groupcode,size,packtype,direction)
if next then
setlink(stop,next)
end
- if front and nuthead ~= start then
- head = tonode(start)
+ if front and head ~= start then
+ head = start
end
end
end
end
- return head, true
- else
- return head, false
end
+ return head
end
-function nodes.handlers.basepass(head)
+local function basepass(head)
if basemodepass then
- head = n_ligaturing(head)
- head = n_kerning(head)
+ head = d_ligaturing(head)
+ head = d_kerning(head)
end
- return head, true
+ 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
+
+-- 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)
- return head, true
- else
- return head, false
+ 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
- else
- pattern=Cs((P(one)/(two or "")+u)^0)
- end
- if makefunction then
- return function(str)
- return lpegmatch(pattern,str)
- 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
- 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
+ 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
- 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
+ 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 a<b
- elseif tb=="string" then
- return tostring(a)<b
- end
- elseif ta=="string" then
- local tb=type(b)
- if ta==tb then
- return a<b
- else
- return a<tostring(b)
- end
+ local ta=type(a)
+ if ta=="number" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ elseif tb=="string" then
+ return tostring(a)<b
+ end
+ elseif ta=="string" then
+ local tb=type(b)
+ if ta==tb then
+ return a<b
+ else
+ return a<tostring(b)
end
- return tostring(a)<tostring(b)
+ end
+ return tostring(a)<tostring(b)
end
local function sortedkeys(tab)
- if tab then
- local srt,category,s={},0,0
- for key in next,tab do
- s=s+1
- srt[s]=key
- if category==3 then
- elseif category==1 then
- if type(key)~="string" then
- category=3
- end
- elseif category==2 then
- if type(key)~="number" then
- category=3
- end
- else
- local tkey=type(key)
- if tkey=="string" then
- category=1
- elseif tkey=="number" then
- category=2
- else
- category=3
- end
- end
- end
- if s<2 then
- elseif category==3 then
- sort(srt,compare)
+ if tab then
+ local srt={}
+ local category=0
+ local s=0
+ for key in next,tab do
+ s=s+1
+ srt[s]=key
+ if category==3 then
+ elseif category==1 then
+ if type(key)~="string" then
+ category=3
+ end
+ elseif category==2 then
+ if type(key)~="number" then
+ category=3
+ end
+ else
+ local tkey=type(key)
+ if tkey=="string" then
+ category=1
+ elseif tkey=="number" then
+ category=2
else
- sort(srt)
+ category=3
end
- return srt
+ end
+ end
+ if s<2 then
+ elseif category==3 then
+ sort(srt,compare)
else
- return {}
+ sort(srt)
end
+ return srt
+ else
+ return {}
+ end
end
local function sortedhashonly(tab)
- if tab then
- local srt,s={},0
- for key in next,tab do
- if type(key)=="string" then
- s=s+1
- srt[s]=key
- end
- end
- 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)=="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 n<m then
- n=n+1
- local k=s[n]
- return k,t[k]
- end
- end
+ 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 n<m then
+ n=n+1
+ local k=s[n]
+ return k,t[k]
end
+ end
end
- return nothing
+ end
+ return nothing
end
table.sortedhash=sortedhash
table.sortedpairs=sortedhash
function table.append(t,list)
- local n=#t
- for i=1,#list do
- n=n+1
- t[n]=list[i]
- end
- return t
+ local n=#t
+ for i=1,#list do
+ n=n+1
+ t[n]=list[i]
+ end
+ return t
end
function table.prepend(t,list)
- local nl=#list
- local nt=nl+#t
- for i=#t,1,-1 do
- t[nt]=t[i]
- nt=nt-1
- end
- for i=1,#list do
- t[i]=list[i]
- end
- return t
+ local nl=#list
+ local nt=nl+#t
+ for i=#t,1,-1 do
+ t[nt]=t[i]
+ nt=nt-1
+ end
+ for i=1,#list do
+ t[i]=list[i]
+ end
+ return t
end
function table.merge(t,...)
- t=t or {}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ if not t then
+ t={}
+ end
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.merged(...)
- local t={}
- for i=1,select("#",...) do
- for k,v in next,(select(i,...)) do
- t[k]=v
- end
+ local t={}
+ for i=1,select("#",...) do
+ for k,v in next,(select(i,...)) do
+ t[k]=v
end
- return t
+ end
+ return t
end
function table.imerge(t,...)
- local nt=#t
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- nt=nt+1
- t[nt]=nst[j]
- end
+ local nt=#t
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ nt=nt+1
+ t[nt]=nst[j]
end
- return t
+ end
+ return t
end
function table.imerged(...)
- local tmp,ntmp={},0
- for i=1,select("#",...) do
- local nst=select(i,...)
- for j=1,#nst do
- ntmp=ntmp+1
- tmp[ntmp]=nst[j]
- end
+ local tmp={}
+ local ntmp=0
+ for i=1,select("#",...) do
+ local nst=select(i,...)
+ for j=1,#nst do
+ ntmp=ntmp+1
+ tmp[ntmp]=nst[j]
end
- return tmp
+ end
+ return tmp
end
local function fastcopy(old,metatabletoo)
- if old then
- local new={}
- for k,v in next,old do
- if type(v)=="table" then
- new[k]=fastcopy(v,metatabletoo)
- else
- new[k]=v
- end
- end
- if metatabletoo then
- local mt=getmetatable(old)
- if mt then
- setmetatable(new,mt)
- end
- end
- return new
- else
- return {}
+ if old then
+ local new={}
+ for k,v in next,old do
+ if type(v)=="table" then
+ new[k]=fastcopy(v,metatabletoo)
+ else
+ new[k]=v
+ end
+ end
+ if metatabletoo then
+ local mt=getmetatable(old)
+ if mt then
+ setmetatable(new,mt)
+ end
end
+ return new
+ else
+ return {}
+ end
end
local function copy(t,tables)
- tables=tables or {}
- local tcopy={}
- if not tables[t] then
- tables[t]=tcopy
- end
- for i,v in next,t do
- if type(i)=="table" then
- if tables[i] then
- i=tables[i]
- else
- i=copy(i,tables)
- end
- end
- if type(v)~="table" then
- tcopy[i]=v
- elseif tables[v] then
- tcopy[i]=tables[v]
- else
- tcopy[i]=copy(v,tables)
- end
- end
- local mt=getmetatable(t)
- if mt then
- setmetatable(tcopy,mt)
+ if not tables then
+ tables={}
+ end
+ local tcopy={}
+ if not tables[t] then
+ tables[t]=tcopy
+ end
+ for i,v in next,t do
+ if type(i)=="table" then
+ if tables[i] then
+ i=tables[i]
+ else
+ i=copy(i,tables)
+ end
+ end
+ if type(v)~="table" then
+ tcopy[i]=v
+ elseif tables[v] then
+ tcopy[i]=tables[v]
+ else
+ tcopy[i]=copy(v,tables)
end
- return tcopy
+ end
+ local mt=getmetatable(t)
+ if mt then
+ setmetatable(tcopy,mt)
+ end
+ return tcopy
end
table.fastcopy=fastcopy
table.copy=copy
function table.derive(parent)
- local child={}
- if parent then
- setmetatable(child,{ __index=parent })
- end
- return child
+ local child={}
+ if parent then
+ setmetatable(child,{ __index=parent })
+ end
+ return child
end
function table.tohash(t,value)
- local h={}
- if t then
- if value==nil then value=true end
- for _,v in next,t do
- h[v]=value
- end
+ local h={}
+ if t then
+ if value==nil then value=true end
+ for _,v in next,t do
+ h[v]=value
end
- return h
+ end
+ return h
end
function table.fromhash(t)
- local hsh,h={},0
- for k,v in next,t do
- if v then
- h=h+1
- hsh[h]=k
- end
+ local hsh={}
+ local h=0
+ for k,v in next,t do
+ if v then
+ h=h+1
+ hsh[h]=k
end
- return hsh
+ end
+ return hsh
end
local noquotes,hexify,handle,compact,inline,functions,metacheck
local reserved=table.tohash {
- 'and','break','do','else','elseif','end','false','for','function','if',
- 'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function is_simple_table(t,hexify)
- 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
+ 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
+ if next(root)~=nil then
+ do_serialize(root,name,"",0)
end
- handle("}")
+ 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 n<m do
- n=n+1
- local k=s[n]
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return kv,s
- else
- local n=next(t)
- local function iterator()
- while n~=nil do
- local k=n
- n=next(t,k)
- if find(k,pattern) then
- return k,t[k]
- end
- end
- end
- return iterator,t
+ 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 n<m do
+ n=n+1
+ local k=s[n]
+ if find(k,pattern) then
+ return k,t[k]
+ end
end
+ end
+ return kv,s
else
- return nothing
+ local n=next(t)
+ local function iterator()
+ while n~=nil do
+ local k=n
+ n=next(t,k)
+ if find(k,pattern) then
+ return k,t[k]
+ end
+ end
+ end
+ return iterator,t
end
+ else
+ return nothing
+ end
end
if not table.move then
- function table.move(a1,f,e,t,a2)
- if a2 and a1~=a2 then
- for i=f,e do
- a2[t]=a1[i]
- t=t+1
- end
- return a2
- else
- t=t+e-f
- for i=e,f,-1 do
- a1[t]=a1[i]
- t=t-1
- end
- return a1
- end
+ function table.move(a1,f,e,t,a2)
+ if a2 and a1~=a2 then
+ for i=f,e do
+ a2[t]=a1[i]
+ t=t+1
+ end
+ return a2
+ else
+ t=t+e-f
+ for i=e,f,-1 do
+ a1[t]=a1[i]
+ t=t-1
+ end
+ return a1
end
+ end
end
end -- closure
@@ -2139,11 +2152,11 @@ end -- closure
do -- begin closure to overcome local limits and interference
if not modules then modules={} end modules ['l-io']={
- 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 io=io
local open,flush,write,read=io.open,io.flush,io.write,io.read
@@ -2151,334 +2164,334 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format
local concat=table.concat
local type=type
if string.find(os.getenv("PATH"),";",1,true) then
- io.fileseparator,io.pathseparator="\\",";"
+ io.fileseparator,io.pathseparator="\\",";"
else
- io.fileseparator,io.pathseparator="/",":"
+ io.fileseparator,io.pathseparator="/",":"
end
local large=0x01000000
local medium=0x00100000
local small=0x00020000
local function readall(f)
- local size=f:seek("end")
- if size>0 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
- f:close()
- flush()
+ if data then
+ g:write(data)
+ end
+ 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)
- else
- return "",str
- end
+ 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 {
- path=path,
- name=name,
- base=base,
- suffix=suffix,
- }
- end
+ 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
+ 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,783 +2965,90 @@ 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)<floor(n)
- end
-end
-
-end -- closure
-
-do -- begin closure to overcome local limits and interference
-
-if not modules then modules={} end modules ['l-unicode']={
- 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"
-}
-utf=utf or (unicode and unicode.utf8) or {}
-utf.characters=utf.characters or string.utfcharacters
-utf.values=utf.values or string.utfvalues
-local type=type
-local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch
-local concat=table.concat
-local P,C,R,Cs,Ct,Cmt,Cc,Carg,Cp=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Ct,lpeg.Cmt,lpeg.Cc,lpeg.Carg,lpeg.Cp
-local lpegmatch=lpeg.match
-local patterns=lpeg.patterns
-local tabletopattern=lpeg.utfchartabletopattern
-local bytepairs=string.bytepairs
-local finder=lpeg.finder
-local replacer=lpeg.replacer
-local utfvalues=utf.values
-local utfgmatch=utf.gmatch
-local p_utftype=patterns.utftype
-local p_utfstricttype=patterns.utfstricttype
-local p_utfoffset=patterns.utfoffset
-local p_utf8char=patterns.utf8character
-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 }
-end
-if not utf.char then
- utf.char=string.utfcharacter or (utf8 and utf8.char)
- if not utf.char then
- local char=string.char
- if bit32 then
- local rshift=bit32.rshift
- function utf.char(n)
- if n<0x80 then
- return char(n)
- elseif n<0x800 then
- return char(
- 0xC0+rshift(n,6),
- 0x80+(n%0x40)
- )
- elseif n<0x10000 then
- return char(
- 0xE0+rshift(n,12),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- elseif n<0x200000 then
- return char(
- 0xF0+rshift(n,18),
- 0x80+(rshift(n,12)%0x40),
- 0x80+(rshift(n,6)%0x40),
- 0x80+(n%0x40)
- )
- else
- return ""
- end
- end
- 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
- end
- end
-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
-end
-local utfchar,utfbyte=utf.char,utf.byte
-function utf.filetype(data)
- return data and lpegmatch(p_utftype,data) or "unknown"
-end
-local toentities=Cs (
- (
- patterns.utf8one+(
- patterns.utf8two+patterns.utf8three+patterns.utf8four
- )/function(s) local b=utfbyte(s) if b<127 then return s else return format("&#%X;",b) end end
- )^0
-)
-patterns.toentities=toentities
-function utf.toentities(str)
- return lpegmatch(toentities,str)
-end
-local one=P(1)
-local two=C(1)*C(1)
-local four=C(R(utfchar(0xD8),utfchar(0xFF)))*C(1)*C(1)*C(1)
-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
-)
-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
- 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
- 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
- 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
-end
-function utf.replacer(t)
- local r=replacer(t,false,false,true)
- return function(str)
- return lpegmatch(r,str)
- end
-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
-end
-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)
-patterns.utflinesplitter=utflinesplitter
-function utf.splitlines(str)
- return lpegmatch(utflinesplitter,str or "")
-end
-function utf.split(str,ignorewhitespace)
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
-end
-function utf.totable(str)
- return lpegmatch(utfcharsplitter_raw,str)
-end
-function utf.magic(f)
- local str=f:read(4) or ""
- local off=lpegmatch(p_utfoffset,str)
- if off<4 then
- f:seek('set',off)
- end
- return lpegmatch(p_utftype,str)
-end
-local utf16_to_utf8_be,utf16_to_utf8_le
-local utf32_to_utf8_be,utf32_to_utf8_le
-local utf_16_be_getbom=patterns.utfbom_16_be^-1
-local utf_16_le_getbom=patterns.utfbom_16_le^-1
-local utf_32_be_getbom=patterns.utfbom_32_be^-1
-local utf_32_le_getbom=patterns.utfbom_32_le^-1
-local utf_16_be_linesplitter=utf_16_be_getbom*lpeg.tsplitat(patterns.utf_16_be_nl)
-local utf_16_le_linesplitter=utf_16_le_getbom*lpeg.tsplitat(patterns.utf_16_le_nl)
-local utf_32_be_linesplitter=utf_32_be_getbom*lpeg.tsplitat(patterns.utf_32_be_nl)
-local utf_32_le_linesplitter=utf_32_le_getbom*lpeg.tsplitat(patterns.utf_32_le_nl)
-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
- 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
-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))
-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))
-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
-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
-end
-utf16_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf16_to_utf8_le,s)
- else
- return s
- 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
-end
-utf32_to_utf8_be=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_be,s)
- else
- return s
- end
-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
-end
-utf32_to_utf8_le=function(s)
- if s and s~="" then
- return lpegmatch(p_utf32_to_utf8_le,s)
- else
- return s
- end
-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
-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
-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
-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
-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
-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
-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 " ")
-end
-function utf.ustring(s)
- return format("U+%05X",type(s)=="number" and s or utfbyte(s))
-end
-function utf.xstring(s)
- return format("0x%05X",type(s)=="number" and s or utfbyte(s))
-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
-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
-end
-if not utf.characters then
- function utf.characters(str)
- return gmatch(str,".[\128-\191]*")
- end
- string.utfcharacters=utf.characters
-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
-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
-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
-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 floor=math.floor
+ function math.tointeger(m,n)
+ return floor(m)<floor(n)
+ end
end
end -- closure
@@ -3734,11 +3056,11 @@ 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"
+ 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 {}
@@ -3751,624 +3073,657 @@ 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 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
if not number then number={} end
-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 ptf=1/65536
+local bpf=(7200/7227)/65536
local function points(n)
- n=tonumber(n)
- return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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))
+ if n==0 then
+ return "0pt"
+ end
+ n=tonumber(n)
+ 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))
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)
+ return lpegmatch(pattern,str)
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
+ 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
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((
+ 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
+ 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)
+ extra,start=0,position
+ end+anything
+ )^1)
function strings.tabtospace(str,tab)
- return lpegmatch(pattern,str,1,tab or 7)
+ return lpegmatch(pattern,str,1,tab or 7)
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 space=spacer^0
-local nospace=space/""
+ 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-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 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,
- ["retain"]=p_retain_normal,
- ["retain and collapse"]=p_retain_collapse,
- ["retain and no empty"]=p_retain_noempty,
- ["collapse"]=patterns.collapser,
+ ["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
+ return str and lpegmatch(striplinepatterns[how],str) or str
+end
+function strings.collapse(str)
+ return str and lpegmatch(p_prune_intospace,str) or str
end
strings.striplong=strings.striplines
function strings.nice(str)
- str=gsub(str,"[:%-+_]+"," ")
- return 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)..'"')
+ 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).."'")
+ 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]",
+ "[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
+ 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
+ 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))*(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==false then
+ if type(n)=="number" then
+ n=tostring(n)
+ end
+ return lpegmatch(splitter3,n,1,sep2 or ".")
+ else
+ if type(n)=="number" then
+ n=format("%0.2f",n)
+ end
if sep1==true then
- return lpegmatch(splitter,s,1,".",",")
+ return lpegmatch(splitter,n,1,".",",")
elseif sep1=="." then
- return lpegmatch(splitter,s,1,sep1,sep2 or ",")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ",")
elseif sep1=="," then
- return lpegmatch(splitter,s,1,sep1,sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1,sep2 or ".")
else
- return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".")
+ return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".")
end
+ 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
- )
+ 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
+ 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 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
- 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))
+ 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
- return tostring(n)
+ 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
+ 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
+ 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 #s<l then
- return format(hs[l],s)
- else
- return s
- end
+ local s=format(hf[a],n)
+ local l=(b or 0)+(a or 0)+1
+ if #s<l then
+ return format(hs[l],s)
+ else
+ return s
+ end
end
local template=[[
%s
%s
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,
+}
local arguments={ "a1" }
setmetatable(arguments,{ __index=function(t,k)
- local v=t[k-1]..",a"..k
- t[k]=v
- return v
- end
+ local v=t[k-1]..",a"..k
+ t[k]=v
+ return v
+ 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)
local format_s=function(f)
- n=n+1
- if f and f~="" then
- return format("format('%%%ss',a%s)",f,n)
- else
- return format("(a%s or '')",n)
- end
+ n=n+1
+ if f and f~="" then
+ return format("format('%%%ss',a%s)",f,n)
+ else
+ return format("(a%s or '')",n)
+ end
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
+ 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 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
+ 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 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ n=n+1
+ return format("utfchar(a%s)",n)
end
local format_C=function()
- n=n+1
- return format("tracedchar(a%s)",n)
+ 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)
+ 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
+ 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
+ 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
+ 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
+ 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)
+ n=n+1
+ return format("points(a%s)",n)
end
local format_b=function()
- n=n+1
- return format("basepoints(a%s)",n)
+ 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
+ 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
+ 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)
+ 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)
+ 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()
+ 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(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("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
-patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
+patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+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
+ elseif vfonts then
+ properties.virtualized=true
+ target.type="virtual"
+ if #vfonts==0 then
+ target.fonts={ { id=0 } }
end
- return target
+ 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(" <loading (extended) adobe glyph list>")
- 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 supnum<cidmax then
- for s=supnum+1,cidmax do
- local c=locate(registry,ordering,s)
- if c then
- found,cidnum=c,s
- break
- end
- end
+ 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 supnum<cidmax then
+ for s=supnum+1,cidmax do
+ local c=locate(registry,ordering,s)
+ if c then
+ found,cidnum=c,s
+ break
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
- 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)
+ 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
- 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
+ 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
- unicode=u
- glyph.unicode=unicode
- end
- elseif u<private then
- unicode=u
- glyph.unicode=unicode
- end
- else
- local t,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
- 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 then
+ unicode=u
+ glyph.unicode=unicode
+ end
+ elseif u<private then
+ unicode=u
+ glyph.unicode=unicode
+ end
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)
+ 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("<missing font database, run: mtxrun --script fonts --reload --simple>")
- 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("<unknown font in database, run: mtxrun --script fonts --reload --simple>")
- 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("<font database loaded: ",foundname,">")
- 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
- if trace_cmap_detail then
- report("format 13 from %C to %C get index %i",first,last,index)
- end
- local glyph=glyphs[index]
- local unicode=glyph.unicode
- if not unicode then
- unicode=first
- glyph.unicode=unicode
- first=first+1
- end
- local list=duplicates[unicode]
- mapping[index]=unicode
- if not list then
- list={}
- duplicates[unicode]=list
- end
- if last>=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
+ if trace_cmap_detail then
+ report("format 13 from %C to %C get index %i",first,last,index)
+ end
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=first
+ glyph.unicode=unicode
+ first=first+1
+ end
+ local list=duplicates[unicode]
+ mapping[index]=unicode
+ if not list then
+ list={}
+ duplicates[unicode]=list
+ end
+ if last>=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
- 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
+ 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 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
- 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
+ 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_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={}
++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
- 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 x<xmin then xmin=x end
- if y>ymax then ymax=y elseif y<ymin then ymin=y end
- else
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- end
- end
- local function xmoveto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"m" }
- end
- if not checked then
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- elseif x>xmax then
- xmax=x
- elseif x<xmin then
- xmin=x
- end
- end
- local function ymoveto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"m" }
- end
- if not checked then
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- elseif y>ymax then
- ymax=y
- elseif y<ymin then
- ymin=y
- end
- end
- local function moveto()
- if trace_charstrings then
- showstate("moveto")
- end
- top=0
- xymoveto()
+ 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 function xylineto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"l" }
- end
- if checked then
- if x>xmax then xmax=x elseif x<xmin then xmin=x end
- if y>ymax then ymax=y elseif y<ymin then ymin=y end
- else
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- end
+ end
+ local function xymoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
end
- local function xlineto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"l" }
- end
- if not checked then
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- elseif x>xmax then
- xmax=x
- elseif x<xmin then
- xmin=x
- end
- end
- local function ylineto()
- if keepcurve then
- r=r+1
- result[r]={ x,y,"l" }
- end
- if not checked then
- xmin=x
- ymin=y
- xmax=x
- ymax=y
- checked=true
- elseif y>ymax then
- ymax=y
- elseif y<ymin then
- ymin=y
- end
- end
- local function xycurveto(x1,y1,x2,y2,x3,y3)
- if trace_charstrings then
- showstate("curveto")
- end
- if keepcurve then
- r=r+1
- result[r]={ x1,y1,x2,y2,x3,y3,"c" }
- end
- if checked then
- if x1>xmax then xmax=x1 elseif x1<xmin then xmin=x1 end
- if y1>ymax then ymax=y1 elseif y1<ymin then ymin=y1 end
- else
- xmin=x1
- ymin=y1
- xmax=x1
- ymax=y1
- checked=true
- end
- if x2>xmax then xmax=x2 elseif x2<xmin then xmin=x2 end
- if y2>ymax then ymax=y2 elseif y2<ymin then ymin=y2 end
- if x3>xmax then xmax=x3 elseif x3<xmin then xmin=x3 end
- if y3>ymax then ymax=y3 elseif y3<ymin then ymin=y3 end
- end
- local function rmoveto()
- if not width then
- if top>2 then
- width=stack[1]
- if trace_charstrings then
- showvalue("backtrack width",width)
- end
- else
- width=true
- end
- end
+ if checked then
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
+ else
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ end
+ end
+ local function xmoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ymoveto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"m" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
+ local function moveto()
+ if trace_charstrings then
+ showstate("moveto")
+ end
+ top=0
+ xymoveto()
+ end
+ local function xylineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if checked then
+ if x>xmax then xmax=x elseif x<xmin then xmin=x end
+ if y>ymax then ymax=y elseif y<ymin then ymin=y end
+ else
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ end
+ end
+ local function xlineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif x>xmax then
+ xmax=x
+ elseif x<xmin then
+ xmin=x
+ end
+ end
+ local function ylineto()
+ if keepcurve then
+ r=r+1
+ result[r]={ x,y,"l" }
+ end
+ if not checked then
+ xmin=x
+ ymin=y
+ xmax=x
+ ymax=y
+ checked=true
+ elseif y>ymax then
+ ymax=y
+ elseif y<ymin then
+ ymin=y
+ end
+ end
+ local function xycurveto(x1,y1,x2,y2,x3,y3)
+ if trace_charstrings then
+ showstate("curveto")
+ end
+ if keepcurve then
+ r=r+1
+ result[r]={ x1,y1,x2,y2,x3,y3,"c" }
+ end
+ if checked then
+ if x1>xmax then xmax=x1 elseif x1<xmin then xmin=x1 end
+ if y1>ymax then ymax=y1 elseif y1<ymin then ymin=y1 end
+ else
+ xmin=x1
+ ymin=y1
+ xmax=x1
+ ymax=y1
+ checked=true
+ end
+ if x2>xmax then xmax=x2 elseif x2<xmin then xmin=x2 end
+ if y2>ymax then ymax=y2 elseif y2<ymin then ymin=y2 end
+ if x3>xmax then xmax=x3 elseif x3<xmin then xmin=x3 end
+ if y3>ymax then ymax=y3 elseif y3<ymin then ymin=y3 end
+ end
+ local function rmoveto()
+ if not width then
+ if top>2 then
+ width=stack[1]
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
+ 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
- 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
+ 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
- showstate("vmoveto")
+ 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
+ y=y+stack[i]
+ ylineto()
+ swap=true
end
- y=y+stack[top]
- top=0
- ymoveto()
+ end
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
+ top=0
+ end
+ local function vlineto()
+ if trace_charstrings then
+ showstate("vlineto")
end
- local function hlineto()
- if trace_charstrings then
- showstate("hlineto")
- end
- if top==1 then
- x=x+stack[1]
- xlineto()
+ if top==1 then
+ y=y+stack[1]
+ ylineto()
+ else
+ local swap=false
+ for i=1,top do
+ if swap then
+ x=x+stack[i]
+ xlineto()
+ swap=false
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()
+ 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=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()
+ 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
+ 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 f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak 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")
+ showstate("endchar")
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]
- 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)")
+ 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
- top=top+1
- stack[top]=0
- else
+ r=r+1;result[r]=chars[12]
+ r=r+1;result[r]=chars[t]
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 f<start or f>stop then
- s=0
- break
- elseif f<peak then
- s=s*(f-start)/(peak-start)
- elseif f>peak then
- s=s*(stop-f)/(stop-peak)
- else
- end
- 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
+ local a=subactions[t]
+ if a then
+ a(t)
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
+ top=0
end
+ 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,
- }
- 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
+ local a=subactions[t]
+ if a then
+ a(t)
+ else
+ if trace_charstrings then
+ showvalue("<subaction>",t)
end
+ top=0
+ 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
+ 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
- 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("<subaction>",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("<action>",t)
- end
- top=0
- i=i+1
- end
+ 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
- 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
+ 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
- width=nominalwidth+width
+ 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
- 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
+ local a=actions[t]
+ if a then
+ local s=a(t)
+ if s then
+ i=i+s+1
+ else
+ i=i+1
+ end
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 trace_charstrings then
+ showvalue("<action>",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),
+ }
+ 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 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
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 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
- 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 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
- 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 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 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 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 x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
- if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
- if px<xmin then xmin=px elseif px>xmax then xmax=px end
- if py<ymin then ymin=py elseif py>ymax 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 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 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 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 x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
- if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
- if px<xmin then xmin=px elseif px>xmax then xmax=px end
- if py<ymin then ymin=py elseif py>ymax 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 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
- 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 x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
- if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
- if px<xmin then xmin=px elseif px>xmax then xmax=px end
- if py<ymin then ymin=py elseif py>ymax 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 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
+ 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 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 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 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 x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax 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 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 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 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 x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax 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 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
+ 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 x2<xmin then xmin=x2 elseif x2>xmax then xmax=x2 end
+ if y2<ymin then ymin=y2 elseif y2>ymax then ymax=y2 end
+ if px<xmin then xmin=px elseif px>xmax then xmax=px end
+ if py<ymin then ymin=py elseif py>ymax 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
- glyph.stream=concat(result,"",1,r)
+ 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
+ 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)
- flags[i]=flag
- if band(flag,0x08)~=0 then
- for j=1,readbyte(f) do
- i=i+1
- flags[i]=flag
- end
- end
+ 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
+ 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
- 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
- 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 p<count do
- local control=readbyte(f)
- local runreader=band(control,0x80)~=0 and readushort or readbyte
- local runlength=band(control,0x7F)
- for i=1,runlength+1 do
- n=n+runreader(f)
- p=p+1
- points[p]=n
- end
- end
- return points,p
end
+ local points={}
+ local p=0
+ local n=1
+ while p<count do
+ local control=readbyte(f)
+ local runreader=band(control,0x80)~=0 and readushort or readbyte
+ local runlength=band(control,0x7F)
+ for i=1,runlength+1 do
+ n=n+runreader(f)
+ p=p+1
+ points[p]=n
+ end
+ end
+ return points,p
+ end
end
local function readdeltas(f,nofpoints)
- local deltas={}
- local p=0
- local z=0
- while nofpoints>0 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 f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak 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 f<start or f>stop then
- s=0
- break
- elseif f<peak then
- s=s*(f-start)/(peak-start)
- elseif f>peak 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,2967 +16723,3141 @@ 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 user<minimum then
- user=minimum
- elseif user>maximum then
- user=maximum
- end
- if user<default then
- default=- (default-user)/(default-minimum)
- elseif user>default 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 user<minimum then
+ user=minimum
+ elseif user>maximum then
+ user=maximum
+ end
+ if user<default then
+ default=- (default-user)/(default-minimum)
+ elseif user>default 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 f<start or f>stop then
- s=0
- break
- elseif f<peak then
- s=s*(f-start)/(peak-start)
- elseif f>peak 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 f<start or f>stop then
+ s=0
+ break
+ elseif f<peak then
+ s=s*(f-start)/(peak-start)
+ elseif f>peak 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)
- 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
+ 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
- report("unknown coverage format %a ",coverageformat)
+ 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={}
+ 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
+ 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
- end
- coverage[index]=hash
+ 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
- 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 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
- return lookups
+ 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
- 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)
- 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
+ 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)
+ 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
- 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
+ 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
- else
- report("no subtables for lookup %a",lookupid)
+ end
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
- 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")
+ 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
+ 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
- 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
+ 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
- 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
+ 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
- local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder)
- setposition(f,variationsoffset)
+ 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 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
- 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),
- }
- 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={}
- for i=1,noflookups do
- lookups[i]=readushort(f)
- end
- record.substitutions=lookups
- end
- 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
+ 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
+ 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)
+ 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 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 },
- }
+ 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
- report("ignoring empty kern table of feature %a",name)
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
- function readers.gsub(f,fontdata,specification)
- if specification.details then
- readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups)
- end
+ end
+ function readers.gsub(f,fontdata,specification)
+ if specification.details then
+ readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups)
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
+ 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
- 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
+ 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
- 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
+ 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 marksetsoffset~=0 then
- marksetsoffset=tableoffset+marksetsoffset
- setposition(f,marksetsoffset)
- local format=readushort(f)
- if format==1 then
- local nofsets=readushort(f)
- local sets={}
- for i=1,nofsets do
- sets[i]=readulong(f)
- end
- for i=1,nofsets do
- local offset=sets[i]
- if offset~=0 then
- marksets[i]=readcoverage(f,marksetsoffset+offset)
- end
- end
- 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
- 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
+ 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
+ end
end
+ end
end
local function readmathvalue(f)
- local v=readshort(f)
- skipshort(f,1)
- return v
+ 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),
- }
+ 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
+ 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
+ glyph.math={ kerns=kernset }
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
+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
- 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
+ if not variants then
+ elseif not math then
+ math={ [kvariants]=variants }
+ glyph.math=math
+ else
+ math[kvariants]=variants
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
+ 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
- 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
- glyph.math={ kerns=kernset }
- end
- end
- end
+ if not math then
+ math={
+ [kparts]=parts
+ }
+ glyph.math=math
+ else
+ math[kparts]=parts
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
- 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
- end
+ if italic and italic~=0 then
+ math[kitalic]=italic
end
+ end
end
+ end
end
- get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic")
- get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic")
+ 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
+ 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
+ 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
- fontdata.hascolor=true
+ 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]
- end
- palettes[i]=p
- end
- fontdata.colorpalettes=palettes
- end
+ 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
+ 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.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),
- data=readstring(f,datasize-8),
- ppem=strikeppem,
- ppi=strikeppi,
- }
- done=done+1
- if done==nofglyphs then
- break
- end
- end
- end
- glyphoffset=nextoffset
- end
+ 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.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),
+ data=readstring(f,datasize-8),
+ ppem=strikeppem,
+ ppi=strikeppi,
+ }
+ done=done+1
+ if done==nofglyphs then
+ break
end
- fontdata.sbixshapes=shapes
+ end
+ end
+ glyphoffset=nextoffset
+ end
end
+ fontdata.pngshapes=shapes
+ end
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={}
- }
- end
- setposition(f,tableoffset+valuesoffset)
- for i=1,nofvalues do
- values[i]=readushort(f)
+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<a.bitdepth
+ else
+ return b.ppemx<a.ppemx
+ end
+ end)
+ 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
- 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),
- }
+ 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
- insert(axis[index].variants,variant)
+ end
end
- sort(axis,function(a,b)
- return a.ordering<b.ordering
- end)
- for i=1,#axis do
- local a=axis[i]
- sort(a.variants,function(a,b)
- return a.name<b.name
- end)
- a.ordering=nil
+ end
+ 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
+ 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
+ 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
+ end
+ subtable.offsets=offsets
+ subtable.metrics=metrics
+ end
+ 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
+ end
+ local x=metrics.width
+ local y=metrics.height
+ shapes[index]={
+ x=x,
+ y=y,
+ data=data,
+ }
+ 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
- setvariabledata(fontdata,"designaxis",axis)
- setvariabledata(fontdata,"fallbackname",fallbackname)
+ end
+ fontdata.pngshapes=shapes
end
+ end
+ function readers.cbdt(f,fontdata,specification)
+ end
+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={}
+ }
+ end
+ setposition(f,tableoffset+valuesoffset)
+ for i=1,nofvalues do
+ values[i]=readushort(f)
+ 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),
+ }
+ end
+ insert(axis[index].variants,variant)
+ end
+ sort(axis,function(a,b)
+ return a.ordering<b.ordering
+ end)
+ for i=1,#axis do
+ local a=axis[i]
+ sort(a.variants,function(a,b)
+ return a.name<b.name
+ end)
+ a.ordering=nil
+ end
+ setvariabledata(fontdata,"designaxis",axis)
+ setvariabledata(fontdata,"fallbackname",fallbackname)
+ end
end
function readers.avar(f,fontdata,specification)
- local tableoffset=gotodatatable(f,fontdata,"avar",true)
- if tableoffset then
- local function collect()
- local nofvalues=readushort(f)
- local values={}
- local lastfrom=false
- local lastto=false
- for i=1,nofvalues do
- local f,t=read2dot14(f),read2dot14(f)
- if lastfrom and f<=lastfrom then
- elseif lastto and t>=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
+ local tableoffset=gotodatatable(f,fontdata,"avar",true)
+ if tableoffset then
+ local function collect()
+ local nofvalues=readushort(f)
+ local values={}
+ local lastfrom=false
+ local lastto=false
+ for i=1,nofvalues do
+ local f=read2dot14(f)
+ local t=read2dot14(f)
+ if lastfrom and f<=lastfrom then
+ elseif lastto and t>=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
- return false
- 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
- setvariabledata(fontdata,"segments",segments)
+ 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
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
+ 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
- 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
+ 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
+ end
end
function readers.vvar(f,fontdata,specification)
- if not specification.variable then
- return
- end
+ 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
+ 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
@@ -18752,11 +19865,11 @@ 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"
+ 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
@@ -18767,8 +19880,15 @@ 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 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"]
@@ -18779,2019 +19899,2241 @@ 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
+ 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]
- end
- 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
+ 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
- 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
+ for i=1,#replacement do
+ n=n+1
+ t[n]=replacement[i]
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
- end
+ for i=index+1,#list do
+ n=n+1
+ t[n]=list[i]
end
- local marks=resources.marks
+ 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
- resources.marks=remark(marks)
- end
- local markclasses=resources.markclasses
- if markclasses then
- for class,marks in next,markclasses do
- markclasses[class]=remark(marks)
+ 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
- local marksets=resources.marksets
- if marksets then
- for class,marks in next,marksets do
- marksets[class]=remark(marks)
+ 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
- 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
- t[indices[k]]=v
+ 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
+ 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]=indices[d1]
+ else
+ report_error("fuzzy case %i in unifying %s: %i",2,kind,g1)
+ end
+ end
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]
+ done[c]=t1
+ end
+ step.coverage=t1
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
+ 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
+ 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
- unifythem(resources.sequences)
- unifythem(resources.sublookups)
-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")
+ 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
+ end
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 }
+ 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
- duplicates[0x2D]={ [0xAD]=true }
+ 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
- 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<m then
- t[n+4]=f_character_n(u)
- end
- else
- local c=copy(du)
- c.unicode=u
- descriptions[u]=c
- if n<m then
- t[n+4]=f_character_y(u)
- end
- end
- n=n+1
- end
- if n<=m then
- report("duplicates: %i : % t",n,t)
+ 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
+ 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
+ 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]
+ 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("duplicates: %i : % t ...",n,t)
+ 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
+ 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
+ end
+ unifythem(resources.sequences)
+ unifythem(resources.sublookups)
end
-local ignore={
- ["notdef"]=true,
- [".notdef"]=true,
- ["null"]=true,
- [".null"]=true,
- ["nonmarkingreturn"]=true,
-}
-local function checklookups(fontdata,missing,nofmissing)
+local function copyduplicates(fontdata)
+ if check_duplicates then
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
+ 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
- end
- local function collectthem(sequences)
- if not sequences then
- return
+ if not duplicates then
+ duplicates={}
+ resources.duplicates=duplicates
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
+ 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<m then
+ t[n+4]=f_character_n(u)
+ end
+ else
+ local c=copy(du)
+ c.unicode=u
+ descriptions[u]=c
+ if n<m then
+ t[n+4]=f_character_y(u)
+ end
end
+ n=n+1
+ end
+ if trace_unicodes then
+ if n<=m then
+ report_unicodes("%i : % t",n,t)
+ else
+ report_unicodes("%i : % t ...",n,t)
+ end
+ end
+ else
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
+ end
+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
- 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
- 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
+ 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
- if nofmissing<=0 then
- report("all done in %s loops",loops)
- return
- elseif old==nofmissing then
- break
+ 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
- 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
+ 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
- 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
+ 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
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
+ 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
- if next(done) then
- report("not unicoded: % t",sortedkeys(done))
+ 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
-local function unifymissing(fontdata)
- if not fonts.mappings then
- require("font-map")
- require("font-agl")
+ 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
- local unicodes={}
- local resources=fontdata.resources
- resources.unicodes=unicodes
- for unicode,d in next,fontdata.descriptions do
- if unicode<privateoffset then
- local name=d.name
- if name then
- unicodes[name]=unicode
- 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
- fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
- resources.unicodes=nil
+ 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 unicode<privateoffset then
+ local name=d.name
+ if name then
+ unicodes[name]=unicode
+ end
+ end
+ end
+ fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups)
+ 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
- local indices={}
- local descriptions={}
- local names=usenames and {}
- local resources=fontdata.resources
- local zero=glyphs[0]
- local zerocode=zero.unicode
- if not zerocode then
- zerocode=private
- zero.unicode=zerocode
+ local private=fontdata.private or privateoffset
+ local glyphs=fontdata.glyphs
+ local indices={}
+ local descriptions={}
+ local names=usenames and {}
+ local resources=fontdata.resources
+ local zero=glyphs[0]
+ local zerocode=zero.unicode
+ if not zerocode then
+ zerocode=private
+ zero.unicode=zerocode
+ private=private+1
+ end
+ descriptions[zerocode]=zero
+ if names then
+ local name=glyphs[0].name or f_private(zerocode)
+ indices[0]=name
+ names[name]=zerocode
+ else
+ indices[0]=zerocode
+ end
+ if names then
+ for index=1,#glyphs do
+ local glyph=glyphs[index]
+ local unicode=glyph.unicode
+ if not unicode then
+ unicode=private
+ local name=glyph.name or f_private(unicode)
+ indices[index]=name
+ names[name]=unicode
private=private+1
- end
- descriptions[zerocode]=zero
- if names then
- local name=glyphs[0].name or f_private(zerocode)
- indices[0]=name
- names[name]=zerocode
- else
- indices[0]=zerocode
- end
+ 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
+ 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
- if names then
- 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
- report("assigning private unicode %U to glyph indexed %05X (%C)",private,index,unicode)
- unicode=private
- if names then
- local name=glyph.name or f_private(unicode)
- indices[index]=name
- names[name]=unicode
- else
- indices[index]=unicode
- end
- private=private+1
+ 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
- if names then
- local name=glyph.name or f_unicode(unicode)
- indices[index]=name
- names[name]=unicode
- else
- indices[index]=unicode
- end
+ report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private)
end
- descriptions[unicode]=glyph
- 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
+ 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
- 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
+ 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
- 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)
+ 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
- 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
- end
- end
- if n>0 then
- report("%s bogus names removed (verbose unicode)",n)
+ 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
- if c>0 then
- report("%s base class tags removed (default is base)",c)
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
end
+ end
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
+ 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 coverage=steps[i].coverage
- if coverage then
- for k,v in next,coverage do
- traverse(k,k,v)
- end
- end
- end
- end
+ 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
+ traverse(k,k,v)
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
+ 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
- return collected
+ end
end
+ end
+ if not done then
+ break
+ end
end
+ return collected
+ 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
+ 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
+ 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
+ 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 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]
+ 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
- sort(s)
- return concat(s,",")
+ 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
+ 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
+ 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
- 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,",")
+ 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]
+ local s={}
+ local n=0
+ for k,v in next,t do
+ n=n+1
+ if v then
+ s[n]=k.."+"
else
- sort(s)
- return concat(s,",")
+ 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
+ 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 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=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
- nt=nt+1
- t[nt]=v
- h[tag]=nt
- c[nt]=1
- return nt
+ rest=rest+1
end
- end
- local function pack_final(v)
- if c[v]<=criterium then
- return t[v]
+ end
+ else
+ for k,v in next,cc do
+ if v>20 then
+ rest=rest+1
+ elseif v>10 then
+ two=two+1
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
+ one=one+1
end
+ end
+ data.tables=tt
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
+ 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
+ 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
- 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
+ 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 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
+ else
+ for g1,d1 in next,c do
+ c[g1]=pack_normal(d1)
end
- data.tables=tt
+ end
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)
+ 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
- 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)
+ 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
- return false
- 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)
+ local c=step.coverage
+ if c then
+ for g1,d1 in next,c do
+ d1[2]=pack_indexed(d1[2])
+ end
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
+ 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
- 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
- end
- if flags then
- sequence.flags=pack_normal(flags)
- 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
- if sequences then
- packthem(sequences)
+ 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 sublookups then
- packthem(sublookups)
+ end
+ if flags then
+ sequence.flags=pack_normal(flags)
+ end
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 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])
+ 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
- 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 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
- 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
- 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
- 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
- packdeltas(variable.global)
- packdeltas(variable.horizontal)
- packdeltas(variable.vertical)
- packdeltas(variable.metrics)
+ end
end
- if not success(1,pass) then
- return
+ 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)
end
+ 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)
- 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
- end
- end
- if sequences then
- packthem(sequences)
- end
- if sublookups then
- packthem(sublookups)
+ 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
- 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)
+ 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
- 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)
+ if features then
+ sequence.features=pack_normal(features)
+ 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
+ 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
end
+ end
end
local unpacked_mt={
- __index=function(t,k)
- t[k]=false
- return k
- end
+ __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 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
- 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
+ kerns[k]=tv
end
+ end
+ 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 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]
+ 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
- sequence.features=tv
- features=tv
- end
- for script,feature in next,features do
- local tv=tables[feature]
- if tv then
- features[script]=tv
- end
+ 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 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
+ else
+ for g1,d1 in next,c do
+ local tv=tables[d1]
+ if tv then
+ c[g1]=tv
+ end
end
- if order then
- local tv=tables[order]
- if tv then
- sequence.order=tv
- 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
- if flags then
- local tv=tables[flags]
- if tv then
- sequence.flags=tv
- 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
- 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]
+ 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
- list[feature]=tv
+ d2[g3]=tv
end
+ end
end
+ 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
+ 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
- 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
+ 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
+ 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
+ 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
+ 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
- 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
+ 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
- else
- local n=new[k]
- if n then
- nested(v,n)
- else
- new[k]=v
- end
- 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]
- 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
+ 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
+ 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 "<noname>",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 "<noname>",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 "<error in base mode tracing>"
- 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 "<error in base mode tracing>"
+ 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
- if i then
- i.cursiveanchor=true
- else
- 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
+ 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
- properties[nxt]={
- injections={
- cursivex=dx,
- cursivey=dy,
- },
- }
- end
- return dx,dy,nofregisteredcursives
+ 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]
- 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
+ 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
+ if leftkern~=0 then
+ i.leftkern=(i.leftkern or 0)+leftkern
end
- end
- return x,y,w,h
+ 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
+ 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
- return 0,0
+ properties[current]={
+ [injection]={
+ leftkern=dx,
+ },
+ }
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
+ 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
- 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
+ replace=fontkern(rightkern)
+ done=true
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
+ 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
- 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
+ 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 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
+ 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 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(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 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
- 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 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
- prevglyph=nil
- prevdisc=current
- else
- prevglyph=nil
- 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 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
- nofregisteredpositions=0
+ prevglyph=nil
+ prevdisc=nil
end
- if trace_injections then
- show_result(head)
- end
- return tonode(head),true
+ 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
+ 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
- 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 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
- local yoffset=pn.yoffset
- if yoffset then
- oy=oy+yoffset
- end
+ ox=ox+(pn.leftkern or 0)
end
- setoffsets(n,ox,oy)
- if trace_marks then
- showoffset(n,true)
+ else
+ if false then
+ local leftkern=pp.leftkern
+ if leftkern then
+ ox=ox-leftkern
+ end
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
- 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
+ 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 "<error in node mode tracing>"
+ 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 "<error in node mode tracing>"
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 take_components=getcomponents
+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 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)
- 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])
- end
+ 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
- return head,start,false
+ 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
+ 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 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
+ 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
end
- return head,start,false,0,false
+ end
+ return head,start,false,0,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)
+ 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
- if mapping then
- local startchar=getchar(start)
- local kerns=mapping[startchar]
- if kerns then
+ 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
+ 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 l<s then
+ local i=l
+ local t=sweeptype=="post" or sweeptype=="replace"
+ while current and i<s do
+ local id=getid(current)
+ if id==glyph_code then
+ i=i+1
+ current=getnext(current)
+ elseif id==glue_code then
+ i=i+1
+ current=getnext(current)
+ hasglue=true
+ elseif id==disc_code then
+ if keepdisc then
+ keepdisc=false
+ if notmatchpre[current]~=notmatchreplace[current] then
+ lookaheaddisc=current
+ end
+ local replace=getfield(current,"replace")
+ while replace and i<s do
+ if getid(replace)==glyph_code then
+ i=i+1
end
+ replace=getnext(replace)
+ end
+ current=getnext(current)
+ elseif notmatchpre[current]~=notmatchreplace[current] then
+ head,current=flattendisk(head,current)
else
- break
+ current=getnext(current)
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)
+ else
+ current=getnext(current)
+ end
+ if not current and t then
+ current=getnext(sweepnode)
+ if current then
+ sweeptype=nil
end
+ end
end
- if l<s then
- local i=l
- local t=sweeptype=="post" or sweeptype=="replace"
- while current and i<s do
- local id=getid(current)
- if id==glyph_code then
- i=i+1
- current=getnext(current)
- elseif id==glue_code then
- i=i+1
- current=getnext(current)
- hasglue=true
- elseif id==disc_code then
- if keepdisc then
- keepdisc=false
- if notmatchpre[current]~=notmatchreplace[current] then
- lookaheaddisc=current
- end
- local replace=getfield(current,"replace")
- while replace and i<s do
- if getid(replace)==glyph_code then
- i=i+1
- end
- replace=getnext(replace)
- end
- current=getnext(current)
- elseif notmatchpre[current]~=notmatchreplace[current] then
- head,current=flattendisk(head,current)
- else
- current=getnext(current)
- end
- else
- current=getnext(current)
- end
- if not current and t then
- current=getnext(sweepnode)
- if current then
- sweeptype=nil
- end
- end
- 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
- 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)
+ 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
- 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
+ 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
+ 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 n<l then
+ last=getnext(last)
+ end
+ n=n+1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
+ else
break
+ end
+ else
+ goto next
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
+ 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=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
+ 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
- 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<l then
- last=getnext(last)
- end
- n=n+1
- elseif discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
- else
- break
- 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
- goto next
+ posttail=getprev(posttail)
end
- elseif char==false then
- if discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
- else
- break
- 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
- 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
- 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
+ break
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 n<s then
+ current=getnext(current)
+ end
+ n=n+1
+ elseif discfound then
+ notmatchreplace[discfound]=true
+ if notmatchpre[discfound] then
+ goto next
else
- goto next
+ break
end
- else
+ 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
- current=getnext(current)
- elseif seq[n][char] then
- if n<s then
- current=getnext(current)
- end
- n=n+1
- elseif discfound then
- notmatchreplace[discfound]=true
- if notmatchpre[discfound] then
- goto next
- else
- break
- end
- else
- goto next
- 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
- 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 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 discseen then
- notmatchpre={}
- notmatchpost={}
- notmatchreplace={}
+ if done then
+ break
end
- return head,start,done
+ ::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
- 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
+ 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
- setdisc(disc,pre,post,replace)
+ 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
- return getnext(disc),renewed
+ 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 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
- 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 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
- sweepnode=disc
- sweeptype="post"
- local new,ok=c_run(post,...)
- if ok then
- post=new
- renewed=true
- end
+ setlink(posttail,next)
+ else
+ post=next
end
if replace then
- sweepnode=disc
- sweeptype="replace"
- local new,ok=c_run(replace,...)
- if ok then
- replace=new
- renewed=true
- end
+ 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
- sweepnode=nil
- sweeptype=nil
- if renewed then
- setdisc(disc,pre,post,replace)
- if trace_testruns then
- report_disc("done",disc)
- end
+ end
+ sweepnode=nil
+ sweeptype=nil
+ if renewed then
+ setdisc(disc,pre,post,replace)
+ if trace_testruns then
+ report_disc("done",disc)
end
- return getnext(disc),renewed
+ 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 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)
+ 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 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
- return head,done
+ 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)
+ 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
- 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
- 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
- else
- 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
- if lastd then
- return lastd
- end
- start=startnext
+ end
+ if l and l.ligature then
+ lastd=d
+ end
else
- break
end
+ else
+ end
+ if lastd then
+ return lastd
+ end
+ start=startnext
+ else
+ break
end
- return 0
+ 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)
- 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
+ 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
+ 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
- if start then
- start=getnext(start)
- end
- else
- start=getnext(start)
+ 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
- elseif char==false then
- return head,done
- elseif sweep then
- return head,done
- else
- start=getnext(start)
+ end
end
+ 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
- return head,done
+ 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)
+ 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 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
+ 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
+ else
+ break
+ end
end
- if lastd then
- return lastd
+ if l and l.ligature then
+ lastd=d
end
- start=startnext
- else
- break
+ end
end
+ else
+ end
+ if lastd then
+ return lastd
+ end
+ start=startnext
+ else
+ break
end
- return 0
+ 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 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
+ 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
+ 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
+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
- top=top-1
- if stack[top]=="+TRT" then
- return nxt,top,-1
- else
- return nxt,top,1
- end
- end
+ 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 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
+ 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 nxt,-1,-1
+ return -1,-1
else
- return nxt,0,0
+ return 0,0
end
+ 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 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)
+ 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
+ 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
end
+ 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
+ if start then
+ start=getprev(start)
end
+ else
+ start=getprev(start)
+ end
+ else
+ start=getprev(start)
end
- if trace_steps then
- registerstep(head)
- end
+ else
+ start=getprev(start)
+ 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={}
+ else
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
+ 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,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
+ end
+ else
+ local merged=steps.merged
+ while start do
local char,id=ischar(start,font)
if char then
- position=position+1
+ if skiphash and skiphash[char] then
+ start=getnext(start)
+ else
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)
+ 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
end
+ end
end
- else
+ 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_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))
+ 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)
else
- start=getnext(start)
+ start=getnext(start)
end
+ end
end
- return tonode(head)
+ end
+ if trace_steps then
+ registerstep(head)
+ 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
+ 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
+ topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode)
+ start=getnext(start)
+ else
+ start=getnext(start)
+ end
end
+ return head
+ 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 }
- end
+ 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
function otf.plugininitializer(tfmdata,value)
- if type(value)=="string" then
- tfmdata.shared.plugin=plugins[value]
- end
+ 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
- local n=getnext(c)
+ 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
+ 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)
- if not n then
- return c
- end
- v=ischar(n,font)
- if not v then
- return c
- 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 dependent_vowel[v] then
- c=n
- n=getnext(c)
+ 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
- if nukta[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 halant[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
- 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 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
+ 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
- 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
+ syllableend=current
+ current=n
+ 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
+ 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
- else
+ 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
- start=false
- end
- if nbspaces>0 then
- head=replace_all_nbsp(head)
+ end
+ else
+ current=getnext(current)
end
- return tonode(head),done
+ start=false
+ end
+ if nbspaces>0 then
+ head=replace_all_nbsp(head)
+ end
+ return 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
+ 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
- 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
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
+ 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
- start=false
- current=getnext(current)
+ 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 nbspaces>0 then
- head=replace_all_nbsp(head)
+ 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
- return tonode(head),done
+ start=false
+ current=getnext(current)
+ end
+ if nbspaces>0 then
+ head=replace_all_nbsp(head)
+ end
+ return head,done
end
for i=1,nofscripts do
- methods[scripts_one[i]]=method_one
- methods[scripts_two[i]]=method_two
+ 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 <feff"..s.."> >> BDC",
- "EMC"
- end
+ local tounicode=fonts.mappings.tounicode16
+ function otf.getactualtext(s)
+ return
+ "/Span << /ActualText <feff"..s.."> >> 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 i<s and goback then
- n=n+1 t[n]=goback
- end
- end
- if f then
- n=n+1 t[n]=pop
- end
- n=n+1 t[n]=actuale
- character.commands=t
- end
+ 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
+ else
+ if f then
+ n=n+1 t[n]=pop
end
+ f=false
+ l=nil
+ end
+ n=n+1 t[n]=charcommand[entry.slot]
+ if s>1 and i<s and goback then
+ n=n+1 t[n]=goback
+ end
+ end
+ if f then
+ n=n+1 t[n]=pop
end
+ n=n+1 t[n]=actuale
+ character.commands=t
+ end
end
+ end
end
+ end
end
fonts.handlers.otf.features.register {
- name="colr",
- description="color glyphs",
- manipulators={
- base=initializecolr,
- node=initializecolr,
- }
+ name="colr",
+ description="color glyphs",
+ manipulators={
+ base=initialize,
+ node=initialize,
+ }
}
do
- 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={}
+ 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={}
+ 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=epdf.openMemStream(pdf,#pdf,f_name(nofstreams))
- cache[n]=o
- done=f_used(n)
- hashed[pdf]=done
- end
- return nil,done,nil
- end
+ local done=hashed[pdf]
+ if not done then
+ nofstreams=nofstreams+1
+ local o,n=openpdf(pdf,#pdf,f_name(nofstreams))
+ cache[n]=o
+ done=f_used(n)
+ hashed[pdf]=done
+ end
+ return done
+ end
+ else
+ local openpdf=pdfe.new
+ 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
+ end
end
local function pdftovirtual(tfmdata,pdfshapes,kind)
- if not tfmdata or not pdfshapes or not kind then
- return
- end
- local characters=tfmdata.characters
- local properties=tfmdata.properties
- local parameters=tfmdata.parameters
- local hfactor=parameters.hfactor
- properties.virtualized=true
- tfmdata.fonts={
- { id=0 }
- }
- local getactualtext=otf.getactualtext
- local storepdfdata=otf.storepdfdata
- local b,e=getactualtext(tounicode(0xFFFD))
- local actualb={ "pdf","page",b }
- local actuale={ "pdf","page",e }
- for unicode,character in sortedhash(characters) do
- local index=character.index
- if index then
- local pdf=pdfshapes[index]
- local typ=type(pdf)
- local data=nil
- local dx=nil
- local dy=nil
- if typ=="table" then
- data=pdf.data
- dx=pdf.dx or 0
- dy=pdf.dy or 0
- elseif typ=="string" then
- data=pdf
- dx=0
- 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 },
- { "image",{ filename=name,width=wd,height=ht,depth=dp } },
- actuale,
- }
- character[kind]=true
- end
- end
- end
+ if not tfmdata or not pdfshapes or not kind then
+ return
+ end
+ local characters=tfmdata.characters
+ local properties=tfmdata.properties
+ local parameters=tfmdata.parameters
+ local hfactor=parameters.hfactor
+ properties.virtualized=true
+ tfmdata.fonts={
+ { id=0 }
+ }
+ local getactualtext=otf.getactualtext
+ local storepdfdata=otf.storepdfdata
+ local b,e=getactualtext(tounicode(0xFFFD))
+ local actualb={ "pdf","page",b }
+ local actuale={ "pdf","page",e }
+ local vfimage=lpdf and lpdf.vfimage or function(wd,ht,dp,data,name)
+ local name=storepdfdata(data)
+ return { "image",{ filename=name,width=wd,height=ht,depth=dp } }
+ end
+ for unicode,character in sortedhash(characters) do
+ local index=character.index
+ if index then
+ local pdf=pdfshapes[index]
+ local typ=type(pdf)
+ local data=nil
+ local dx=nil
+ local dy=nil
+ if typ=="table" then
+ data=pdf.data
+ dx=pdf.dx or 0
+ dy=pdf.dy or 0
+ elseif typ=="string" then
+ data=pdf
+ dx=0
+ dy=0
+ end
+ if data 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)) },
+ 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
do
- 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
- 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
+ lookups[k]=false
end
- elseif kind=="number" then
- if position<0 then
- position=last-position+1
+ 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
- if position>last then
- position=last+1
- elseif position<first then
- position=first
+ 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
- else
- position=last+1
+ end
+ sequence.n=nofsequences
end
+ end
+ rulehash.n=rulesize
+ end
+ 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,position,first,last,sequences)
- end
- insert(sequences,position,sequence)
- end
- for s=1,#dataset do
- local specification=dataset[s]
- local valid=specification.valid
- local feature=specification.name or feature
- if not feature or feature=="" then
- report_otf("no valid name given for extra feature")
- elseif not valid or valid(data,specification,feature) then
- local initialize=specification.initialize
- if initialize then
- specification.initialize=initialize(specification,data) and initialize or nil
- end
- local askedfeatures=specification.features or everywhere
- local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
- local featuretype=normalized[specification.type or "substitution"] or "substitution"
- local featureflags=specification.flags or noflags
- local nocheck=specification.nocheck
- local futuresteps=specification.futuresteps
- local featureorder=specification.order or { feature }
- local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
- local nofsteps=0
- local steps={}
- local sublookups=specification.lookups
- local category=nil
- checkflags(specification,resources)
- if sublookups then
- local s={}
- for i=1,#sublookups do
- local specification=sublookups[i]
- local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
- local featuretype=normalized[specification.type or "substitution"] or "substitution"
- local featureflags=specification.flags or noflags
- local nofsteps=0
- local steps={}
- for i=1,#askedsteps do
- local list=askedsteps[i]
- local coverage=nil
- local format=nil
- if featuretype=="substitution" then
- coverage=prepare_substitution(list,featuretype,nocheck)
- elseif featuretype=="ligature" then
- coverage=prepare_ligature(list,featuretype,nocheck)
- elseif featuretype=="alternate" then
- coverage=prepare_alternate(list,featuretype,nocheck)
- elseif featuretype=="multiple" then
- coverage=prepare_multiple(list,featuretype,nocheck)
- elseif featuretype=="kern" or featuretype=="move" then
- format=featuretype
- coverage=prepare_kern(list,featuretype)
- elseif featuretype=="pair" then
- format="pair"
- coverage=prepare_pair(list,featuretype)
- elseif featuretype=="single" then
- format="single"
- coverage=prepare_single(list,featuretype)
- end
- if coverage and next(coverage) then
- nofsteps=nofsteps+1
- steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
- end
- end
- checkmerge(specification)
- checksteps(specification)
- s[i]={
- [stepkey]=steps,
- nofsteps=nofsteps,
- flags=featureflags,
- type=types[featuretype],
- }
- end
- sublookups=s
- end
- for i=1,#askedsteps do
- local list=askedsteps[i]
- local coverage=nil
- local format=nil
- if featuretype=="substitution" then
- category="gsub"
- coverage=prepare_substitution(list,featuretype,nocheck)
- elseif featuretype=="ligature" then
- category="gsub"
- coverage=prepare_ligature(list,featuretype,nocheck)
- elseif featuretype=="alternate" then
- category="gsub"
- coverage=prepare_alternate(list,featuretype,nocheck)
- elseif featuretype=="multiple" then
- category="gsub"
- coverage=prepare_multiple(list,featuretype,nocheck)
- elseif featuretype=="kern" or featuretype=="move" then
- category="gpos"
- format=featuretype
- coverage=prepare_kern(list,featuretype)
- elseif featuretype=="pair" then
- category="gpos"
- format="pair"
- coverage=prepare_pair(list,featuretype)
- elseif featuretype=="single" then
- category="gpos"
- format="single"
- coverage=prepare_single(list,featuretype)
- elseif featuretype=="chainsubstitution" then
- category="gsub"
- coverage=prepare_chain(list,featuretype,sublookups)
- elseif featuretype=="chainposition" then
- category="gpos"
- coverage=prepare_chain(list,featuretype,sublookups)
- else
- 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
+ report(name,category,first,first,last,sequences)
+ end
+ insert(sequences,first,sequence)
+ return
+ 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
+ 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 position<first then
+ position=first
+ end
+ else
+ position=last+1
end
if trace_loading then
- report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip)
+ report(name,category,position,first,last,sequences)
+ end
+ insert(sequences,position,sequence)
+ end
+ for s=1,#dataset do
+ local specification=dataset[s]
+ local valid=specification.valid
+ local feature=specification.name or feature
+ if not feature or feature=="" then
+ report_otf("no valid name given for extra feature")
+ elseif not valid or valid(data,specification,feature) then
+ local initialize=specification.initialize
+ if initialize then
+ specification.initialize=initialize(specification,data) and initialize or nil
+ end
+ local askedfeatures=specification.features or everywhere
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nocheck=specification.nocheck
+ local futuresteps=specification.futuresteps
+ local featureorder=specification.order or { feature }
+ local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0
+ local nofsteps=0
+ local steps={}
+ local sublookups=specification.lookups
+ local category=nil
+ checkflags(specification,resources)
+ if sublookups then
+ local s={}
+ for i=1,#sublookups do
+ local specification=sublookups[i]
+ local askedsteps=specification.steps or specification.subtables or { specification.data } or {}
+ local featuretype=normalized[specification.type or "substitution"] or "substitution"
+ local featureflags=specification.flags or noflags
+ local nofsteps=0
+ local steps={}
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ end
+ if coverage and next(coverage) then
+ nofsteps=nofsteps+1
+ steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources)
+ end
+ end
+ checkmerge(specification)
+ checksteps(specification)
+ s[i]={
+ [stepkey]=steps,
+ nofsteps=nofsteps,
+ flags=featureflags,
+ type=types[featuretype],
+ }
+ end
+ sublookups=s
+ end
+ for i=1,#askedsteps do
+ local list=askedsteps[i]
+ local coverage=nil
+ local format=nil
+ if featuretype=="substitution" then
+ category="gsub"
+ coverage=prepare_substitution(list,featuretype,nocheck)
+ elseif featuretype=="ligature" then
+ category="gsub"
+ coverage=prepare_ligature(list,featuretype,nocheck)
+ elseif featuretype=="alternate" then
+ category="gsub"
+ coverage=prepare_alternate(list,featuretype,nocheck)
+ elseif featuretype=="multiple" then
+ category="gsub"
+ coverage=prepare_multiple(list,featuretype,nocheck)
+ elseif featuretype=="kern" or featuretype=="move" then
+ category="gpos"
+ format=featuretype
+ coverage=prepare_kern(list,featuretype)
+ elseif featuretype=="pair" then
+ category="gpos"
+ format="pair"
+ coverage=prepare_pair(list,featuretype)
+ elseif featuretype=="single" then
+ category="gpos"
+ format="single"
+ coverage=prepare_single(list,featuretype)
+ elseif featuretype=="chainsubstitution" then
+ category="gsub"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ elseif featuretype=="chainposition" then
+ category="gpos"
+ coverage=prepare_chain(list,featuretype,sublookups)
+ else
+ 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.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
+ 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
+ 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
- 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)
-registerotffeature {
- name='anum',
- description='arabic digits',
-}
-local lookups={}
-local protect={}
-local revert={}
-local zwjchar=0x200C
-local zwj={ zwjchar }
-otf.addfeature {
- name="blockligatures",
- type="chainsubstitution",
- nocheck=true,
- prepend=true,
- future=true,
- lookups={
- {
- type="multiple",
- data=lookups,
- },
- },
- data={
- rules=protect,
- }
-}
-otf.addfeature {
- 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 settings_to_array=utilities.parsers and utilities.parsers.settings_to_array
- or function(s) return string.split(s,",") end
-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
- interfaces.implement {
- name="blockligatures",
- arguments="string",
- actions=blockligatures,
- }
-end
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' }
+ },
+ ['fi']={
+ { 'i','fii' }
+ },
+ ['fl']={
+ { 'i','fli' }
+ },
+ ['s']={
+ { 't','st' }
+ },
+ ['i']={
+ { 'j','ij' }
+ },
+ },
+ texligatures=allocate {
+ ['quoteleft']={
+ { 'quoteleft','quotedblleft' }
},
- 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",
+ ['quoteright']={
+ { 'quoteright','quotedblright' }
},
- 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",
+ ['hyphen']={
+ { 'hyphen','endash' }
},
- 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",
+ ['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,
- }
+local specification={
+ 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 },
-}
-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]
}
- setmetatableindex(new_c,old_c)
- characters[unicode]=new_c
- additions[private]=old_c
+ end
+ else
+ if commands then
+ prependcommands (commands,
+ hshift
+ )
+ else
+ character.commands={
+ hshift,
+ charcommand[unicode]
+ }
+ 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("<missing font database, run: mtxrun --script fonts --reload --simple>")
+ logs.report("fonts","missing font database, run: mtxrun --script fonts --reload --simple")
fonts.names.reportmissingbase = nil
end
function fonts.names.reportmissingname()
- texio.write("<unknown font in database, run: mtxrun --script fonts --reload --simple>")
+ 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("<font database loaded: ",foundname,">")
+ 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(" <push namespace>")
+ -- 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(" <pop namespace>")
+ -- 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(" <fatal error: invalid pop of generic_context>")
+ 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(" <luatex-fonts: unable to locate %s>",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(" <luatex-fonts.lua loaded in %0.3f seconds>", 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("<unknown language file for: " .. tag .. ">")
+ 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("<language file: " .. tag .. ">")
+ 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("<invalid language table: " .. tag .. ">")
+ logs.report("languages","invalid language table for '%s'",tag)
os.exit()
end
else
- texio.write("<invalid language file: " .. tag .. ">")
+ 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("<mplib: %s>",format(...)))
+ if logs.report then
+ logs.report("metapost",...)
+ else
+ texio.write(format("<mplib: %s>",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