texlive[76089] Master: context 2025-08-17 17:57 A

commits+karl at tug.org commits+karl at tug.org
Mon Aug 18 21:08:11 CEST 2025


Revision: 76089
          https://tug.org/svn/texlive?view=revision&revision=76089
Author:   karl
Date:     2025-08-18 21:08:11 +0200 (Mon, 18 Aug 2025)
Log Message:
-----------
context 2025-08-17 17:57 A

Modified Paths:
--------------
    trunk/Master/bin/aarch64-linux/luametatex
    trunk/Master/bin/i386-linux/luametatex
    trunk/Master/bin/universal-darwin/luametatex
    trunk/Master/bin/windows/context.exe
    trunk/Master/bin/windows/luametatex.exe
    trunk/Master/bin/windows/mtxrun.exe
    trunk/Master/bin/windows/mtxrun.lua
    trunk/Master/bin/x86_64-darwinlegacy/luametatex
    trunk/Master/bin/x86_64-linux/luametatex
    trunk/Master/texmf-dist/doc/context/VERSION
    trunk/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-characters.pdf
    trunk/Master/texmf-dist/doc/context/documents/general/manuals/signals.pdf
    trunk/Master/texmf-dist/doc/context/documents/general/manuals/tagging.pdf
    trunk/Master/texmf-dist/doc/context/presentations/examples/present-stepper-001.pdf
    trunk/Master/texmf-dist/doc/context/presentations/examples/present-stepper-001.tex
    trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-grep.html
    trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-grep.xml
    trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.html
    trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.man
    trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.xml
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-characters.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/tagging/signals.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/tagging/tagging.tex
    trunk/Master/texmf-dist/doc/man/man1/context.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mptopdf.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-babel.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-bibtex.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-cache.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-chars.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-check.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-colors.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-context.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-convert.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-ctan.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-dvi.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-epub.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-evohome.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-fcd.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-fixpdf.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-flac.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-fonts.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-grep.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-interface.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-kpse.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-metapost.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-modules.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-package.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-patterns.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-pdf.1
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-pdf.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-plain.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-profile.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-rsync.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-scite.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-server.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-spell.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-synctex.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-texworks.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-tools.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-unicode.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-unzip.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-update.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-vscode.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-watch.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun-youless.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/mtxrun.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/texexec.man1.pdf
    trunk/Master/texmf-dist/doc/man/man1/texmfstart.man1.pdf
    trunk/Master/texmf-dist/scripts/context/lua/mtx-grep.lua
    trunk/Master/texmf-dist/scripts/context/lua/mtx-patterns.lua
    trunk/Master/texmf-dist/scripts/context/lua/mtx-pdf.lua
    trunk/Master/texmf-dist/scripts/context/lua/mtx-squid.lua
    trunk/Master/texmf-dist/scripts/context/lua/mtxrun.lua
    trunk/Master/texmf-dist/tex/context/base/mkii/cont-new.mkii
    trunk/Master/texmf-dist/tex/context/base/mkii/context.mkii
    trunk/Master/texmf-dist/tex/context/base/mkiv/bibl-bib.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/chem-str.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/cldf-ini.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/cont-new.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/data-tex.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/export-example.css
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-imp-combining.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-otd.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-ots.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-oup.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-sel.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/font-shp.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/grph-img.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/l-dir.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/l-sandbox.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/lang-txt.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-tab.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-tex.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-xml.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/meta-imp-outlines.mkiv
    trunk/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/node-ref.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/publ-ini.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/spac-ali.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/status-files.pdf
    trunk/Master/texmf-dist/tex/context/base/mkiv/status-lua.pdf
    trunk/Master/texmf-dist/tex/context/base/mkiv/strc-lst.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/strc-syn.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/strc-tag.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/trac-par.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/typo-tal.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-rnd.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-sci.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-parallel.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-quadrant.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-runner.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-segment.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-squid.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig.lua
    trunk/Master/texmf-dist/tex/context/base/mkiv/util-tab.lua
    trunk/Master/texmf-dist/tex/context/base/mkxl/anch-bck.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/anch-loc.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/anch-pos.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/attr-ini.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/attr-lay.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/back-exp-imp-tag.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/back-exp.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ini.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/buff-par.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ver.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ver.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/cont-log.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/cont-new.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/context-libraries.tma
    trunk/Master/texmf-dist/tex/context/base/mkxl/context.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/core-sys.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/core-uti.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/driv-shp.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/file-job.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/font-cff.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/font-ogr.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/font-otd.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/font-ots.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/font-oup.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/font-shp.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/font-sty.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/grph-exp.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/grph-fig.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/grph-inc.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lang-ini.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/lang-lab.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/lang-tra.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-ano.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fix-imp-contents.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fix-imp-fonts.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fld.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fmt.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-img.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-ini.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-lmt.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-pde.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-mkiv.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/luat-usr.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/lxml-mms.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-acc.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-act.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-ali.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-del.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-dld.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-frc.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-ini.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-noa.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-rad.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/math-vfu.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/meta-ini.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/meta-pdf.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-cnt.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-pdf.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-ptr.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-svg.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/node-fin.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/node-nut.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/node-ref.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/node-res.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/node-rul.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/node-tra.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/pack-bck.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/pack-box.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/pack-com.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/pack-mat.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/pack-mis.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/pack-rul.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-app.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-blk.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-cst.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-cst.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-lin.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-mak.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-mix.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-mvl.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-mvl.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/page-pcl.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/phys-dim.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-but.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-fld.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-hlp.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-ini.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-wid.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/scrp-ini.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/scrp-ini.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ali.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ali.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/spac-hor.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/spac-lin.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/spac-prf.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ver.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ver.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-con.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-des.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-enu.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-flt.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ind.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-itm.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lab.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lnt.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lst.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lst.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-mat.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-not.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ref.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ref.mklx
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-reg.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-reg.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-sec.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-syn.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-syn.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tag.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tag.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tnt.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/strc-usr.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/supp-box.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/syst-aux.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/syst-aux.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/tabl-mis.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/tabl-xtb.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/trac-bld.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/trac-inf.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/trac-riv.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/trac-vis.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/typo-del.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/typo-dif.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/typo-itc.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/typo-krn.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/typo-mar.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/typo-stc.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/typo-swp.mkxl
    trunk/Master/texmf-dist/tex/context/base/mkxl/typo-tal.lmt
    trunk/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.lua
    trunk/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.lua
    trunk/Master/texmf-dist/tex/context/modules/mkiv/s-present-stepper.mkiv
    trunk/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.lua
    trunk/Master/texmf-dist/tex/context/modules/mkxl/m-dirtree.mkxl
    trunk/Master/texmf-dist/tex/context/modules/mkxl/s-math-verbatim.mkxl
    trunk/Master/texmf-dist/tex/context/modules/mkxl/s-squid.mkxl
    trunk/Master/texmf-dist/tex/context/modules/mkxl/x-asciimath.lmt
    trunk/Master/texmf-dist/tex/luatex/context/luatex-fonts-merged.lua

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/context/examples/tagging/
    trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.pdf
    trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.tex
    trunk/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-shift.tex
    trunk/Master/texmf-dist/source/context/base/luametatex-20250816.src.zip
    trunk/Master/texmf-dist/tex/context/base/mkxl/cldf-ini.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-crp.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-combination.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-delimited.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-description.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-float.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-formula.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-itemgroup.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-list.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-margin.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-section.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-verbatim.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-whatever.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-demo.lmt
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-uac.lmt
    trunk/Master/texmf-dist/tex/context/modules/mkxl/s-signals-example.mkxl
    trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-cn.llg
    trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-deo.llg
    trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-farsi.llg
    trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-kr.llg
    trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-ua.llg

Removed Paths:
-------------
    trunk/Master/texmf-dist/source/context/base/luametatex-20250725.src.zip
    trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-crap.lmt

Modified: trunk/Master/bin/aarch64-linux/luametatex
===================================================================
(Binary files differ)

Modified: trunk/Master/bin/i386-linux/luametatex
===================================================================
(Binary files differ)

Modified: trunk/Master/bin/universal-darwin/luametatex
===================================================================
(Binary files differ)

Modified: trunk/Master/bin/windows/context.exe
===================================================================
(Binary files differ)

Modified: trunk/Master/bin/windows/luametatex.exe
===================================================================
(Binary files differ)

Modified: trunk/Master/bin/windows/mtxrun.exe
===================================================================
(Binary files differ)

Modified: trunk/Master/bin/windows/mtxrun.lua
===================================================================
--- trunk/Master/bin/windows/mtxrun.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/bin/windows/mtxrun.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -577,7 +577,7 @@
 
 package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
 
--- original size: 9604, stripped down to: 6394
+-- original size: 9700, stripped down to: 6452
 
 if not modules then modules={} end modules ['l-sandbox']={
  version=1.001,
@@ -735,12 +735,6 @@
   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
   debug={
@@ -800,10 +794,19 @@
   sandboxed=true
  end
 end
-blockrequire("lfs",lfs)
-blockrequire("io",io)
-blockrequire("os",os)
-blockrequire("ffi",ffi)
+do
+ local function blockrequire(name,lib)
+  if trace then
+   report("preventing reload of: %s",name)
+  end
+  blocked[name]=lib or _G[name] or false
+ end
+ blockrequire("lfs",lfs)
+ blockrequire("io",io)
+ blockrequire("os",os)
+ blockrequire("ffi",ffi)
+ sandbox.blockrequire=blockrequire
+end
 local function supported(library)
  local l=_G[library]
  return l
@@ -5221,7 +5224,7 @@
 
 package.loaded["l-dir"] = package.loaded["l-dir"] or true
 
--- original size: 19139, stripped down to: 11345
+-- original size: 19379, stripped down to: 11553
 
 if not modules then modules={} end modules ['l-dir']={
  version=1.001,
@@ -5323,7 +5326,7 @@
   end
  end
 end
-local function glob_pattern_table(path,patt,recurse,result)
+local function glob_pattern_table(path,patt,recurse,result,dirresult)
  if not result then
   result={}
  end
@@ -5363,12 +5366,16 @@
  end
  if dirs then
   for i=1,nofdirs do
-   glob_pattern_table(dirs[i],patt,recurse,result)
+   local dir=dirs[i]
+   glob_pattern_table(dir,patt,recurse,result,dirresult)
+   if dirresult then
+    dirresult[#dirresult+1]=dir
+   end
   end
  end
- return result
+ return result,dirresult
 end
-local function globpattern(path,patt,recurse,method)
+local function globpattern(path,patt,recurse,method,dirmethod)
  local kind=type(method)
  if patt and sub(patt,1,-3)==path then
   patt=false
@@ -5378,8 +5385,11 @@
   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
+ elseif okay then
+  local files,dirs=glob_pattern_table(path,patt,recurse,{},{})
+  return files or {},dirs or {}
  else
-  return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+  return {},dirmethod and {} or nil
  end
 end
 dir.globpattern=globpattern
@@ -5434,7 +5444,7 @@
 local filter=Cs ((
  P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
 )^0 )
-local function glob(str,t)
+local function glob(str,t,dirstoo)
  if type(t)=="function" then
   if type(str)=="table" then
    for s=1,#str do
@@ -5451,31 +5461,29 @@
     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
+ elseif 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
-  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
+   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,dirstoo)
+  else
+   return {},dirstoo and {} or nil
+  end
  end
 end
 dir.glob=glob
@@ -7667,7 +7675,7 @@
 
 package.loaded["util-tab"] = package.loaded["util-tab"] or true
 
--- original size: 34169, stripped down to: 18433
+-- original size: 35024, stripped down to: 18453
 
 if not modules then modules={} end modules ['util-tab']={
  version=1.001,
@@ -7682,7 +7690,7 @@
 local format,gmatch,gsub,sub=string.format,string.gmatch,string.gsub,string.sub
 local concat,insert,remove,sort=table.concat,table.insert,table.remove,table.sort
 local setmetatable,getmetatable,tonumber,tostring,rawget=setmetatable,getmetatable,tonumber,tostring,rawget
-local type,next,rawset,tonumber,tostring,load,select=type,next,rawset,tonumber,tostring,load,select
+local type,next,rawset,rawget,tonumber,tostring,load,select=type,next,rawset,rawget,tonumber,tostring,load,select
 local lpegmatch,P,Cs,Cc=lpeg.match,lpeg.P,lpeg.Cs,lpeg.Cc
 local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs
 local formatters=string.formatters
@@ -8403,7 +8411,7 @@
   return function() end
  end
 end
-function combine(target,source)
+local function combine(target,source)
  if target then
   for k,v in next,source do
    if type(v)=="table" then
@@ -16668,7 +16676,7 @@
 
 package.loaded["util-sig"] = package.loaded["util-sig"] or true
 
--- original size: 5924, stripped down to: 3207
+-- original size: 5963, stripped down to: 3240
 
 if not modules then modules={} end modules ['util-sig']={
  version=1.001,
@@ -16686,6 +16694,7 @@
 local serialwrite=serial and serial.write
 if serialwrite then
  signals.serialwrite=serialwrite
+ signals.serialprefix=":lmtx:1:"
  local ports={}
  local function clean(port)
   return "serial_port_"..string.gsub(port,"[^a-zA-Z0-9]","")..""
@@ -16823,7 +16832,7 @@
 
 package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
 
--- original size: 62833, stripped down to: 36542
+-- original size: 62856, stripped down to: 36566
 
 if not modules then modules={} end modules ['lxml-tab']={
  version=1.001,
@@ -16864,12 +16873,13 @@
 end
 end
 local nsremap,resolvens=xml.xmlns,xml.resolvens
-local stack,level,top,at,xmlnms,errorstr
+local stack,level,top,at,xmlns,errorstr
 local entities,parameters
 local strip,utfize,resolve,cleanup,resolve_predefined,unify_predefined
 local dcache,hcache,acache
 local mt,dt,nt
 local currentfilename,currentline,linenumbers
+local reported_at_errors
 local grammar_parsed_text_one
 local grammar_parsed_text_two
 local grammar_unparsed_text
@@ -20632,7 +20642,7 @@
 
 package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
 
--- original size: 11096, stripped down to: 7702
+-- original size: 11118, stripped down to: 7721
 
 if not modules then modules={} end modules ['lxml-xml']={
  version=1.001,
@@ -20736,6 +20746,7 @@
   return ""
  end
 end
+local result=false
 local xmltexthandler=xmlnewhandlers {
  name="string",
  initialize=function()
@@ -26959,8 +26970,8 @@
 
 -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua util-sig.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua util-jsn.lua
 -- skipped libraries : -
--- original bytes    : 1077465
--- stripped bytes    : 429343
+-- original bytes    : 1078740
+-- stripped bytes    : 430256
 
 -- end library merge
 

Modified: trunk/Master/bin/x86_64-darwinlegacy/luametatex
===================================================================
(Binary files differ)

Modified: trunk/Master/bin/x86_64-linux/luametatex
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/context/VERSION
===================================================================
--- trunk/Master/texmf-dist/doc/context/VERSION	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/VERSION	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1 +1 @@
-2025-07-27 21:43 A
+2025-08-17 17:57 A

Modified: trunk/Master/texmf-dist/doc/context/documents/general/manuals/lowlevel-characters.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/context/documents/general/manuals/signals.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/context/documents/general/manuals/tagging.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.pdf	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.pdf	2025-08-18 19:08:11 UTC (rev 76089)

Property changes on: trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.tex	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,851 @@
+% language=en
+
+\setupbodyfont
+  [dejavu]
+
+\setupinteraction
+  [state=start,
+   focus=standard,
+   color=,
+   contrastcolor=,
+   style=]
+
+% \setupinteractionscreen
+%   [option=bookmark]
+%
+% \placebookmarks
+%   [section,subsection]
+%   [force=yes]
+
+% \enabledirectives[backend.usetags=basic]
+% \enabletrackers[backend.tags]
+% \enabletrackers[structures.tags.endpoints]
+% \enabletrackers[structures.tags.analyze]
+% \enabletrackers[structures.tags.rolemap]
+
+% We only do this as test; it is not needed in UA2 and actually it
+% also doesn't mix well with a granular mapping
+
+% \enabletrackers[structures.tags.objects]
+
+% Input file 19.750 bytes:
+
+% no tagging   : 155,428
+% just tagging : 179,421
+% ua2 tagging  : 198,652  uncompressed 688,203
+
+\setupbackend
+  [%level=0,
+   format=pdf/ua-2]
+
+\setuptagging
+  [state=start,
+   preset=basic,
+   option=interaction,
+   level=3,
+   comment={A document explaining a basic tagging setup}]
+
+\setuplayout
+  [backspace=.75es,
+   leftmargin=0es,
+   rightmargin=1es,
+   width=fit,
+   header=0es,
+   footer=.5es,
+   height=fit]
+
+\setupwhitespace
+  [medium]
+
+\setupheadertexts
+  []
+
+\setupfootertexts
+  []
+  [pagenumber]
+
+\setupheads
+  [section,subsection]
+  [color=darkred]
+
+\setuphead
+  [section]
+  [style=\bfb]
+
+\setuphead
+  [subsection]
+  [style=\bfa]
+
+\setupexternalfigures
+  [location={local,global,default}]
+
+\setupcombinedlist
+  [content]
+  [list={section,subsection},
+   alternative=a]
+
+\setuplist
+  [section,subsection]
+  [numberstyle=bold,
+   numbercolor=darkred]
+
+\setuplist
+  [subsection]
+  [margin=1em]
+
+\setupmargindata
+  [right]
+  [style=small]
+
+\startbuffer[bib]
+
+ at techreport{iso32000,
+    author      = {{ISO}},
+    title       = {Document management — Portable document format — Part 2: PDF 2.0},
+    institution = {International Organization for Standardization},
+    address     = {Geneva, Switzerland},
+    year        = {2020},
+    type        = {International Standard},
+    number      = {ISO 32000-2:2020}
+}
+
+ at techreport{iso32005,
+    author      = {{ISO}},
+    title       = {Document management — Portable Document Format — PDF 1.7 and 2.0 structure namespace inclusion in ISO 32000-2},
+    institution = {International Organization for Standardization},
+    address     = {Geneva, Switzerland},
+    year        = {2023},
+    type        = {Technical Specification},
+    number      = {ISO/TS 32005:2023}
+}
+
+ at techreport{iso14289,
+    author      = {{ISO}},
+    title       = {Document management applications — Electronic document file format enhancement for accessibility — Part 2: Use of ISO 32000-2 (PDF/UA-2)},
+    institution = {International Organization for Standardization},
+    address     = {Geneva, Switzerland},
+    year        = {2024},
+    type        = {International Standard},
+    number      = {ISO 14289-2:2024}
+}
+\stopbuffer
+
+\usebtxdataset
+  [bib.buffer]
+
+\usebtxdefinitions
+  [aps]
+
+\setupbtxrendering
+  [aps]
+  [sorttype=dataset,
+   numbering=short,
+   before={\blank[big]}]
+
+\setupbtxlist
+  [aps]
+  [width=fit,
+   align=flushleft,
+   alternative=paragraph,
+   distance=0.5em,
+   interaction=start,
+   style=small]
+
+\setupbtx
+  [aps:cite]
+  [alternative=short]
+
+\usemodule[abbreviations-logos]
+
+\startdocument
+  [title=Basic tagging]
+
+\startpagemakeup
+  [pagestate=start]
+
+\startimage[alternativetext=Frontpage with some tags]
+\startluacode
+  local metafun  = context.metafun
+  local pdftags  = table.load(resolvers.findfile("lpdf-tag-imp-uac.lmt"))
+  local tagtable = pdftags.quack
+
+  -- inspect(pdftags)
+
+  metafun.start()
+
+  for k, v in table.sortedhash(tagtable) do
+
+        metafun([[
+            numeric ry ;
+              ry := uniformdeviate(1)*uniformdeviate(1) ;
+              label("\bold %s",(0,0))
+              rotated (-15 + uniformdeviate(30))
+              scaled (2 + uniformdeviate(4))
+              shifted (uniformdeviate(PaperWidth), (0.7 - 0.2*ry)*PaperHeight)
+              withcolor (ry)[darkgray,white]
+              withstacking -1 ;
+        ]],k)
+
+        for i = 1, #v do
+
+            metafun([[
+                numeric ry ;
+                ry := uniformdeviate(1)*uniformdeviate(1) ;
+                label("\bold %s",(0,0))
+                rotated (-45 + uniformdeviate(90))
+                scaled (1 + uniformdeviate(3))
+                shifted (uniformdeviate(PaperWidth), (0.3 + 0.2*ry)*PaperHeight)
+                withcolor (ry)[darkgray,white]
+                withstacking -2 ;
+            ]],v[i])
+
+        end
+
+    end
+
+    metafun("fill unitsquare xyscaled(PaperWidth,0.3PaperHeight) withcolor darkred ;")
+    metafun("fill unitsquare xyscaled(PaperWidth,0.3PaperHeight) yshifted 0.7 PaperHeight withcolor darkred ;")
+
+    metafun([[
+        label("\bold (basic)",origin)
+        xsized 0.9PaperWidth
+        shifted (0.5*PaperWidth,0.85*PaperHeight)
+        withcolor white ;
+    ]])
+
+    metafun([[
+        label("\bold tagging",origin)
+                xsized 0.9PaperWidth
+                shifted (0.5*PaperWidth,0.15*PaperHeight)
+                withcolor white ;
+    ]])
+
+    metafun("clip currentpicture to unitsquare xyscaled(PaperWidth,PaperHeight) ;")
+
+    metafun.stop()
+\stopluacode
+\stopimage
+
+\stoppagemakeup
+
+\startsubject
+  [title={Contents}]
+
+\startcolumns
+  [distance=3em]
+
+\placecombinedlist[content]
+
+\stopcolumns
+
+\stopsubject
+
+\startsection
+  [title=Introduction]
+
+In this document we describe one possible way to tag basic \PDF\ files. With
+basic we mean simple, rather flat structure documents, like articles. This
+document is itself one such example. Our hope is that this simplified approach to
+tagging can be useful for the \CONTEXT\ community, but we do not pretend that the
+tagging setup we suggest here will fit the more advanced structures often present
+in \CONTEXT\ documents. On the other hand, you will hopefully see that you can
+set up your own mapping as you wish, so this document is at the same time a show
+case for a possible way to do that.
+
+If you do not change the mappings in your file, most content will get mapped to
+\typ {NonStruct}. The reason is that it is a somewhat safe tag, and even though
+it might not be the most informative tag to use, it will (very likely) lead to a
+document that validates. To use the mappings discussed in this document you need
+to enable tagging, for example by adding
+
+\starttyping
+\setupbackend[format=pdf/ua-2]
+\stoptyping
+
+and then add
+
+\starttyping
+\setuptagging[state=start,preset=basic]
+\stoptyping
+
+to get the specific setup.
+
+Reading the various \ISO\ standards \cite[iso32000,iso32005,iso14289] (we
+mainly include the references here to be able to test a basic bibliography setup
+in this document) is not always so easy, and sometimes wonder how the reasoning
+behind them were going. Their table(s) on permitted nesting of tags feels very
+arbitrary and not always logical. Some of them are claimed to be explained
+elsewhere than in the table (in another standard!), but even when reading the
+rules are not clear to us. Some of the possible tags do even seem less useful
+or extra complicated to handle, and we simply do not map to them.
+
+Below we provide, section by section, examples and comments on the various types
+of content and tag we do have in mind for the so-called basic tagging. This
+serves the purpose of showing the reader on examples that we think work good
+enough. There is, however, no guarantee. If you start to nest these things or use
+some low-level hacking or so, you are on your own.
+
+The rules we discuss here are defined in various files, depending on the type of
+mechanism. They are then collected (or linked to) in the file \typ
+{lpdf-tag-imp-basic.lmt} This way, you as a user, can create your own file(s) and
+make your own mappings with your favorite tagging setup, in particular by using
+parts of the setups we provide here.
+
+We will soon turn to the details, but let us mention that a few more details on
+reasoning and comments are available in \in {Section} [sec:moredetails].
+By the way, this version was validated by verapdf 1.29.90.
+\stopsection
+
+\startsection
+  [title=Some basics]
+
+The good news when it comes to tagging is that \CONTEXT\ was built with structure
+in mind. It has for a very long time been possible to export to structured XML.
+Thus, for example, when one adds a section (using \tex {startsection} and \tex
+{stopsection}) one gets
+
+\starttyping
+<section>
+  <sectioncaption>
+    <sectionnumber>
+      2
+    </sectionnumber>
+    <sectiontitle>
+      Some basics
+    </sectiontitle>
+  </sectioncaption>
+  <sectioncontent>
+    ...
+  </sectioncontent>
+</section>
+\stoptyping
+
+So, our problem has been to map each of these onto something that is safe and
+useful for the \PDF\ accessibility standards. All our documents start with a \typ
+{<document>} structure that is mapped to a \typ {Document} structure type, and
+then at the next level sits \typ {<documentpart>}, which we map to \typ {Part}.
+These two has category \typ {Document} and \typ {Grouping}, respectively. Neither
+of them can contain content directly, so extra level(s) are needed. We only
+mention here that if those extra levels are not naturally present, we enforce
+(almost always) a \typ {P} tag, that indeed can have content.
+
+We can easily get an overview over this document by invoking
+
+\starttyping
+mtxrun --script pdf --check tagging-basic.pdf
+\stoptyping
+
+That creates a file \typ {tagging-basic-tagview.xml} with lots of data. If
+you have verapdf installed, it also runs a validation check on the file.
+
+\stopsection
+
+\startsection
+  [title=Headings]
+
+When we add a section we will get \typ {<section>} mapped onto \typ {Sect} and
+\typ {<sectioncontent>} mapped onto \typ {Div}. These are also in the \typ
+{Grouping} category, and therefore do not directly contain content. We also get
+\typ {<sectioncaption>} mapped onto some \typ {Hn} and \typ {<sectionnumber>} and
+\typ {<sectiontitle>} mapped onto \typ {Lbl}. Since we map \typ
+{<sectioncontent>} to \typ {Div}, we need some structure type below that can
+contain content. If we just type text, we get \typ {P}. Thus, a single section
+can give rise to (here we indicate content in parentheses)
+
+\starttyping
+Document
+  Part
+    Sect
+      H1
+        Lbl (3)
+        Lbl (Headings)
+      Div
+        P   (When we add...)
+\stoptyping
+
+So far so good. When we start to nest sections and subsections and so on, we need
+to use tags that nest well. The \typ {Div} can have \typ {Sect}, so nesting sections
+should work.
+
+We support a few levels of headings, and one is supposed to map them onto \typ
+{H1}, \typ {H2} and so on upto \typ {H5}, see \in {Table} [table:headings].
+
+\startbuffer[headingtable]
+\startplacetable
+  [title=Different heading mappings.,
+   reference=table:headings]
+  \starttabulatehead
+    \FL
+    \NC {\bf Heading} \NC {\bf Tag} \NC \NR
+    \ML
+  \stoptabulatehead
+  \starttabulate[|T|T|]
+    \NC part                         \NC H1 \NC \NR
+    \NC chapter, title               \NC H2 \NC \NR
+    \NC section, subject             \NC H3 \NC \NR
+    \NC subsection, subsubject       \NC H4 \NC \NR
+    \NC subsubsection, subsubsubject \NC H5 \NC \NR
+    \LL
+  \stoptabulate
+\stopplacetable
+\stopbuffer
+
+\getbuffer[headingtable]
+
+If you, as in this document, start at another level than \typ {part}, it might be
+good to map your highest level to \typ {H1}. In this document, where section is
+the highest level, we have done
+
+\starttyping
+\setuptagging[level=3]
+\stoptyping
+
+which means that we map the third level onto \typ {H1}. The interested reader can
+peek into \typ {lpdf-tag-imp-basic-section.lmt}, to see how that was implemented.
+
+\stopsection
+
+\startsection
+  [title=Itemgroups]
+
+There are several types of lists available and they are all using the \typ
+{itemgroup} mechanism. We add a bullet list with the code
+
+\startbuffer
+\startitemize
+  \startitem First item.  \stopitem
+  \startitem Second item. \stopitem
+\stopitemize
+\stopbuffer
+
+\typebuffer
+
+and the typeset output is shown below.
+
+\getbuffer
+
+This gets mapped into
+
+\starttyping
+L
+  LI
+    Lbl (•)
+    LBody (First item.)
+  LI
+    Lbl (•)
+    LBody (Second item.)
+\stoptyping
+
+We can indeed use simple lists, bulleted or with numbers or characters. It is
+assumed that items are added with \tex {startitem} and \tex {stopitem}, not
+just \tex {item}. It also works to nest lists.
+
+\startitemize[n]
+  \startitem
+    Here is some text in the numbered list. This item
+    also contains a second list.
+    \startitemize
+      \startitem First item in the nested list.  \stopitem
+      \startitem Second item in the nested list. \stopitem
+      \startitem Third item in the nested list.  \stopitem
+    \stopitemize
+  \stopitem
+  \startitem
+    Here is some more text in the second item of the numbered list.
+  \stopitem
+\stopitemize
+
+\stopsection
+
+\startsection
+  [title=Floats]
+
+We mention the two most common type of float elements, tables and figures,
+but in principle other floats will work in the same way.
+
+\startsubsection
+  [title=Tables]
+
+We have already used a table in this document, see \in {Table} [table:headings].
+That table was entered with
+
+\typebuffer[headingtable]
+
+We do not show all details here, but we typically get
+
+\starttyping
+Aside
+  Div
+    Table
+      TR
+        TD (Heading)
+        TD (Tag)
+      ...
+  Div
+    Lbl (Table)
+    Lbl (1)
+    P   (Different heading mappings.)
+\stoptyping
+
+and so on. The \typ {Aside} and the two \typ {Div} come from the floating mechanism
+while the \typ {Table}, \typ {TD} and \typ {TR} come from the tabulate.
+
+\stopsubsection
+
+\startsubsection
+  [title=Graphics]
+
+\startbuffer
+\startplacefigure
+  [title={This is the caption of the figure.},
+   reference=figure:cow]
+  \externalfigure
+    [cow]
+    [width=5cm,
+     alternativetext=A Dutch cow!]
+\stopplacefigure
+\stopbuffer
+
+With the code
+
+\typebuffer
+
+we get a floating element as in \in {Figure} [figure:cow].
+
+\getbuffer
+
+The \typ {alternativetext} adds a \typ {Alt} tag on the graphic (that is tagged
+as a \typ {Figure}). This alternative text will be taken verbatim, so no math or
+other stuff should go there. The structure in the \PDF\ file is similar to the one
+for the table, but \typ {Table} is instead \typ {Figure}, so we leave it out.
+
+MetaPost content is also working. It uses its own tags, but we can again add
+an alternative text, this time with \typ {alternativetext}.
+
+\startbuffer
+\startplacefigure
+  [title=A MP figure]
+  \startMPcode
+    [alternativetext=A circle]
+    draw fullcircle
+      scaled 3cm
+      withpen pencircle scaled 3
+      withcolor darkred ;
+  \stopMPcode
+\stopplacefigure
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+\stopsubsection
+
+\stopsection
+
+\startsection
+  [title=Descriptions]
+
+Mathematical theorems and similar environments use the description mechanism.
+
+\startbuffer
+\defineenumeration
+  [theorem]
+  [text=Theorem,
+   alternative=serried,
+   title=yes,
+   width=fit]
+\stopbuffer
+
+We define an instance by
+
+\typebuffer
+\getbuffer
+
+\startbuffer
+\starttheorem
+  [title=Pythagoras]
+  In a right triangle, the square of the hypotenuse
+  is equal to the sum of the squares of the legs.
+\stoptheorem
+\stopbuffer
+
+\typebuffer
+\getbuffer
+
+The structure we get is
+
+\starttyping
+Sect
+  Lbl (Theorem 1 (Pythagoras))
+  Div
+    P (In a right ...)
+\stoptyping
+
+As we have explained earlier, inside the \typ {Div} we need a tag that have
+content, and in this case the \typ {P} is enforced. This happens automatically
+when \typ {Div} is the endpoint. When we generate the structure XML file, these
+enforced paragraphs are seen as \typ {<p>}.
+
+\stopsection
+
+\startsection
+  [title=Notes]
+
+There are several types of notes possible, footnotes\footnote{Like this one.} is
+a probably the most common one. They do in fact also use the description
+structure. In \typ {lpdf-tag-imp-basic-description.lmt} we give an example on how
+to remap to \typ {FENote}. If you have any problems with footnotes, it might be
+a good idea to use endnotes instead, since then they are not done as inserts, and
+probably less fragile.
+
+\stopsection
+
+\startsection
+  [title=Code]
+
+We have already shown code several times. For inline code \typ {like this}, done
+with \tex {typ}, \tex {type}, or similar, we use a \typ {Code} tag.
+
+When typesetting a block of code with \tex {starttyping} and \tex {stoptyping},
+like
+
+\starttyping
+Here is some code
+Here is more code
+\stoptyping
+
+we do get
+
+\starttyping
+Div
+  Code
+    Sub (Here is some code)
+    Sub (Here is more code)
+\stoptyping
+
+% Blarg
+%
+% \definetyping[MyCode]
+%
+% \setuptyping
+%   [MyCode]
+%   [numbering=line]
+%
+% \startMyCode
+% Code line one
+% Code line two
+% Code line three
+% \stopMyCode
+
+\stopsection
+
+\startsection
+  [title=Quotations]
+
+We can use \tex {quotation} which results in \quotation {quotation}, or \tex
+{quote} which results in \quote {quote}. We get here \typ {NonStruct}. That is
+perhaps not optimal, but the reason is that the \typ {Quote} tag that is probably
+meant for this is quite limited.
+
+\startbuffer
+\startquotation
+  This quote contains two paragraphs.
+
+  You just read the first one, this is the second one.
+\stopquotation
+\stopbuffer
+
+Similarly, for block quotes, we can type
+
+\typebuffer
+
+which typesets as
+
+\getbuffer
+
+Here we use \typ {BlockQuote}, that seems to work better than \typ {Quote}. The
+NVDA screen reader did not read the quotes, neither for the inline nor the
+displayed versions. It did not matter if we tagged them as \typ {Artifact} or
+\typ {Lbl}.
+
+\stopsection
+
+\startsection
+  [title=Contents]
+
+We felt that the \typ {TOC} and \typ {TOCI} tags are difficult to handle. Some
+bogus reference type element are needed and it quickly gets messy. We therefore
+ended up mapping the table of contents onto an ordinary list. Thus, the structure
+we get is
+
+\starttyping
+L
+  LI
+    Lbl   (1)
+    LBody (Introduction)
+    Lbl   (2)
+\stoptyping
+
+\stopsection
+
+\startsection
+  [title=Languages]
+
+Language switches are in principle handled. On the todo is to add a
+\typ {language=...} for more mechanisms in \CONTEXT.
+
+\stopsection
+
+\startsection
+  [title=Mathematics]
+
+We tag inline formulas such as \m {1 + 2 = 3} (this was typed \typ {\m {1 + 2 =
+3}}). In the \PDF\ file we find back this:
+
+\starttyping
+<!-- 1 plus 2 equals 3 -->
+<math>
+  <mrow>
+    <mn>1</mn>
+    <mo>+</mo>
+    <mn>2</mn>
+    <mo>=</mo>
+    <mn>3</mn>
+  </mrow>
+</math>
+\stoptyping
+
+The comment just shows what goes into the \typ {Alt} tag and the \typ {<math>} is
+put into a \typ {Formula} tag.
+
+For displayed formulas, we type as usual
+
+\startbuffer
+\startformula
+  a^2 + b^2 = c^2
+  \numberhere[equation:Pythagoras]
+\stopformula
+\stopbuffer
+
+\typebuffer
+
+to get the typeset results
+
+\getbuffer
+
+In the \PDF\ file, this gets the structure
+
+\starttyping
+Div
+  Formula
+  Artifact (()
+    Lbl (1)
+  Artifact ())
+\stoptyping
+
+To Hans: Can we disable the Alt for formulas and just rely on the XML somehow? If so,
+it should be mentioned here.
+
+\stopsection
+
+\startsection
+  [title=Margin material]
+
+We can put simple stuff in the margin, as can be seen in the example.
+
+\inright {%
+  This is just a small margin note.\par
+
+  We add some math \m {\abs {a} = \sqrt {a ^ 2}} in a new paragraph.\par}
+
+In the \PDF\ file, this gets the \typ {Aside} structure, which can contain content,
+so it seems we are fine.
+
+\stopsection
+
+\startsection
+  [title=User elements]
+
+It is possible for the user to define their own tagging elements. This can better
+be done in one of the \typ {lmt} files. We have given one example in the \typ
+{lpdf-tag-imp-basic-whatever.lmt} file, where we point \typ {whatever} onto the
+\typ {P} structure element. Thus, with
+
+\startbuffer
+\startelement[whatever]
+  This is a test using the whatever element.
+\stopelement
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+and this is indeed mapped to \typ {P}.
+\stopsection
+
+\startsection
+  [title=Bibliography]
+
+We place the bibliography in this document with \tex {placelistofpublications}.
+There is some kind of tagging support for bibliography, but we consider it just
+as a list, as we do for the table of contents. The bibliography list items are
+put into the \typ {LI} tag, and hence mapped to \typ {Lbl}. The rest of the
+publication fields are put into the \typ {LBody} tag. They go under the \CONTEXT\
+types \typ {publication} and \typ {pubfld} tags, both mapped to \typ {NonStruct},
+so they inherit the \typ {LBody} properties. Enough talking. Here comes the
+bibliography itself:
+
+\placelistofpublications
+
+\stopsection
+
+\startsection
+  [title=Some final words,
+   reference=sec:moredetails]
+
+If you decide (or are forced) to use tagging, then you should also be aware that
+it adds overhead. For a book we tested on, runtime doubled, and the size of the
+file was also much larger. This will quickly interrupt the work flow. One way to
+avoid this overhead while working is to add the tagging setups in a mode. So,
+perhaps do something like
+
+\starttyping
+\startmode[tagging]
+\setupbackend
+  [format=pdf/ua-2]
+
+\setuptagging
+  [state=start,
+   preset=basic]
+\stopmode
+\stoptyping
+
+Then tagging is by default off, and you need to do
+
+\starttyping
+context --mode=tagging file.tex
+\stoptyping
+
+if you want it enabled.
+
+If you have interaction enabled in your document, as we have in this one, you
+will by default get validation errors. The reason is that the standard requires a
+few \typ {Link} and \typ {Reference} tags added here and there, always pointing
+to \quotation {real content}. If you want those elements added add
+
+\starttyping
+\setuptagging
+  [option=interaction]
+\stoptyping
+
+Remember, however, that if that breaks validation, you are on your own, and the
+best choice is probably to disable interaction. Or to live with those validation
+errors specific for the links. In one of our test documents the table of contents
+was added inside a MetaPost graphic. There the solution was to move it into an
+overlay.
+
+\stopsection
+
+\stopdocument


Property changes on: trunk/Master/texmf-dist/doc/context/examples/tagging/tagging-basic.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/context/presentations/examples/present-stepper-001.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/context/presentations/examples/present-stepper-001.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/presentations/examples/present-stepper-001.tex	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/presentations/examples/present-stepper-001.tex	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1,5 +1,7 @@
 \usemodule[present-stepper]
 
+% \nopdfcompression
+
 \starttext
 
 \TitlePage{Stepwise\\Refinement}
@@ -8,6 +10,10 @@
 
 \Topic{Female Artists}
 
+% \definesymbol[whatever][AAA]
+% \definefieldbody[test][kind=button,values={whatever,whatever}]
+% \field[test]
+
 \StartSteps
 
 \startitemize

Modified: trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-grep.html
===================================================================
--- trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-grep.html	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-grep.html	2025-08-18 19:08:11 UTC (rev 76089)
@@ -57,6 +57,8 @@
 <br/><tt>mtxrun --script grep --pattern=module --first *.mkiv</tt>
 <br/><tt>mtxrun --script grep --pattern=module --nocomment *.mkiv</tt>
 <br/><tt>mtxrun --script grep --pattern=module --n=10 *.mkiv</tt>
+<br/><tt>mtxrun --script grep framed **.tex</tt>
+<br/><tt>mtxrun --script grep framed **.tex --count</tt>
 <br/><br/>            </div>
         </div>
         </body>

Modified: trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-grep.xml
===================================================================
--- trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-grep.xml	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-grep.xml	2025-08-18 19:08:11 UTC (rev 76089)
@@ -30,6 +30,8 @@
     <example><command>mtxrun --script grep --pattern=module --first *.mkiv</command></example>
     <example><command>mtxrun --script grep --pattern=module --nocomment *.mkiv</command></example>
     <example><command>mtxrun --script grep --pattern=module --n=10 *.mkiv</command></example>
+    <example><command>mtxrun --script grep framed **.tex</command></example>
+    <example><command>mtxrun --script grep framed **.tex --count</command></example>
    </subcategory>
   </category>
  </examples>

Modified: trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.html
===================================================================
--- trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.html	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.html	2025-08-18 19:08:11 UTC (rev 76089)
@@ -50,9 +50,10 @@
         <tr><th>--comments</th><td></td><td>show comments</td></tr>
         <tr><th>--sign</th><td></td><td>sign document (assumes signature template)</td></tr>
         <tr><th>--verify</th><td></td><td>verify document</td></tr>
+        <tr><th>--validate</th><td></td><td>validate document (calls verapdf)</td></tr>
         <tr><th>--detail</th><td></td><td>print detail to the console</td></tr>
         <tr><th>--userdata</th><td></td><td>print userdata to the console</td></tr>
-        <tr><th>--structure</th><td></td><td>show the structure of the content</td></tr>
+        <tr><th>--structure</th><td></td><td>check the (context speficic) structure of the content</td></tr>
         <tr><th/><td/><td/></tr>
     </table>
 <br/>

Modified: trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.man
===================================================================
--- trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.man	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.man	2025-08-18 19:08:11 UTC (rev 76089)
@@ -44,6 +44,9 @@
 .B --verify
 verify document
 .TP
+.B --validate
+validate document (calls verapdf)
+.TP
 .B --detail
 print detail to the console
 .TP
@@ -51,7 +54,7 @@
 print userdata to the console
 .TP
 .B --structure
-show the structure of the content
+check the (context speficic) structure of the content
 .SH AUTHOR
 More information about ConTeXt and the tools that come with it can be found at:
 

Modified: trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.xml
===================================================================
--- trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.xml	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/scripts/mkiv/mtxrun-pdf.xml	2025-08-18 19:08:11 UTC (rev 76089)
@@ -19,9 +19,10 @@
     <flag name="comments"><short>show comments</short></flag>
     <flag name="sign"><short>sign document (assumes signature template)</short></flag>
     <flag name="verify"><short>verify document</short></flag>
+    <flag name="validate"><short>validate document (calls verapdf)</short></flag>
     <flag name="detail"><short>print detail to the console</short></flag>
     <flag name="userdata"><short>print userdata to the console</short></flag>
-    <flag name="structure"><short>show the structure of the content</short></flag>
+    <flag name="structure"><short>check the (context speficic) structure of the content</short></flag>
    </subcategory>
    <subcategory>
     <example><command>mtxrun --script pdf --info foo.pdf</command></example>
@@ -32,6 +33,7 @@
     <example><command>mtxrun --script pdf --verify --certificate=somesign.pem --password=test --uselibrary somefile</command></example>
     <example><command>mtxrun --script pdf --detail=nofpages somefile</command></example>
     <example><command>mtxrun --script pdf --userdata=keylist [--format=lua|json|lines] somefile</command></example>
+    <example><command>mtxrun --script pdf --validate --structure --details --save somefile</command></example>
    </subcategory>
   </category>
  </flags>

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-characters.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-characters.tex	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/lowlevel/lowlevel-characters.tex	2025-08-18 19:08:11 UTC (rev 76089)
@@ -239,7 +239,7 @@
 
 \typebuffer
 
-The \type {hccode} tells the machinery that the underscore is a valid word
+The \type {\hccode} tells the machinery that the underscore is a valid word
 separator (think compound words).
 
 \start \getbuffer \stop
@@ -246,6 +246,206 @@
 
 \stopsectionlevel
 
+\startsectionlevel[title=Casing]
+
+We started by mentioning that \TEX\ was primarily made and used for typesetting
+English although quickly other Latin scripts were supported. As long as a
+language uses a script that fits nicely in a few hundred characters we're okay.
+Of course mixing scripts and languages is more demanding, but Latin, Cyrillic and
+Greek were no problem.
+
+A characteristic of western languages and these scripts is that there is a mix of
+upper and lowercase characters. Now, in most cases the input has the right usage
+of casing so there is little for \TEX\ to worry about. However, in the
+traditional approach every character has a so called \type {\lccode} and \type
+{\uccode}. These are used to map from upper- to lowercase or reverse and the
+lowercase code, when set, is also a signal that controls hyphenation. In \LUATEX\
+and \LUAMETATEX\ that role is taken over by the \type {\hccode}.
+
+Good old \TEX\ has two primitives that deal with case swapping.
+
+\startbuffer
+\lowercase{Don't get fooled!}
+\uppercase{Don't get fooled!}
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+This does what one expects:
+
+\startlines
+\getbuffer
+\stoplines
+
+So, what do you expect here?
+
+\startbuffer
+\edef\fooled{\lowercase{Don't get fooled!}}\meaning\fooled
+\edef\fooled{\uppercase{Don't get fooled!}}\meaning\fooled
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines
+\getbuffer
+\stoplines
+
+And here?
+
+\startbuffer
+\lowercase{\edef\fooled{Don't get fooled!}}\meaning\fooled
+\uppercase{\edef\fooled{Don't get fooled!}}\meaning\fooled
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines
+\getbuffer
+\stoplines
+
+These primitives are non-expandable but act on a token list when interpretation
+takes place.
+
+\startbuffer
+\begingroup
+    \lowercase{\edefcsname fooled\endcsname{Guess}}
+    \meaningfull\fooled
+    \meaningfull\FOOLED
+\endgroup
+\begingroup
+    \uppercase{\edefcsname fooled\endcsname{Guess}}
+    \meaningfull\fooled
+    \meaningfull\FOOLED
+\endgroup
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines
+\getbuffer
+\stoplines
+
+It will be clear that using these primitives in a situation where you want
+expansion you really need to make sure that in getting there no side effects take
+place. Instead of these primitives, that we keep around for compatibility
+reasons, you can better use the converters that \CONTEXT\ provides. Even these
+are probably of little used when typesetting is your main focus, because when
+case mapping of various kind is needed there are high level mechanism for just
+that.
+
+\startbuffer
+\edef\fooled{\utflower{Don't get fooled!}}\meaning\fooled
+\edef\fooled{\utfupper{Don't get fooled!}}\meaning\fooled
+\stopbuffer
+
+\typebuffer[option=TEX]
+
+\startlines
+\getbuffer
+\stoplines
+
+It will be clear that in an \UNICODE\ environment there is more than an English
+alphabet involved. The primitive case mapping as well as the \CONTEXT\ variants
+use of course \UNICODE\ specified mapping but the last two macros are just
+wrappers around a lot more character related properties.
+
+In \MKII\ we supported various encodings and each came with a case mapping. We
+gradually moved to \UTF8 and for instance hyphenation patterns came in that
+format so that they could easily be shared. \footnote {This was reason for Arthur
+and Mojca to start the hyphenation project that resulted in \UTF\ patterns being
+that standard now. It's a nice example of prototyping and exploring in \CONTEXT\
+and applying it to a wider audience.}
+
+When we started in 2005 with a follow up a major change in approach to dealing
+with characters between \MKII\ and \MKIV\ was that we could get rid of, if really
+needed, remapping at the \TEX\ end. We delegate much to \LUA\ which also has the
+advantage that we operate on the text as intended, possibly resulting from
+generated input. This means that right from the start we had support for
+\UNICODE, although of course that standard also evolved over time. Some was
+driven by specific user need: for the oriental \TEX\ project we needed
+bidirectional interpretation, for some scripts we needed (de)composition, we
+needed sorting, tracing, special purpose conversions, etc. \footnote {If
+manipulation of character properties in the \TEX\ language is your hobby, maybe
+\MKII\ is a better choice as it pretty much belongs to that period.}
+
+Most of this is rather stable and as it has been present from the start and it
+hasn't been touched much, although we do keep up with \UNICODE. But one has to
+keep in mind that much is about control and user input and demand so we can
+deviate from what is considered \quote {standard}: we target typesetting, not
+programming and text manipulation! We keep most (not all) information in the
+\type {char-def.lua} file and actually although it gets adapted to \UNICODE\
+updates (for which of course we use a script) it hasn't changed much, apart from
+an update with respect to math classes and such when we upgraded the math engine.
+It can be an interesting read.
+
+That said: if users want some more explanations or low level examples, just let
+us know and we will add them here (or to the low level manual that makes sense).
+
+% amcode     active math
+% hccode     hyphenation control
+% hmcode     math discretionary
+% lccode     lower case
+% uccode     upper case
+% sfcode     space factor
+% cccode     classification
+% catcode    command category
+% delcode    math delimiter
+% mathcode   math character
+
+\stopsectionlevel
+
+\startsectionlevel[title=Specials]
+
+Traditionally \TEX\ has a few specially interpreted characters. Most noticeably
+the backslash starts a control sequence. Any programming languages has some
+escape and this the one that \TEX\ uses. Of course any character can be an escape
+character.
+
+The dollar is well known for bounding inline math. A pair of dollars wraps
+display math. In \CONTEXT\ you can use the dollars but double ones act as single ones
+and trigger inline display style math. In practice one will use \type {\im {...}} and \type {\dm {...}}
+and for display math \typ {\startformula} and \typ {\stopformula}.
+
+The ampersand is, unlike in other macro packages, just that and not a table cell
+separator. The circumflex character is also just that. However, in math upto four
+are used for super scripts (pre, post and index) while the underscore(s) handle
+the subscripts. The single quote is in math signaling a prime (multiple primes
+are supported).
+
+The end of line character(s) are in fact spaces unless configured to be obeyed,
+what can be the case when you use \typ {\startlines} and \typ {\stoplines} or
+display verbatim.
+
+The tilde is normally active and equivalent to a \type {\nbsp} character. In
+\CONTEXT\ it as an \type {\amcode} set so that it will never expand in for
+instance an \type {\edef} like situation. The hash mark is used to signal a
+parameter in a macro body and is followed by a (hexadecimal) digit. They get
+duplicated in nested macro definitions. The percent sign starts comment that then
+runs till the end of the line.
+
+Hyphens are also special, as they can become a discretionary (hyphenation point),
+or when entered double or triple can become an en- of emdash, either or not with
+similar hyphenation behavior (think compound words).
+
+Quotation and explanation marks and some punctuation like periods, commas, colons
+and semicolons can get different spacing depending on the \type {\sfcode}. Here
+\quote {french spacing} is the buzzword.
+
+In \CONTEXT\ the vertical bar has always been an active character used for
+compound word marks and other word bounding characters. They come in pairs where
+the second one is a delimiter of a possible argument. In math it behaves as
+normal bar, although bars in math are sort special too. In fact, all characters
+in math get a treatment depending on what they represent. More about that
+can be read in the math manual.
+
+The various spacing characters in \UNICODE\ are interpreted but normally can't be
+seen in an editor. Instead one can use commands. {\em todo: list them here}
+
+Of course all can be changed to ones need but be careful and aware of interferences,
+especially when loading code that assumes otherwise.
+
+\stopsectionlevel
+
 \stopdocument
 
 % on an old machine, so consider them just relative measures

Added: trunk/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-shift.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-shift.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-shift.tex	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,190 @@
+% language=us runpath=texruns:manuals/musings
+
+\startcomponent musings-shift
+
+\environment musings-style
+
+\startchapter[title={The shift (or: just moving on)}]
+
+When you use a programming language like \CCODE\ or \PASCAL, the language \TEX\
+was originally written in, there can be various results, most of which have
+little relation to each other. A word processor written in some language is not
+the same as a program that controls traffic lights. In addition to the core
+language, which provides data types, loops, conditionals, etc. there can be
+specific features like native support for strings, or a defined set of libraries
+to be provided, for instance for memory management or math. At some point if was
+fashion to add layers of abstraction to languages, for instance object oriented
+layers, or database oriented functionality. One can add to a language or use
+pre-processors for that. One can talk macros and templates.
+
+If we look at \TEX\ we also have a core language but at the same time there is a
+rather large set of built in functionality. You can mix programming with content
+and the content gets processed into something that eventually might end up on
+paper or on a screen. The built in functionality deals with paragraphs of text,
+rendering math formulas, splitting of pages, making tables, and so on. It's
+actually an attractive mix.
+
+When \TEX\ showed up the idea was that one writes a specific set of macros that
+help to structure and render the input. Although there is a basic set of plain
+\TEX\ macros, the look and feel got programmed per document. However, as not all
+authors have the skills to program or want to be bothered with that larger sets
+of macros popped up: macro packages. Some survived, some went extinct, but in the
+end we only find a few.
+
+If you go back in time, the users of \TEX\ found each other in shared interest
+and a common need for resources. Of course there is the program, that needs to be
+available for the platform that one uses, then there was the backend driver
+needed for previewing or printing, and of course fonts and hyphenation patterns
+could be shared too. There was even some common ground for further development.
+At user group meetings it was not uncommon to hear about something new, successes
+and failures, usage patterns that can inspire etc.
+
+But over the decades things changed. New engines showed up that added
+functionality. For instance \LUATEX\ brought an efficient mix of \TEX, \LUA, and
+\METAPOST, and \LUAMETATEX\ adds to the language as well as typesetting
+functionality. The first one resulted in the more hybrid \CONTEXT\ variant \MKIV,
+and the second in \MKXL\ (aka \LMTX\ as it pairs with the engine in a lean and
+mean installation). The later is what most users nowadays use. And the principles
+can be summarized as:
+
+\startitemize
+\startitem
+    We use the \TEX\ input method by default, which means commands that start
+    with a backslash. As always with \CONTEXT\ commands can have options:
+    keywords (arrays), key|/|value pairs (hashes), or both. We do also accept
+    \XML, \LUA\ (so called cld documents), some other formats and a mix of it.
+\stopitem
+\startitem
+    It being a major \TEX\ features, we support math in the usual way but we
+    don't want users to tweak to much which is made possible by the enhanced
+    engine.
+\stopitem
+\startitem
+    Solutions not available via the more high level user commands can be
+    programmed using the regular \TEX\ language, \LUA, or \METAPOST\ or a
+    combinations. There are of course helpers but we don't discourage going
+    primitive.
+\stopitem
+\startitem
+    We consider \TEX\ as a niche product. For sure it excels at math but for many
+    it is not beforehand a better solution than alternatives like word processors
+    and web based rendering. It should never be enforced. Using \CONTEXT\ is best
+    a positive choice.
+\stopitem
+\startitem
+    It is users and usage that drives what features are added, extended,
+    upgraded. As development and support is volunteer work there is also no or at
+    least little (occasional projects) that binds it to big tech, publishers and
+    hidden backend usage.
+\stopitem
+\stopitemize
+
+So how does \CONTEXT\ then fit into the larger \TEX\ picture. As mentioned above
+in the beginning there was common ground but today one can wonder if that is
+still the case. With for instance \LATEX\ moving to the web and competing with
+other large scale word processing, there is little in common. Also, we never had
+the same approach to styles (low level hacking) and definitely don't want to
+enforce some intermediate programming layer hides (and discourages) the use of
+the primitive language, although we do impose some restrictions with respect to
+overloading. We don't want to end up in competition with other systems out there
+either: one should be free to use whatever ones likes. There is no overlap in
+development and macro package development is rather isolated. You can see that
+reflected in use group meetings: they are small compared to the early days. The
+generic meetings bring little news and the more dedicated ones are (indeed)
+dedicated to specific solutions (macro packages). There is still some common
+ground to be found, like in distributions, specific resources like hyphenation
+patterns, and journals but even there macro packages go their own way. One has to
+look deep down to see to what extend they share concepts and usage patterns. Of
+course this is natural for a program that has evolved over four decades and where
+usage patterns also evolved.
+
+So to come full circle, if we see \TEX\ as a programming language it is not much
+different from other languages. Of course its domain is typesetting but in what
+way the results are achieved can differ a lot. When someone says to be using
+\TEX\ that doesn't tell much more than saying that one programs in \PASCAL ,
+although it is an indication of how typesetting solutions can be reached.
+
+In a nostalgic mood I took a look at the rather large archive of \MODULA\ files I
+wrote in the second half of the 80's and first half of the 90's. Among the dozens
+of programs are a few that sort of translate to what we have today. We're talking
+\MSDOS\ here using a common text based windowing system that I wrote for \VAX\
+mainframes and ported to the personal computer.
+
+There is an editor that could handle relatively large files, supported a project
+structure, had syntax highlighting and did real time spell checking. I just
+translated that to \SCITE\ extensions and for instance the project structure
+(including fast opening of files) is not much different from what we have now.
+The syntax highlighting evolved to a mixture of languages but still determines
+how I look at files and thereby how \CONTEXT\ is programmed.
+
+But before we actually used \TEX\ that same editor was used for just \ASCII\
+based rendering so in addition we then had a converter that turned simple tagged
+text into something for a printer. It actually is not that different from these
+markdown ways of coding. We also could split of pages and move reserved areas
+(floats) around. Of course all that was left behind when we moved on to \TEX. It
+is kind of curious that much of this actually was written for terminals connected
+to a VAX (at the university) where we printed out on these fast daisy wheel line
+printers. Only decades later we figured that already at that time there could
+have been \TEX\ or precursors running on those machines, probably of little use
+because there one needs an (expensive) phototypesetter and some workstation for
+previewing.
+
+Yet another program was the one that we used for making computer assisted
+learning programs, think of presenting text, questions, feedback, video and
+audio. Equipment was controlled via serial connections connected to for instance
+random access video tape players. We made a small language for that with regular
+programming features enhanced with some specific for learning environments.
+Interesting is that it involved parsers, scripts in that language, efficient
+storage, and bytecode ran through what I later learned was called a virtual
+machine. I guess that around that time, when we were not connected to the (not
+yet existing) web, many people were inventing the same wheels. As a side note:
+there was never a real market in a small country like ours so this was typically
+only applied in projects where it somehow fit in, as goodie. Of course all this
+is now done in browsers and \JAVASCRIPT, but I guess the experiences somehow
+translated into interfaces mixed into \CONTEXT. I never felt the need to abstract
+\TEX\ away behind layers like the one mentioned her because nowadays we have
+these interpreted scripting languages.
+
+Then there were graphics. At some point we were involved in making a heavy duty
+(3D) milling machine using simple robust of the shelf components. The friend we
+did this with needed it for some production process. We controlled motors with
+brakes and couplers and feedback happened with optical feedback. All was
+programmed in \MODULA\ and controlled via an \IO\ board. Here again we made some
+simple language for describing shapes but also handled output from drawing
+programs (exporting to hpgl). Looking backward it was a lot of fun and there was
+nothing on the market that could do the same for that price but the (more than
+square meter devices) were mostly used for milling displays and components for an
+automated film development machine. Here we can wonder how that translated to
+today's \CONTEXT. Using \METAPOST\ for this is not an option although with the
+library we have we could actually cook up some backend. Also, you can now use
+micro controllers that cost a few euros and stepper motors than come cheap. So,
+looking back it's probably mostly the learning experience that translates. And
+the recent serial \CONTEXT\ signal gadget brings us back to connected hardware.
+
+There are more programs, some concern databases, others concern for instance
+distributing structured handbooks (on floppies, meant for portable simple
+laptops). One easily forgets what has been done. The same is true for manuals: we
+can find plenty of early \CONTEXT\ manuals dating from the time it evolved. Most
+never made it into the public. Much also had to be done on computers from the
+i386 times. And it definitely was from before we were connected to the internet.
+But in the end, with intermediate steps using \PERL\ and \RUBY\ for scripting and
+run management, we eventually arrived at this \TEX, \LUA\ and \METAPOST\ mix, now
+with even a bit of connected hardware to watch the process. There is no need to
+look back apart from realizing that we didn't arrive here by accident.
+
+So to wrap this up: at some point we arrived at using \TEX\ combined with various
+programs we made that themselves evolved but eventually all those became obsolete
+and the \LUA\ plus \TEX\ plus \METAPOST\ approach was the winner, with an
+occasional resemblance of what came before. First we operated in isolation, then
+entered the \TEX\ community that at that time was also exploring several
+solutions for similar problems and adapting itself to what it was confronted
+with. But in the end, just as we forget the past, that \TEX\ related past also
+starts fading away: the current \TEX\ solutions evolved independent and share
+little. But what remains is that they are built upon Don Knuths masterpiece and
+that we share forever.
+
+{\em comment: this text is not yet corrected for errors}
+
+\stopchapter
+
+\stopcomponent


Property changes on: trunk/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings-shift.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings.tex	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/musings/musings.tex	2025-08-18 19:08:11 UTC (rev 76089)
@@ -42,6 +42,7 @@
   % \component musings-kerns          % probably article
     \component musings-deserved       % probably article
     \component musings-riscv
+    \component musings-shift
 \stopbodymatter
 
 \stopproduct

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/tagging/signals.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/tagging/signals.tex	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/tagging/signals.tex	2025-08-18 19:08:11 UTC (rev 76089)
@@ -808,6 +808,10 @@
 {dialout} group, which can be done with \typ {sudo usermod -a -G dialout
 yourname} (you need to re-login).
 
+On \OSX\ I could only test on an old intel mac and there it just worked
+with \type {/dev/tty.usbmodem14101}. Using \typ {ls -la /dev/tty.usbserial*}
+can be your friend here.
+
 When you connect the device visa for instance a \USB\ hub in a keyboard you
 should expect uncomfortable delays, at least that is what I encountered on the
 \LINUX\ box.

Modified: trunk/Master/texmf-dist/doc/context/sources/general/manuals/tagging/tagging.tex
===================================================================
--- trunk/Master/texmf-dist/doc/context/sources/general/manuals/tagging/tagging.tex	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/context/sources/general/manuals/tagging/tagging.tex	2025-08-18 19:08:11 UTC (rev 76089)
@@ -3,7 +3,8 @@
 % todo: use concrete
 
 \usemodule
-  [abbreviations-logos,scite,math-verbatim]
+% [abbreviations-logos,scite,math-verbatim] % math verbatim messes up text
+  [abbreviations-logos,scite] % math verbatim messes up text
 
 % \showframe
 
@@ -254,9 +255,18 @@
 like validators aim for that. Also, if you find pre level 2 documents produced
 elsewhere, often tagging is so bad or weird that one can as well ignore it.
 
-Tagging in a document is enabled with:
+You should realize that tagging is actually rather old, it was already available
+in the early version. You can enable tagging with:
 
 \starttyping
+\setuptagging[state=start]
+\stoptyping
+
+This will give you basic tagging: directives in the page stream combined with
+a structure tree. You can also decide to add mapping to \PDF\ specific tags. This
+is done with:
+
+\starttyping
 \setupbackend[format=pdf/ua-2]
 \setuptagging[state=start]
 \stoptyping
@@ -272,22 +282,43 @@
 limitations in nesting \PDF\ specific tags cf.\ checkers) but you can say this:
 
 \starttyping
-\enabledirectives [backend.usetags=crap]
+\setuptagging[preset=basic]
 \stoptyping
 
-and get an you can map to an alternative set. With
+The basic mapping is defined in \typ {lpdf-tag-imp-basic*} files and get and of
+course define your own. The basic set works for a few complex documents we tried
+but has to work around limitations. We have no clue how that works out in the
+long term because (as mentioned) validation, standardization and whatever relates
+are fluid. We still provide:
 
 \starttyping
-\enabledirectives [backend.usetags=mkiv]
+\setuptagging [preset=mkiv]
 \stoptyping
 
-you get the mapping used in \MKIV\ but that one fails level 2 validation. The
-\quote {crap} file has some notes on how to define things. The somewhat strange
-section title mapping is due to the fact that nested sections are not really
-supported in a way that permits the title and content to be properly tagged.
+you get the mapping used in \MKIV\ but that one fails level 2 validation. In due
+time we might explain (re)mapping here in more detail. There are various features
+controlled by directives but these mostly serve(d) testing.
 
 \stopchapter
 
+\startchapter[title=Interactivity]
+
+By default we ignore references and links in the mapping. This because we found
+it to be confusing, unreliable, limited and (some searching indicated) open to
+interpretations and changes. It doesn't bring anything to the table anyway. In
+\CONTEXT\ users can make advanced interactive documents; it was always a strong
+point and for for some users a reason to use this system. If you really want
+it to be taken into account, you can do this:
+
+\starttyping
+\setuptagging [option=interactivity]
+\stoptyping
+
+You might need to change your document if validation fails, for instance because
+you add buttons and such in constructs that no one could envisage.
+
+\stopchapter
+
 \startchapter[title=Tagging math]
 
 Tagging math at level 2 is still experimental but works as follows. Instead of
@@ -580,7 +611,8 @@
 read \quotation {The \type {H} structure type requires processors to track
 section depth, which adds an unnecessary burden on processors and can cause
 ambiguity.} This is a quite baffling remark given the complexity of \PDF\ and web
-technologies in general.
+technologies in general. So in the end it was dropped in order to make some
+developers lives easier, while complicating that of others.
 
 It is this, and other vague (and changing) descriptions, take for instance \type
 {Part} and \type {Sect}, that made us decide to draw a line. We tried some in our
@@ -607,11 +639,42 @@
 \enabletrackers[structures.tags.blobs]
 \enabletrackers[structures.tags.internals]
 \enabletrackers[structures.tags.suspects]
+\enabletrackers[structures.tags.attribute]
+\enabletrackers[structures.tags.paragraphs]
+\enabletrackers[structures.tags.objects]
 \stoptyping
 
-The first one is probably the most useful as it shows how \CONTEXT\ sees the
-structure of your document.
+The first few are probably the most useful as it shows how \CONTEXT\ sees the
+structure of your document. Others are there because they help figuring out
+issues.
 
+We also have a script that can help checking:
+
+\starttyping
+mtxrun --script pdf --validate yourfile
+\stoptyping
+
+This will use (currently only) verapdf to check the file and show a summary.
+Another feature is:
+
+\starttyping
+mtxrun --script pdf --structure yourfile  [--details --save]
+\stoptyping
+
+and both can be done in one step with:
+
+\starttyping
+mtxrun --script pdf --check yourfile
+\stoptyping
+
+When you tag a document, best do that as late as possible because it adds runtime
+and checking doesn't really help much when writing something. You might want to
+put the setup in a mode so that you can enable it from the command line. The
+documents also become way bigger. And, if you really care about accessibility,
+consider making two versions: one that suits your typographic needs, and one that
+targets the audience that needs accessibility. And, for printed documents, you
+can just ignore it.
+
 \stopchapter
 
 \stopdocument

Modified: trunk/Master/texmf-dist/doc/man/man1/context.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mptopdf.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-babel.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-bibtex.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-cache.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-chars.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-check.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-colors.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-context.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-convert.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-ctan.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-dvi.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-epub.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-evohome.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-fcd.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-fixpdf.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-flac.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-fonts.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-grep.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-interface.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-kpse.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-metapost.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-modules.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-package.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-patterns.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-pdf.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/mtxrun-pdf.1	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/doc/man/man1/mtxrun-pdf.1	2025-08-18 19:08:11 UTC (rev 76089)
@@ -44,6 +44,9 @@
 .B --verify
 verify document
 .TP
+.B --validate
+validate document (calls verapdf)
+.TP
 .B --detail
 print detail to the console
 .TP
@@ -51,7 +54,7 @@
 print userdata to the console
 .TP
 .B --structure
-show the structure of the content
+check the (context speficic) structure of the content
 .SH AUTHOR
 More information about ConTeXt and the tools that come with it can be found at:
 

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-pdf.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-plain.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-profile.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-rsync.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-scite.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-server.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-spell.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-synctex.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-texworks.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-tools.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-unicode.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-unzip.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-update.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-vscode.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-watch.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun-youless.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/mtxrun.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/texexec.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/texmfstart.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/scripts/context/lua/mtx-grep.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/context/lua/mtx-grep.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/scripts/context/lua/mtx-grep.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -42,6 +42,8 @@
     <example><command>mtxrun --script grep --pattern=module --first *.mkiv</command></example>
     <example><command>mtxrun --script grep --pattern=module --nocomment *.mkiv</command></example>
     <example><command>mtxrun --script grep --pattern=module --n=10 *.mkiv</command></example>
+    <example><command>mtxrun --script grep framed **.tex</command></example>
+    <example><command>mtxrun --script grep framed **.tex --count</command></example>
    </subcategory>
   </category>
  </examples>

Modified: trunk/Master/texmf-dist/scripts/context/lua/mtx-patterns.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/context/lua/mtx-patterns.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/scripts/context/lua/mtx-patterns.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -686,14 +686,25 @@
         leftchar        = false,
         rightchar       = false,
     }
-    trackers.enable("hyphenator.steps")
-    for i=1,#words do
-        local word = words[i]
-        report("%s %s %s : %s : %s",
-            language, left, right,
-            word,
-            traditional.injecthyphens(dictionary,word,specification)
-        )
+    if environment.argument("direct") then
+        for i=1,#words do
+            words[i] = traditional.injecthyphens(dictionary,words[i],specification)
+        end
+        words = concat(words," ")
+        if environment.argument("soft") then
+            words = gsub(words,"%-",utf.char(0xAD))
+        end
+        print(words)
+    else
+        trackers.enable("hyphenator.steps")
+        for i=1,#words do
+            local word = words[i]
+            report("%s %s %s : %s : %s",
+                language, left, right,
+                word,
+                traditional.injecthyphens(dictionary,word,specification)
+            )
+        end
     end
 end
 

Modified: trunk/Master/texmf-dist/scripts/context/lua/mtx-pdf.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/context/lua/mtx-pdf.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/scripts/context/lua/mtx-pdf.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -35,9 +35,10 @@
     <flag name="comments"><short>show comments</short></flag>
     <flag name="sign"><short>sign document (assumes signature template)</short></flag>
     <flag name="verify"><short>verify document</short></flag>
+    <flag name="validate"><short>validate document (calls verapdf)</short></flag>
     <flag name="detail"><short>print detail to the console</short></flag>
     <flag name="userdata"><short>print userdata to the console</short></flag>
-    <flag name="structure"><short>show the structure of the content</short></flag>
+    <flag name="structure"><short>check the (context speficic) structure of the content</short></flag>
    </subcategory>
    <subcategory>
     <example><command>mtxrun --script pdf --info foo.pdf</command></example>
@@ -48,6 +49,7 @@
     <example><command>mtxrun --script pdf --verify --certificate=somesign.pem --password=test --uselibrary somefile</command></example>
     <example><command>mtxrun --script pdf --detail=nofpages somefile</command></example>
     <example><command>mtxrun --script pdf --userdata=keylist [--format=lua|json|lines] somefile</command></example>
+    <example><command>mtxrun --script pdf --validate --structure --details --save somefile</command></example>
    </subcategory>
   </category>
  </flags>
@@ -84,7 +86,9 @@
 local function loadpdffile(filename)
     if not filename or filename == "" then
         report("no filename given")
-    elseif not lfs.isfile(filename) then
+    end
+    filename = file.addsuffix(filename,"pdf")
+    if not lfs.isfile(filename) then
         report("unknown file %a",filename)
     else
         local ownerpassword = environment.arguments.ownerpassword
@@ -462,6 +466,107 @@
     }
 end
 
+function scripts.pdf.validate(filename)
+    local pdffile = file.addsuffix(filename,"pdf")
+    if not lfs.isfile(pdffile) then
+        report("invalid pdf file %a",pdffile)
+        return
+    end
+    -- runner
+    local data = os.resultof('verapdf "' .. pdffile .. '"')
+    if data and #data > 0 then
+        local x = xml.convert(data)
+        if x then
+            local r = xml.first(x,"buildInformation/releaseDetails[id='core'")
+            if r then
+                report("validator    : %s","verapdf")
+                report("version      : %s",r.at.version or "unknown")
+                report()
+            else
+                report("unsupported %a validator","verapdf")
+                return
+            end
+            local r = xml.first(x,"validationReport")
+            if r then
+                local interaction  = environment.arguments.interaction
+                local destinations = 0
+                local annotations  = 0
+                local at = r.at
+                report("compliant    : %s",at.isCompliant  or "unknown")
+                report("job status   : %s",at.jobEndStatus or "unknown")
+                report("profile      : %s",at.profileName  or "unknown")
+                report("statement    : %s",at.statement    or "unknown")
+                r = xml.first(r,"/details")
+                if r then
+                    local at = r.at
+                    report()
+                    report("checks       : %i passed, %i failed",tonumber(at.passedChecks) or 0,tonumber(at.failedChecks) or 0)
+                    report("rules        : %i passed, %i failed",tonumber(at.passedRules ) or 0,tonumber(at.failedRules ) or 0)
+                 -- <rule> <!-- why is clause not an element but an attribute -->
+                 --   <description>...</description>
+                 --   <object>...</object>
+                 --   <test>...</test>
+                 --   <check>
+                 --     <context>root/document[0]/StructTreeRoot[0](15 0 obj PDStructTreeRoot)</context>
+                 --     <errorMessage>...</errorMessage>
+                 --   </check>
+                 -- </rule>
+                    local reported   = { }
+                    local duplicates = 0
+                    local total      = 0
+                    for e in xml.collected(r, "/rule/check[@status='failed']/..") do
+                        local tc = xml.text(e,"/check/context")
+                        local td = xml.text(e,"/description")
+                        local te = xml.text(e,"/check/errorMessage")
+                        if tc then
+                            tc = gsub(tc,"%((%d+).-%)","(%1)")
+                        end
+                        if find(te,"annotation") then
+                            annotations = annotations + 1
+                        end
+                        if find(te,"estination") then
+                            destinations = destinations + 1
+                        end
+                        if interaction and not reported[te] then
+                            report()
+                            report("condition    : %s",td or "unknown")
+                            report("error message: %s",te or "unknown")
+                            report("object tree  : %s",tc or "unknown")
+                            reported[te] = true
+                            duplicates = duplicates + 1
+                        end
+                        total = total + 1
+                    end
+                    if total > 0 then
+                        report()
+                        report("duplicates   : %i",duplicates)
+                        report("failed checks: %i",total)
+                        if destinations or annotations then
+                            report()
+                            report("destinations : %i",destinations)
+                            report("annotations  : %i",annotations)
+                            if destinations + annotations >= total then
+                                report()
+                                report("the document looks okay, interaction is fragile in tagging and validation")
+                            end
+                            if not interaction then
+                                report()
+                                report("use --interaction to get more details")
+                            end
+                        end
+                    end
+                end
+            end
+        else
+            report()
+            report("no valid test result")
+        end
+    else
+        report()
+        report("make sure verapdf is installed")
+    end
+end
+
 function scripts.pdf.metadata(filename,pretty)
     local pdffile = loadpdffile(filename)
     if pdffile then
@@ -968,14 +1073,26 @@
             if arguments.detail      ~= nil then options.detail      = arguments.detail      end
             local result, statistics = lpdf.collectcontent(pdffile,options)
             if result and #result > 0 then
-                if options.save then
-                    local filename = file.nameonly(filename) .. "-crap.xml"
-                    statistics["saved file"] = filename
-                    io.savedata(filename,result)
+                local savename = options.save and file.nameonly(filename) .. "-tagview.xml"
+                report()
+                report("disclaimer:")
+                report()
+                report("This mostly is a simple check utility and we will complete this when we")
+                report("feel the need or when a user has a test file and needs some checker. So,")
+                report("feel free to ask on the mailing list. The output is yet sub-optimal and")
+                report("complete (but it's not that hard to do).")
+                report()
+                report("This is not an official export, just a way to check how a text can be")
+                report("seen and/or read. Users can define their own mappings and this is a way")
+                report("to see what happens. Tags are sanitized to serve that purpose and some")
+                report("extra information is provided by attributes.")
+                if savename then
+                    io.savedata(savename,result)
                 else
-                    print("")
+                    report()
+                    report()
                     print(result)
-                    print("")
+                    report()
                 end
                 report()
                 report("options:")
@@ -989,19 +1106,28 @@
                 for k, v in sortedhash(statistics) do
                     report("%-12s : %S",k,v)
                 end
+                if savename then
+                    report()
+                    report("result:",savename)
+                    report()
+                    report("%-12s : %S","filename",savename)
+                    report("%-12s : %S bytes","filesize",#result)
+                end
+                if environment.argument("validate") then
+                    report()
+                    report("validation:")
+                    report()
+                    scripts.pdf.validate(filename)
+                end
                 report()
-                report("disclaimer:")
-                report()
-                report("This mostly is a simple check utility and we will complete this when we")
-                report("feel the need or when a user has a test file and needs some checker. So,")
-                report("feel free to ask on the mailing list. The output is yet sub-optimal and")
-                report("complete (but it's not that hard to do).")
-                report()
-                report("This is not an official export, just a way to check how a text can be")
-                report("seen and/or read.")
-                report()
+            else
+                report("this file has no tags")
             end
+        else
+            report("this file is invalid")
         end
+    else
+        report("this feature is not supported")
     end
 end
 
@@ -1102,10 +1228,20 @@
 
 local filename = environment.files[1] or ""
 
+if environment.argument("check") then
+    -- an undocumented shortcut, mostly for ourselves
+    environment.arguments.validate  = true
+    environment.arguments.structure = true
+    environment.arguments.details   = true
+    environment.arguments.save      = true
+end
+
 if filename == "" then
     application.help()
 elseif environment.argument("info") then
     scripts.pdf.info(filename)
+elseif environment.argument("structure") then
+    scripts.pdf.structure(filename)
 elseif environment.argument("identify") then
     scripts.pdf.identify(filename)
 elseif environment.argument("metadata") then
@@ -1125,8 +1261,8 @@
 elseif environment.argument("highlights") then
     scripts.pdf.highlights(filename,tonumber(environment.argument("page")))
 ------ structure before attachments and comments (are options there)
-elseif environment.argument("structure") then
-    scripts.pdf.structure(filename)
+elseif environment.argument("verify") then
+    scripts.pdf.verify(filename)
 elseif environment.argument("comments") then
     scripts.pdf.comments(filename,tonumber(environment.argument("page")))
 elseif environment.argument("signature") then
@@ -1133,12 +1269,12 @@
     scripts.pdf.signature(filename,environment.argument("save"))
 elseif environment.argument("sign") then
     scripts.pdf.sign(filename)
+elseif environment.argument("validate") then
+    scripts.pdf.validate(filename)
+elseif environment.argument("split") then
+    scripts.pdf.split(filename)
 elseif environment.argument("detail") then
     scripts.pdf.detail(filename,environment.argument("detail"))
-elseif environment.argument("verify") then
-    scripts.pdf.verify(filename)
-elseif environment.argument("split") then
-    scripts.pdf.split(filename)
 elseif environment.argument("exporthelp") then
     application.export(environment.argument("exporthelp"),filename)
 else

Modified: trunk/Master/texmf-dist/scripts/context/lua/mtx-squid.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/context/lua/mtx-squid.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/scripts/context/lua/mtx-squid.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -59,7 +59,7 @@
   <category name="basic">
    <subcategory>
     <flag name="configure"><short>create configuration</short></flag>
-    <flag name="signal"><short>set segmets state</short></flag>
+    <flag name="signal"><short>set segments state</short></flag>
     <flag name="squid"><short>set page state</short></flag>
    </subcategory>
   </category>
@@ -95,6 +95,8 @@
 local baud    = arguments.baud or (server and server.baud) or 115200
 local port    = arguments.port or (server and server.port)
 
+local prefix  = signals.serialprefix
+
 if not osserialwrite then
     report("no support for serial communication")
     return
@@ -159,6 +161,7 @@
 end
 
 local function send(str)
+    str = prefix .. str
     local r = osserialwrite(port,baud,str)
     if verbose then
         report("%s : %s",r and "sent" or "fail",str)
@@ -320,15 +323,33 @@
 end
 
 function scripts.squid.text()
-    local text = string.upper(environment.files[1] or "")
+    local text  = string.upper(environment.files[1] or "")
+    local delay = tonumber(arguments.delay) or .2
+    local pause = tonumber(arguments.pause) or delay/2
     send("ar")
     for c in string.gmatch(text,".") do
         send("tf"..c)
-        ossleep(tonumber(arguments.delay) or .2)
+        ossleep(delay)
+        send("ar")
+        ossleep(pause)
     end
+    ossleep(1)
     send("ar")
 end
 
+function scripts.squid.number()
+    local str = string.upper(environment.files[1] or "1:25")
+    send("ar")
+    utilities.parsers.stepper(str,99,function(i)
+        if i >= 0 and i <= 99 then
+            send("nf"..i)
+            ossleep(tonumber(arguments.delay) or 1)
+        end
+    end)
+    ossleep(1)
+    send("ar")
+end
+
 function scripts.squid.squid()
     if arguments.test then
         local cmd = "qf"
@@ -391,6 +412,8 @@
     scripts.squid.squid()
 elseif arguments.text then
     scripts.squid.text()
+elseif arguments.number then
+    scripts.squid.number()
 elseif arguments.info then
     scripts.squid.info()
 elseif arguments.show then

Modified: trunk/Master/texmf-dist/scripts/context/lua/mtxrun.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/context/lua/mtxrun.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/scripts/context/lua/mtxrun.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -577,7 +577,7 @@
 
 package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true
 
--- original size: 9604, stripped down to: 6394
+-- original size: 9700, stripped down to: 6452
 
 if not modules then modules={} end modules ['l-sandbox']={
  version=1.001,
@@ -735,12 +735,6 @@
   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
   debug={
@@ -800,10 +794,19 @@
   sandboxed=true
  end
 end
-blockrequire("lfs",lfs)
-blockrequire("io",io)
-blockrequire("os",os)
-blockrequire("ffi",ffi)
+do
+ local function blockrequire(name,lib)
+  if trace then
+   report("preventing reload of: %s",name)
+  end
+  blocked[name]=lib or _G[name] or false
+ end
+ blockrequire("lfs",lfs)
+ blockrequire("io",io)
+ blockrequire("os",os)
+ blockrequire("ffi",ffi)
+ sandbox.blockrequire=blockrequire
+end
 local function supported(library)
  local l=_G[library]
  return l
@@ -5221,7 +5224,7 @@
 
 package.loaded["l-dir"] = package.loaded["l-dir"] or true
 
--- original size: 19139, stripped down to: 11345
+-- original size: 19379, stripped down to: 11553
 
 if not modules then modules={} end modules ['l-dir']={
  version=1.001,
@@ -5323,7 +5326,7 @@
   end
  end
 end
-local function glob_pattern_table(path,patt,recurse,result)
+local function glob_pattern_table(path,patt,recurse,result,dirresult)
  if not result then
   result={}
  end
@@ -5363,12 +5366,16 @@
  end
  if dirs then
   for i=1,nofdirs do
-   glob_pattern_table(dirs[i],patt,recurse,result)
+   local dir=dirs[i]
+   glob_pattern_table(dir,patt,recurse,result,dirresult)
+   if dirresult then
+    dirresult[#dirresult+1]=dir
+   end
   end
  end
- return result
+ return result,dirresult
 end
-local function globpattern(path,patt,recurse,method)
+local function globpattern(path,patt,recurse,method,dirmethod)
  local kind=type(method)
  if patt and sub(patt,1,-3)==path then
   patt=false
@@ -5378,8 +5385,11 @@
   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
+ elseif okay then
+  local files,dirs=glob_pattern_table(path,patt,recurse,{},{})
+  return files or {},dirs or {}
  else
-  return okay and glob_pattern_table(path,patt,recurse,{}) or {}
+  return {},dirmethod and {} or nil
  end
 end
 dir.globpattern=globpattern
@@ -5434,7 +5444,7 @@
 local filter=Cs ((
  P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1)
 )^0 )
-local function glob(str,t)
+local function glob(str,t,dirstoo)
  if type(t)=="function" then
   if type(str)=="table" then
    for s=1,#str do
@@ -5451,31 +5461,29 @@
     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
+ elseif 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
-  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
+   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,dirstoo)
+  else
+   return {},dirstoo and {} or nil
+  end
  end
 end
 dir.glob=glob
@@ -7667,7 +7675,7 @@
 
 package.loaded["util-tab"] = package.loaded["util-tab"] or true
 
--- original size: 34169, stripped down to: 18433
+-- original size: 35024, stripped down to: 18453
 
 if not modules then modules={} end modules ['util-tab']={
  version=1.001,
@@ -7682,7 +7690,7 @@
 local format,gmatch,gsub,sub=string.format,string.gmatch,string.gsub,string.sub
 local concat,insert,remove,sort=table.concat,table.insert,table.remove,table.sort
 local setmetatable,getmetatable,tonumber,tostring,rawget=setmetatable,getmetatable,tonumber,tostring,rawget
-local type,next,rawset,tonumber,tostring,load,select=type,next,rawset,tonumber,tostring,load,select
+local type,next,rawset,rawget,tonumber,tostring,load,select=type,next,rawset,rawget,tonumber,tostring,load,select
 local lpegmatch,P,Cs,Cc=lpeg.match,lpeg.P,lpeg.Cs,lpeg.Cc
 local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs
 local formatters=string.formatters
@@ -8403,7 +8411,7 @@
   return function() end
  end
 end
-function combine(target,source)
+local function combine(target,source)
  if target then
   for k,v in next,source do
    if type(v)=="table" then
@@ -16668,7 +16676,7 @@
 
 package.loaded["util-sig"] = package.loaded["util-sig"] or true
 
--- original size: 5924, stripped down to: 3207
+-- original size: 5963, stripped down to: 3240
 
 if not modules then modules={} end modules ['util-sig']={
  version=1.001,
@@ -16686,6 +16694,7 @@
 local serialwrite=serial and serial.write
 if serialwrite then
  signals.serialwrite=serialwrite
+ signals.serialprefix=":lmtx:1:"
  local ports={}
  local function clean(port)
   return "serial_port_"..string.gsub(port,"[^a-zA-Z0-9]","")..""
@@ -16823,7 +16832,7 @@
 
 package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true
 
--- original size: 62833, stripped down to: 36542
+-- original size: 62856, stripped down to: 36566
 
 if not modules then modules={} end modules ['lxml-tab']={
  version=1.001,
@@ -16864,12 +16873,13 @@
 end
 end
 local nsremap,resolvens=xml.xmlns,xml.resolvens
-local stack,level,top,at,xmlnms,errorstr
+local stack,level,top,at,xmlns,errorstr
 local entities,parameters
 local strip,utfize,resolve,cleanup,resolve_predefined,unify_predefined
 local dcache,hcache,acache
 local mt,dt,nt
 local currentfilename,currentline,linenumbers
+local reported_at_errors
 local grammar_parsed_text_one
 local grammar_parsed_text_two
 local grammar_unparsed_text
@@ -20632,7 +20642,7 @@
 
 package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true
 
--- original size: 11096, stripped down to: 7702
+-- original size: 11118, stripped down to: 7721
 
 if not modules then modules={} end modules ['lxml-xml']={
  version=1.001,
@@ -20736,6 +20746,7 @@
   return ""
  end
 end
+local result=false
 local xmltexthandler=xmlnewhandlers {
  name="string",
  initialize=function()
@@ -26959,8 +26970,8 @@
 
 -- used libraries    : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua util-sig.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua util-jsn.lua
 -- skipped libraries : -
--- original bytes    : 1077465
--- stripped bytes    : 429343
+-- original bytes    : 1078740
+-- stripped bytes    : 430256
 
 -- end library merge
 

Deleted: trunk/Master/texmf-dist/source/context/base/luametatex-20250725.src.zip
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/source/context/base/luametatex-20250816.src.zip
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/source/context/base/luametatex-20250816.src.zip
===================================================================
--- trunk/Master/texmf-dist/source/context/base/luametatex-20250816.src.zip	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/source/context/base/luametatex-20250816.src.zip	2025-08-18 19:08:11 UTC (rev 76089)

Property changes on: trunk/Master/texmf-dist/source/context/base/luametatex-20250816.src.zip
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/context/base/mkii/cont-new.mkii
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkii/cont-new.mkii	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkii/cont-new.mkii	2025-08-18 19:08:11 UTC (rev 76089)
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2025.07.27 21:40}
+\newcontextversion{2025.08.17 17:53}
 
 %D This file is loaded at runtime, thereby providing an
 %D excellent place for hacks, patches, extensions and new

Modified: trunk/Master/texmf-dist/tex/context/base/mkii/context.mkii
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkii/context.mkii	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkii/context.mkii	2025-08-18 19:08:11 UTC (rev 76089)
@@ -20,7 +20,7 @@
 %D your styles an modules.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2025.07.27 21:40}
+\edef\contextversion{2025.08.17 17:53}
 
 %D For those who want to use this:
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/bibl-bib.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/bibl-bib.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/bibl-bib.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -742,7 +742,6 @@
 
 end
 
-
 --~ local function test(sample)
 --~     local authors = splitauthors(sample)
 --~     print(table.serialize(authors))

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/chem-str.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/chem-str.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/chem-str.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -266,7 +266,7 @@
     }
 end
 
-local metacode, variant, keys, max, txt, pstack, sstack, align
+local metacode, variant, keys, max, txt, stack, pstack, sstack, align
 local molecule = chemistry.molecule -- or use lpegmatch(chemistry.moleculeparser,...)
 
 local function fetch(txt)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/cldf-ini.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/cldf-ini.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/cldf-ini.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -383,65 +383,14 @@
 
 storage.register("interfaces/storedscanners", storedscanners, "interfaces.storedscanners")
 
--- local function registerscanner(name,action,protected,public,usage) -- todo: combine value and condition
---     rawset(interfacescanners,name,action)
---     local n = storedscanners[name]
---     n = registerfunction("interfaces.scanners."..name,true,n)
---     storedscanners[name] = n
---     namesofscanners[n] = name
---     name = public and name or (privatenamespace .. name)
---  -- print(">>",name,protected and "protected" or "",usage or "macro")
---     setluatoken(name,n,"global",protected and "protected" or "",usage or "macro")
--- end
-
--- todo: bitmap
-
-local registerscanner if CONTEXTLMTXMODE > 0 then
-
-    -- always permanent but we can consider to obey permanent==false
-
-    -- todo: make bitset instead of keys (nil is skipped anyway)
-
-    local function toflags(specification)
-        local protected = (specification.protected and "protected") or (specification.semiprotected and "semiprotected")
-        local untraced  = specification.untraced and "untraced"
-        local noaligned = specification.noaligned and "noaligned"
-        local usage     = specification.usage
-        if usage == "value" then
-            return "global", "value", "permanent", "untraced", protected
-        elseif usage == "condition" then
-            return "global", "conditional", "permanent", "untraced", protected
-        elseif specification.frozen then
-            return "global", "frozen", untraced, protected
-        elseif specification.permanent == false or specification.onlyonce then -- for now onlyonce here
-            return "global", untraced, protected, semiprotected, noaligned
-        else
-            return "global", "permanent", untraced, protected, noaligned
-        end
-    end
-
-    registerscanner = function(name,action,specification)
-        rawset(interfacescanners,name,action)
-        local n = registerfunction("interfaces.scanners."..name,true,storedscanners[name])
-        storedscanners[name] = n
-        namesofscanners[n] = name
-        name = specification.public and name or (privatenamespace .. name)
-     -- print(name,n,toflags(specification))
-        setluatoken(name,n,toflags(specification))
-    end
-
-else
-
-    registerscanner = function(name,action,specification)
-        rawset(interfacescanners,name,action)
-        local n = storedscanners[name]
-        n = registerfunction("interfaces.scanners."..name,true,n)
-        storedscanners[name] = n
-        namesofscanners[n] = name
-        name = specification.public and name or (privatenamespace .. name)
-        setluatoken(name,n,"global",specification.protected and "protected" or "")
-    end
-
+local function registerscanner(name,action,specification)
+    rawset(interfacescanners,name,action)
+    local n = storedscanners[name]
+    n = registerfunction("interfaces.scanners."..name,true,n)
+    storedscanners[name] = n
+    namesofscanners[n] = name
+    name = specification.public and name or (privatenamespace .. name)
+    setluatoken(name,n,"global",specification.protected and "protected" or "")
 end
 
 interfaces.registerscanner = registerscanner
@@ -454,16 +403,6 @@
     return namesofscanners[slot] or slot
 end
 
-if CONTEXTLMTXMODE > 0 then
-
-    callbacks.register("show_lua_call", function(what, slot)
-        local name = namesofscanners[slot]
-     -- return name and formatters["%s: \\%s, slot: %i"](what,name,slot) or ""
-        return name and formatters["%s \\%s"](what,name) or ""
-    end, "provide lua call details")
-
-end
-
 setmetatablenewindex(interfacescanners, function(t,k,v)
     report_cld("don't register scanner %a directly",k)
  -- registerscanner(k,v)
@@ -1792,13 +1731,9 @@
 
     for i=1,#t do local k = t[i] modelevels[-k] = modelevels[k] end
 
-    if CONTEXTLMTXMODE > 0 then
+end
 
-        -- also elsewhere
-
-        local flagcodes = tex.getflagvalues()
-        tex.flagcodes   = table.swapped(flagcodes,flagcodes) -- utilities.storage.allocate()
-
-    end
-
+function lua.registerglobal(k,v)
+    rawset(_G,k,v)
+    return v
 end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/cont-new.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/cont-new.mkiv	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/cont-new.mkiv	2025-08-18 19:08:11 UTC (rev 76089)
@@ -13,7 +13,7 @@
 
 % \normalend % uncomment this to get the real base runtime
 
-\newcontextversion{2025.07.27 21:43}
+\newcontextversion{2025.08.17 17:57}
 
 %D This file is loaded at runtime, thereby providing an excellent place for hacks,
 %D patches, extensions and new features. There can be local overloads in cont-loc

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkiv	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/context.mkiv	2025-08-18 19:08:11 UTC (rev 76089)
@@ -49,7 +49,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2025.07.27 21:43}
+\edef\contextversion{2025.08.17 17:57}
 
 %D Kind of special:
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/data-tex.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/data-tex.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/data-tex.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -163,8 +163,7 @@
             if trace_locating then
                 report_tex("%a closer: %a closed",tag,filename)
             end
-            handler = nil
-            lines   = nil
+            lines = nil
         end,
         reader      = function(self)
             self = self or handler

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/export-example.css
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/export-example.css	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/export-example.css	2025-08-18 19:08:11 UTC (rev 76089)
@@ -988,6 +988,7 @@
 /* floatcontent : mixed   */
 
 float,
+subfloat,
 div.float {
     display       : block ;
     margin-top    : 1em ;

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-imp-combining.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-imp-combining.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-imp-combining.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -92,6 +92,8 @@
 
 -- see analyzeprocessor in case we want scripts
 
+local sorter = false
+
 local function reorder(head)
     if count == 2 then
         local first = slide[1]

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-otd.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-otd.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-otd.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -47,7 +47,7 @@
     local features = contextsetups[attribute]
     if features then
         local dynamics = fontdynamics[font]
-        dynamic = contextmerged[attribute] or 0
+        local dynamic  = contextmerged[attribute] or 0
         local script, language
         if dynamic == 2 then -- merge
             language  = features.language or fontproperties[font].language or "dflt"

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-ots.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-ots.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-ots.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -297,6 +297,7 @@
 local spaces             = false
 
 local sweepnode          = nil
+local sweeptype          = nil
 local sweephead          = { } -- we don't nil entries but false them (no collection and such)
 
 local notmatchpre        = { } -- to be checked: can we use false instead of nil / what if a == b tests

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-oup.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-oup.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-oup.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -26,7 +26,7 @@
 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_cleanup        = false  trackers.register("otf.cleanups",      function(v) trace_cleanup       = 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)
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-sel.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-sel.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-sel.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -466,7 +466,7 @@
         if arguments and arguments ~= "" then
             local entries = settings_to_array(arguments)
             for index, entry in next, entries do
-                method, argument = lpegmatch(colon,entry)
+                local method, argument = lpegmatch(colon,entry)
                 if not argument then
                     argument = method
                     method   = "name"

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/font-shp.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/font-shp.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/font-shp.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -169,7 +169,7 @@
     local size = attr and attr.size or 0
     local time = attr and attr.modification or 0
     local sub  = tonumber(sub)
-
+    local data = nil
     -- fonts.formats
 
     if size > 0 and (kind == "otf" or kind == "ttf" or kind == "tcc") then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/grph-img.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/grph-img.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/grph-img.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -257,6 +257,7 @@
         end
         local xres         = 0
         local yres         = 0
+        local units        = 1
         local orientation  = 1
         local okay         = false
         local filesize     = f:getsize() -- seek end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/l-dir.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/l-dir.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/l-dir.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -135,7 +135,7 @@
     end
 end
 
-local function glob_pattern_table(path,patt,recurse,result)
+local function glob_pattern_table(path,patt,recurse,result,dirresult)
     if not result then
         result = { }
     end
@@ -175,13 +175,17 @@
     end
     if dirs then
         for i=1,nofdirs do
-            glob_pattern_table(dirs[i],patt,recurse,result)
+            local dir = dirs[i]
+            glob_pattern_table(dir,patt,recurse,result,dirresult)
+            if dirresult then
+                dirresult[#dirresult+1] = dir
+            end
         end
     end
-    return result
+    return result, dirresult
 end
 
-local function globpattern(path,patt,recurse,method)
+local function globpattern(path,patt,recurse,method,dirmethod)
     local kind = type(method)
     if patt and sub(patt,1,-3) == path then
         patt = false
@@ -191,8 +195,11 @@
         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
+    elseif okay then
+        local files, dirs = glob_pattern_table(path,patt,recurse,{ },{ })
+        return files or { }, dirs or { }
     else
-        return okay and glob_pattern_table(path,patt,recurse,{ }) or { }
+        return { }, dirmethod and { } or nil
     end
 end
 
@@ -271,7 +278,7 @@
     P(1)
 )^0 )
 
-local function glob(str,t)
+local function glob(str,t,dirstoo)
     if type(t) == "function" then
         if type(str) == "table" then
             for s=1,#str do
@@ -288,31 +295,29 @@
                 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
+    elseif 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
-        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) -- we could use the file splitter
-            if root and path and base then
-                local recurse = find(base,"**",1,true) -- find(base,"%*%*")
-                local start   = root .. path
-                local result  = lpegmatch(filter,start .. base)
-                return globpattern(start,result,recurse,t)
-            else
-                return { }
-            end
+            return { str }
         end
+    else
+        local root, path, base = lpegmatch(pattern,str) -- we could use the file splitter
+        if root and path and base then
+            local recurse = find(base,"**",1,true) -- find(base,"%*%*")
+            local start   = root .. path
+            local result  = lpegmatch(filter,start .. base)
+            return globpattern(start,result,recurse,t,dirstoo)
+        else
+            return { }, dirstoo and { } or nil
+        end
     end
 end
 
@@ -394,7 +399,8 @@
 
 dir.globdirs = globdirs
 
--- inspect(globdirs("e:/tmp"))
+-- inspect(globfiles("t:/sources"))
+-- inspect(globdirs("t:/sources"))
 
 -- t = dir.glob("c:/data/develop/context/sources/**/????-*.tex")
 -- t = dir.glob("c:/data/develop/tex/texmf/**/*.tex")

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/l-sandbox.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/l-sandbox.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/l-sandbox.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -181,13 +181,6 @@
     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
         debug = {
@@ -249,11 +242,24 @@
     end
 end
 
-blockrequire("lfs",lfs)
-blockrequire("io",io)
-blockrequire("os",os)
-blockrequire("ffi",ffi)
+do
 
+    local function blockrequire(name,lib)
+        if trace then
+            report("preventing reload of: %s",name)
+        end
+        blocked[name] = lib or _G[name] or false
+    end
+
+    blockrequire("lfs",lfs)
+    blockrequire("io",io)
+    blockrequire("os",os)
+    blockrequire("ffi",ffi)
+
+    sandbox.blockrequire = blockrequire
+
+end
+
 -- require = register(require,"require")
 
 -- we sandbox some of the built-in functions now:

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/lang-txt.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/lang-txt.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/lang-txt.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -4942,7 +4942,7 @@
     ["ca"]="Projecte de licenciatura",
     ["cnr"]="Дипломски пројекат",
     ["cnr-latn"]="Diplomski projekat",
-    ["cs"]="Bakalářská práce",
+    ["cs"]="Bakalářský projekt",
     ["en"]="Bachelor's Project",
     ["es"]="Proyecto de licenciatura",
     ["fa"]="",
@@ -5079,7 +5079,7 @@
     ["fi"]="Konsultti",
     ["fr"]="Consultant",
     ["gr"]="Σύμβουλος",
-    ["hy"]="խորհրդատու",
+    ["hy"]="Խորհրդատու",
     ["id"]="Konsultan",
     ["lt"]="Konsultantas",
     ["ml"]="Perunding",

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/lpdf-fld.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -334,6 +334,7 @@
     local fontsize        = specification.fontsize or "12pt"
     local fontstyle       = specification.fontstyle or "rm"
     local fontalternative = specification.fontalternative or "tf"
+    local fontraise       = 0
     local colorvalue      = tonumber(specification.colorvalue)
     local s = fontnames[fontstyle]
     if not s then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-tab.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-tab.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-tab.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -130,13 +130,13 @@
 
 local nsremap, resolvens = xml.xmlns, xml.resolvens
 
-local stack, level, top, at, xmlnms, errorstr
+local stack, level, top, at, xmlns, errorstr
 local entities, parameters
 local strip, utfize, resolve, cleanup, resolve_predefined, unify_predefined
 local dcache, hcache, acache
 local mt, dt, nt
 local currentfilename, currentline, linenumbers
-
+local reported_at_errors
 local grammar_parsed_text_one
 local grammar_parsed_text_two
 local grammar_unparsed_text

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-tex.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-tex.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-tex.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -324,6 +324,8 @@
     forceraw = false
 end
 
+local rawroot = nil
+
 function lxml.rawroot()
     return rawroot
 end
@@ -1054,9 +1056,9 @@
                 root = xmldespecialized(xmltostring(root))
                 lpegmatch(xmltextcapture,root) -- goes to toc
             else
-if setfilename and p then -- and not root.cl
-    syncfilename(p,"sprint t")
-end
+                if setfilename and p then -- and not root.cl
+                    syncfilename(p,"sprint t")
+                end
                 xmlserialize(root,xmltexhandler)
             end
         end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-xml.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-xml.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/lxml-xml.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -136,6 +136,8 @@
 
 --
 
+local result = false
+
 local xmltexthandler = xmlnewhandlers {
     name       = "string",
     initialize = function()

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1649,7 +1649,7 @@
         return true -- not needed
     end
 
-    local enable = function()
+    local function enable()
         enableaction("math", "noads.handlers.italics")
         if trace_italics then
             report_italics("enabling math italics")
@@ -1896,7 +1896,7 @@
         return true -- not needed
     end
 
-    local enable = function()
+    local function enable()
         enableaction("math", "noads.handlers.collapse")
         if trace_collapsing then
             report_collapsing("enabling math collapsing")
@@ -2189,9 +2189,7 @@
         return attr
     end
 
-    local enable
-
-    enable = function()
+    local function enable()
         enableaction("math", "noads.handlers.domains")
         if trace_domains then
             report_domains("enabling math domains")

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/meta-imp-outlines.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/meta-imp-outlines.mkiv	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/meta-imp-outlines.mkiv	2025-08-18 19:08:11 UTC (rev 76089)
@@ -77,7 +77,7 @@
                     (all or options[v_box])     and f_in_red   (metapost.boundingbox(glyph,factor)) or "",
                     (all or options[v_width])   and f_in_green (metapost.widthline(glyph,factor)) or "",
                     (all or options[v_min])     and f_in_blue  (metapost.zeroline(glyph,factor)) or "",
-                    (all or options[v_max])     and f_setbounds(metapost.maxbounds(data,index,factor),offset or 1) or "",
+                    (all or options[v_max])     and f_setbounds(metapost.maxbounds(shapedata,index,factor),offset or 1) or "",
                     (all or options[v_comment]) and f_comment  (what,1) or "",
                 })
                 if alternative == v_page then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/node-fin.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -136,7 +136,7 @@
 
 local nsdata, nsnone, nslistwise, nsforced, nsselector, nstrigger
 local current, current_selector = 0, 0 -- nb, stack has a local current !
-local nsbegin, nsend, nsreset
+local nsbegin, nsend, nsreset, nsstep, nspush, nspop
 
 function states.initialize(namespace,attribute,head)
     nsdata           = namespace.data

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/node-ref.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/node-ref.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/node-ref.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -503,8 +503,8 @@
 local function colorize(width,height,depth,n,reference,what,sr,offset)
     if force_gray then n = 0 end
     u_transparency = u_transparency or transparencies.register(nil,2,.65)
-    local ucolor = u_colors[n]
-    if not ucolor then
+    local u_color = u_colors[n]
+    if not u_color then
         if n == 1 then
             u_color = register_color(nil,'rgb',.75,0,0)
         elseif n == 2 then

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/publ-ini.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/publ-ini.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/publ-ini.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1211,13 +1211,9 @@
                                 local author = getcasted(dataset,tag,field,specifications[btxspc])
                                 local kind   = type(author)
                                 if kind == "table" or kind == "string" then
-                                    if u then
-                                        u = listentry.entries.text -- hm
-                                    else
-                                        u = "0"
-                                    end
-                                    local year  = tonumber(entry.year) or 9999
-                                    local data  = { tag, year, u, i }
+                                    local text = listentry.entries.text or "0"
+                                    local year = tonumber(entry.year) or 9999
+                                    local data = { tag, year, text, i }
                                     -- authors
                                     local hash  = hasher(author)
                                     local found = authors[hash]
@@ -3639,3 +3635,8 @@
     }
 
 end
+
+-- Here we also predefine the global bibtex namespace. It will be populated
+-- when there is need for it.
+
+bibtex = { }

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/spac-ali.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/spac-ali.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/spac-ali.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -58,8 +58,8 @@
 local alignments       = { }
 typesetters.alignments = alignments
 
-local report_realign   = logs.reporter("typesetters","margindata")
-local trace_realign    = trackers.register("typesetters.margindata", function(v) trace_margindata = v end)
+local report_realign   = logs.reporter("typesetters","realign")
+local trace_realign    = trackers.register("typesetters.realign", function(v) trace_realign = v end)
 
 local nofrealigned     = 0
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/status-files.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/status-lua.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/strc-lst.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/strc-lst.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/strc-lst.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -323,7 +323,7 @@
 
 local enhanced = { }
 
-local synchronizepage = function(r)  -- bah ... will move
+local function synchronizepage(r)  -- bah ... will move
     synchronizepage = references.synchronizepage
     return synchronizepage(r)
 end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/strc-syn.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/strc-syn.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/strc-syn.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -261,10 +261,11 @@
     local lasttag  = nil
     local lasttag  = nil
     local nofdone  = 0
+    local done     = nil
     for k=1,#result do
         local entry = result[k]
         local first, tag = firstofsplit(entry)
-        if tag ~= lasttag then
+        if tag ~= lasttag or not done then
          -- if trace_registers then
          --     report_registers("splitting at %a",tag)
          -- end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/strc-tag.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/strc-tag.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/strc-tag.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -104,7 +104,7 @@
 
     lines                 = { pdf = "Code",       nature = "display" },
     line                  = { pdf = "Code",       nature = "mixed"   },
-    linenumber            = { pdf = "Span",       nature = "inline"   },
+    linenumber            = { pdf = "Span",       nature = "inline"  },
 
     synonym               = { pdf = "Span",       nature = "inline"  },
     sorting               = { pdf = "Span",       nature = "inline"  },

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/trac-par.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/trac-par.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/trac-par.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -39,9 +39,10 @@
 
 -- scale = multiplier + ef/multiplier
 
-local trace_both    = false  trackers.register("builders.paragraphs.expansion.both",    function(v) trace_verbose = false trace_both  = v end)
-local trace_verbose = false  trackers.register("builders.paragraphs.expansion.verbose", function(v) trace_verbose = v     trace_color = v end)
+local trace_verbose = false
 
+trackers.register("builders.paragraphs.expansion.verbose", function(v) trace_verbose = v end)
+
 local report_verbose = logs.reporter("fonts","expansion")
 
 local function colorize(n)
@@ -137,4 +138,4 @@
 end
 
 trackers.register("builders.paragraphs.expansion.verbose",set)
-trackers.register("builders.paragraphs.expansion.both",set)
+trackers.register("builders.paragraphs.expansion.both",   set)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/trac-vis.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -927,7 +927,7 @@
 
 end
 
-local ruledglue do
+local ruledglue, ruledspace do
 
     local gluecodes             = nodes.gluecodes
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/typo-tal.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/typo-tal.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/typo-tal.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -136,7 +136,6 @@
             signs      = validsigns,
         }
         datasets[column] = dataset
-        used = true
     end
     return dataset
 end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-rnd.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-rnd.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-rnd.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1,5 +1,5 @@
 if not modules then modules = { } end modules ['util-rnd'] = {
-    version   = 1.001,
+    version   = 1.003,
     comment   = "companion to luat-lib.mkiv",
     author    = "Tamara, Adriana, Tomáš Hála & Hans Hagen",
     copyright = "ConTeXt Development Team", -- umbrella
@@ -44,25 +44,25 @@
         return ceil(num * coef -0.5) / coef
     end,
     halfabsup = function(num,coef)
-        -- rounds deciaml numbers as usual, numbers with 0.5 away from zero, e.g. numbers -0.5 and 0.5 will be rounded to -1 and 1
+        -- rounds decimal numbers as usual, numbers with 0.5 away from zero, e.g. numbers -0.5 and 0.5 will be rounded to -1 and 1, respectively
         coef = coef and pow(10,coef) or 1
         return (num >= 0 and floor(num * coef + 0.5) or ceil(num * coef - 0.5)) / coef
     end,
     halfabsdown = function(num,coef)
-        -- rounds deciaml numbers as usual, numbers with 0.5 towards zero, e.g. numbers -0.5 and 0.5 will be rounded both to 0
+        -- rounds decimal numbers as usual, numbers with 0.5 towards zero, e.g. numbers -0.5 and 0.5 will be rounded both to 0
         coef = coef and pow(10,coef) or 1
         return (num <  0 and floor(num * coef + 0.5) or ceil(num * coef - 0.5)) / coef
     end,
     halfeven = function(num,coef)
-       -- rounds deciaml numbers as usual, numbers with 0.5 to the nearest even, e.g. numbers 1.5 and 2.5 will be rounded both to 2
+       -- rounds decimal numbers as usual, numbers with 0.5 to the nearest even, e.g. numbers 1.5 and 2.5 will be rounded both to 2
         coef = coef and pow(10,coef) or 1
-        num = num*coef
+        num  = num*coef
         return floor(num + (((num - floor(num)) ~= 0.5 and 0.5) or ((floor(num) % 2 == 1) and 1) or 0)) / coef
     end,
     halfodd = function(num,coef)
-        -- rounds deciaml numbers as usual, numbers with 0.5 to the nearest odd (e.g. numbers 1.5 and 2.5 will be rounded to 1 and 3
+        -- rounds decimal numbers as usual, numbers with 0.5 to the nearest odd (e.g. numbers 1.5 and 2.5 will be rounded to 1 and 3
         coef = coef and pow(10,coef) or 1
-        num = num * coef
+        num  = num * coef
         return floor(num + (((num - floor(num)) ~= 0.5 and 0.5) or ((floor(num) % 2 == 1) and 0) or 1)) / coef
     end,
 }
@@ -73,22 +73,20 @@
     local s = gsub(lower(k),"[^a-z]","")
     local v = rawget(t,s)
     if not v then
-        v = t.halfup
+        v = t.default
     end
-    t[k] = v
+    t[k] = v -- we keep this
     return v
 end)
 
 -- If needed I can make a high performance one.
 
-local defaultmethod = methods.halfup
-
 rounding.round = function(num,dec,mode)
     if type(dec) == "string" then
         mode = dec
         dec  = 1
     end
-    return (mode and methods[mode] or defaultmethod)(num,dec)
+    return methods[mode or ""](num,dec)
 end
 
 number.rounding = rounding
@@ -113,4 +111,17 @@
 --     print(n,"HALF_ABS_DOWN",myround(n,1))
 -- end
 
+--[[
+
+-- Tomáš' test parameters:
+
+context( round(6.55,1,"halfdown") )
+context( round(6.55,1,"xxx") )
+context( round(6.55,1) )
+context( round(6.55,"halfdown") )
+context( round(6.55,"yyy") )
+context( round(6.55) )
+
+--]]
+
 return rounding

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-sci.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-sci.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-sci.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -18,10 +18,7 @@
 local report = logs.reporter("scite")
 
 do
---     local lexerroot = "c:/data/system/scite/wscite/context/lexers"
---     if not lexerroot then
-        lexerroot = file.dirname(resolvers.findfile("scite-context-lexer.lua"))
---     end
+    local lexerroot = file.dirname(resolvers.findfile("scite-context-lexer.lua"))
     if lfs.isdir(lexerroot) then
     -- pushluapath
         package.extraluapath(lexerroot)
@@ -59,6 +56,8 @@
  -- todo: pat/hyp ori
 }
 
+-- use context loader instead of require
+
 lexers = nil -- main lexer, global (for the moment needed for themes)
 
 local function loadscitelexer()
@@ -69,7 +68,6 @@
             (lexers.disablewordcheck or lexers.context.disablewordcheck)()
         end
     end
-    return lexer
 end
 
 local loadedlexers = setmetatableindex(function(t,k)

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-parallel.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-parallel.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-parallel.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -40,7 +40,8 @@
         return
     end
 
-    local prefix = "s"
+ -- local prefix = "s"
+    local prefix = signals.serialprefix .. "s"
 
     local function squidsome(cmd,run)
         cmd = prefix .. cmd .. (run or "0") .. "\r"

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-quadrant.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-quadrant.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-quadrant.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -40,7 +40,8 @@
         return
     end
 
-    local prefix = "k"
+ -- local prefix = "k"
+    local prefix = signals.serialprefix .. "k"
 
     local function squidsome(cmd,run)
         cmd = prefix .. cmd .. (run or "0") .. "\r"

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-runner.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-runner.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-runner.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -22,8 +22,9 @@
 
 local trace    = environment.arguments.verbose
 
-local report   = utilities.signals.report or logs.reporter("signal")
-local state    = utilities.signals.loadstate()
+local signals  = utilities.signals
+local report   = signals.report or logs.reporter("signal")
+local state    = signals.loadstate()
 
 local server   = state and state.servers[state.usage.server or "default"]
 local protocol = server and server.protocol or "hue"
@@ -70,6 +71,8 @@
         lamps = lamps_8
     end
 
+    local prefix = signals.serialprefix
+
     enable = function(state,first,last)
         local command = states[state]
         if command then
@@ -76,7 +79,10 @@
             local count = #lamps
             for i=first,last do
                 -- q=squid k=quadrant s=segment a=all
-                local cmd = (count == 8 and "s" or "k") .. command .. i
+                local cmd = prefix .. (count == 8 and "s" or "k") .. command .. i
+--                 .. "\n"
+--                 .. " "
+--                 print(cmd)
                 serialwrite(port,baud,cmd)
             end
         end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-segment.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-segment.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-segment.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -40,7 +40,8 @@
         return
     end
 
-    local prefix = "s"
+ -- local prefix = "s"
+    local prefix = signals.serialprefix .. "s"
 
     local function squidsome(cmd,run)
         cmd = prefix .. cmd .. (run or "0") .. "\r"

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-squid.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-squid.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig-imp-squid.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -27,6 +27,8 @@
 
 if protocol == "serial" then
 
+    -- use signals.serialwrite
+
     local port = false
     local baud = 115200
 
@@ -40,8 +42,10 @@
         return
     end
 
+    local prefix = signals.serialprefix
+
     local function squidsome(cmd)
-        serialwrite(port,baud,cmd .. "\r")
+        serialwrite(port,baud,prefix .. cmd .. "\r")
     end
 
     local function squidreset  () squidsome("qr") end
@@ -52,11 +56,11 @@
     local function squiderror  () squidsome("qe") end
 
     local function squidstep()
-        signals.serialfast(port,baud,"qs")
+        signals.serialfast(port,baud,prefix .. "qs")
     end
 
     local function squiddone(currentrun,details)
-        signals.serialfast(port,baud,"qf")
+        signals.serialfast(port,baud,prefix .. "qf")
         if details and statistics and statistics.feedback then
             statistics.feedback.processstates(function(s)
                 local index    = s.index
@@ -70,7 +74,12 @@
                     command = "fe"
                 end
                 if command then
-                    signals.serialfast(port,baud,command .. index .. "\n")
+                    command = prefix .. command .. index
+                    -- "\n"
+--                     command = command .. " "
+--                     command = command .. "\n"
+-- print(command)
+                    signals.serialfast(port,baud,command)
                 end
             end)
         end

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-sig.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -25,7 +25,8 @@
 
 if serialwrite then
 
-    signals.serialwrite = serialwrite
+    signals.serialwrite  = serialwrite
+    signals.serialprefix = ":lmtx:1:"
 
     local ports = { }
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkiv/util-tab.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkiv/util-tab.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkiv/util-tab.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -13,7 +13,7 @@
 local format, gmatch, gsub, sub = string.format, string.gmatch, string.gsub, string.sub
 local concat, insert, remove, sort = table.concat, table.insert, table.remove, table.sort
 local setmetatable, getmetatable, tonumber, tostring, rawget = setmetatable, getmetatable, tonumber, tostring, rawget
-local type, next, rawset, tonumber, tostring, load, select = type, next, rawset, tonumber, tostring, load, select
+local type, next, rawset, rawget, tonumber, tostring, load, select = type, next, rawset, rawget, tonumber, tostring, load, select
 local lpegmatch, P, Cs, Cc = lpeg.match, lpeg.P, lpeg.Cs, lpeg.Cc
 local sortedkeys, sortedpairs = table.sortedkeys, table.sortedpairs
 local formatters = string.formatters
@@ -980,7 +980,7 @@
 --     end
 -- end
 
-function combine(target,source)
+local function combine(target,source)
     -- no copy so if that is needed one needs to deepcopy source first
     if target then
         for k, v in next, source do
@@ -1019,3 +1019,36 @@
 --     end
 --     return result
 -- end
+
+-- can be a helper
+
+-- function table.identify(t)
+--     local size = #t
+--     if size > 0 then
+--         local count  = 0
+--         local simple = true
+--         for k, v in next, t do
+--             if type(k) ~= "number" then
+--                 count = -1
+--                 break
+--             end
+--             count = count + 1
+--             if simple and type(v) == "table" then
+--                 simple = false
+--             end
+--         end
+--         if rawget(t,0) then
+--             return
+--                 (size == count - 1) and size,
+--                 true,
+--                 simple
+--         else
+--             return
+--                 (size == count) and size,
+--                 false,
+--                 simple
+--         end
+--     else
+--         return false, false, false
+--     end
+-- end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/anch-bck.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/anch-bck.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/anch-bck.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -97,9 +97,9 @@
 \installcommandhandler \??textbackground {textbackground} \??textbackground
 
 \appendtoks
-    \frozen\instance\protected\edefcsname        \currenttextbackground\endcsname{\groupedcommand{\starttextbackground[\currenttextbackground]}{\stoptextbackground}}%
-    \frozen\instance\protected\edefcsname\e!start\currenttextbackground\endcsname{\starttextbackground[\currenttextbackground]}%
-    \frozen\instance\protected\edefcsname\e!stop \currenttextbackground\endcsname{\stoptextbackground}%
+    \protected\frozen\instance\edefcsname        \currenttextbackground\endcsname{\groupedcommand{\starttextbackground[\currenttextbackground]}{\stoptextbackground}}%
+    \protected\frozen\instance\edefcsname\e!start\currenttextbackground\endcsname{\starttextbackground[\currenttextbackground]}%
+    \protected\frozen\instance\edefcsname\e!stop \currenttextbackground\endcsname{\stoptextbackground}%
 \to \everydefinetextbackground
 
 \newconstant   \c_anch_backgrounds_pos_state

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/anch-loc.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/anch-loc.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/anch-loc.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -493,10 +493,10 @@
     registerscript("anchorspan", function()
         local l = valid(scanstring(),scaninteger(),scaninteger())
         local r = valid(scanstring(),scaninteger(),scaninteger())
-        local llx, lly, urx, ury, lb, ub
+        local llx, lly, urx, ury
         if l and r then
-            lb  = l[7]
-            rb  = r[7]
+            local lb = l[7]
+            local rb = r[7]
             llx = min((l[1]        ),(r[1]        )) * bpfactor
             lly = min((l[2] - lb[3]),(r[2] - rb[3])) * bpfactor
             urx = max((l[1] + lb[1]),(r[1] + rb[1])) * bpfactor

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/anch-pos.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/anch-pos.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/anch-pos.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -863,7 +863,7 @@
 
 -- beware ... we're not sparse here as lua will reserve slots for the nilled
 
-local getpos, gethpos, getvpos, getrpos
+local getpos, gethvrpos, gethpos, getvpos, getrpos
 
 function jobpositions.registerhandlers(t)
     getpos    = t and t.getpos    or function() return 0, 0 end
@@ -970,7 +970,7 @@
     -- officially there should have been a settobesaved
     local data = enhance(value or {})
     if value then
-        container = tobesaved[name]
+        local container = tobesaved[name]
         if not container then
             tobesaved[name] = {
                 [index] = data
@@ -989,7 +989,7 @@
     local value = specification.value
     local data  = enhance(value or {})
     if value then
-        container = tobesaved[name]
+        local container = tobesaved[name]
         if not container then
             tobesaved[name] = {
                 [index] = data

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/attr-ini.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/attr-ini.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/attr-ini.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -64,6 +64,7 @@
        \aliased\gletcsname#2\s!attribute\expandafter\endcsname\csname\??attributeid#2\endcsname% \attribute\fooattribute
      \fi
      % used to sync in the page builder .. used for directions and scripts ... i start forgetting these details .. (seldom used)
+     % also resync tagging in margin texts
      \ifinset\s!pickup{#3}%
        \global\expandafter\integerdef\csname\??attributepickup#2\endcsname\attributeunsetvalue
        \xtoksapp\t_attr_list_pickup{\csname\??attributeprefix#2\endcsname\csname\??attributepickup#2\endcsname}%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/attr-lay.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/attr-lay.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/attr-lay.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -52,9 +52,9 @@
 \appendtoks
   \attr_layoutcomponent_whatever\clf_defineviewerlayer
   \ifcstok{\viewerlayerparameter\c!method}\v!command
-    \frozen\protected\instance\xdefcsname\e!start\currentviewerlayer\endcsname{\startviewerlayer[\currentviewerlayer]}%
+    \protected\frozen\instance\xdefcsname\e!start\currentviewerlayer\endcsname{\startviewerlayer[\currentviewerlayer]}%
   \else
-    \frozen\protected\instance\xdefcsname\e!stop \currentviewerlayer\endcsname{\stopviewerlayer}%
+    \protected\frozen\instance\xdefcsname\e!stop \currentviewerlayer\endcsname{\stopviewerlayer}%
   \fi
 \to \everydefineviewerlayer
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/back-exp-imp-tag.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/back-exp-imp-tag.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/back-exp-imp-tag.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -261,6 +261,8 @@
 
 do
 
+    -- todo: register prerolled alt
+
     local synonyms = { }
     local sortings = { }
 
@@ -301,6 +303,9 @@
     structurestags.setsynonym = setsynonym
     structurestags.setsorting = setsorting
 
+    structurestags.getsynonym = function(fulltag) return synonyms[fulltag] end
+    structurestags.getsorting = function(fulltag) return sortings[fulltag] end
+
 end
 
 do
@@ -308,9 +313,25 @@
     local descriptions = { }
     local symbols      = { }
     local linked       = { }
+    local listindices  = { }
 
     -- we could move the notation itself to the first reference (can be an option)
 
+    -- this is not ok ...
+
+    local function setdescriptionindex(n,l)
+        local fulltag = locatedtag("description")
+        if fulltag then
+            -- why not in ... we are not to much off here
+         -- local spec = specifications[fulltag]
+            listindices[fulltag] = {
+                noteindex = n,
+                listindex = l,
+            }
+        else
+        end
+    end
+
     local function setnotation(tag,n) -- needs checking (is tag needed)
         -- we can also use the internals hash or list
         local nd = structures.notes.get(tag,n)
@@ -355,6 +376,12 @@
     end
 
     implement {
+        name      = "settagdescriptionindex",
+        actions   = setdescriptionindex,
+        arguments = "2 integers",
+    }
+
+    implement {
         name      = "settagnotation",
         actions   = setnotation,
         arguments = { "string", "integer" }
@@ -366,9 +393,14 @@
         arguments = { "string", "integer" }
     }
 
-    structurestags.setnotation       = setnotation
-    structurestags.setnotationsymbol = setnotationsymbol
+    structurestags.setdescriptionindex = setdescriptionindex
+    structurestags.setnotation         = setnotation
+    structurestags.setnotationsymbol   = setnotationsymbol
 
+    function structurestags.getdescriptionindex(fulltag)
+        return listindices[fulltag]
+    end
+
 end
 
 
@@ -421,11 +453,15 @@
 
 do
 
-    local image      = { }
-    local nofimages  = 0
-    usedimages.image = image
+    local image          = { }
+    local mpgraphic      = { }
+    local nofimages      = 0
+    local nofmpgraphics  = 0
+    usedimages.image     = image
+    usedimages.mpgraphic = mpgraphic
 
-    structurestags.usewithcare.images = image
+    structurestags.usewithcare.image     = image
+    structurestags.usewithcare.mpgraphic = mpgraphic
 
     local function setfigure(
         name,used,page,
@@ -433,7 +469,7 @@
         category,exported,
         descriptiontext,alternativetext
     )
-        local fulltag = locatedtag("image")
+        local fulltag = locatedtag("image") -- we actually can be deeper
         local spec    = specifications[fulltag]
         if spec then
             local id
@@ -444,6 +480,24 @@
                 id = tex.jobname .. "-image-" .. nofimages
             end
             local page = tonumber(page)
+            --
+            -- This is rather ugly but very much a side effect of MS wanting to be able to tag
+            -- them as figure so these /Alt's are mandate then .. sigh:
+            --
+            -- \startimage[alternativetext=outer] \startMPcode
+            -- \startimage                        \startMPcode[alternativetext=inner wins]
+            -- \startMPcode[alternativetext=inner wins]
+            -- \startimage                        \startMPcode
+            -- \startMPcode
+            --
+            -- which gets processed (set) in the reverse order but so be it.
+            --
+            local found = image[fulltag]
+            if found then
+                if descriptiontext == "" then descriptiontext = found.descriptiontext or descriptiontext end
+                if alternativetext == "" then alternativetext = found.alternativetext or alternativetext end
+            end
+            --
             image[fulltag] = {
                 exported        = exported,
                 id              = id,
@@ -464,6 +518,19 @@
         end
     end
 
+    local function setmpgraphic(
+        descriptiontext,alternativetext
+    )
+        local fulltag = locatedtag("mpgraphic")
+        local spec    = specifications[fulltag]
+        if spec then
+            mpgraphic[fulltag] = {
+                descriptiontext = descriptiontext,
+                alternativetext = alternativetext,
+            }
+        end
+    end
+
     function extras.image(di,element,n,fulltag)
         local data = image[fulltag]
         if data then
@@ -484,6 +551,14 @@
         end
     end
 
+    function extras.mpgraphic(di,element,n,fulltag)
+        local data = image[fulltag]
+        if data then
+            setattribute(di,"descriptiontext",data.descriptiontext)
+            setattribute(di,"alternativetext",data.alternativetext)
+        end
+    end
+
     implement {
         name      = "settagfigure",
         actions   = setfigure,
@@ -502,8 +577,18 @@
         }
     }
 
-    structurestags.setfigure = setfigure
+   implement {
+        name      = "settagmpgraphic",
+        actions   = setmpgraphic,
+        arguments = {
+            "string",    -- descriptiontext
+            "string",    -- alternativetext
+        }
+    }
 
+    structurestags.setfigure    = setfigure
+    structurestags.setmpgraphic = setmpgraphic
+
 end
 
 do
@@ -760,11 +845,25 @@
     implement {
         name      = "settaglist",
         actions   = setlist,
-        arguments = "integer"
+        arguments = "integer",
     }
 
-    structurestags.setlist = setlist
+end
 
+do
+
+    local list = { }
+
+    function structurestags.gettagreferencedescription(id)
+        return list[id]
+    end
+
+    implement {
+        name      = "settagsetreferencedescription",
+        actions   = function(id,str) list[id] = str end,
+        arguments = { "integer", "string" },
+    }
+
 end
 
 do

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/back-exp.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/back-exp.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/back-exp.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -50,9 +50,11 @@
      \expandafter\ctxcommand
    \fi}
 
+% todo: \c_strc_tags_enabled for the setters
+
 \appendtoks
     \enforced\permanent\protected\def\dotagTABLEcell
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagtablecell{\tablecellrows}{\tablecellcolumns}{\raggedstatus}%
        \fi}%
     % brrr, we need to tag empty cells (unless we start numbering)
@@ -62,7 +64,7 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagtabulatecell
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagtabulatecell\c_tabl_tabulate_align\c_tabl_tabulate_kind
        \fi}%
     \enforced\permanent\protected\def\dotagtabulatesignal
@@ -71,17 +73,21 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagsynonym
-      {\iftrialtypesetting\else\clf_settagsynonym{\currentsynonymtag}\fi}%
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
+         \clf_settagsynonym{\currentsynonymtag}%
+       \fi}%
 \to \everyenableelements
 
 \appendtoks
     \enforced\permanent\protected\def\dotagsorting
-      {\iftrialtypesetting\else\clf_settagsorting{\currentsortingtag}\fi}%
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
+         \clf_settagsorting{\currentsortingtag}%
+       \fi}%
 \to \everyenableelements
 
 \appendtoks % frozen and assumed global per highlight class
     \enforced\permanent\protected\def\dotagconstruct
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagconstruct
            {\currentstartstop}%
            {\startstopparameter\c!style}%
@@ -93,7 +99,7 @@
 
 \appendtoks % frozen and assumed global per highlight class
     \enforced\permanent\protected\def\dotaghighlight
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settaghighlight
            {\currenthighlight}%
            {\highlightparameter\c!style}
@@ -108,7 +114,7 @@
 
 \appendtoks % we can have differently scaled images
     \enforced\permanent\protected\def\dotagfigure
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagfigure
            {\figurefileoriginal}%
            {\figurefullname}%
@@ -125,14 +131,34 @@
 \to \everyenableelements
 
 \appendtoks
+    \enforced\permanent\protected\def\dotagimage
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
+         \clf_settagimage
+           {\figurelabel}%
+           {\figuredescriptiontext}%
+           {\figurealternativetext}%
+       \fi}%
+\to \everyenableelements
+
+
+\appendtoks
+    \enforced\permanent\protected\def\dotagmpgraphic
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
+         \clf_settagmpgraphic
+           {\figuredescriptiontext}%
+           {\figurealternativetext}%
+       \fi}%
+\to \everyenableelements
+
+\appendtoks
     \enforced\permanent\protected\def\dotagcombination
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagcombination
             {\combinationparameter\c!nx}%
             {\combinationparameter\c!ny}%
        \fi}%
     \enforced\permanent\protected\def\dotagcombinationpair#1#2%
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagcombinationpair{#1}{#2}%
        \fi}%
 \to \everyenableelements
@@ -139,7 +165,7 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagsetitemgroup
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagitemgroup
            \ifconditional\c_strc_itemgroups_pack     true\else false\fi\relaxedspace
            \ifconditional\c_strc_itemgroups_continue true\else false\fi\relaxedspace
@@ -147,21 +173,21 @@
            {\currentitemgroupsymbol}%
        \fi}%
     \enforced\permanent\protected\def\dotagsetitem#1%
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagitem{#1}%
        \fi}%
 \to \everyenableelements
 
-%     \appendtoks
-%         \enforced\permanent\protected\def\dotagsetdescription
-%           {\iftrialtypesetting\else
-%              \clf_settagdescription{\currentdescription}\currentdescriptionnumberentry\relax
-%            \fi}%
-%     \to \everyenableelements
+\appendtoks
+    \enforced\permanent\protected\def\dotagsetdescriptionindex#1#2%
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
+         \clf_settagdescriptionindex{#1}{#2}\relax
+       \fi}%
+\to \everyenableelements
 
 \appendtoks
     \enforced\permanent\protected\def\dotagsetnotation
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
         \clf_settagnotation{\currentnote}\currentnotenumber\relax
        \fi}%
 \to \everyenableelements
@@ -168,7 +194,7 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagsetnotesymbol
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagnotationsymbol{\currentnote}\currentnotenumber\relax
        \fi}%
 \to \everyenableelements
@@ -175,21 +201,23 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagregisterlocation
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagregister{\currentregister}\currentregisternumber\relax
        \fi}%
 \to \everyenableelements
 
+\aliased\let\dotagsetreferencedescription\gobbletwoarguments
+
 \appendtoks
-    \enforced\permanent\protected\def\dotaglistlocation
-      {\iftrialtypesetting\else
-         \clf_settaglist\currentlistindex\relax
+    \enforced\permanent\protected\def\dotagsetreferencedescription#1#2%
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
+         \clf_settagsetreferencedescription{#1}{#2}\relax
        \fi}%
 \to \everyenableelements
 
 \appendtoks
     \enforced\permanent\protected\def\dotagsetdelimitedsymbol#1%
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagdelimitedsymbol{#1}\relax
        \fi}%
 \to \everyenableelements
@@ -196,7 +224,7 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagsetsubsentencesymbol#1%
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagsubsentencesymbol{#1}\relax
        \fi}%
 \to \everyenableelements
@@ -203,7 +231,7 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagregisterfloat#1#2%
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagfloat{#1}{#2}\relax
        \fi}%
 \to \everyenableelements
@@ -217,7 +245,7 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagregisterformula#1#2%
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagformulacontent{#1}{#2}%
        \fi}%
 \to \everyenableelements
@@ -224,14 +252,18 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagmarginanchor#1%
-      {\iftrialtypesetting\else\clf_settagmarginanchor#1\relax\fi}%
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
+         \clf_settagmarginanchor#1\relax
+       \fi}%
     \enforced\permanent\protected\def\dotagmargintext#1%
-      {\iftrialtypesetting\else\clf_settagmargintext#1\relax\fi}%
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
+         \clf_settagmargintext#1\relax
+       \fi}%
 \to \everyenableelements
 
 \appendtoks
     \enforced\permanent\protected\def\dotagpublication#1#2%
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagpublication{#1}{#2}\relax
        \fi}%
 \to \everyenableelements
@@ -238,11 +270,22 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagparagraph#1%
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagparagraph{#1}\relax
        \fi}%
 \to \everyenableelements
 
+% bah bah bah
+
+% \lettonothing\dotagmarklist
+
+\appendtoks
+    \enforced\permanent\protected\def\dotagmarklist
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
+         \strc_lists_add_list_description
+       \fi}%
+\to \everyenableelements
+
 % For more elements, so an extra argument:
 
 \ifdefined\dotagcodepoint \else \aliased\let\dotagcodepoint\gobbletwoarguments \fi
@@ -249,7 +292,7 @@
 
 \appendtoks
     \enforced\permanent\protected\def\dotagcodepoint#1#2%
-      {\iftrialtypesetting\else
+      {\iftrialtypesetting\orelse\ifconditional\c_strc_tags_enabled
          \clf_settagcodepoint{#1}#2\relax
        \fi}%
 \to \everyenableelements

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ini.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ini.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ini.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -128,9 +128,9 @@
     \setexpandedbufferparameter\c!number{\the\c_buff_n_of_defined}%
     \cdef\currentdefinedbuffer{def-\the\c_buff_n_of_defined}%
     \ifcstok{\bufferparameter\c!define}\v!yes
-      \frozen\instance\protected\edefcsname\e!start\currentbuffer\endcsname
+      \protected\frozen\instance\edefcsname\e!start\currentbuffer\endcsname
         {\buff_start_defined{\currentbuffer}{\currentdefinedbuffer}{\e!start\currentbuffer}{\e!stop\currentbuffer}}%
-      \frozen\instance\protected\edefcsname\e!get  \currentbuffer\endcsname
+      \protected\frozen\instance\edefcsname\e!get  \currentbuffer\endcsname
         {\buff_get_stored   {\currentbuffer}{\currentdefinedbuffer}}%
     \fi
 \to \everydefinebuffer

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/buff-par.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/buff-par.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/buff-par.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -72,8 +72,8 @@
    \clf_defineparallel{#name}{#instances}%
    \expandafter\newtoks\csname\??parallelhandler#name\endcsname
    \processcommacommand[#instances]{\buff_parallel_define_instance{#name}}%
-   \frozen\instance\protected\edefcsname\e!start#name\endcsname{\buff_parallel_start{#name}}%
-   \frozen\instance\protected\edefcsname\e!stop #name\endcsname{\buff_parallel_stop}}
+   \protected\frozen\instance\edefcsname\e!start#name\endcsname{\buff_parallel_start{#name}}%
+   \protected\frozen\instance\edefcsname\e!stop #name\endcsname{\buff_parallel_stop}}
 
 \popoverloadmode
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ver.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ver.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ver.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -411,13 +411,13 @@
         if type(processors) ~= "table" then processors = { processors } end
         for i=1,#befores do
             local before    = befores[i]
+            local after     = space_pattern * P("\n")
             local processor = processors[i]
+            local action    = nil
             if trace_visualize then
                 report_visualizers("registering escape line pattern, name %a, before %a, after <<newline>>",name,before)
             end
             before = P(before) * space_pattern
-            after = space_pattern * P("\n")
-            local action
             if processor then
                 action = function(s) apply_processor(processor,s) end
             else

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ver.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ver.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/buff-ver.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -162,7 +162,7 @@
 \installcommandhandler \??type {type} \??type
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\currenttype\endcsname{\buff_verbatim_type{\currenttype}}%
+    \protected\frozen\instance\edefcsname\currenttype\endcsname{\buff_verbatim_type{\currenttype}}%
 \to \everydefinetype
 
 \appendtoks
@@ -190,8 +190,8 @@
 \installcommandhandler \??typing {typing} \??typing
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\e!start\currenttyping\endcsname{\buff_verbatim_typing_start{\currenttyping}{\currenttyping}}%
-    \frozen\protected\instance\edefcsname\e!stop \currenttyping\endcsname{\buff_verbatim_typing_stop}%
+    \protected\frozen\instance\edefcsname\e!start\currenttyping\endcsname{\buff_verbatim_typing_start{\currenttyping}{\currenttyping}}%
+    \protected\frozen\instance\edefcsname\e!stop \currenttyping\endcsname{\buff_verbatim_typing_stop}%
     \ifempty\currenttypingparent
       \expanded{\definelinenumbering[\currenttyping]}%
     \else
@@ -617,7 +617,7 @@
 \mutable\lettonothing\currenttypingwrapper
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\e!type\currenttyping\v!file\endcsname{\typefile[\currenttyping]}%
+    \protected\frozen\instance\edefcsname\e!type\currenttyping\v!file\endcsname{\typefile[\currenttyping]}%
 \to \everydefinetyping
 
 \permanent\tolerant\protected\def\typefile[#S#1]#*[#S#2]#:#3%
@@ -807,17 +807,17 @@
   {\buff_verbatim_type_defined_buffer[\v!buffer][\thedefinedbuffer{#1}]}%
 
 % \appendtoks
-%     \frozen\instance\protected\edefcsname\e!type\currentbuffer\endcsname
+%     \protected\frozen\instance\edefcsname\e!type\currentbuffer\endcsname
 %       {\buff_verbatim_type_defined_buffer[\v!buffer][\currentdefinedbuffer]}%
 % \to \everydefinebuffer
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\e!type\currentbuffer\endcsname
+    \protected\frozen\instance\edefcsname\e!type\currentbuffer\endcsname
       {\buff_verbatim_type_defined_buffer[\currentbuffer][\currentdefinedbuffer]}%
 \to \everydefinebuffer
 
 \appendtoks % \e!buffer
-    \frozen\instance\protected\edefcsname\e!type\currenttyping\v!buffer\endcsname
+    \protected\frozen\instance\edefcsname\e!type\currenttyping\v!buffer\endcsname
       {\buff_verbatim_type_buffer_class{\currenttyping}}%
 \to \everydefinetyping
 

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/cldf-ini.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/cldf-ini.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/cldf-ini.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,1896 @@
+if not modules then modules = { } end modules ['cldf-ini'] = {
+    version   = 1.001,
+    comment   = "companion to cldf-ini.mkiv",
+    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+    copyright = "PRAGMA ADE / ConTeXt Development Team",
+    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
+-- a bit slower but often more readable when mixed with lua code. It can also be handy
+-- when generating documents from databases or when constructing large tables or so.
+--
+-- In cldf-tod.lua I have some code that might end up here. In cldf-old.lua the
+-- code that precedes more modern solutions (made possible by features in the engine),
+-- most noticeably function handling, which worked well for a decade, but by now the
+-- more efficient approach is stable enough to move the original code to the obsolete
+-- module.
+--
+-- maybe:  (escape) or 0x2061 (apply function) or 0x2394 (software function ⎔) (old)
+-- note : tex.print == line with endlinechar appended
+--
+-- 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.
+--
+-- context(lpeg.match(lpeg.patterns.texescape,"${}"))
+-- context(string.formatters["%!tex!"]("${}"))
+-- context("%!tex!","${}")
+--
+-- We try not to polute the context namespace too much. For that reason the commands are
+-- registered in the context.core namespace. You can call all context commands using
+-- context.foo etc. and pipe to context with context("foo"). Defining a local command
+-- foo being context.foo is okay, as is context.core.foo. We will have some definitions
+-- that are plugged into the core namespace (mostly for speedup) but otherwise specialized
+-- writers are in the context namespace only. In your documents you can best use the
+-- context.foo(...) and context(...) variant but in some core modules we use the faster
+-- ones in critical places (no one will notice of course). The standard syntax highlighter
+-- that I use knows how to visualize ctx related code.
+
+-- I cleaned this code up a bit when updating the cld manual but got distracted a bit by
+-- 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.
+
+-- The code here has evolved over time, and was already present in the early versions of
+-- mkiv. However, it got adapted when feature were added to luatex, like the ability to
+-- "print" nodes and later tokens. We use to have control over the method used (if only
+-- for testing) but the older code has been removed now. The history is in the archives.
+-- These were the controls:
+
+-- local tokenflushmode    = true
+-- local nodeflushmode     = true
+-- local scannerdefmode    = true
+-- local maxflushnodeindex = 0x10FFFF - 1
+
+-- 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 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
+local lpegmatch, lpegC, lpegS, lpegP, lpegV, lpegCc, lpegCs, patterns = lpeg.match, lpeg.C, lpeg.S, lpeg.P, lpeg.V, lpeg.Cc, lpeg.Cs, lpeg.patterns
+
+local formatters           = string.formatters -- using formatters is slower in this case
+local setmetatableindex    = table.setmetatableindex
+local setmetatablecall     = table.setmetatablecall
+local setmetatablenewindex = table.setmetatablenewindex
+
+context                 = context    or { }
+commands                = commands   or { }
+interfaces              = interfaces or { }
+
+local context           = context
+local commands          = commands
+local interfaces        = interfaces
+
+local loaddata          = io.loaddata
+
+local tex               = tex
+local texsprint         = tex.sprint    -- just appended (no space,eol treatment)
+local texprint          = tex.print     -- each arg a separate line (not last in directlua)
+----- texwrite          = tex.write     -- all 'space' and 'character'
+
+-- In this stage we don't yet have nodes populated so we access the library
+-- directly ...
+
+local isnode            = node.isnode
+local copynodelist      = node.copylist
+local writenode         = node.write
+local tonut             = node.direct.todirect
+local tonode            = node.direct.tonode
+
+local newtoken          = token.new
+local istoken           = token.istoken
+local setluatoken       = token.setlua
+
+local isprintable       = tex.isprintable
+local overloadpermitted = tex.overloadpermitted
+
+tex.runtoks             = tex.runlocal   -- obselete name
+tex.quittoks            = tex.quitlocal  -- obselete name
+
+local catcodenumbers    = catcodes.numbers
+
+local ctxcatcodes       = catcodenumbers.ctxcatcodes
+local prtcatcodes       = catcodenumbers.prtcatcodes
+local texcatcodes       = catcodenumbers.texcatcodes
+local txtcatcodes       = catcodenumbers.txtcatcodes
+local vrbcatcodes       = catcodenumbers.vrbcatcodes
+local xmlcatcodes       = catcodenumbers.xmlcatcodes
+
+local flush             = texsprint   -- snippets
+local flushdirect       = texprint    -- lines
+----- flushraw          = texwrite
+
+local report_context    = logs.reporter("cld","tex")
+local report_cld        = logs.reporter("cld","stack")
+----- report_template   = logs.reporter("cld","template")
+
+local processlines      = true -- experiments.register("context.processlines", function(v) processlines = v end)
+
+local trialtypesetting  = function() return false end
+
+function context.settrialtypesettingmethod(f)
+    trialtypesetting         = f
+    context.trialtypesetting = f
+end
+
+context.trialtypesetting = function() return trialtypesetting() end -- can be aliased !
+
+local knownfunctions = lua.getfunctionstable(true)
+local showstackusage = false
+
+trackers.register("context.stack",function(v) showstackusage = v end)
+
+local freed    = { }
+local nofused  = 0
+local noffreed = 0
+
+local usedstack = function()
+    return nofused, noffreed
+end
+
+local function flushfunction(slot,arg)
+    if arg() or trialtypesetting() then
+        -- keep
+    else
+        noffreed = noffreed + 1
+        freed[noffreed] = slot
+        knownfunctions[slot] = false
+    end
+end
+
+local function storefunction(arg)
+    local f = function(slot) flushfunction(slot,arg) end
+    if noffreed > 0 then
+        local n = freed[noffreed]
+        freed[noffreed] = nil
+        noffreed = noffreed - 1
+        knownfunctions[n] = f
+        return n
+    else
+        nofused = nofused + 1
+        knownfunctions[nofused] = f
+        return nofused
+    end
+end
+
+local function flushnode(slot,arg)
+    if trialtypesetting() then
+        writenode(copynodelist(arg))
+    else
+        writenode(arg)
+        noffreed = noffreed + 1
+        freed[noffreed] = slot
+        knownfunctions[slot] = false
+    end
+end
+
+local function storenode(arg)
+    local f = function(slot) flushnode(slot,arg) end
+    if noffreed > 0 then
+        local n = freed[noffreed]
+        freed[noffreed] = nil
+        noffreed = noffreed - 1
+        knownfunctions[n] = f
+        return n
+    else
+        nofused = nofused + 1
+        knownfunctions[nofused] = f
+        return nofused
+    end
+end
+
+storage.storedfunctions = storage.storedfunctions or { }
+local storedfunctions   = storage.storedfunctions
+local initex            = environment.initex
+
+storage.register("storage/storedfunctions", storedfunctions, "storage.storedfunctions")
+
+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)
+    if type(str) == "string" then
+        f_resolve = _G
+        lpegmatch(p_resolve,str)
+        return f_resolve
+    else
+        return str
+    end
+end
+
+local function expose(slot,f,...) -- so we can register yet undefined functions
+    local func = resolvestoredfunction(f)
+    if not func then
+        func = function() report_cld("beware: unknown function %i called: %s",slot,f) end
+    end
+    knownfunctions[slot] = func
+    return func(...)
+end
+
+if initex then
+    -- todo: log stored functions
+else
+    local slots = table.sortedkeys(storedfunctions)
+    local last  = #slots
+    if last > 0 then
+        -- we restore the references
+        for i=1,last do
+            local slot = slots[i]
+            local data = storedfunctions[slot]
+            knownfunctions[slot] = function(...)
+                -- print(data) -- could be trace
+                return expose(slot,data,...)
+            end
+        end
+        -- we now know how many are defined
+        nofused = slots[last]
+        -- normally there are no holes in the list yet
+        for i=1,nofused do
+            if not knownfunctions[i] then
+                noffreed = noffreed + 1
+                freed[noffreed] = i
+            end
+        end
+     -- report_cld("%s registered functions, %s freed slots",last,noffreed)
+    end
+end
+
+local registerfunction = function(f,direct,slot) -- either f=code or f=namespace,direct=name
+    local func
+    if slot then
+        -- already used
+    elseif noffreed > 0 then
+        slot = freed[noffreed]
+        freed[noffreed] = nil
+        noffreed = noffreed - 1
+    else
+        nofused = nofused + 1
+        slot = nofused
+    end
+    if direct then
+        if initex then
+            func = function(...) return expose(slot,f,...) end
+            storedfunctions[slot] = f
+        else
+            func = resolvestoredfunction(f)
+        end
+        if type(func) ~= "function" then
+            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, case %s",f,2) end
+        end
+    elseif type(f) == "function" then
+        func = f
+    else
+        func = function() report_cld("invalid function %A, case %s",f,3) end
+    end
+    knownfunctions[slot] = func
+    return slot
+end
+
+local unregisterfunction = function(slot)
+    if knownfunctions[slot] then
+        noffreed = noffreed + 1
+        freed[noffreed] = slot
+        knownfunctions[slot] = false
+    else
+        report_cld("invalid function slot %A",slot)
+    end
+end
+
+local reservefunction = function()
+    if noffreed > 0 then
+        local n = freed[noffreed]
+        freed[noffreed] = nil
+        noffreed = noffreed - 1
+        return n
+    else
+        nofused = nofused + 1
+        return nofused
+    end
+end
+
+local callfunctiononce = function(slot)
+    knownfunctions[slot](slot)
+    noffreed = noffreed + 1
+    freed[noffreed] = slot
+    knownfunctions[slot] = false
+end
+
+setmetatablecall(knownfunctions,function(t,n) return knownfunctions[n](n) end)
+
+-- some protection
+
+do
+
+    local stub    = { }
+    local done    = false
+    local message = function()
+        -- one time message
+        if not done then
+            report_cld("")
+            report_cld("use : slot = context.functions.register(f)")
+            report_cld("and : context.functions.unregister(slot)")
+            report_cld("")
+            done = true
+        end
+    end
+
+    setmetatable(stub, {
+        __index    = message,
+        __newindex = message,
+    })
+
+    function lua.getfunctionstable()
+        message()
+        return stub
+    end
+
+    lua.get_functions_table = lua.getfunctionstable
+
+end
+
+-- The next hack is a convenient way to define scanners at the Lua end and get them
+-- available at the TeX end. There is some dirty magic needed to prevent overload
+-- during format loading. Nowadays we prefer to use the slightly less efficient way
+-- of defining interfaces using the implementer. There is a little more overhead in
+-- defining as well as runtime overhead, but we accept that.
+
+-- interfaces.scanners.foo = function() context("[%s]",tokens.scanners.string()) end : \scan_foo
+
+local storedscanners    = interfaces.storedscanners or { }
+local namesofscanners   = interfaces.namesofscanners or { }
+local interfacescanners = { }
+local privatenamespace  = "clf_"
+
+interfaces.storedscanners  = storedscanners
+interfaces.namesofscanners = namesofscanners
+
+storage.register("interfaces/storedscanners", storedscanners, "interfaces.storedscanners")
+
+-- todo: bitmap
+
+-- always permanent but we can consider to obey permanent==false
+-- todo: make bitset instead of keys (nil is skipped anyway)
+
+local function toflags(specification)
+    local protected = (specification.protected and "protected") or (specification.semiprotected and "semiprotected")
+    local untraced  = specification.untraced and "untraced"
+    local noaligned = specification.noaligned and "noaligned"
+    local usage     = specification.usage
+    if usage == "value" then
+        return "global", "value", "permanent", "untraced", protected
+    elseif usage == "condition" then
+        return "global", "conditional", "permanent", "untraced", protected
+    elseif specification.frozen then
+        return "global", "frozen", untraced, protected
+    elseif specification.permanent == false or specification.onlyonce then -- for now onlyonce here
+        return "global", untraced, protected, semiprotected, noaligned
+    else
+        return "global", "permanent", untraced, protected, noaligned
+    end
+end
+
+local flagged = { }
+
+local function registerscanner(name,action,specification)
+    rawset(interfacescanners,name,action)
+    local n = registerfunction("interfaces.scanners."..name,true,storedscanners[name])
+    storedscanners[name] = n
+    namesofscanners[n] = name
+    name = specification.public and name or (privatenamespace .. name)
+ -- print(name,n,toflags(specification))
+    local flags = setluatoken(name,n,toflags(specification))
+    if flags then
+        flagged[n] = flags
+    end
+end
+
+interfaces.registerscanner = registerscanner
+
+function interfaces.knownscanner(name)
+    return interfacescanners[name]
+end
+
+function interfaces.nameofscanner(slot)
+    return namesofscanners[slot] or slot
+end
+
+callbacks.register("show_lua_call", function(what, slot)
+    local name = namesofscanners[slot]
+ -- return name and formatters["%s: \\%s, slot: %i"](what,name,slot) or ""
+    return name and formatters["%s \\%s"](what,name) or ""
+end, "provide lua call details")
+
+setmetatablenewindex(interfacescanners, function(t,k,v)
+    report_cld("don't register scanner %a directly",k)
+ -- registerscanner(k,v)
+end)
+
+interfaces.scanners = storage.mark(interfacescanners)
+
+-- We have to make sure that functions don't get overloaded. This is unlikely to
+-- happen in \CONTEXT\ but we have to keep in mind that unknown code can be
+-- loaded. We still provide access but might drop that when abuse is noticed.
+--
+-- For the moment we don't check register, unregister and reserve but if that is
+-- also a security risk we might drop all access and replace the few times that
+-- it's used in \CONTEXT\ by more dedicated mechanisms.
+
+local warned = { }
+local strict = true -- false -- can become true when abused
+
+local onlyknownfunctions = setmetatable({ }, {
+    __index = function(t,k)
+        return knownfunctions[k]
+    end,
+    __newindex = function(t,k,v)
+        if not strict then
+            local f = flagged[k]
+            if not f then
+                knownfunctions[k] = b
+            elseif overloadpermitted(f) then
+                knownfunctions[k] = b
+            end
+        end
+        if not warned then
+            warned[k] = true
+            report_cld("don't assign function %a directly",k)
+        end
+    end,
+})
+
+context.functions = {
+    register   = function(qualifiedname) return registerfunction(qualifiedname) end, -- only one argument
+    unregister = unregisterfunction,
+    reserve    = reservefunction,
+ -- known      = knownfunctions,
+    known      = onlyknownfunctions,
+    callonce   = callfunctiononce,
+}
+
+function commands.ctxfunction(code,namespace)
+    context(registerfunction(code,namespace))
+end
+
+function commands.ctxscanner(name,code,namespace)
+    local n = registerfunction(code,namespace)
+    if storedscanners[name] then
+        storedscanners[name] = n
+    end
+    context(n)
+end
+
+local function dummy() end
+
+local texsetmacro = token.setmacro or token.set_macro
+
+function commands.ctxresetter(name) -- to be checked
+    return function()
+        if storedscanners[name] then
+            rawset(interfacescanners,name,dummy)
+         -- context.resetctxscanner(privatenamespace .. name)
+            texsetmacro(privatenamespace .. name,"","global")
+        end
+    end
+end
+
+-- Should we keep the catcodes with the function?
+
+local catcodestack    = { }
+local currentcatcodes = ctxcatcodes
+local contentcatcodes = ctxcatcodes
+
+local catcodes = {
+    ctx = ctxcatcodes, ctxcatcodes = ctxcatcodes, context  = ctxcatcodes,
+    prt = prtcatcodes, prtcatcodes = prtcatcodes, protect  = prtcatcodes,
+    tex = texcatcodes, texcatcodes = texcatcodes, plain    = texcatcodes,
+    txt = txtcatcodes, txtcatcodes = txtcatcodes, text     = txtcatcodes,
+    vrb = vrbcatcodes, vrbcatcodes = vrbcatcodes, verbatim = vrbcatcodes,
+    xml = xmlcatcodes, xmlcatcodes = xmlcatcodes,
+}
+
+-- maybe just increment / decrement
+
+-- local function pushcatcodes(c)
+--     insert(catcodestack,currentcatcodes)
+--     currentcatcodes = (c and catcodes[c] or tonumber(c)) or currentcatcodes
+--     contentcatcodes = currentcatcodes
+-- end
+--
+-- local function popcatcodes()
+--     currentcatcodes = remove(catcodestack) or currentcatcodes
+--     contentcatcodes = currentcatcodes
+-- end
+
+local catcodelevel = 0
+
+local function pushcatcodes(c)
+    catcodelevel = catcodelevel + 1
+    catcodestack[catcodelevel] = currentcatcodes
+    currentcatcodes = (c and catcodes[c] or tonumber(c)) or currentcatcodes
+    contentcatcodes = currentcatcodes
+end
+
+local function popcatcodes()
+    if catcodelevel > 0 then
+        currentcatcodes = catcodestack[catcodelevel] or currentcatcodes
+        catcodelevel = catcodelevel - 1
+    end
+    contentcatcodes = currentcatcodes
+end
+
+function context.unprotect()
+    -- at the lua end
+    catcodelevel = catcodelevel + 1
+    catcodestack[catcodelevel] = currentcatcodes
+    currentcatcodes = prtcatcodes
+    contentcatcodes = prtcatcodes
+    -- at the tex end
+    flush("\\unprotect")
+end
+
+function context.protect()
+    -- at the tex end
+    flush("\\protect")
+    -- at the lua end
+    if catcodelevel > 0 then
+        currentcatcodes = catcodestack[catcodelevel] or currentcatcodes
+        catcodelevel = catcodelevel - 1
+    end
+    contentcatcodes = currentcatcodes
+end
+
+context.catcodes     = catcodes
+context.pushcatcodes = pushcatcodes
+context.popcatcodes  = popcatcodes
+
+-- -- --
+
+local newline       = patterns.newline
+local space         = patterns.spacer
+local spacing       = newline * space^0
+local content       = lpegC((1-spacing)^1)            -- texsprint
+local emptyline     = space^0 * newline^2             -- texprint("")
+                    + newline * space^1 * newline^1
+local endofline     = space^0 * newline * space^0     -- texsprint(" ")
+local simpleline    = endofline * lpegP(-1)           --
+
+local verbose       = lpegC((1-space-newline)^1)
+local beginstripper = (lpegS(" \t")^1 * newline^1) / ""
+local endstripper   = beginstripper * lpegP(-1)
+
+local justaspace    = space * lpegCc("")
+local justanewline  = newline * lpegCc("")
+
+local function n_content   (s) flush      (contentcatcodes,s    ) end
+local function n_verbose   (s) flush      (vrbcatcodes,    s    ) end
+local function n_endofline ()  flush      (currentcatcodes," \r") end
+local function n_emptyline ()  flushdirect(currentcatcodes,"\r" ) end
+local function n_simpleline()  flush      (currentcatcodes," \r") end
+
+local n_exception = ""
+
+-- better a table specification
+
+function context.newtexthandler(specification)
+    specification = specification or { }
+    --
+    local s_catcodes   = specification.catcodes
+    --
+    local f_before     = specification.before
+    local f_after      = specification.after
+    --
+    local f_endofline  = specification.endofline  or n_endofline
+    local f_emptyline  = specification.emptyline  or n_emptyline
+    local f_simpleline = specification.simpleline or n_simpleline
+    local f_content    = specification.content    or n_content
+    local f_space      = specification.space
+    --
+    local p_exception  = specification.exception
+    --
+    if s_catcodes then
+        f_content = function(s)
+            flush(s_catcodes,s)
+        end
+    end
+    --
+    local pattern
+    if f_space then
+        if p_exception then
+            local content = lpegC((1-spacing-p_exception)^1)
+            pattern =
+              (
+                    justaspace   / f_space
+                  + justanewline / f_endofline
+                  + p_exception
+                  + content      / f_content
+                )^0
+        else
+            local content = lpegC((1-space-endofline)^1)
+            pattern =
+                (
+                    justaspace   / f_space
+                  + justanewline / f_endofline
+                  + content      / f_content
+                )^0
+        end
+    else
+        if p_exception then
+            local content = lpegC((1-spacing-p_exception)^1)
+            pattern =
+                simpleline / f_simpleline
+              +
+              (
+                    emptyline  / f_emptyline
+                  + endofline  / f_endofline
+                  + p_exception
+                  + content    / f_content
+                )^0
+        else
+            local content = lpegC((1-spacing)^1)
+            pattern =
+                simpleline / f_simpleline
+                +
+                (
+                    emptyline / f_emptyline
+                  + endofline / f_endofline
+                  + content   / f_content
+                )^0
+        end
+    end
+    --
+    if f_before then
+        pattern = (P(true) / f_before) * pattern
+    end
+    --
+    if f_after then
+        pattern = pattern * (P(true) / f_after)
+    end
+    --
+    return function(str) return lpegmatch(pattern,str) end, pattern
+end
+
+function context.newverbosehandler(specification) -- a special variant for e.g. cdata in lxml-tex
+    specification = specification or { }
+    --
+    local f_line    = specification.line    or function() flushdirect("\r") end
+    local f_space   = specification.space   or function() flush      (" ")  end
+    local f_content = specification.content or n_verbose
+    local f_before  = specification.before
+    local f_after   = specification.after
+    --
+    local pattern =
+        justanewline / f_line    -- so we get call{}
+      + verbose      / f_content
+      + justaspace   / f_space   -- so we get call{}
+    --
+    if specification.strip then
+        pattern = beginstripper^0 * (endstripper + pattern)^0
+    else
+        pattern = pattern^0
+    end
+    --
+    if f_before then
+        pattern = (lpegP(true) / f_before) * pattern
+    end
+    --
+    if f_after then
+        pattern = pattern * (lpegP(true) / f_after)
+    end
+    --
+    return function(str) return lpegmatch(pattern,str) end, pattern
+end
+
+local flushlines = context.newtexthandler {
+    content    = n_content,
+    endofline  = n_endofline,
+    emptyline  = n_emptyline,
+    simpleline = n_simpleline,
+}
+
+-- The next variant is only used in rare cases (buffer to mp):
+
+local printlines_ctx = (
+    (newline)     / function()  texprint("") end +
+    (1-newline)^1 / function(s) texprint(ctxcatcodes,s) end * newline^-1
+)^0
+
+local printlines_raw = (
+    (newline)     / function()  texprint("") end +
+    (1-newline)^1 / function(s) texprint(s)  end * newline^-1
+)^0
+
+function context.printlines(str,raw)     -- todo: see if via file is useable
+    if raw then
+        lpegmatch(printlines_raw,str)
+    else
+        lpegmatch(printlines_ctx,str)
+    end
+end
+
+function context.printtable(t,separator)     -- todo: see if via file is useable
+    if separator == nil or separator == true then
+        separator = "\r"
+    elseif separator == "" or separator == false then
+        separator = ""
+    end
+    local s = concat(t,separator)
+    if s ~= "" then
+        context(s)
+    end
+end
+
+-- -- -- "{" .. ti .. "}" is somewhat slower in a cld-mkiv run than "{",ti,"}"
+
+local containseol = patterns.containseol
+
+local lua_call_code = tokens.commands.lua_expandable_call or tokens.commands.lua_call
+
+local sortedhashindeed = false
+
+directives.register("context.sorthash",function(v)
+    sortedhashindeed = v and table.sortedhash or nil
+end)
+
+local function writer(parent,command,...) -- already optimized before call
+    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
+    for i=1,select("#",...) do
+        local ti = select(i,...)
+        if direct then
+            local typ = type(ti)
+            if typ == "string" or typ == "number" then
+                flush(currentcatcodes,ti)
+            else -- node.write
+                report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ)
+            end
+            direct = false
+        elseif ti == nil then
+            -- nothing
+        elseif ti == "" then
+            flush(currentcatcodes,"{}")
+     -- elseif ti == 1 then
+     --     flush(currentcatcodes,"{1}")
+        else
+            local typ = type(ti)
+            if typ == "string" then
+                -- is processlines seen ?
+                if processlines and lpegmatch(containseol,ti) then
+                    flush(currentcatcodes,"{")
+                    flushlines(ti)
+                    flush(currentcatcodes,"}")
+                elseif currentcatcodes == contentcatcodes then
+                    flush(currentcatcodes,"{",ti,"}")
+                else
+                    flush(currentcatcodes,"{")
+                    flush(contentcatcodes,ti)
+                    flush(currentcatcodes,"}")
+                end
+            elseif typ == "number" then
+                -- numbers never have funny catcodes
+                flush(currentcatcodes,"{",ti,"}")
+            elseif typ == "table" then
+                local tn = #ti
+                if tn == 0 then
+                    local done = false
+                    if sortedhashindeed then
+                        for k, v in sortedhashindeed(ti) do
+                            if done then
+                                if v == "" then
+                                    flush(currentcatcodes,",",k,'=')
+                                else
+                                    flush(currentcatcodes,",",k,"={",v,"}")
+                                end
+                            else
+                                if v == "" then
+                                    flush(currentcatcodes,"[",k,"=")
+                                else
+                                    flush(currentcatcodes,"[",k,"={",v,"}")
+                                end
+                                done = true
+                            end
+                        end
+                    else
+                        for k, v in next, ti do
+                            if done then
+                                if v == "" then
+                                    flush(currentcatcodes,",",k,'=')
+                                else
+                                    flush(currentcatcodes,",",k,"={",v,"}")
+                                end
+                            else
+                                if v == "" then
+                                    flush(currentcatcodes,"[",k,"=")
+                                else
+                                    flush(currentcatcodes,"[",k,"={",v,"}")
+                                end
+                                done = true
+                            end
+                        end
+                    end
+                    if done then
+                        flush(currentcatcodes,"]")
+                    else
+                        flush(currentcatcodes,"[]")
+                    end
+                elseif tn == 1 then -- some 20% faster than the next loop
+                    local tj = ti[1]
+                    if type(tj) == "function" then
+                        tj = storefunction(tj)
+                        flush(currentcatcodes,"[",newtoken(tj,lua_call_code),"]")
+                    else
+                        flush(currentcatcodes,"[",tj,"]")
+                    end
+                else
+                    flush(currentcatcodes,"[")
+                    for j=1,tn do
+                        local tj = ti[j]
+                        if type(tj) == "function" then
+                            tj = storefunction(tj)
+                            flush(currentcatcodes,"[",newtoken(tj,lua_call_code),j == tn and "]" or ",")
+                        else
+                            if j == tn then
+                                flush(currentcatcodes,tj,"]")
+                            else
+                                flush(currentcatcodes,tj,",")
+                            end
+                        end
+                    end
+                end
+            elseif typ == "function" then
+                -- todo: ctx|prt|texcatcodes
+                ti = storefunction(ti)
+                flush(currentcatcodes,"{",newtoken(ti,lua_call_code),"}")
+            elseif typ == "boolean" then
+                if ti then
+                    flushdirect(currentcatcodes,"\r")
+                else
+                    direct = true
+                end
+            elseif typ == "thread" then
+                report_context("coroutines not supported as we cannot yield across boundaries")
+         -- elseif isnode(ti) or istoken(ti) then
+            elseif isprintable(ti) then
+                flush(currentcatcodes,"{",ti,"}")
+            else
+                local s = tostring(ti)
+                if s then
+                    flushdirect(currentcatcodes,s)
+                else
+                    report_context("error: %a gets a weird argument %a",command,ti)
+                end
+            end
+     -- else
+     --     local n = isnode(ti)
+     --     if n then
+     --         flush(ti)
+     --     else
+     --         report_context("error: %a gets a weird argument %a",command,ti)
+     --     end
+        end
+    end
+end
+
+local toks = tokens.cache
+context.tokenizedcs = toks
+
+local 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.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)
+
+local indexer = function(parent,k)
+    if type(k) == "string" then
+        return core[k]
+    else
+        return context -- catch
+    end
+end
+
+context.core = core
+
+-- only for internal usage:
+
+-- local prtindexer = nil
+--
+-- do
+--
+--     -- the only variant is not much faster than the full but it's more
+--     -- memory efficient
+--
+--     local protected     = { }
+--     local protectedcs   = { }
+--     context.protected   = protected
+--     context.protectedcs = protectedcs
+--
+--     local function fullindexer(t,k)
+--         local c = "\\" .. k -- tostring(k)
+--         local v = function(first,...)
+--             if first == nil then
+--                 flush(prtcatcodes,c)
+--             else
+--                 return prtwriter(c,first,...)
+--             end
+--         end
+--         rawset(t,k,v) -- protected namespace
+--         return v
+--     end
+--
+--     local function onlyindexer(t,k)
+--         local c = "\\" .. k -- tostring(k)
+--         local v = function()
+--             flush(prtcatcodes,c)
+--         end
+--         rawset(protected,k,v)
+--         rawset(t,k,v)
+--         return v
+--     end
+--
+--     protected.cs = setmetatableindex(function(parent,k)
+--         local c = "\\" .. k -- tostring(k)
+--         local v = function()
+--             flush(prtcatcodes,c)
+--         end
+--         parent[k] = v
+--         return v
+--     end
+--
+--     setmetatableindex(protected,fullindexer)
+--     setmetatablecall (protected,prtwriter)
+--
+--     setmetatableindex(protectedcs,onlyindexer)
+--     setmetatablecall (protectedcs,prtwriter)
+--
+-- end
+
+-- local splitformatters = utilities.strings.formatters.new(true) -- not faster (yet)
+
+local caller = function(parent,f,a,...)
+    if not parent then
+        -- so we don't need to test in the calling (slower but often no issue)
+    elseif f ~= nil then
+        local typ = type(f)
+        if typ == "string" then
+            if f == "" then
+                -- new, can save a bit sometimes
+             -- if trace_context then
+             --     report_context("empty argument to context()")
+             -- end
+            elseif a then
+                flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes
+             -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes
+            elseif processlines and lpegmatch(containseol,f) then
+                flushlines(f)
+            else
+                flush(contentcatcodes,f)
+            end
+        elseif typ == "number" then
+            if a then
+                flush(currentcatcodes,f,a,...)
+            else
+                flush(currentcatcodes,f)
+            end
+        elseif typ == "function" then
+            -- ignored: a ...
+            f = storefunction(f)
+            flush(currentcatcodes,"{",newtoken(f,lua_call_code),"}")
+        elseif typ == "boolean" then
+            if f then
+                if a ~= nil then
+                    flushlines(a)
+                else
+                    flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise
+                end
+            else
+                if a ~= nil then
+                    -- no command, same as context(a,...)
+                    writer(parent,"",a,...)
+                else
+                    -- ignored
+                end
+            end
+        elseif typ == "thread" then
+            report_context("coroutines not supported as we cannot yield across boundaries")
+     -- elseif isnode(f) or istoken(f) then
+        elseif isprintable(f) then
+            flush(f)
+        else
+            local s = tostring(f)
+            if s then
+                flushdirect(currentcatcodes,s)
+            else
+                report_context("error: %a gets a weird argument %a","context",f)
+            end
+        end
+ -- else
+ --     local n = isnode(f)
+ --     if n then
+ --         flush(f)
+ --     else
+ --         report_context("error: %a gets a weird argument %a","context",f)
+ --     end
+    end
+end
+
+context.nodes = { -- todo
+    store = storenode,
+    flush = function(n)
+        flush(n)
+    end,
+}
+
+context.nuts = { -- todo
+    store = function(n)
+        return storenode(tonut(n))
+    end,
+    flush = function(n,d)
+        flush(tonode(n))
+    end,
+}
+
+local defaultcaller = caller
+
+setmetatableindex(context,indexer)
+setmetatablecall (context,caller)
+
+function  context.sprint(...) -- takes catcodes as first argument
+    flush(...)
+end
+
+function context.fprint(first,second,third,...)
+    if type(first) == "number" then
+        if third then
+            flush(first,formatters[second](third,...))
+        else
+            flush(first,second)
+        end
+    else
+        if second then
+            flush(formatters[first](second,third,...))
+        else
+            flush(first)
+        end
+    end
+end
+
+tex.fprint = context.fprint
+
+-- logging
+
+local trace_stack       = { report_context }
+
+local normalflush       = flush
+local normalflushdirect = flushdirect
+----- normalflushraw    = flushraw
+local normalwriter      = writer
+local currenttrace      = report_context
+local nofwriters        = 0
+local nofflushes        = 0
+
+local tracingpermitted  = true
+
+local visualizer = lpeg.replacer {
+    { "\n", "<<newline>>" },
+    { "\r", "<<par>>" },
+}
+
+statistics.register("traced context lua functions", function()
+    local used, freed = usedstack()
+    local unreachable = used - freed
+    if nofwriters > 0 or nofflushes > 0 then
+        return format("writers: %s, flushes: %s, maxstack: %s",nofwriters,nofflushes,used,freed,unreachable)
+    elseif showstackusage or unreachable > 0 then
+        return format("maxstack: %s, freed: %s, unreachable: %s",used,freed,unreachable)
+    end
+end)
+
+-- The cmd names were synchronized with the normal call cmd names.
+
+local luacalls = {
+    lua_function_call  = true,
+    lua_protected_call = true,
+    lua_value          = true,
+    lua_local_call     = true,
+    lua_call           = true,
+}
+
+local function userdata(argument)
+    if isnode(argument) then
+        return formatters["<< %s node %i>>"](nodes.nodecodes[argument.id],tonut(argument))
+    elseif istoken(argument) then
+        local csname = argument.csname
+        if csname then
+         -- return formatters["<<\\%s>>"](csname)
+            return formatters["\\%s"](csname)
+        end
+        if luacalls[argument.cmdname] then
+            return "<<function>>" -- argument.mode
+        end
+        return "<<token>>"
+    else
+        return "<<userdata>>"
+    end
+end
+
+
+local tracedwriter = function(parent,...) -- also catcodes ?
+    nofwriters = nofwriters + 1
+    local savedflush       = flush
+    local savedflushdirect = flushdirect -- unlikely to be used here
+    local t = { "w : - : " }
+    local n = 1
+    local traced = function(catcodes,...) -- todo: check for catcodes
+        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
+    end
+    flush = function(...)
+        normalflush(...)
+        if tracingpermitted then
+            traced(...)
+        end
+    end
+    flushdirect = function(...)
+        normalflushdirect(...)
+        if tracingpermitted then
+            traced(...)
+        end
+    end
+    normalwriter(parent,...)
+    flush       = savedflush
+    flushdirect = savedflushdirect
+    currenttrace(concat(t))
+end
+
+-- we could reuse collapsed
+
+local traced = function(one,two,...)
+    if two ~= nil then
+        -- only catcodes if 'one' is number
+        local catcodes  = type(one) == "number" and one
+        local arguments = catcodes and { two, ... } or { one, two, ... }
+        local collapsed = { formatters["f : %s : "](catcodes or '-') }
+        local c         = 1
+        for i=1,#arguments do
+            local argument = arguments[i]
+            local argtype = type(argument)
+            c = c + 1
+            if argtype == "string" then
+                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
+        end
+        currenttrace(concat(collapsed))
+    elseif one ~= nil then
+        -- no catcodes
+        local argtype = type(one)
+        if argtype == "string" then
+            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
+    end
+end
+
+local tracedflush = function(one,two,...)
+    nofflushes = nofflushes + 1
+    if two ~= nil then
+        normalflush(one,two,...)
+    else
+        normalflush(one)
+    end
+    if tracingpermitted then
+        traced(one,two,...)
+    end
+end
+
+local tracedflushdirect = function(one,two,...)
+    nofflushes = nofflushes + 1
+    if two ~= nil then
+        normalflushdirect(one,two,...)
+    else
+        normalflushdirect(one)
+    end
+    if tracingpermitted then
+        traced(one,two,...)
+    end
+end
+
+function context.pushlogger(trace)
+    trace = trace or report_context
+    insert(trace_stack,currenttrace)
+    currenttrace = trace
+end
+
+function context.poplogger()
+    if #trace_stack > 1 then
+        currenttrace = remove(trace_stack) or report_context
+    else
+        currenttrace = report_context
+    end
+end
+
+function context.settracing(v)
+    if v then
+        flush       = tracedflush
+        flushdirect = tracedflushdirect
+        writer      = tracedwriter
+    else
+        flush       = normalflush
+        flushdirect = normalflushdirect
+        writer      = normalwriter
+    end
+    return flush, writer, flushdirect
+end
+
+function context.getlogger()
+    return flush, writer, flushdirect
+end
+
+trackers.register("context.trace",context.settracing)
+
+local trace_cld = false  trackers.register("context.files", function(v) trace_cld = v end)
+
+do
+
+    -- This is the most reliable way to deal with nested buffers and other
+    -- catcode sensitive data.
+
+    local resolve     = resolvers.savers.byscheme
+    local validstring = string.valid
+    local input       = context.input
+
+    local function viafile(data,tag)
+        if data and data ~= "" then
+            local filename = resolve("virtual",validstring(tag,"viafile"),data)
+         -- context.startregime { "utf" }
+            input(filename)
+         -- context.stopregime()
+        end
+    end
+
+    context.viafile    = viafile
+
+    -- experiment for xtables, don't use it elsewhere yet
+
+    local collected    = nil
+    local nofcollected = 0
+    local sentinel     = string.char(26) -- ASCII SUB character : endoffileasciicode : ignorecatcode
+    local level        = 0
+
+    local function collect(c,a,...) -- can be optimized
+        if type(c) == "userdata" then
+            nofcollected = nofcollected + 1
+         -- 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 collectdirect = collect
+    local permitted     = true
+
+    -- doesn't work well with tracing do we need to avoid that when
+    -- collecting stuff
+
+    function context.startcollecting()
+        if level == 0 then
+            collected    = { }
+            nofcollected = 0
+            flush        = collect
+            flushdirect  = collectdirect
+            permitted    = tracingpermitted
+        end
+        level = level + 1
+    end
+
+    function context.stopcollecting()
+        level = level - 1
+        if level < 1 then
+            local result     = concat(collected,sentinel)
+            flush            = normalflush
+            flushdirect      = normalflushdirect
+            tracingpermitted = permitted
+            collected        = nil
+            nofcollected     = 0
+            level            = 0
+            viafile(result)
+        end
+    end
+
+    local findtexfile = resolvers.findtexfile
+    local findfile    = resolvers.findfile
+
+    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
+        else
+            report_context("unknown file %a",filename)
+        end
+    end
+
+    function context.loadfile(filename)
+        context(stripstring(loaddata(findfile(filename))))
+    end
+
+    function context.loadviafile(filename)
+        viafile(stripstring(loaddata(findfile(filename))))
+    end
+
+end
+
+-- some functions
+
+function context.direct(first,...)
+    if first ~= nil then
+        return writer(context,"",first,...)
+    end
+end
+
+-- context.delayed (todo: lines)
+
+do
+
+    local delayed = { }
+
+    local function indexer(parent,k)
+        local f = function(...)
+            local a = { ... } -- this also freezes ...
+            return function()
+             -- return context[k](unpack(a))
+                return core[k](unpack(a))
+            end
+        end
+        parent[k] = f
+        return f
+    end
+
+    local function caller(parent,...) -- todo: nodes
+        local a = { ... }
+        return function()
+         -- return context(unpack(a))
+            return defaultcaller(context,unpack(a))
+        end
+    end
+
+    setmetatableindex(delayed,indexer)
+    setmetatablecall (delayed,caller)
+
+    context.delayed = delayed
+
+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
+--
+-- end
+
+context.nested = context.delayed
+
+-- verbatim
+
+function context.newindexer(catcodes,cmdcodes)
+    local handler = { }
+
+    local function indexer(parent,k)
+        local command = core[k]
+        local f = function(...)
+            local savedcatcodes = contentcatcodes
+            contentcatcodes = catcodes
+            command(...)
+            contentcatcodes = savedcatcodes
+        end
+        parent[k] = f
+        return f
+    end
+
+    local function caller(parent,...)
+        local savedcatcodes = contentcatcodes
+        contentcatcodes = catcodes
+        defaultcaller(parent,...)
+        contentcatcodes = savedcatcodes
+    end
+
+    handler.cs = core.cs
+
+    setmetatableindex(handler,indexer)
+    setmetatablecall (handler,caller)
+
+    return handler
+end
+
+context.verbatim  = context.newindexer(vrbcatcodes,ctxcatcodes)
+context.puretext  = context.newindexer(txtcatcodes,ctxcatcodes)
+context.protected = context.newindexer(prtcatcodes,prtcatcodes)
+
+-- formatted
+
+do
+
+    local formatted = { }
+
+    -- formatted.command([catcodes,]format[,...])
+
+    local function formattedflush(parent,c,catcodes,fmt,...)
+        if not catcodes then
+            return writer(parent,c)
+        elseif not fmt then
+            return writer(parent,c,catcodes)
+        elseif type(catcodes) == "number" then
+            local result
+            pushcatcodes(catcodes)
+            result = writer(parent,c,formatters[fmt](...))
+            popcatcodes()
+            return result
+        else
+            return writer(parent,c,formatters[catcodes](fmt,...))
+        end
+    end
+
+    local toks = tokens.cache
+
+    local 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
+
+    -- formatted([catcodes,]format[,...])
+
+    local function caller(parent,catcodes,fmt,...)
+        if not catcodes then
+            -- nothing
+        elseif not fmt then
+            flush(catcodes)
+        elseif type(catcodes) == "number" then
+            flush(catcodes,formatters[fmt](...))
+        else
+            flush(formatters[catcodes](fmt,...))
+        end
+    end
+
+    setmetatableindex(formatted,indexer)
+    setmetatablecall (formatted,caller)
+
+    context.formatted = formatted
+
+end
+
+do
+
+    -- metafun (this will move to another file)
+
+    local metafun = { }
+
+    function metafun.start()
+        context.startMPcode()
+    end
+
+    function metafun.stop()
+        context.stopMPcode()
+    end
+
+    setmetatablecall(metafun,defaultcaller)
+
+    function metafun.color(name) -- obsolete
+        return name -- formatters[ [[\MPcolor{%s}]] ](name)
+    end
+
+    -- metafun.delayed
+
+    local delayed = { }
+
+    local function indexer(parent,k)
+        local f = function(...)
+            local a = { ... }
+            return function()
+                return metafun[k](unpack(a))
+            end
+        end
+        parent[k] = f
+        return f
+    end
+
+
+    local function caller(parent,...)
+        local a = { ... }
+        return function()
+            return metafun(unpack(a))
+        end
+    end
+
+    setmetatableindex(delayed,indexer)
+    setmetatablecall (delayed,caller)
+
+    context.metafun = metafun
+    metafun.delayed = delayed
+
+end
+
+-- helpers:
+
+do
+
+    function context.concat(...)
+        context(concat(...))
+    end
+
+    local p_texescape = patterns.texescape
+    local p_ctxescape = patterns.ctxescape
+
+    function context.escaped   (s) if s then context(lpegmatch(p_texescape,s) or s) end end
+    function context.ctxescaped(s) if s then context(lpegmatch(p_ctxescape,s) or s) end end
+
+    function context.escape   (s) return (s and lpegmatch(p_texescape,s)) or s or "" end
+    function context.ctxescape(s) return (s and lpegmatch(p_ctxescape,s)) or s or "" end
+
+end
+
+-- templates
+
+do
+
+    local single  = lpegP("%")
+    local double  = lpegP("%%")
+    local lquoted = lpegP("%[")
+    local rquoted = lpegP("]%")
+    local space   = lpegP(" ")
+
+    local start = [[
+    local texescape = lpeg.patterns.texescape
+    local lpegmatch = lpeg.match
+    return function(variables) return
+    ]]
+
+    local stop  = [[
+    end
+    ]]
+
+    local replacer = lpegP { "parser",
+        parser   = lpegCs(lpegCc(start) * lpegV("step") * (lpegCc("..") * lpegV("step"))^0 * lpegCc(stop)),
+        unquoted = (lquoted*space/'')
+                 * ((lpegC((1-space*rquoted)^1)) / "lpegmatch(texescape,variables%0 or '')" )
+                 * (space*rquoted/'')
+                 + (lquoted/'')
+                 * ((lpegC((1-rquoted)^1)) / "lpegmatch(texescape,variables['%0'] or '')" )
+                 * (rquoted/''),
+        key      = (single*space/'')
+                 * ((lpegC((1-space*single)^1)) / "(variables%0 or '')" )
+                 * (space*single/'')
+                 + (single/'')
+                 * ((lpegC((1-single)^1)) / "(variables['%0'] or '')" )
+                 * (single/''),
+        escape   = double/'%%',
+        step     = lpegV("unquoted")
+                 + lpegV("escape")
+                 + lpegV("key")
+                 + lpegCc("\n[===[") * (1 - lpegV("unquoted") - lpegV("escape") - lpegV("key"))^1 * lpegCc("]===]\n"),
+    }
+
+    local templates = { }
+
+    local function indexer(parent,k)
+        local v = lpegmatch(replacer,k)
+        if not v then
+         -- report_template("invalid template:\n%s",k)
+            v = "error: no valid template (1)"
+        else
+            local f = loadstring(v)
+            if type(f) ~= "function" then
+             -- report_template("invalid template:\n%s\n=>\n%s",k,v)
+                v = "error: no valid template (2)"
+            else
+                f = f()
+                if not f then
+                 -- report_template("invalid template:\n%s\n=>\n%s",k,v)
+                    v = "error: no valid template (3)"
+                else
+                    v = f
+                end
+            end
+        end
+        if type(v) == "function" then
+            local f = function(first,second)
+                if second then
+                    pushcatcodes(first)
+                    flushlines(v(second))
+                    popcatcodes()
+                else
+                    flushlines(v(first))
+                end
+            end
+            parent[k] = f
+            return f
+        else
+            return function()
+                flush(v)
+            end
+        end
+
+    end
+
+    local function caller(parent,k,...)
+        return parent[k](...)
+    end
+
+    setmetatableindex(templates,indexer)
+    setmetatablecall (templates,caller)
+
+    context.templates = templates
+
+end
+
+-- The above is a bit over the top as we could also stick to a simple context.replace
+-- which is fast enough anyway, but the above fits in nicer, also with the catcodes.
+--
+-- local replace = utilities.templates.replace
+--
+-- function context.template(template,variables)
+--     context(replace(template,variables))
+-- end
+
+do
+
+    -- not the best namespace -- some day maybe texs a la nodes and tokens .. also,
+    -- we already have tex.modes so we need a different name
+
+    local modelevels = tex.getmodevalues()
+    local t          = table.keys(modelevels)
+    tex.modelevels   = table.swapped(modelevels,modelevels) -- utilities.storage.allocate()
+
+    for i=1,#t do local k = t[i] modelevels[-k] = modelevels[k] end
+
+    local flagcodes = tex.getflagvalues()
+    tex.flagcodes   = table.swapped(flagcodes,flagcodes) -- utilities.storage.allocate()
+
+end
+
+do
+
+    local rawset, rawget, setmetatable, type = rawset, rawget, setmetatable, type
+    local basename = file.basename
+
+    local report = logs.reporter("system")
+
+    local getdebuginfo = lua.getdebuginfo or function() end
+
+    local collected = setmetatableindex("table")
+
+    local exceptions = {
+        lexers = true, -- for scite
+    }
+
+    local function registerglobal(k,v,warn)
+        if exceptions[k] then
+            rawset(_G,k,v)
+            return
+        end
+        local current = rawget(_G,k)
+        local verdict = false
+        if current == v then
+            verdict = "value retained"
+        elseif current then
+            verdict = "overloading blocked"
+        else
+            rawset(_G,k,v)
+            if warn then
+                verdict = "might clash"
+            end
+        end
+        if verdict then
+            local name, source, line = getdebuginfo(true)
+            local detail = type(source) == "string" and type(line) == "number"
+            if collected then
+                local c = collected[k]
+                if detail then
+                    source = basename(source)
+                else
+                    source = "<unknown>"
+                    line   = 0
+                end
+                local s = c[source]
+                if not s then
+                    s = setmetatableindex("number")
+                    c[source] = s
+                end
+                s[line] = s[line] + 1
+            else
+                report()
+                if detail then
+                    report("global %a : %s : source %a, line %i",k,verdict,basename(source),line)
+                else
+                    report("global %a : %s",k,verdict)
+                end
+                report()
+            end
+        end
+    end
+
+    statistics.register("global variables", function()
+        if collected and next(collected) then
+            for name, files in table.sortedhash(collected) do
+                report()
+                report("global %a",name)
+                for file, lines in table.sortedhash(files) do
+                    local t = { }
+                    for line, count in table.sortedhash(lines) do
+                        t[#t+1] = line .. "=" .. count
+                    end
+                    report("  %s : % t",file,t)
+                end
+            end
+            report()
+        end
+    end)
+
+    function lua.protectglobal()
+        setmetatable(_G, {
+            __newindex = function(t,k,v)
+                registerglobal(k,v,true)
+            end
+        })
+    end
+
+    function lua.registerglobal(k,v)
+        registerglobal(k,v,false)
+        return v
+    end
+
+    local function protectmodule(name)
+        setmetatable(_G[name], {
+            __newindex = function(t,k)
+                report("module %a is protected, assignment %a is ignored",name,k)
+            end
+        })
+    end
+
+    protectmodule("string")
+
+end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/cont-log.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/cont-log.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/cont-log.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -23,7 +23,7 @@
 
 \unprotect
 
-% \frozen\instance\protected\def\TeX
+% \protected\frozen\instance\def\TeX
 %   {\dontleavehmode
 %    \begingroup
 %    T%
@@ -34,7 +34,7 @@
 %    X%
 %    \endgroup}
 
-\frozen\instance\protected\def\TeX
+\protected\frozen\instance\def\TeX
   {\dontleavehmode
    \begingroup
    \scratchdimen\scaledfontcharwd\font`M%
@@ -46,8 +46,8 @@
    X%
    \endgroup}
 
-\frozen\instance\protected\def\TeXsuffix{\wordboundary\TeX}
-\frozen\instance\protected\def\TeXprefix{\TeX\wordboundary}
+\protected\frozen\instance\def\TeXsuffix{\wordboundary\TeX}
+\protected\frozen\instance\def\TeXprefix{\TeX\wordboundary}
 
 \def\syst_logos_context
   {Con%
@@ -57,7 +57,7 @@
    \discretionary{-}{}{\kern{\wd\scratchboxtwo-\wd\scratchboxone}}%
    \TeX t}
 
-\frozen\instance\protected\def\ConTeXt
+\protected\frozen\instance\def\ConTeXt
   {\dontleavehmode
    \begingroup
    \ifcase\getcharactercasingcategory % todo: also other logos
@@ -72,9 +72,9 @@
    \fi
    \endgroup}
 
-\frozen\instance\protected\def\PPCHTeX{ppch\TeX}
+\protected\frozen\instance\def\PPCHTeX{ppch\TeX}
 
-\frozen\instance\protected\def\LaTeX % requested by erik frambach
+\protected\frozen\instance\def\LaTeX % requested by erik frambach
   {\dontleavehmode
    \begingroup
    \setbox\scratchbox\hbox{L}%
@@ -85,7 +85,7 @@
    \kern-.2\wd\scratchbox\TeX
    \endgroup}
 
-\frozen\instance\protected\def\TaBlE
+\protected\frozen\instance\def\TaBlE
   {T%
    \kern-.27\emwidth\lower.5\exheight\hbox{A}%
    \kern-.18\emwidth B%
@@ -92,7 +92,7 @@
    \kern-.1\emwidth\lower.5\exheight\hbox{L}%
    \kern-.075\emwidth E}
 
-\frozen\instance\protected\def\PiCTeX
+\protected\frozen\instance\def\PiCTeX
   {P%
    \kern-.12\emwidth\lower.5\exheight\hbox{I}%
    \kern-.075\emwidth C%
@@ -103,7 +103,7 @@
    \cal\ifdim\bodyfontsize>1.1\emwidth\scriptstyle\fi#1%
    \normalstopimath}
 
-\frozen\instance\protected\def\AmSTeX
+\protected\frozen\instance\def\AmSTeX
   {\dontleavehmode
    \syst_logos_ams_script A%
    \kern-.5\emwidth\lower.5\exheight\hbox{\syst_logos_ams_script M}% was .1667 for old math
@@ -110,7 +110,7 @@
    \kern-.125\emwidth\syst_logos_ams_script S%
    -\TeX}
 
-\frozen\instance\protected\def\LamSTeX
+\protected\frozen\instance\def\LamSTeX
   {L%
    \kern-.4\emwidth\raise.4\exheight\hbox{\syst_logos_ams_script A}% was .4 .3 for old math
    \kern-.5\emwidth\lower.3\exheight\hbox{\syst_logos_ams_script M}% was .25 for old math
@@ -125,7 +125,7 @@
 %D
 %D I changed this into one that adapts itself:
 
-\frozen\instance\protected\def\Context % wrong usage of \getscaledglyph
+\protected\frozen\instance\def\Context % wrong usage of \getscaledglyph
   {\dontleavehmode
    \begingroup
    C%
@@ -164,7 +164,7 @@
 \def\syst_logos_meta_hyphen % there is no hyphenchar in this font
   {\discretionary{\vrule\s!height.33\emwidth\s!depth-.27\emwidth\s!width.33\emwidth}{}{}}
 
-\frozen\instance\protected\def\MetaFontLogo
+\protected\frozen\instance\def\MetaFontLogo
   {\dontleavehmode
    \begingroup
    \setMFPfont META\syst_logos_meta_hyphen FONT%
@@ -184,9 +184,9 @@
 
 % As decided on the ConText Meeting 2013 the logo has been simplified:
 
-\instance\protected\def\MetaFont{MetaFont}
-\instance\protected\def\MetaPost{MetaPost}
-\instance\protected\def\MetaFun {MetaFun}
+\protected\instance\def\MetaFont{MetaFont}
+\protected\instance\def\MetaPost{MetaPost}
+\protected\instance\def\MetaFun {MetaFun}
 
 %D \macros
 %D  {TEX, METAFONT, METAPOST, METAFUN,
@@ -198,22 +198,22 @@
 %D (in \CONTEXT\ we tend to write all user defined commands, like abbreviations, in
 %D uppercase.)
 
-\instance\protected\def\METAFONT{\MetaFont}
-\instance\protected\def\METAPOST{\MetaPost}
-\instance\protected\def\PPCHTEX {\PPCHTeX}
-\instance\protected\def\CONTEXT {\ConTeXt}
-\instance\protected\def\METAFUN {\MetaFun}
+\protected\instance\def\METAFONT{\MetaFont}
+\protected\instance\def\METAPOST{\MetaPost}
+\protected\instance\def\PPCHTEX {\PPCHTeX}
+\protected\instance\def\CONTEXT {\ConTeXt}
+\protected\instance\def\METAFUN {\MetaFun}
 
-\instance\protected\def\TEX     {\TeX}
-\instance\protected\def\LATEX   {\LaTeX}
-\instance\protected\def\PICTEX  {\PiCTeX}
-\instance\protected\def\TABLE   {\TaBlE}
-\instance\protected\def\AMSTEX  {\AmSTeX}
-\instance\protected\def\LAMSTEX {\LamSTeX}
-\instance\protected\def\INRSTEX {inrs\TeX}
+\protected\instance\def\TEX     {\TeX}
+\protected\instance\def\LATEX   {\LaTeX}
+\protected\instance\def\PICTEX  {\PiCTeX}
+\protected\instance\def\TABLE   {\TaBlE}
+\protected\instance\def\AMSTEX  {\AmSTeX}
+\protected\instance\def\LAMSTEX {\LamSTeX}
+\protected\instance\def\INRSTEX {inrs\TeX}
 
-\instance\protected\def\PRAGMA  {Pragma ADE}
-\instance\protected\def\LUA     {\Lua} % below
+\protected\instance\def\PRAGMA  {Pragma ADE}
+\protected\instance\def\LUA     {\Lua} % below
 
 %D And this is how they show up: \TeX, \MetaFont, \MetaPost, \PiCTeX, \TaBlE, \ConTeXt,
 %D \PPCHTeX, \AmSTeX, \LaTeX, \LamSTeX.
@@ -220,15 +220,15 @@
 
 %D Some placeholders:
 
-%frozen\instance\protected\def\eTeX      {\mathematics{\varepsilon}-\TeX}
-\frozen\instance\protected\def\eTeX      {{\tf \nocap $\varepsilon$}-\TeX} % compact mode hack for epsilon
-\frozen\instance\protected\def\pdfTeX    {pdf\wordboundary\TeX}
-\frozen\instance\protected\def\pdfeTeX   {pdfe-\wordboundary\TeX}
-\frozen\instance\protected\def\luaTeX    {lua\wordboundary\TeX}
-\frozen\instance\protected\def\Lua       {Lua}
-\frozen\instance\protected\def\luajitTeX {lua\wordboundary jit\wordboundary\TeX}
-\frozen\instance\protected\def\luametaTeX{lua\wordboundary meta\wordboundary\TeX}
-\frozen\instance\protected\def\XeTeX     {X\lower.5\exheight\hbox{\kern-.15\emwidth\mirror{E}}\kern-.1667\emwidth\TeX}
+%protected\frozen\instance\def\eTeX      {\mathematics{\varepsilon}-\TeX}
+\protected\frozen\instance\def\eTeX      {{\tf \nocap $\varepsilon$}-\TeX} % compact mode hack for epsilon
+\protected\frozen\instance\def\pdfTeX    {pdf\wordboundary\TeX}
+\protected\frozen\instance\def\pdfeTeX   {pdfe-\wordboundary\TeX}
+\protected\frozen\instance\def\luaTeX    {lua\wordboundary\TeX}
+\protected\frozen\instance\def\Lua       {Lua}
+\protected\frozen\instance\def\luajitTeX {lua\wordboundary jit\wordboundary\TeX}
+\protected\frozen\instance\def\luametaTeX{lua\wordboundary meta\wordboundary\TeX}
+\protected\frozen\instance\def\XeTeX     {X\lower.5\exheight\hbox{\kern-.15\emwidth\mirror{E}}\kern-.1667\emwidth\TeX}
 
 
 % % Adapted from a patch by Mojca:
@@ -237,7 +237,7 @@
 %   {\setbox\scratchbox\hbox{E}%
 %    \raise\dimexpr\ht\scratchbox+\dp\scratchbox\relax\hbox{\rotate[\c!rotation=180]{\box\scratchbox}}}
 %
-% \frozen\instance\protected\def\XeTeX
+% \protected\frozen\instance\def\XeTeX
 %   {X\lower.5\exheight
 %    \hbox
 %      {\kern-.15\emwidth
@@ -266,20 +266,20 @@
      \fi
    \egroup}
 
-\frozen\instance\protected\def\XeTeX  {\syst_logos_xe\kern-.1667\emwidth\TeX}
-\frozen\instance\protected\def\XeLaTeX{\syst_logos_xe\LaTeX}
+\protected\frozen\instance\def\XeTeX  {\syst_logos_xe\kern-.1667\emwidth\TeX}
+\protected\frozen\instance\def\XeLaTeX{\syst_logos_xe\LaTeX}
 
-\instance\protected\def\ETEX      {\eTeX}
-\instance\protected\def\PDFTEX    {\pdfTeX}
-\instance\protected\def\PDFETEX   {\pdfeTeX}
-\instance\protected\def\LUATEX    {\luaTeX}
-\instance\protected\def\LUAJITTEX {\luajitTeX}
-\instance\protected\def\LuaTeX    {\luaTeX}
-\instance\protected\def\LuaMetaTeX{\luametaTeX}
-\instance\protected\def\LUAMETATEX{\luametaTeX}
-\instance\protected\def\XETEX     {\XeTeX}
+\protected\instance\def\ETEX      {\eTeX}
+\protected\instance\def\PDFTEX    {\pdfTeX}
+\protected\instance\def\PDFETEX   {\pdfeTeX}
+\protected\instance\def\LUATEX    {\luaTeX}
+\protected\instance\def\LUAJITTEX {\luajitTeX}
+\protected\instance\def\LuaTeX    {\luaTeX}
+\protected\instance\def\LuaMetaTeX{\luametaTeX}
+\protected\instance\def\LUAMETATEX{\luametaTeX}
+\protected\instance\def\XETEX     {\XeTeX}
 
-\frozen\instance\protected\def\LuaTeX
+\protected\frozen\instance\def\LuaTeX
   {\dontleavehmode
    \begingroup
      Lua%
@@ -303,7 +303,7 @@
      \TeX
    \endgroup}
 
-\frozen\instance\protected\def\LuajitTeX
+\protected\frozen\instance\def\LuajitTeX
   {\dontleavehmode
    \begingroup
      % at this moment there is no real need for kerning tT
@@ -313,27 +313,27 @@
 \frozen\instance\let\luaTeX   \LuaTeX
 \frozen\instance\let\luajitTeX\LuajitTeX
 
-\instance\protected\def\LUATEX   {\LuaTeX}
-\instance\protected\def\LUAJITTEX{\LuajitTeX}
+\protected\instance\def\LUATEX   {\LuaTeX}
+\protected\instance\def\LUAJITTEX{\LuajitTeX}
 
-\instance\protected\def\MKII{MkII} % MarkTwo
-\instance\protected\def\MKIV{MkIV} % MarkFour   : MKIV
-\instance\protected\def\MKVI{MkVI} % MarkSix    : MKIV
-\instance\protected\def\MKXL{MkXL} % MarkFourty : LMTX
-\instance\protected\def\MKLX{MkLX} % MarkSixty  : LMTX
-\instance\protected\def\MKIX{MkIX} %            : MKIV / LMTX
-\instance\protected\def\MKXI{MkXI} %            : MKIV / LMTX
+\protected\instance\def\MKII{MkII} % MarkTwo
+\protected\instance\def\MKIV{MkIV} % MarkFour   : MKIV
+\protected\instance\def\MKVI{MkVI} % MarkSix    : MKIV
+\protected\instance\def\MKXL{MkXL} % MarkFourty : LMTX
+\protected\instance\def\MKLX{MkLX} % MarkSixty  : LMTX
+\protected\instance\def\MKIX{MkIX} %            : MKIV / LMTX
+\protected\instance\def\MKXI{MkXI} %            : MKIV / LMTX
 
-\instance\protected\def\MPII{MpII} % MarkTwo
-\instance\protected\def\MPIV{MpIV} % MarkFour   : MetaFun
-\instance\protected\def\MPVI{MpVI} % MarkSix    : MetaFun
-\instance\protected\def\MPXL{MpXL} % MarkFourty : LuaMetaFun
-\instance\protected\def\MPLX{MpLX} % MarkSixty  : LuaMetaFun
+\protected\instance\def\MPII{MpII} % MarkTwo
+\protected\instance\def\MPIV{MpIV} % MarkFour   : MetaFun
+\protected\instance\def\MPVI{MpVI} % MarkSix    : MetaFun
+\protected\instance\def\MPXL{MpXL} % MarkFourty : LuaMetaFun
+\protected\instance\def\MPLX{MpLX} % MarkSixty  : LuaMetaFun
 
-\instance\protected\def\LMTX{LMTX} % for LuaMetaTeX + Mk[X.|.X] i.e. the distribition / ecosystem
+\protected\instance\def\LMTX{LMTX} % for LuaMetaTeX + Mk[X.|.X] i.e. the distribition / ecosystem
 
-\instance\protected\def\MKMI{MkMI} % Mark One O O One   : reserved for unvailable machine intelligence
-\instance\protected\def\MKML{MkML} % Mark One O O Fifty : reserved for unvailable machine learning
+\protected\instance\def\MKMI{MkMI} % Mark One O O One   : reserved for unvailable machine intelligence
+\protected\instance\def\MKML{MkML} % Mark One O O Fifty : reserved for unvailable machine learning
 
 \appendtoks
     \enforced\instance\def\ConTeXt   {ConTeXt}%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/cont-new.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/cont-new.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/cont-new.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2025.07.27 21:43}
+\newcontextversion{2025.08.17 17:57}
 
 %D This file is loaded at runtime, thereby providing an excellent place for hacks,
 %D patches, extensions and new features. There can be local overloads in cont-loc

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/context-libraries.tma
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/context-libraries.tma	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/context-libraries.tma	2025-08-18 19:08:11 UTC (rev 76089)
@@ -126,12 +126,17 @@
   ["kurier-math.lfg"]=true,
   ["l-macro-imp-optimize.lua"]=true,
   ["lang-agr.llg"]=true,
+  ["lang-cn.llg"]=true,
   ["lang-de.llg"]=true,
+  ["lang-deo.llg"]=true,
   ["lang-en.llg"]=true,
+  ["lang-farsi.llg"]=true,
   ["lang-imp-indic.lua"]=true,
   ["lang-imp-serbian.lua"]=true,
   ["lang-imp-simpleascii-data.lgz"]=true,
   ["lang-imp-simpleascii.lua"]=true,
+  ["lang-kr.llg"]=true,
+  ["lang-ua.llg"]=true,
   ["libertinus-math.lfg"]=true,
   ["libertinus-text.lfg"]=true,
   ["libs-imp-curl.lmt"]=true,
@@ -181,8 +186,21 @@
   ["lpdf-fmt-imp-x5g.lmt"]=true,
   ["lpdf-fmt-imp-x5n.lmt"]=true,
   ["lpdf-fmt-imp-x5pg.lmt"]=true,
-  ["lpdf-tag-imp-crap.lmt"]=true,
+  ["lpdf-tag-imp-basic-combination.lmt"]=true,
+  ["lpdf-tag-imp-basic-delimited.lmt"]=true,
+  ["lpdf-tag-imp-basic-description.lmt"]=true,
+  ["lpdf-tag-imp-basic-float.lmt"]=true,
+  ["lpdf-tag-imp-basic-formula.lmt"]=true,
+  ["lpdf-tag-imp-basic-itemgroup.lmt"]=true,
+  ["lpdf-tag-imp-basic-list.lmt"]=true,
+  ["lpdf-tag-imp-basic-margin.lmt"]=true,
+  ["lpdf-tag-imp-basic-section.lmt"]=true,
+  ["lpdf-tag-imp-basic-verbatim.lmt"]=true,
+  ["lpdf-tag-imp-basic-whatever.lmt"]=true,
+  ["lpdf-tag-imp-basic.lmt"]=true,
+  ["lpdf-tag-imp-demo.lmt"]=true,
   ["lpdf-tag-imp-mkiv.lmt"]=true,
+  ["lpdf-tag-imp-uac.lmt"]=true,
   ["lucida-math.lfg"]=true,
   ["lucida-text.lfg"]=true,
   ["lucida-typeone-math.lfg"]=true,

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/context.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/context.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/context.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -56,7 +56,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \permanent\edef\contextformat {\jobname}
-\permanent\edef\contextversion{2025.07.27 21:43}
+\permanent\edef\contextversion{2025.08.17 17:57}
 
 %overloadmode 1 % check frozen / warning
 %overloadmode 2 % check frozen / error
@@ -691,6 +691,10 @@
 % \ifcsname\endcsname\fi % make sure that we reset it
 
 \prependtoks
+    \ctxlua{lua.protectglobal()}% can also be done at the lua end
+\to \everyjob
+
+\prependtoks
     \overloadmode\plusthree
 \to \everyjob
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/core-sys.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/core-sys.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/core-sys.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -198,13 +198,13 @@
 
 \appendtoks
     \ifcstok{\startstopparameter\c!arguments}\v!yes
-        \frozen\instance\protected\edefcsname\e!start\currentstartstop\endcsname{\syst_startstop_start_yes {\currentstartstop}}%
-        \frozen\instance\protected\edefcsname\e!stop \currentstartstop\endcsname{\syst_startstop_stop_yes  }%
-        \frozen\instance\protected\edefcsname        \currentstartstop\endcsname{\syst_startstop_indeed_yes{\currentstartstop}}%
+        \protected\frozen\instance\edefcsname\e!start\currentstartstop\endcsname{\syst_startstop_start_yes {\currentstartstop}}%
+        \protected\frozen\instance\edefcsname\e!stop \currentstartstop\endcsname{\syst_startstop_stop_yes  }%
+        \protected\frozen\instance\edefcsname        \currentstartstop\endcsname{\syst_startstop_indeed_yes{\currentstartstop}}%
     \else
-        \frozen\instance\protected\edefcsname\e!start\currentstartstop\endcsname{\syst_startstop_start_nop {\currentstartstop}}%
-        \frozen\instance\protected\edefcsname\e!stop \currentstartstop\endcsname{\syst_startstop_stop_nop  {\currentstartstop}}%
-        \frozen\instance\protected\edefcsname        \currentstartstop\endcsname{\syst_startstop_indeed_nop{\currentstartstop}}%
+        \protected\frozen\instance\edefcsname\e!start\currentstartstop\endcsname{\syst_startstop_start_nop {\currentstartstop}}%
+        \protected\frozen\instance\edefcsname\e!stop \currentstartstop\endcsname{\syst_startstop_stop_nop  {\currentstartstop}}%
+        \protected\frozen\instance\edefcsname        \currentstartstop\endcsname{\syst_startstop_indeed_nop{\currentstartstop}}%
     \fi
 \to \everydefinestartstop
 
@@ -304,7 +304,7 @@
 
 \appendtoks
     \ifcstok{\highlightparameter\c!define}\v!yes
-        \frozen\instance\protected\edefcsname\currenthighlight\endcsname
+        \protected\frozen\instance\edefcsname\currenthighlight\endcsname
            {\typo_highlights_indeed{\currenthighlight}}%
     \fi
 \to \everydefinehighlight

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/core-uti.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/core-uti.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/core-uti.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -425,7 +425,10 @@
             unpacked.job.packed = nil -- nicer in inspecting
             othercache[filename] = unpacked
             --
-            utilitydata.components, utilitydata.namestack = collectstructure(utilitydata.job.structure.collected)
+            local collectstructure = resolvers.jobs.collectstructure
+            if collectstructure then
+                utilitydata.components, utilitydata.namestack = collectstructure(utilitydata.job.structure.collected)
+            end
             --
             structures.lists     .integrate(utilitydata)
             structures.registers .integrate(utilitydata)

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/driv-shp.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/driv-shp.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/driv-shp.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -133,6 +133,10 @@
 local flushliteral
 local flushwhatsit
 local flushspace
+local flushsimplerule
+local flushspecialrule
+local pushleaderlevel
+local popleaderlevel
 
 -- make local
 
@@ -691,7 +695,7 @@
 local anchors  = { }
 local befores  = setmetatableindex("table")
 local afters   = setmetatableindex("table")
-local stired   = false
+local stored   = false
 
 local function reset_directions()
     dirstack = { }
@@ -1453,7 +1457,7 @@
                                 local edge = cur_v + glueheight
                                 local ly   = 0
                                 if subtype == gleaders_code then
-                                    save_v = cur_v
+                                    local save_v = cur_v
                                     cur_v  = ref_v - shipbox_v - cur_v
                                     cur_v  = total * (cur_v / total)
                                     cur_v  = ref_v - shipbox_v - cur_v
@@ -1463,7 +1467,7 @@
                                     local lr = glueheight % total
                                     cur_v = cur_v + lr / 2
                                 elseif subtype == leaders_code then -- aleader
-                                    save_v = cur_v
+                                    local save_v = cur_v
                                     cur_v = top_edge + total * ((cur_v - top_edge) // total)
                                     if cur_v < save_v then
                                         cur_v = cur_v + total
@@ -1805,9 +1809,6 @@
 
     end
 
-    shipbox_ref_h = pos_h
-    shipbox_ref_v = pos_v
-
     details = {
         shippingmode  = smode, -- target
         boundingbox   = { 0, 0, page_size_h, page_size_v },

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/file-job.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/file-job.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/file-job.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -678,7 +678,7 @@
 jobstructure.components = { }
 jobstructure.namestack  = { }
 
-function collectstructure(collected)
+local function collectstructure(collected)
     local namestack = { }
     local n         = 0
     local function collect(root,result,stack)

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/font-cff.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/font-cff.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/font-cff.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -2779,7 +2779,7 @@
 
     stopparsing = function(fontdata,data)
         stack        = { }
-        glyphs       = false
+     -- glyphs       = false
         result       = { }
         top          = 0
         locals       = false

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/font-ogr.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/font-ogr.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/font-ogr.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -93,7 +93,8 @@
         if method and shapes then
             local characters   = tfmdata.characters
             local descriptions = tfmdata.descriptions
-            local droppedin, tfmdrop, dropchars, dropdescs, colrshapes, props
+         -- local droppedin, tfmdrop, dropchars, dropdescs, colrshapes, props
+            local droppedin, tfmdrop, dropchars, colrshapes, props
             local idx  = 255
             local slot = 0
             -- sorted ?
@@ -109,7 +110,7 @@
                                 colrshapes = setmetatableindex({ },shapes)
                                 slot, droppedin, tfmdrop, props = dropins.provide(method,tfmdata,colrshapes)
                                 dropchars = tfmdrop.characters
-                                dropdescs = tfmdrop.descriptions
+                             -- dropdescs = tfmdrop.descriptions
                             else
                                 idx = idx + 1
                             end
@@ -122,7 +123,7 @@
                             setmetatableindex(c,v)
                             setmetatableindex(d,description)
                             dropchars[idx] = c
-                            dropdescs[idx] = d -- not needed
+                         -- dropdescs[idx] = d -- not needed
                         end
                     end
                 end
@@ -139,7 +140,7 @@
             local droppedin    = tfmdata.droppedin
             local tfmdrop      = tfmdata.tfmdrop
             local dropchars    = tfmdata.dropchars
-            local dropdescs    = tfmdata.dropdescs
+         -- local dropdescs    = tfmdata.dropdescs
             local colrshapes   = tfmdata.colrshapes
             local idx          = tfmdata.dropindex or 255
             local slot         = tfmdata.dropslot  or 0
@@ -154,7 +155,7 @@
                             colrshapes = setmetatableindex({ },shapes)
                             slot, droppedin, tfmdrop = dropins.provide(method,tfmdata,colrshapes)
                             dropchars = tfmdrop.characters
-                            dropdescs = tfmdrop.descriptions
+                         -- dropdescs = tfmdrop.descriptions
                         else
                             idx = idx + 1
                         end
@@ -167,7 +168,7 @@
                         setmetatableindex(c,v)
                         setmetatableindex(d,description)
                         dropchars[idx] = c
-                        dropdescs[idx] = d -- not needed
+                     -- dropdescs[idx] = d -- not needed
                     end
                 end
             end
@@ -174,7 +175,7 @@
             tfmdata.droppedin  = droppedin
             tfmdata.tfmdrop    = tfmdrop
             tfmdata.dropchars  = dropchars
-            tfmdata.dropdescs  = dropdescs
+         -- tfmdata.dropdescs  = dropdescs
             tfmdata.colrshapes = colrshapes
             tfmdata.dropindex  = idx
             tfmdata.dropslot   = slot
@@ -190,12 +191,12 @@
             local droppedin    = tfmdata.droppedin
             local tfmdrop      = tfmdata.tfmdrop
             local dropchars    = tfmdata.dropchars
---             local dropdescs    = tfmdata.dropdescs
+        --  local dropdescs    = tfmdata.dropdescs
             local colrshapes   = tfmdata.colrshapes
             local idx          = tfmdata.dropindex or 255
             local slot         = tfmdata.dropslot  or 0
             local character    = characters[unicode]
---             local description  = descriptions[unicode] or { }
+        --  local description  = descriptions[unicode] or { }
             if character then
                 if idx >= 255 then
                     idx = 1
@@ -202,7 +203,7 @@
                     colrshapes = setmetatableindex({ },shapes)
                     slot, droppedin, tfmdrop = dropins.provide(method,tfmdata,colrshapes)
                     dropchars = tfmdrop.characters
-                    dropdescs = tfmdrop.descriptions
+                 -- dropdescs = tfmdrop.descriptions
                 else
                     idx = idx + 1
                 end
@@ -211,16 +212,16 @@
                 character.commands = { slotcommand[slot][idx] }
                 -- hack to prevent that type 3 also gets 'use' flags .. todo
                 local c = { commands = false, index = idx, dropin = tfmdrop }
---                 local d = { } -- index = idx, dropin = tfmdrop }
+             -- local d = { } -- index = idx, dropin = tfmdrop }
                 setmetatableindex(c,character)
---                 setmetatableindex(d,description)
+             -- setmetatableindex(d,description)
                 dropchars[idx] = c
---                 dropdescs[idx] = d -- not needed
+             -- dropdescs[idx] = d -- not needed
             end
             tfmdata.droppedin  = droppedin
             tfmdata.tfmdrop    = tfmdrop
             tfmdata.dropchars  = dropchars
---             tfmdata.dropdescs  = dropdescs
+         -- tfmdata.dropdescs  = dropdescs
             tfmdata.colrshapes = colrshapes
             tfmdata.dropindex  = idx
             tfmdata.dropslot   = slot
@@ -508,7 +509,8 @@
                 if colorvalues then
                     local characters   = tfmdata.characters
                     local descriptions = tfmdata.descriptions
-                    local droppedin, tfmdrop, dropchars, dropdescs, colrshapes
+                 -- local droppedin, tfmdrop, dropchars, dropdescs, colrshapes
+                    local droppedin, tfmdrop, dropchars, colrshapes
                     local idx  = 255
                     local slot = 0
                     --
@@ -526,7 +528,7 @@
                                         colrshapes = { }
                                         slot, droppedin, tfmdrop = fonts.dropins.provide("color",tfmdata,colrshapes,colorvalues)
                                         dropchars = tfmdrop.characters
-                                        dropdescs = tfmdrop.descriptions
+                                     -- dropdescs = tfmdrop.descriptions
                                     else
                                         idx = idx + 1
                                     end
@@ -549,7 +551,7 @@
                                     setmetatableindex(c,v)
                                     setmetatableindex(d,description)
                                     dropchars[idx] = c
-                                    dropdescs[idx] = d -- not needed
+                                 -- dropdescs[idx] = d -- not needed
                                 end
                             end
                         end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/font-otd.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/font-otd.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/font-otd.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -47,7 +47,7 @@
     local features = contextsetups[attribute]
     if features then
         local dynamics = fontdynamics[font]
-        dynamic = contextmerged[attribute] or 0
+        local dynamic  = contextmerged[attribute] or 0
         local script, language
         if dynamic == 2 then -- merge
             language  = features.language or fontproperties[font].language or "dflt"

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/font-ots.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/font-ots.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/font-ots.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -299,6 +299,7 @@
 local spaces             = false
 
 local sweepnode          = nil
+local sweeptype          = nil
 local sweephead          = { } -- we don't nil entries but false them (no collection and such)
 
 local notmatchpre        = { } -- to be checked: can we use false instead of nil / what if a == b tests

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/font-oup.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/font-oup.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/font-oup.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -24,7 +24,7 @@
 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_cleanup        = false  trackers.register("otf.cleanups",      function(v) trace_cleanup       = 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)
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/font-shp.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/font-shp.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/font-shp.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -183,7 +183,7 @@
     local size = attr and attr.size or 0
     local time = attr and attr.modification or 0
     local sub  = tonumber(sub)
-
+    local data = nil
     -- fonts.formats
     if size > 0 and (kind == "otf" or kind == "ttf" or kind == "tcc") then
         local hash = makehash(filename,sub,instance,extrahash)
@@ -241,6 +241,7 @@
     local size = attr and attr.size or 0
     local time = attr and attr.modification or 0
     local sub  = tonumber(sub)
+    local data = nil
     if size > 0 and (kind == "otf" or kind == "ttf" or kind == "ttc") then
         local hash = makehash(filename,sub,instance,extrahash)
         data = containers.read(cache,hash)

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/font-sty.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/font-sty.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/font-sty.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -236,9 +236,9 @@
 \appendtoks
     \letcsname\??stylecheck\currentstyle\endcsname\relax
     \ifcstok{\styleparameter\c!method}\v!command
-        \frozen\instance\protected\edefcsname\e!start\currentstyle\endcsname{\font_styles_apply_start{\currentstyle}}%
-        \frozen\instance\protected\edefcsname\e!stop \currentstyle\endcsname{\font_styles_apply_stop}%
-        \frozen\instance\protected\edefcsname        \currentstyle\endcsname{\font_styles_apply_grouped{\currentstyle}}% no longer groupedcommand here
+        \protected\frozen\instance\edefcsname\e!start\currentstyle\endcsname{\font_styles_apply_start{\currentstyle}}%
+        \protected\frozen\instance\edefcsname\e!stop \currentstyle\endcsname{\font_styles_apply_stop}%
+        \protected\frozen\instance\edefcsname        \currentstyle\endcsname{\font_styles_apply_grouped{\currentstyle}}% no longer groupedcommand here
     \fi
 \to \everydefinestyle
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/grph-exp.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/grph-exp.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/grph-exp.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -57,6 +57,7 @@
 \newinteger\nofexportedboxes
 
 \newconditional\c_grph_exported
+\newconditional\c_grph_in_image
 
 \definesystemconstant{exported}
 
@@ -98,12 +99,22 @@
 
 \newbox\b_grph_image
 
-\permanent\protected\def\grph_start_image_tagged
+% todo : simple handler as with mp
+
+\permanent\tolerant\protected\def\grph_start_image_tagged[#1]%
   {\begingroup
+   \c_grph_in_image\conditionaltrue
+   %
+   \resetdummyparameter\c!descriptiontext
+   \resetdummyparameter\c!alternativetext
+   \getdummyparameters[#1]%
+   \enforced\edef\figuredescriptiontext{\dummyparameter\c!descriptiontext}%
+   \enforced\edef\figurealternativetext{\dummyparameter\c!alternativetext}%
+   %
    \global\advanceby\nofexportedboxes\plusone
    \edef\figureexported{\the\nofexportedboxes}%
    \dostarttaggednodetail\t!image
-   \setbox\b_grph_image\hpack\bgroup
+   \setbox\b_grph_image\hpack attr \imageattribute \plustwo\bgroup
    \ignorepars
    \ignorespaces}
 
@@ -121,8 +132,9 @@
 
 %D We want to get compatible packaging (beware of spaces)
 
-\permanent\protected\def\grph_start_image_normal
+\permanent\tolerant\protected\def\grph_start_image_normal[#1]%
   {\hpack\bgroup
+   \c_grph_in_image\conditionaltrue
    \ignorepars
    \ignorespaces}
 
@@ -160,9 +172,9 @@
 
 %D So we go for explicit wrapping plus an extra MP command:
 
-\permanent\protected\def\startMPimage#1\stopMPimage
-  {\startimage
-   \startMPcode#1\stopMPcode
+\permanent\tolerant\protected\def\startMPimage[#1]#2\stopMPimage
+  {\startimage[#1]%
+   \startMPcode#2\stopMPcode
    \stopimage}
 
 \permanent\protected\lettonothing\stopMPimage
@@ -175,9 +187,10 @@
 \newdimension\justimageleftoffset
 \newdimension\justimagerightoffset
 
-\permanent\protected\def\grph_start_image_only
+\permanent\tolerant\protected\def\grph_start_image_only[#1]%
   {\begingroup
    \setbox\b_grph_image\hpack\bgroup
+   \c_grph_in_image\conditionaltrue
    \ignorepars
    \ignorespaces}
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/grph-fig.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/grph-fig.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/grph-fig.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -81,7 +81,7 @@
 
 \tolerant\permanent\protected\def\definetypesetting[#1]#*[#2]#*[#S#3]% <name> options settings-a
   {\ifparameter#1\or
-     \frozen\instance\protected\defcsname\??typesettingfile#1\endcsname{\grph_typesetting_process_indeed{#2}{#3}}%
+     \protected\frozen\instance\defcsname\??typesettingfile#1\endcsname{\grph_typesetting_process_indeed{#2}{#3}}%
    \fi}
 
 \tolerant\permanent\protected\def\typesetfile[#1]#*[#S#2]#*[#S#3]% <name> filename settings-b | filename options settings

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/grph-inc.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/grph-inc.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/grph-inc.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -128,7 +128,7 @@
 
 -- extensions
 
-function checkimage(figure)
+local function checkimage(figure)
     if figure then
         local width  = figure.width or 0
         local height = figure.height or 0

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lang-ini.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lang-ini.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lang-ini.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -211,7 +211,7 @@
 
 \def\lang_basics_install_indeed#1#2%
   {\ifcstok{\specificlanguageparameter{#1}\c!define}\v!no\orelse\ifcsname#1\endcsname\else
-     \frozen\instance\protected\defcsname#1\endcsname{\lang_basics_set_current[#2]}%
+     \protected\frozen\instance\defcsname#1\endcsname{\lang_basics_set_current[#2]}%
    \fi}
 
 %D When the second argument is a language identifier, a synonym is created. This

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lang-lab.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lang-lab.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lang-lab.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -89,10 +89,10 @@
 \mutable\lettonothing\currenttextprefixname
 
 \protected\def\lang_labels_define_class_indeed#1#2#3#4#5#6#7#8#9%
-  {\permanent\instance\protected\defcsname  setup#1text\endcsname{\protecttextprefixes      #2\def\currenttextprefixclass{#1}\lang_labels_text_prefix_setup}%
-   \permanent\instance\protected\defcsname preset#1text\endcsname{\protecttextprefixes\plusone\def\currenttextprefixclass{#1}\lang_labels_text_prefix_setup}%
-   \permanent\instance\protected\defcsname   copy#1text\endcsname{\protecttextprefixes\plusone\def\currenttextprefixclass{#1}\lang_labels_text_prefix_copy }%
-   \permanent\instance\protected\defcsname  start#1text\endcsname{\protecttextprefixes\plusone\def\currenttextprefixclass{#1}\lang_labels_text_prefix_start[#1]}%
+  {\permanent\protected\instance\defcsname  setup#1text\endcsname{\protecttextprefixes      #2\def\currenttextprefixclass{#1}\lang_labels_text_prefix_setup}%
+   \permanent\protected\instance\defcsname preset#1text\endcsname{\protecttextprefixes\plusone\def\currenttextprefixclass{#1}\lang_labels_text_prefix_setup}%
+   \permanent\protected\instance\defcsname   copy#1text\endcsname{\protecttextprefixes\plusone\def\currenttextprefixclass{#1}\lang_labels_text_prefix_copy }%
+   \permanent\protected\instance\defcsname  start#1text\endcsname{\protecttextprefixes\plusone\def\currenttextprefixclass{#1}\lang_labels_text_prefix_start[#1]}%
    \permanent\instance          \letcsname   stop#1text\endcsname \relax
    \permanent\instance\def#4{\reallanguagetag{\defaultlanguage\currentmainlanguage}}%
    \ifnum#2=\plustwo % used for math and tags
@@ -132,8 +132,8 @@
      \permanent\instance\let#8\gobbletwoarguments
      \permanent\instance\let#9#3%
    \else
-     \instance\protected\def#3{#5#4}%
-     \instance\protected\def#5##1##2%
+     \protected\instance\def#3{#5#4}%
+     \protected\instance\def#5##1##2%
        {\ifcsname\??label#1:##1:##2\endcsname
           \enforced\expandafter\let\expandafter\thetextprefix\lastnamedcs
         \orelse\ifcsname\??language#4\s!default\endcsname
@@ -145,10 +145,10 @@
         \else
           \enforced\let\thetextprefix\dummytextprefix
         \fi}%
-     \permanent\instance\protected\def#6##1{#3{##1}\expandafter\firstoftwoarguments   \thetextprefix}% \flushleftlabelclass
-     \permanent\instance\protected\def#7##1{#3{##1}\expandafter\secondoftwoarguments  \thetextprefix}% \flushrightlabelclass
-     \permanent\instance\protected\def#8##1{#3{##1}\expandafter\lang_labels_flush_both\thetextprefix}% \flushbothlabelclass #2
-     \permanent\instance\protected\def#9##1{#3{##1}\expandafter\firstoftwoarguments   \thetextprefix}% \flushleftlabelclass
+     \permanent\protected\instance\def#6##1{#3{##1}\expandafter\firstoftwoarguments   \thetextprefix}% \flushleftlabelclass
+     \permanent\protected\instance\def#7##1{#3{##1}\expandafter\secondoftwoarguments  \thetextprefix}% \flushrightlabelclass
+     \permanent\protected\instance\def#8##1{#3{##1}\expandafter\lang_labels_flush_both\thetextprefix}% \flushbothlabelclass #2
+     \permanent\protected\instance\def#9##1{#3{##1}\expandafter\firstoftwoarguments   \thetextprefix}% \flushleftlabelclass
    \fi
    \appendtoks
      \enforced\permanent\instance\let#6\firstofoneargument % to be checked
@@ -194,8 +194,11 @@
    \fi
    \grabuntil{stop#1text}\lang_labels_text_prefix_start_indeed}
 
+% \def\lang_labels_text_prefix_start_indeed#1% text (not special checking done here yet, only for long texts anyway)
+%   {\edefcsname\??label\currenttextprefixclass:\currenttextprefixtag:\currenttextprefixname\endcsname{{\clf_strip{#1}}\empty}}
+
 \def\lang_labels_text_prefix_start_indeed#1% text (not special checking done here yet, only for long texts anyway)
-  {\edefcsname\??label\currenttextprefixclass:\currenttextprefixtag:\currenttextprefixname\endcsname{{\clf_strip{#1}}\empty}}
+  {\edefcsname\??label\currenttextprefixclass:\currenttextprefixtag:\currenttextprefixname\endcsname{{\utfstrip{#1}}\empty}}
 
 \tolerant\def\lang_labels_text_prefix_setup[#1]#*[#2]%
   {\ifarguments\or

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lang-tra.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lang-tra.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lang-tra.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -69,9 +69,9 @@
 \appendtoks
     \clf_registertransliteration{\currenttransliterationparent}{\currenttransliteration}%
     \ifcstok{\transliterationparameter\c!define}\v!yes
-      \frozen\protected\instance\edefcsname\e!start\currenttransliteration\endcsname{\starttransliteration[\currenttransliteration]}%
-      \frozen\protected\instance\edefcsname\e!stop \currenttransliteration\endcsname{\stoptransliteration}%
-      \frozen\protected\instance\edefcsname        \currenttransliteration\endcsname{\transliteration[\currenttransliteration]}%
+      \protected\frozen\instance\edefcsname\e!start\currenttransliteration\endcsname{\starttransliteration[\currenttransliteration]}%
+      \protected\frozen\instance\edefcsname\e!stop \currenttransliteration\endcsname{\stoptransliteration}%
+      \protected\frozen\instance\edefcsname        \currenttransliteration\endcsname{\transliteration[\currenttransliteration]}%
     \fi
 \to \everydefinetransliteration
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-ano.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-ano.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-ano.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1046,7 +1046,6 @@
             local contents = action.arguments
             local color    = pdfcolorarray(author and "pdfhighlight:" .. author or nil)
             local bs, bc   = pdfborder(actions)
-
             local main = pdfdictionary {
                 Subtype     = pdf_highlight,
                 Border      = pdfshareobjectreference(bs),
@@ -1182,6 +1181,7 @@
     local checkmesh     = false
     local lastprerolled = false
     local lastmeshedup  = false
+    local lastmeshed    = false
     local lastrealpage  = 0
 
     local count = 0
@@ -1197,6 +1197,7 @@
             lastrealpage  = r
             lastprerolled = false
             lastmeshedup  = false
+            lastmeshed    = false
         end
         if prerolled == lastprerolled then
             if not more then
@@ -1266,6 +1267,7 @@
  --         lastrealpage  = r
  --         lastprerolled = false
  --         lastmeshedup  = false
+ --         lastmeshed    = false
  --     end
  --     if prerolled == lastprerolled then
  --         if not more then
@@ -1336,6 +1338,7 @@
             lastrealpage  = r
             lastprerolled = false
             lastmeshedup  = false
+            lastmeshed    = false
         end
         if prerolled == lastprerolled then
             if not more then
@@ -1935,7 +1938,7 @@
     local noflevels  = #levels
     local i = start
     local n = 0
-    local child, entry, m, prev, first, last, f, l
+    local child, entry, m, prev, first, last, f, l, realpage
     while i and i <= noflevels do
         local current = levels[i]
         if current.usedpage == false then

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-crp.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-crp.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-crp.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,613 @@
+if not modules then modules = { } end modules ['lpdf-crp.lmt'] = {
+    version   = 1.001,
+    comment   = "companion to lpdf-ini.mkxl and mtx-pdf.lua",
+    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+    copyright = "PRAGMA ADE / ConTeXt Development Team",
+    license   = "see context related readme files"
+}
+
+-- One reason for having a look at it is that we might need to be able to merge ..
+-- bah. I'm sure someone on the list will ask for it. For now we keep it local as
+-- not all is valid (xml or whatever).
+--
+-- A first quick pick-up-on-this (I lost old code) with Riverside Live ID (2025)
+-- blasting from the speakers. A pitty I missed one of these shows live (went
+-- to few in NL before).
+
+local type, tonumber, rawget = type, tonumber, rawget
+local gsub, formatters, lower = string.gsub, string.formatters, string.lower
+local concat, setmetatableindex, sortedhash = table.concat, table.setmetatableindex, table.sortedhash
+
+local getpagecontent = lpdf.epdf.getpagecontent
+
+local xmlescaped = xml.escaped
+
+local softhyphen = utf.char(0xAD) .. " +"
+
+local function striphyphens(str)
+    return str and gsub(str,softhyphen,"") or ""
+end
+
+local function collectcontent(pdffile,first,last,everything)
+    local current = false
+    for i=first,last do
+        local collected = setmetatableindex("table")
+        local content   = getpagecontent(pdffile,i,false,true)
+        everything[i] = collected
+        if content then
+            local mcid = false
+            for i=1,#content do
+                local ci   = content[i]
+                local what = ci[#ci]
+                if what == "BDC" then
+                 -- if mcid then
+                 --     print("! nesting in mcid",mcid)
+                 -- end
+                    local name = ci[1]
+                    local dict = ci[2]
+                    if name and name[1] == "name" then
+                        name = name[2]
+                    else
+                        name = false
+                    end
+                    if dict and dict[1] == "dict" then
+                        dict = dict[2]
+                        for i=1,#dict,2 do
+                            local key = dict[i]
+                            local val = dict[i+1]
+                            if key[1] == "name" and key[2] ==  "MCID" then
+                                mcid = val
+                            end
+                        end
+                    else
+                        dict = false
+                    end
+                    if name and mcid then
+                        current = collected[tonumber(mcid) or false]
+                     -- print("BDC",mcid,name,current)
+                    else
+                        current = false
+                     -- mcid    = false
+                     -- current = collected[tonumber(mcid) or false]
+                    end
+                elseif what == "BMC" then -- artifact
+                 -- print("BMC")
+                    if mcid then
+                     -- print("! nesting in mcid",mcid)
+                        current = false
+                        mcid    = false
+                    else
+                    end
+                elseif what == "EMC" then
+                 -- if mcid then
+                 --     print("EMC",mcid)
+                 -- end
+                    current = false
+                    mcid    = false
+                elseif current then
+-- if what == "Tm" then
+-- end
+
+                    if what == "TJ" then
+                        local list = ci[1]
+                        if list[1] == "array" then
+                            list = list[2]
+                            if type(list) == "table" then
+                                current[#current+1] = concat(list)
+                            end
+                        end
+                 -- elseif what == "Tj" or what == "'" or what == '"' then
+                    elseif what == "Tj" then
+                        -- needs checking
+                        local list = ci[1]
+                        if list[1] == "array" then
+                            list = list[2]
+                            if type(list) == "string" then
+                                current[#current+1] = list
+                            end
+                        end
+                    end
+                end
+            end
+        end
+   end
+   setmetatableindex(collected,nil)
+   return collected
+end
+
+-- options  : attachments
+-- comments : add alt as comment
+
+function lpdf.collectcontent(pdffile,options)
+
+    -- todo: fetch one page
+
+    if not pdffile then
+        return
+    end
+
+    local tree = pdffile.Catalog.StructTreeRoot
+    if not tree then
+        return
+    end
+
+    local pages    = pdffile.pages
+    local nofpages = pdffile.nofpages
+    if nofpages == 0 then
+        return
+    end
+
+    local statistics = {
+        pages = nofpages,
+    }
+
+    local sharedroles = { }
+
+    local rolemap = tree.RoleMap
+    if rolemap then
+        for k, v in lpdf.epdf.expanded(rolemap) do
+            sharedroles[k] = v
+        end
+    end
+
+    local preferattachments = false
+    local addaltascomment   = true
+    local nobreaks          = false
+    local details           = true -- false
+
+    if type(options) == "table" then
+        if options.attachments ~= nil then
+            preferattachments = options.attachments
+        end
+        if options.comments ~= nil then
+            addaltascomment = options.comments
+        end
+        if options.nobreaks ~= nil then
+            nobreaks = options.nobreaks
+        end
+        if options.details ~= nil then
+            details = options.details
+        end
+    end
+
+    local nofnamespaces = 0
+
+    local namespaces = setmetatableindex(function(t,k)
+        local map  = { }
+        local url  = k.NS
+        local rns  = k.RoleMapNS
+        if rns then
+            for k, v in lpdf.epdf.expanded(rns) do
+                map[k] = tostring(v[1])
+            end
+        end
+        nofnamespaces = nofnamespaces + 1
+        local v = {
+            url   = url,
+            map   = map,
+            index = nofnamespaces,
+            name  = k.LMTX_NameSpace or "unset",
+        }
+        t[k] = v
+        return v
+    end)
+
+    local everything = { }
+
+    collectcontent(pdffile,1,nofpages,everything)
+
+    -- Todo: also collect in table so that we can include.
+
+    local r      = 1
+    local result = {
+        [[
+<?xml version="1.0" standalone=yes"?>
+
+<!--
+    This representation serves no other purpose than testing because tagging is
+    not suitable for advanced structuring or fancy typesetting (unless a document
+    is relatively simple). This tracing is a side effect of testing (mostly math).
+
+    This is work in progress, and some needs to be implemented and /or finished
+    but we will pick up this thread when there is demand for this kind of tracing.
+
+    It's not hard to add more here but most time goes into deciding how to present
+    it as we mostly uses it for checking and tracing.
+-->
+]],
+    }
+
+    -- at some point we can use the template mechanism because we can then be
+    -- selective but it is slower (no that relevant here)
+
+    local f_text      = formatters[ [[%w%s]] ]
+    local f_simple_b  = formatters[ [[%w<%s>]] ]
+    local f_simple_e  = formatters[ [[%w</%s>]] ]
+ -- local f_element_b = formatters[ [[%w<%s namespace="%s" rolemap="%s">]] ]
+    local f_element_e = f_simple_e
+    local f_comment   = formatters[ [[%w<!-- %s -->]] ]
+
+    local common =
+        [[%?overload: overload="%overload%"?%]] ..
+        [[%?title: title="%title%"?%]] ..
+        [[%?language: language="%language%"?%]] ..
+        [[%?rowspan: rowspan="%rowspan%"?%]] ..
+        [[%?colspan: colspan="%colspan%"?%]] ..
+        [[%?symbol: symbol="%symbol%"?%]] ..
+        [[%?description: description="%description%"?%]] ..
+        [[%?continue: continue="%continue%"?%]]
+
+    local detail =
+        [[%?attribute: attribute="%attribute%"?%]] ..
+        [[%?namespace: ns="%namespace%"?%]] ..
+        [[%?rolemap: pdf="%rolemap%"?%]]
+
+    local fuzzy =
+        [[%?attribute: attribute="%attribute%"?%]] ..
+        [[%?namespace: ns="%namespace%"?%]] ..
+        [[%?overload: overload="%overload%"?%]] ..
+        [[%?description: description="%description%"?%]]
+
+    local f_comment_d = utilities.templates.replacer (
+        [[%:w:level%]] ..
+        [[<!--]] ..
+        detail ..
+        common ..
+        [[ -->]]
+    )
+
+    local f_comment_n = utilities.templates.replacer (
+        [[%:w:level%]] ..
+        [[<!--]] ..
+        common ..
+        [[ -->]]
+    )
+
+    local f_simple_l = utilities.templates.replacer (
+        [[%:w:level%]] ..
+        [[<%element%]] ..
+        common ..
+        [[>]]
+    )
+
+    local f_element_f = utilities.templates.replacer (
+        [[%:w:level%]] ..
+        [[<%element%]] ..
+        detail ..
+        fuzzy ..
+        [[/>]]
+    )
+
+    local f_element_b = utilities.templates.replacer (
+        [[%:w:level%]] ..
+        [[<%element%]] ..
+        detail ..
+        common ..
+        [[>]]
+    )
+
+    local f_element_i = utilities.templates.replacer (
+        [[%:w:level%]] ..
+        [[<%element%]] ..
+        [[%?index: index="%index%"?%]] ..
+        [[>]] ..
+        [[%value%]] ..
+        [[</%element%>]]
+    )
+
+    local f_simple_url = formatters [
+        [[%w<%s name="%s" index="%s" url="%s">]]
+    ]
+    local f_simple_map = formatters [
+        [[%w<%s user="%s" pdf="%s" />]]
+    ]
+
+    local f_element_kv = utilities.templates.replacer (
+        [[%:w:level%]] ..
+        [[<%element%>]] ..
+        [[%value%]] ..
+        [[</%element%>]]
+    )
+
+ -- local attachments = lpdf.epdf.resolvers.embeddedfiles(pdffile)
+ -- inspect(attachments)
+
+    local collected      = false
+    local nothing        = { }
+    local nofelements    = 0
+    local nofendpoints   = 0
+    local nofattachments = 0
+    local nofalternates  = 0
+    local nofbreaks      = 0
+    local noflevels      = 0
+
+    local function flushcontent(index,level)
+        -- We assume proper spaces being used, otherwise expansion and protrusion start
+        -- interfering, introducing spaces if we would concatinate with a space.
+        if not collected then
+            -- error
+         -- print("no collected")
+        elseif not index then
+            -- suspicious
+         -- print("no index")
+        else
+            local text = rawget(collected,index)
+            if text then
+                text = concat(text," ")
+                collected[index] = false
+                if #text > 0 then
+                    r = r + 1 ; result[r] = f_text(level,xmlescaped(striphyphens(text)))
+                    nofendpoints = nofendpoints + 1
+                end
+            else
+                -- weird but okay
+            end
+        end
+    end
+
+    local showkids -- defined later
+
+    local function showkid(kid,level)
+        if type(kid) == "table" then
+            if kid.Type == "MCR" then
+              -- inspect(kid)
+            else
+                local element     = kid.S
+                local namespace   = kid.NS
+                local page        = kid.Pg
+             -- local id          = kid.ID
+                local parent      = kid.P
+                local kids        = kid.K
+                local alternate   = kid.Alt
+                local content     = kid.Contents
+                local attached    = kid.AF
+                local title       = kid.T
+                local rolemap     = false
+                local iscontext   = false
+                local language    = kid.Lang
+                local attributes  = kid.A or nothing
+                local realelement = kid.LMTX_S or element
+                local attribute   = kid.LMTX_A
+                -- only relevant when Pg
+                collected = everything[page and page.number or 0]
+                -- print(realelement,element)
+                -- todo: level 1 rolemap based
+                if not namespace then
+                 -- inspect(kid)
+                elseif namespace.Type == "Namespace" then -- resolves so we can hash
+                    local LMTX = namespace.LMTX_NameSpace
+                    if details then
+                        local n = namespaces[namespace]
+                     -- namespace = n.url or ""
+                        namespace = n.index or ""
+                        rolemap   = n.map[element] or ""
+                    else
+                        namespace = false
+                        rolemap   = false
+                    end
+                    iscontext = LMTX == "context"
+                else
+                    if details then
+                        namespace = ""
+                        rolemap   = sharedroles[element] or ""
+                    else
+                        namespace = false
+                        rolemap   = false
+                    end
+                end
+                -- element == "math"
+                if attached then
+                    if alternate and not preferattachments then
+                        -- let's forget about this
+                    else
+                        attached = attached[1]
+                        if attached then
+                            attached = attached.EF
+                            if attached then
+                                attached = attached.F
+                                if attached then
+                                    attached = attached()
+                                end
+                            end
+                        end
+                    end
+                end
+                -- if attachments and id then
+                --     attached = attachments[id].EF.F()
+                -- end
+                if type(attached) == "string" then
+                    if addaltascomment and type(alternate) == "string" then
+                        r = r + 1 ; result[r] = f_comment(level,xmlescaped(alternate))
+                    end
+                    attached = gsub(attached,"[\r\n]+","\n" .. string.nspaces[level])
+                    if details then
+                        r = r + 1 ; result[r] = f_comment_d {
+                            level     = level,
+                            element   = original,
+                            attribute = attribute,
+                            namespace = namespace,
+                            rolemap   = rolemap,
+                            title     = title,
+                            overload  = realelement ~= element and element or nil,
+                        }
+                    else
+                        r = r + 1 ; result[r] = f_comment_n {
+                            level     = level,
+                            element   = original,
+                            attribute = attribute,
+                        }
+                    end
+                    r = r + 1 ; result[r] = f_text(level,attached)
+                    nofattachments = nofattachments + 1
+                elseif type(contents) == "string" and (element == "link" or element == "reference") then
+                    r = r + 1 ; result[r] = f_element_f {
+                        level       = level,
+                        element     = element,
+                        attribute   = attribute,
+                        namespace   = details and namespace or nil,
+                        rolemap     = details and rolemap or nil,
+                        description = xmlescaped(contents)
+                    }
+                    nofelements = nofelements + 1
+                elseif type(alternate) == "string" then
+                    r = r + 1 ; result[r] = f_text(level,xmlescaped(alternate))
+                    nofalternates = nofalternates + 1
+                elseif not kids then
+                    -- go on
+                elseif iscontext and nobreaks and element == "break" then
+                    r = r + 1 ; result[r] = "\n"
+                    nofbreaks = nofbreaks + 1
+                elseif details then
+                    local original = realelement or element
+                 -- r = r + 1 ; result[r] = f_element_b(level,element,namespace,rolemap)
+                    r = r + 1 ; result[r] = f_element_b {
+                        level     = level,
+                        element   = original,
+                        attribute = attribute,
+                        namespace = namespace,
+                        rolemap   = rolemap,
+                        title     = title,
+                        rowspan   = attributes.RowSpan,
+                        colspan   = attributes.ColSpan,
+                        symbol    = attributes.ListNumbering and lower(attributes.ListNumbering),
+                        continue  = attributes.ContinuedList and "yes" or nil,
+                        overload  = realelement ~= element and element or nil,
+                    }
+                    showkids(kids,level+1)
+                    r = r + 1 ; result[r] = f_element_e(level,original)
+                    nofelements = nofelements + 1
+                else
+                 -- r = r + 1 ; result[r] = f_simple_b(level,element)
+                    r = r + 1 ; result[r] = f_simple_l {
+                        level     = level,
+                        element   = element,
+                        attribute = attribute,
+                        language  = language
+                    }
+                    showkids(kids,level+1)
+                    r = r + 1 ; result[r] = f_simple_e(level,element)
+                    nofelements = nofelements + 1
+                end
+                if level > noflevels then
+                    noflevels = level
+                end
+             end
+        else
+            flushcontent(tonumber(kid),level)
+        end
+    end
+
+    showkids = function(kids,level)
+        if type(kids) == "number" then
+            flushcontent(kids,level)
+        elseif #kids == 0 then
+            showkid(kids,level)
+        else
+            for i=1,#kids do
+                showkid(kids[i],level)
+            end
+        end
+    end
+
+    local nofsharedroles = 0
+    local nofspacedroles = 0
+
+    local function flush_kv(level,element,value)
+        if type(value) == "table" then
+            for i=1,#value do
+                value[i] = tostring(value[i])
+            end
+            value = xmlescaped(concat(value," "))
+        elseif type(value) == "string" then
+            value  = xmlescaped(value)
+        elseif value then
+            value  = tostring(value)
+        else
+            return
+        end
+        if value and #value > 0 then
+            r = r + 1 ; result[r] = f_element_kv {
+                level   = 3,
+                element = element,
+                value   = value
+            }
+        end
+    end
+    local kids = tree.K
+    if not kids then
+        return -- no need to show something
+    elseif details then
+        r = r + 1 ; result[r] = f_simple_b(0,"pdfstructure")
+        r = r + 1 ; result[r] = f_simple_b(1,"pdfcontent")
+        showkids(kids,2)
+        r = r + 1 ; result[r] = f_simple_e(1,"pdfcontent")
+        if next(namespaces) then
+            r = r + 1 ; result[r] = f_simple_b(1,"pdfnamespaces")
+            for k, v in sortedhash(namespaces) do
+                r = r + 1 ; result[r] = f_simple_url(2,"pdfnamespace", v.name or "*", v.index, xmlescaped(v.url or""))
+                for k, v in sortedhash(v.map) do
+                    r = r + 1 ; result[r] = f_simple_map(4,"pdfrolemap",k,v)
+                    nofspacedroles = nofspacedroles + 1
+                end
+                r = r + 1 ; result[r] = f_simple_e(2,"pdfnamespace")
+            end
+            r = r + 1 ; result[r] = f_simple_e(1,"pdfnamespaces")
+        end
+        if next(sharedroles) then
+            r = r + 1 ; result[r] = f_simple_b(1,"pdfroles")
+            for k, v in sortedhash(sharedroles) do
+                r = r + 1 ; result[r] = f_simple_map(2,"pdfrolemap",k,v)
+                nofsharedroles = nofsharedroles + 1
+            end
+            r = r + 1 ; result[r] = f_simple_e(1,"pdfroles")
+        end
+        local tagging = pdffile.catalog.LMTX_Tagging
+        if tagging then
+            r = r + 1 ; result[r] = f_simple_b(1,"pdfprofiles")
+            flush_kv(1,"comment",tagging.Comment)
+            flush_kv(1,"versiont",tagging.Version)
+            local profiles = tagging.Profiles
+            if profiles then
+                for i=1,#profiles do
+                    local profile = profiles[i]
+                    r = r + 1 ; result[r] = f_simple_b(2,"profile")
+                    flush_kv(3,"name",     profile.name)
+                    flush_kv(3,"version",  profile.version)
+                    flush_kv(3,"size",     profile.size)
+                    flush_kv(3,"mapping",  profile.mapping)
+                    flush_kv(3,"remapping",profile.remapping)
+                    flush_kv(3,"endpoints",profile.endpoints)
+                    r = r + 1 ; result[r] = f_simple_e(2,"profile")
+                end
+            end
+            r = r + 1 ; result[r] = f_simple_e(1,"pdfprofiles")
+        end
+
+        --
+        r = r + 1 ; result[r] = f_simple_e(0,"pdfstructure")
+    else
+        showkids(kids,0)
+    end
+
+    result = concat(result,"\n")
+
+    result = gsub(result,     "<(paragraph[^>]-)>%s+</paragraph>",     "<%1/>")
+    result = gsub(result,           "<(div[^>]-)>%s+</div>",           "<%1/>")
+    result = gsub(result,          "<(span[^>]-)>%s+</span>",          "<%1/>")
+    result = gsub(result,         "<(break[^>]-)>%s+</break>",         "<%1/>")
+    result = gsub(result,"<(navigationpage[^>]-)>%s+</navigationpage>","<%1/>")
+    result = gsub(result,     "<(reference[^>]-)>%s+</reference>",     "<%1/>")
+    result = gsub(result,          "<(link[^>]-)>%s+</link>",          "<%1/>")
+
+    statistics.namespaces  = nofnamespaces
+    statistics.spacedroles = nofspacedroles
+    statistics.sharedroles = nofsharedroles
+    statistics.elements    = nofelements
+    statistics.attachments = nofattachments
+    statistics.alternates  = nofalternates
+    statistics.endpoints   = nofendpoints
+    statistics.breaks      = nofbreaks
+    statistics.levels      = noflevels
+
+    return result, statistics
+end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fix-imp-contents.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fix-imp-contents.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fix-imp-contents.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -147,8 +147,12 @@
                     end
                     --
                     local r = v.Resources
-                    if r then
-                        if procset_done and r.__raw__.ProcSet then r.__raw__.ProcSet = nil procset_done = procset_done + 1 end
+                    if r and not r.__resources_processed__ then
+                        r.__resources_processed__ = true
+                        if procset_done and r.__raw__.ProcSet then
+                            r.__raw__.ProcSet = nil
+                            procset_done = procset_done + 1
+                        end
                         local x = r.XObject
                         if x then
                             for k, v in expanded(x) do
@@ -279,7 +283,8 @@
         if x then
             for k, v in expanded(x) do
                 local resources = v.Resources
-                if resources then
+                if resources and not resources.__resources_cidsets_cleanedup__ then
+                    resources.__resources_cidsets_cleanedup__ = true
                     pdf_cleanup_cidsets(pdfdoc,page,pagenumber,resources,compactor,action)
                 end
             end
@@ -313,7 +318,8 @@
         if x then
             for k, v in expanded(x) do
                 local resources = v.Resources
-                if resources then
+                if resources and not resources.__resources_procsets_cleanedup__ then
+                    resources.__resources_procsets_cleanedup__ = true
                     pdf_cleanup_procsets(pdfdoc,page,pagenumber,resources,compactor)
                 end
             end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fix-imp-fonts.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fix-imp-fonts.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fix-imp-fonts.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1152,7 +1152,7 @@
                 if op == "Tf" then
                     -- maybe use /R<N> for replacement
                     f = ti[1][2]
-                    d = data[f]
+                    local d = data[f]
                     if d then
                         m = d.map
                         u = d.used
@@ -1217,7 +1217,6 @@
                                         end
                                     end
                                 end
-                            else
                             end
                         end
                     end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fld.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fld.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fld.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -335,6 +335,7 @@
     local fontsize        = specification.fontsize or "12pt"
     local fontstyle       = specification.fontstyle or "rm"
     local fontalternative = specification.fontalternative or "tf"
+    local fontraise       = 0
     local colorvalue      = tonumber(specification.colorvalue)
     local s = fontnames[fontstyle]
     if not s then

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fmt.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fmt.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-fmt.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -542,6 +542,8 @@
                     majorversion,minorversion)
             end
             --
+            lpdf.setutfstringmode(majorversion >= 2)
+            --
             -- maybe block by pdf version
             --
             codeinjections.settaggingsupport(formatspecification.tagging)

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-img.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-img.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-img.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -52,7 +52,6 @@
 local pdfdictionary        = lpdf.dictionary
 local pdfarray             = lpdf.array
 local pdfconstant          = lpdf.constant
-local pdfstring            = lpdf.string
 local pdfreference         = lpdf.reference
 local pdfverbose           = lpdf.verbose
 local pdfflushstreamobject = lpdf.flushstreamobject
@@ -304,7 +303,7 @@
     local pngtomask      = pngdecode.tomask
     local pngmakemask    = pngdecode.makemask
 
-    local filtermask, decodemask, decodestrip, transpose, expand, tocmyk
+    local createmask, filtermask, decodemask, decodestrip, transpose, expand, tocmyk
 
     local newindex = lua.newindex
     local newtable = lua.newtable

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-ini.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-ini.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-ini.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -471,11 +471,8 @@
         if not s or s == "" then
             return ""
         elseif flags & utf16flags ~= 0 then
--- print("original",s)
--- print("utf8    ",utf16toutf8(s))
             return utf16toutf8(s)
         else
--- print("original",s)
             return s
         end
     end
@@ -762,6 +759,55 @@
 local mt_v = { __index = { __lpdftype__ = "verbose"    }, __tostring = tostring_v, __call = value_v }
 local mt_l = { __index = { __lpdftype__ = "literal"    }, __tostring = tostring_l, __call = value_l }
 
+do
+
+    -- these can become helpers
+
+    local find = string.find
+
+    local tostring_u1 = function(t)
+        local s = t[1]
+        if #s == 0 then
+            return "()"
+        elseif find(s,"[\x00-\x1F\x27-\x28\x80-\xBF]") then
+            -- nop: control codes         : 0x00 .. 0x1F
+            -- yes: before left parent    : we don't like escaping
+            -- nop: left and right parent : 0x27 .. 0x28
+            -- yes: after right parent    : we don't like escaping
+            -- nop: after tilde           : 0x80 .. 0xBF
+            print(s)
+            return tosixteen(s)
+        else
+            return "(" .. s .. ")"
+        end
+    end
+
+    local tostring_u2 = function(t)
+        local s = t[1]
+        if #s == 0 then
+            return "()"
+        elseif find(s,"[\x80-\xBF]") then
+         -- return "(\xEF\xBB\xBF" .. s .. ")"
+            return "(\239\187\191" .. s .. ")"
+        else
+            return "(" .. s .. ")"
+        end
+    end
+
+    local function setutfstringmode(mode)
+        tostring_u = mode and tostring_u2 or tostring_u1
+        mt_u.__tostring = tostring_u
+    end
+
+    lpdf.setutfstringmode = setutfstringmode
+
+    directives.register("backend.pdf.utf", setutfstringmode)
+
+    setutfstringmode(false)
+
+end
+
+
 local function pdfstream(t) -- we need to add attributes
     if t then
         local tt = type(t)
@@ -1160,7 +1206,7 @@
             --
             local labels = structures.pages.getlabels()
             if labels and next(labels) then
-                for k, v in next, labels do
+                for k, v in sortedhash(labels) do
                     if type(v) == "table" then
                         labels[k] = pdfarray(v)
                     end
@@ -1172,6 +1218,17 @@
                 catalog.LMTX_Pages = pdfreference(pdfimmediateobject(tostring(labels)))
             end
             --
+            local tagging = lpdf.gettaggingstatus()
+
+            if tagging and next(tagging) then
+                tagging = pdfdictionary {
+                    Type     = pdfconstant("Tagging"),
+                    Version  = "1.00",
+                    Profiles = tagging.profiles,
+                    Comment  = tagging.comment,
+                }
+                catalog.LMTX_Tagging = pdfreference(pdfimmediateobject(tostring(tagging)))
+            end
             return pdfreference(pdfimmediateobject(tostring(catalog)))
         end
     end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-lmt.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-lmt.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-lmt.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -747,7 +747,7 @@
 
     local width_factor = 72.27 / 72.0
 
-    local last_fpdf
+    local last_pdf
 
     local function set_font()
      -- if need_width and need_width ~= 0 then
@@ -3645,8 +3645,7 @@
     local function embedimage(specification)
         if specification then
             lastindex = lastindex + 1
-            index     = lastindex
-            specification.index = index
+            specification.index = lastindex
             local xobject = pdfdictionary { }
             if not specification.notype then
                 xobject.Type     = pdf_xobject
@@ -3702,7 +3701,7 @@
             specification.stream      = nil
             specification.attr        = nil
             specification.type        = specification.kind or specification.type or img_none
-            indices[index]            = specification -- better create a real specification
+            indices[lastindex]        = specification -- better create a real specification
             return specification
         end
     end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-pde.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-pde.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-pde.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -96,7 +96,7 @@
 
 local allocate          = utilities.storage.allocate
 
-local bpfactor          <const> = number.dimenfactors.bp
+local bpfactor  <const> = number.dimenfactors.bp
 
 local objectcodes = { [0] =
     "none",
@@ -907,7 +907,8 @@
                         tounicode = lpegmatch(fromunicode,tounicode,1,{})
                     end
                     fonts[id] = {
-                        tounicode = type(tounicode) == "table" and tounicode or { }
+                        tounicode = type(tounicode) == "table" and tounicode or { },
+                        wide      = data.Subtype ~= "Type3" and data.Subtype ~= "Type1",
                     }
                     setmetatableindex(fonts[id],"self")
                 end
@@ -922,7 +923,7 @@
 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 p_hex_to_utf_4 = C(4) / function(s) -- needs checking !
     local now = hextointeger(s)
     if more > 0 then
         now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong
@@ -936,13 +937,19 @@
     end
 end
 
+local p_hex_to_utf_2 = C(2) / function(s) -- needs checking !
+    local now = hextointeger(s)
+    return unic[now] or utfchar(now)
+end
+
 local p_dec_to_utf = C(1) / function(s) -- needs checking ! not needed now that we always go hex
     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)
+local p_hex_to_utf_4 = P(true) / function() more = 0 end * Cs(p_hex_to_utf_4^1)
+local p_hex_to_utf_2 = P(true) / function() more = 0 end * Cs(p_hex_to_utf_2^1)
+local p_dec_to_utf   = P(true) / function() more = 0 end * Cs(p_dec_to_utf  ^1)
 
 -- also xform?
 
@@ -973,9 +980,12 @@
     end
 
     local content = allcontent(page.Contents or "")
+
     local list    = lpegmatch(fast and fastparser or parser,content)
 
-    if asis then
+    if not list then
+        return
+    elseif asis then
         return list -- , fonts
     end
 
@@ -990,6 +1000,7 @@
         if operator == "Tf" then
             font = fonts[entry[1][2]]
             unic = font and font.tounicode or { }
+            wide = font and font.wide or false
         elseif operator == "TJ" then
             local data = entry[1] -- { "array", { ... } }
             local list = data[2]  -- { { ... }, { ... } }
@@ -1000,7 +1011,7 @@
                     local kind = li[1]
                     local what = li[2]
                     if kind == "hex" then
-                        list[i] = lpegmatch(p_hex_to_utf,what)
+                        list[i] = lpegmatch(wide and p_hex_to_utf_4 or p_hex_to_utf_2,what)
                     elseif kind == "string" then
                         list[i] = lpegmatch(p_dec_to_utf,what)
                     else
@@ -1020,7 +1031,7 @@
             local kind = list[1]
             local what = list[2]
             if kind == "hex" then
-                list[2] = lpegmatch(p_hex_to_utf,what) -- was li[2]
+                list[2] = lpegmatch(wide and p_hex_to_utf_4 or p_hex_to_utf_2,what) -- was li[2]
             elseif kind == "string" then
                 list[2] = lpegmatch(p_dec_to_utf,what) -- was li[2]
             end

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-combination.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-combination.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-combination.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,17 @@
+return {
+
+    name      = "basic pdf specific tagging : combination",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        combination        = { pdf = "Table" },
+        combinationpair    = { pdf = "TR"    },
+        combinationcontent = { pdf = "TD"    },
+        combinationcaption = { pdf = "TD"    },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-delimited.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-delimited.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-delimited.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,19 @@
+return {
+
+    name      = "basic pdf specific tagging : delimited",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        delimitedblock   = { pdf = "BlockQuote" },
+        delimited        = { pdf = "Artifact"   },
+     -- delimited        = { pdf = "Quote"      }, -- Quote is not read differently
+        delimitedcontent = { pdf = "NonStruct"  },
+        delimitedsymbol  = { pdf = "NonStruct"  },
+     -- delimitedsymbol  = { pdf = "Lbl"        }, -- Lbl is not distinguished here in reading
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-description.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-description.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-description.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,24 @@
+return {
+
+    name      = "basic pdf specific tagging : description",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        description        = { pdf = "Sect"      },
+        descriptiontag     = { pdf = "Lbl"       },
+        descriptioncontent = { pdf = "Div"       },
+        descriptionsymbol  = { pdf = "NonStruct" },
+
+    },
+
+    remapping = {
+
+        { element = "description",    detail = "footnote", pdf = "FENote" },
+     -- { element = "descriptiontag", parent = "footnote", pdf = "" },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-float.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-float.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-float.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,30 @@
+return {
+
+    name      = "basic pdf specific tagging : float",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        float        = { pdf = "Aside" },
+        subfloat     = { pdf = "Div"   },
+        floatcaption = { pdf = "Div"   }, -- Caption contains the three below
+        floatlabel   = { pdf = "Lbl"   },
+        floatnumber  = { pdf = "Lbl"   },
+        floattext    = { pdf = "P"     },
+        floatcontent = { pdf = "Div"   }, -- the figure/table
+
+     -- float        = { pdf = "Div"       },
+     -- floatcaption = { pdf = "NonStruct" }, -- contains the three below
+     -- floatlabel   = { pdf = "Lbl"       },
+     -- floatnumber  = { pdf = "Lbl"       },
+     -- floattext    = { pdf = "Lbl"       },
+     -- floatcontent = { pdf = "Div"       }, -- the figure/table
+
+        image        = { pdf = "Figure"   },
+     -- mpgraphic    = { pdf = "Artifact" },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-formula.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-formula.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-formula.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,22 @@
+return {
+
+    name      = "basic pdf specific tagging : formula",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        formulaset     = { pdf = "Div"       },
+        formula        = { pdf = "Div"       },
+        formulacaption = { pdf = "Artifact"  }, -- Lbl
+        formulalabel   = { pdf = "NonStruct" },
+        formulanumber  = { pdf = "Lbl"       }, -- Span
+        formulacontent = { pdf = "Formula"   },
+     -- subformula     = { pdf = "NonStruct" },
+
+        math           = { pdf = "Formula"   },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-itemgroup.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-itemgroup.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-itemgroup.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,19 @@
+return {
+
+    name      = "basic pdf specific tagging : itemgroup",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        itemgroup   = { pdf = "L"         },
+        item        = { pdf = "LI"        },
+        itemtag     = { pdf = "Lbl"       },
+        itemcontent = { pdf = "LBody"     },
+        itemhead    = { pdf = "NonStruct" },
+        itembody    = { pdf = "NonStruct" },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-list.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-list.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-list.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,22 @@
+return {
+
+    name      = "basic pdf specific tagging: list",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        -- trying the same as itemgroup
+
+        list        = { pdf = "L"         },
+        listitem    = { pdf = "LI"        },
+        listtag     = { pdf = "Lbl"       },
+        listcontent = { pdf = "LBody"     },
+        listdata    = { pdf = "NonStruct" },
+        listpage    = { pdf = "Lbl"       },
+        listtext    = { pdf = "NonStruct" },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-margin.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-margin.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-margin.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,16 @@
+return {
+
+    name      = "basic pdf specific tagging : margin",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+     -- margintextblock = { pdf = "NonStruct" },
+        margintext      = { pdf = "Aside" },
+     -- marginanchor    = { pdf = "NonStruct" },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-section.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-section.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-section.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,94 @@
+-- This is a hack to get around the specifications "We can't expect an application
+-- to keep track of nested H's (but otherwise expect very complex things things to
+-- be properly dealt with)". A typical example of bugs becoming features, standards
+-- being not really standards as they get adapted, etc. That said: it is up to the
+-- user to decide what to do but don't blame us for the resulting less optimal
+-- structure.
+--
+-- Because we don't want to spoil the otherwise rather clean structure in ConTeXt,
+-- this kicks in very late in the backend. We might extend this hackery but there
+-- are limits to what is desired. After all, in over a decade of pdf tagging nothing
+-- significant happened (we're speaking 2024) nor proper viewer support showed up
+-- and we can anyway expect LLM's to deal with proper tags anyway some day.
+--
+-- criterium : parent    : use parent "detail"
+--             parents   : use first in parent "parents" list
+--             otherwise : look at self "detail"
+--
+-- We need violate the proper structure by getting a Hn on the title so we
+-- have to backtrack to what we're in, thereby also denying the proper
+-- section instance. Don't ask. The plural "parents" will make sure we
+-- consult the first in the chain and not the instance that is encoded in
+-- "detail".
+
+local level   = structures.tags.getoption("level")
+local current = 0
+local used    = 0
+
+local function HN(bump)
+    if bump then
+        current = current + 1
+        if current >= level then
+            used = used + 1
+        end
+    end
+    if used > 0 and used < 10 then
+        return "H" .. used
+    else
+        return "NonStruct"
+    end
+end
+
+return {
+
+    name      = "basic pdf specific tagging",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        sectionblock   = { pdf = "NonStruct" },
+
+        -- 1.28.1 1.29.57 (otherwise complaints about P)
+
+        section        = { pdf = "Sect" },
+        sectioncaption = { pdf = "Div"  },
+        sectiontitle   = { pdf = "Lbl"  }, -- Span is fragile
+        sectionnumber  = { pdf = "Lbl"  }, -- Span is fragile
+        sectioncontent = { pdf = "Div"  },
+
+    },
+
+
+    remapping = {
+
+        { element = "sectioncaption", parent = "part",                            pdf = HN(true ) },
+        { element = "sectioncaption", parent = "chapter",                         pdf = HN(true ) },
+        { element = "sectioncaption", parent = "title",                           pdf = HN(false) },
+        { element = "sectioncaption", parent = "section",                         pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subject",                         pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsection",                      pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubject",                   pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsection",                   pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubject",                pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsubsection",                pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubsubject",             pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsubsubsection",             pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsubject",          pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsection",          pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsubsubject",       pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsubsubsection",    pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsubsubsubsubject", pdf = HN(false) },
+
+        { element = "sectionblock",   pdf = "NonStruct" },
+
+        { element = "section",        pdf = "Sect" },
+        { element = "sectioncaption", pdf = "Div"  },
+        { element = "sectiontitle",   pdf = "Lbl"  },
+        { element = "sectionnumber",  pdf = "Lbl"  },
+        { element = "sectioncontent", pdf = "Div"  },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-verbatim.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-verbatim.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-verbatim.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,21 @@
+return {
+
+    name      = "basic pdf specific tagging : verbatim",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        verbatimblock = { pdf = "Div"  },
+        verbatimlines = { pdf = "Code" },
+        verbatimline  = { pdf = "Sub"  },
+        verbatim      = { pdf = "Code" },
+
+     -- lines         = { pdf = "NonStruct" },
+     -- line          = { pdf = "NonStruct" },
+     -- linenumber    = { pdf = "NonStruct" },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-whatever.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-whatever.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic-whatever.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,14 @@
+return {
+
+    name      = "basic pdf specific tagging : whatever",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    mapping   = {
+
+        whatever       = { pdf = "P" },
+
+    },
+
+}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-basic.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,51 @@
+return {
+    name      = "basic pdf specific tagging",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    validated = {
+        {
+            name    = "verapdf",
+            version = "1.29.90",
+            date    = "20250801",
+        },
+    },
+
+    includes  = {
+
+        "basic-combination",
+        "basic-delimited",
+        "basic-description",
+        "basic-float",
+        "basic-formula",
+        "basic-itemgroup",
+        "basic-list",
+        "basic-margin",
+        "basic-section",
+        "basic-verbatim",
+        "basic-whatever",
+
+    },
+
+    endpoints = {
+        Part = "p",
+        Div  = "p",
+        Sect = "p",
+    },
+
+    mapping = {
+
+        -- also in basic
+
+        p         = { pdf = "P",        warning = true },
+        t         = { pdf = "Span",     warning = true },
+        m         = { pdf = "Artifact", warning = true },
+
+        highlight = { pdf = "Artifact" },
+        unit      = { pdf = "Artifact" },
+        narrower  = { pdf = "Div"      },
+        citation  = { pdf = "Artifact" },
+    },
+
+}

Deleted: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-crap.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-crap.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-crap.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1,284 +0,0 @@
-if not modules then modules = { } end modules ['lpdf-tag-imp-crap'] = {
-    version   = 1.001,
-    comment   = "companion to lpdf-tag.mkiv",
-    author    = "Hans Hagen & Mikael Sundqvist",
-    copyright = "PRAGMA ADE / ConTeXt Development Team",
-    license   = "see context related readme files"
-}
-
--- You can enable this at your own risk by saying:
---
--- \enabledirectives[backend.usetags=crap]
---
--- which will try to satisfy the sloppy mapping in pdf. You can also use this file to
--- roll out your own variant. We also use this file for testing so there coule be subtle
--- changes over time.
-
--- Some users want ua2 here so be it ... it doesn't change the crappy nature. Also,
--- out of a sudden validation is picky about NonStruct. We really looked closely at
--- at the spec and it didn't show it being an issue. It makes even more clear that
--- one should just produce HTML and not PDF if needed! A hybrid PDF/HTML mix is just
--- insane.
---
--- As we don't know the endpoint in advance we can't use NonStruct so we go for Div
--- and Span and leave it to users to figure it out depending on their document. Let's
--- assume then can be nested.
-
-return {
-    name      = "old school pdf tagging",
-    version   = "1.00",
-    comment   = "This is our crappy level two mapping, sort of an example.",
-    author    = "Hans Hagen",
-    copyright = "ConTeXt development team",
-    mapping   = {
-
-        -- Part      : no structure
-        -- Sect      : structure
-        -- NonStruct : skip level, no longer okay
-        -- Sub       : line with lbl numbers
-
-        document           = { pua = "ua2", pdf = "Document"   },
-        documentpart       = { pua = "ua2", pdf = "DocumentFragment"  }, -- not in ua1
-
-        division           = { pua = "ua2", pdf = "Part"       },
-        paragraph          = { pua = "ua2", pdf = "P"          },
-        subparagraph       = { pua = "ua2", pdf = "P"          },
-        p                  = { pua = "ua2", pdf = "P"          },
-        highlight          = { pua = "ua2", pdf = "Span"       }, -- not Em as who know what it is.
-        ornament           = { pua = "ua2", pdf = "Span"       },
-        textdisplay        = { pua = "ua2", pdf = "Div"        },
-        placeholder        = { pua = "ua2", pdf = "Span"       },
-
-        ["break"]          = { pua = "ua2", pdf = "Div"        },
-
-        construct          = { pua = "ua2", pdf = "Span"       },
-        constructleft      = { pua = "ua2", pdf = "Span"       },
-        constructright     = { pua = "ua2", pdf = "Span"       },
-        constructcontent   = { pua = "ua2", pdf = "Div"        },
-
-        sectionblock       = { pua = "ua2", pdf = "Part"       },
-
-        section            = { pua = "ua2", pdf = "Sect"       }, -- Part
-        sectioncaption     = { pua = "ua2", pdf = "Div"        },
-        sectiontitle       = { pua = "ua2", pdf = "Span"       },
-        sectionnumber      = { pua = "ua2", pdf = "Lbl"        },
-        sectioncontent     = { pua = "ua2", pdf = "Div"        },
-
-        itemgroup          = { pua = "ua2", pdf = "L"          },
-        item               = { pua = "ua2", pdf = "LI"         },
-        itemtag            = { pua = "ua2", pdf = "Lbl"        },
-        itemcontent        = { pua = "ua2", pdf = "LBody"      },
-        itemhead           = { pua = "ua2", pdf = "Div"        },
-        itembody           = { pua = "ua2", pdf = "Div"        },
-
-        items              = { pua = "ua2", pdf = "Div"        },
-        itemsymbols        = { pua = "ua2", pdf = "Div"        },
-        itemsymbol         = { pua = "ua2", pdf = "Span"       }, -- users  migh ttest Lbl
-        itemtexts          = { pua = "ua2", pdf = "Div"        },
-        itemtext           = { pua = "ua2", pdf = "Span"       },
-
-        description        = { pua = "ua2", pdf = "Sect"       },
-        descriptiontag     = { pua = "ua2", pdf = "Lbl"        },
-        descriptioncontent = { pua = "ua2", pdf = "Div"        },
-        descriptionsymbol  = { pua = "ua2", pdf = "Lbl"        },
-
-        verbatimblock      = { pua = "ua2", pdf = "Part"       },
-        verbatimlines      = { pua = "ua2", pdf = "Part"       },
-        verbatimline       = { pua = "ua2", pdf = "Code"       },
-        verbatim           = { pua = "ua2", pdf = "Code"       },
-
-        lines              = { pua = "ua2", pdf = "Part"       },
-        line               = { pua = "ua2", pdf = "Code"       },
-        linenumber         = { pua = "ua2", pdf = "Span"       },
-
-        synonym            = { pua = "ua2", pdf = "Span"       },
-        sorting            = { pua = "ua2", pdf = "Span"       },
-
-        register           = { pua = "ua2", pdf = "Part"       },
-        registerlocation   = { pua = "ua2", pdf = "Span"       },
-        registersection    = { pua = "ua2", pdf = "Part"       },
-        registertag        = { pua = "ua2", pdf = "Span"       },
-        registerentries    = { pua = "ua2", pdf = "Part"       },
-        registerentry      = { pua = "ua2", pdf = "Part"       },
-        registercontent    = { pua = "ua2", pdf = "Span"       },
-        registersee        = { pua = "ua2", pdf = "Span"       },
-        registerpages      = { pua = "ua2", pdf = "Span"       },
-        registerpage       = { pua = "ua2", pdf = "Span"       },
-        registerseparator  = { pua = "ua2", pdf = "Span"       },
-        registerpagerange  = { pua = "ua2", pdf = "Span"       },
-
-        table              = { pua = "ua2", pdf = "Table"      },
-        tablerow           = { pua = "ua2", pdf = "TR"         },
-        tablecell          = { pua = "ua2", pdf = "TD"         },
-        tableheadcell      = { pua = "ua2", pdf = "TH"         },
-        tablehead          = { pua = "ua2", pdf = "THEAD"      },
-        tablebody          = { pua = "ua2", pdf = "TBODY"      },
-        tablefoot          = { pua = "ua2", pdf = "TFOOT"      },
-
-        tabulate           = { pua = "ua2", pdf = "Table"      },
-        tabulaterow        = { pua = "ua2", pdf = "TR"         },
-        tabulatecell       = { pua = "ua2", pdf = "TD"         },
-        tabulateheadcell   = { pua = "ua2", pdf = "TH"         },
-        tabulatehead       = { pua = "ua2", pdf = "THEAD"      },
-        tabulatebody       = { pua = "ua2", pdf = "TBODY"      },
-        tabulatefoot       = { pua = "ua2", pdf = "TFOOT"      },
-
-        list               = { pua = "ua2", pdf = "TOC"        },
-        listitem           = { pua = "ua2", pdf = "TOCI"       },
-        listtag            = { pua = "ua2", pdf = "Lbl"        },
-        listcontent        = { pua = "ua2", pdf = "Div"        },
-        listdata           = { pua = "ua2", pdf = "Div"        },
-        listpage           = { pua = "ua2", pdf = "Lbl"        },
-        listtext           = { pua = "ua2", pdf = "Span"       },
-
-        delimitedblock     = { pua = "ua2", pdf = "BlockQuote" },
-        delimited          = { pua = "ua2", pdf = "Quote"      },
-        delimitedcontent   = { pua = "ua2", pdf = "Div"        },
-        delimitedsymbol    = { pua = "ua2", pdf = "Span"       },
-
-        subsentence        = { pua = "ua2", pdf = "Span"       },
-        subsentencecontent = { pua = "ua2", pdf = "Span"       },
-        subsentencesymbol  = { pua = "ua2", pdf = "Span"       },
-
-        label              = { pua = "ua2", pdf = "Span"       },
-        number             = { pua = "ua2", pdf = "Span"       },
-
-        float              = { pua = "ua2", pdf = "Part"       }, -- some might like "Aside" more
-        floatcaption       = { pua = "ua2", pdf = "Caption"    },
-        floatlabel         = { pua = "ua2", pdf = "Span"       },
-        floatnumber        = { pua = "ua2", pdf = "Span"       },
-        floattext          = { pua = "ua2", pdf = "Span"       },
-        floatcontent       = { pua = "ua2", pdf = "Div"        },
-
-        image              = { pua = "ua2", pdf = "Figure"     }, -- or just "Span"
-        mpgraphic          = { pua = "ua2", pdf = "Figure"     }, -- or just "Span"
-
-        formulaset         = { pua = "ua2", pdf = "Part"       },
-        formula            = { pua = "ua2", pdf = "Part"       }, -- maybe NonStruct
-     -- math               = { pua = "ua2", pdf = "Formula"    }, -- we deciced not to tag
-        formulacaption     = { pua = "ua2", pdf = "Span"       },
-        formulalabel       = { pua = "ua2", pdf = "Span"       },
-        formulanumber      = { pua = "ua2", pdf = "Span"       },
-        formulacontent     = { pua = "ua2", pdf = "Div"        },
-        subformula         = { pua = "ua2", pdf = "Part"       },
-
-        link               = { pua = "ua2", pdf = "Link"       },
-        reference          = { pua = "ua2", pdf = "Span"       },
-
-        navigation         = { pua = "ua2", pdf = "Div"        },
-        navigationbutton   = { pua = "ua2", pdf = "Span"       },
-        navigationmenu     = { pua = "ua2", pdf = "Div"        },
-        navigationmenuitem = { pua = "ua2", pdf = "Span"       },
-        navigationaction   = { pua = "ua2", pdf = "Span"       },
-        navigationpage     = { pua = "ua2", pdf = "Span"       },
-
-        margintextblock    = { pua = "ua2", pdf = "Aside"      },
-        margintext         = { pua = "ua2", pdf = "Div"        },
-        marginanchor       = { pua = "ua2", pdf = "Span"       },
-
-        linetext           = { pua = "ua2", pdf = "Span"       },
-
-        -- no math here
-
-        ignore             = { pua = "ua2", pdf = "Artifact"   }, -- or just "Div"
-        private            = { pua = "ua2", pdf = "Div"        },
-        metadata           = { pua = "ua2", pdf = "Part"       },
-        metavariable       = { pua = "ua2", pdf = "Span"       },
-
-        mid                = { pua = "ua2", pdf = "Span"       },
-        sub                = { pua = "ua2", pdf = "Span"       },
-        sup                = { pua = "ua2", pdf = "Span"       },
-        subsup             = { pua = "ua2", pdf = "Span"       },
-
-        combination        = { pua = "ua2", pdf = "Table"      },
-        combinationpair    = { pua = "ua2", pdf = "TR"         },
-        combinationcontent = { pua = "ua2", pdf = "TD"         },
-        combinationcaption = { pua = "ua2", pdf = "TD"         },
-
-        publications       = { pua = "ua2", pdf = "Part"       },
-        publication        = { pua = "ua2", pdf = "Div"        },
-        pubfld             = { pua = "ua2", pdf = "Span"       },
-
-        citation           = { pua = "ua2", pdf = "Span"       },
-        cite               = { pua = "ua2", pdf = "Span"       },
-
-        narrower           = { pua = "ua2", pdf = "Part"       },
-
-        block              = { pua = "ua2", pdf = "Part"       },
-
-        userdata           = { pua = "ua2", pdf = "Part"       },
-
-        quantity           = { pua = "ua2", pdf = "Span"       },
-        unit               = { pua = "ua2", pdf = "Span"       },
-
-        verse              = { pua = "ua2", pdf = "Part"       },
-        versetag           = { pua = "ua2", pdf = "Lbl"        },
-        verseseparator     = { pua = "ua2", pdf = "Span"       },
-        versecontent       = { pua = "ua2", pdf = "Div"        },
-
-    },
-
-    -- This is a hack to get around the specifications "We can't expect an
-    -- application to keep track of nested H's (but otherwise expect very complex
-    -- things things to be properly dealt with)". A typical example of bugs
-    -- becoming features, standards being not really standards as they get
-    -- adapted, etc. That said: it is up to the user to decide what to do but
-    -- don't blame us for the resulting less optimal structure.
-
-    -- Because we don't want to spoil the otherwise rather clean structure in
-    -- ConTeXt, this kicks in very late in the backend. We might extend this
-    -- hackery but there are limits to what is desired. After all, in over a
-    -- decade of pdf tagging nothing significant happened (we're speaking 2024)
-    -- nor proper viewer support showed up and we can anyway expect LLM's to deal
-    -- with proper tags anyway some day.
-
-    overloads = {
-
-        -- criterium : parent    : use parent "detail"
-        --             parents   : use first in parent "parents" list
-        --             otherwise : look at self "detail"
-
-        -- We need violate the proper structure by getting a Hn on the title so we
-        -- have to backtrack to what we're in, thereby also denying the proper
-        -- section instance. Don't ask. The plural "parents" will make sure we
-        -- consult the first in the chain and not the instance that is encoded in
-        -- "detail".
-
-        sectioncaption = {
-            criterium = "parents",
-            mapping   = {
-
-                part                         = { pua = "ua2", tag = "section_title_1",  pdf = "H1"  },
-
-                chapter                      = { pua = "ua2", tag = "section_title_2",  pdf = "H2"  },
-                title                        = { pua = "ua2", tag = "subject_title_2",  pdf = "H2"  },
-
-                section                      = { pua = "ua2", tag = "section_title_3",  pdf = "H3"  },
-                subject                      = { pua = "ua2", tag = "subject_title_3",  pdf = "H3"  },
-
-                subsection                   = { pua = "ua2", tag = "section_title_4",  pdf = "H4"  },
-                subsubject                   = { pua = "ua2", tag = "subject_title_4",  pdf = "H4"  },
-
-                subsubsection                = { pua = "ua2", tag = "section_title_5",  pdf = "H5"  },
-                subsubsubject                = { pua = "ua2", tag = "subject_title_5",  pdf = "H5"  },
-
-                subsubsubsection             = { pua = "ua2", tag = "section_title_6",  pdf = "H6"  },
-                subsubsubsubject             = { pua = "ua2", tag = "subject_title_6",  pdf = "H6"  },
-
-                subsubsubsubsection          = { pua = "ua2", tag = "section_title_7",  pdf = "H7"  },
-                subsubsubsubsubject          = { pua = "ua2", tag = "subject_title_7",  pdf = "H7"  },
-
-                subsubsubsubsubsection       = { pua = "ua2", tag = "section_title_8",  pdf = "H8"  },
-                subsubsubsubsubsubject       = { pua = "ua2", tag = "subject_title_8",  pdf = "H8"  },
-
-                subsubsubsubsubsubsection    = { pua = "ua2", tag = "section_title_9",  pdf = "H9"  },
-                subsubsubsubsubsubsubject    = { pua = "ua2", tag = "subject_title_9",  pdf = "H9"  },
-
-                subsubsubsubsubsubsubsection = { pua = "ua2", tag = "section_title_10", pdf = "H10" },
-                subsubsubsubsubsubsubsubject = { pua = "ua2", tag = "subject_title_10", pdf = "H10" },
-
-            },
-        },
-    },
-
-}

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-demo.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-demo.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-demo.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,93 @@
+local level   = structures.tags.getoption("level")
+local current = 0
+local used    = 0
+
+local function HN(bump)
+    if bump then
+        current = current + 1
+        if current >= level then
+            used = used + 1
+        end
+    end
+    if used > 0 and used < 10 then
+        return "H" .. used
+    else
+        return "NonStruct"
+    end
+end
+
+return {
+    name      = "pdf specific tagging : demo",
+    version   = "1.00",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "ConTeXt development team",
+
+    validated = {
+        {
+            name    = "verapdf",
+            version = "1.29.90",
+            date    = "20250801",
+        },
+    },
+
+    includes  = {
+        "basic-combination",
+        "basic-delimited",
+        "basic-description",
+        "basic-float",
+        "basic-formula",
+        "basic-itemgroup",
+        "basic-list",
+        "basic-margin",
+--         "basic-section",
+        "basic-verbatim",
+    },
+
+    endpoints = {
+        Part = "p",
+        Div  = "p",
+        Sect = "p",
+    },
+
+    mapping = {
+
+        p = { pdf = "P",        warning = true },
+        t = { pdf = "Span",     warning = true },
+        m = { pdf = "Artifact", warning = true },
+
+-- dummy     = { pdf = "P"  },
+-- navigationpage     = { pdf = "Reference"  },
+-- reference     = { pdf = "Link"  },
+
+    },
+
+    remapping = {
+
+        { element = "sectioncaption", parent = "chapter",                         pdf = HN(true ) },
+        { element = "sectioncaption", parent = "title",                           pdf = HN(false) },
+        { element = "sectioncaption", parent = "section",                         pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subject",                         pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsection",                      pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubject",                   pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsection",                   pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubject",                pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsubsection",                pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubsubject",             pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsubsubsection",             pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsubject",          pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsection",          pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsubsubject",       pdf = HN(false) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsubsubsection",    pdf = HN(true ) },
+        { element = "sectioncaption", parent = "subsubsubsubsubsubsubsubsubject", pdf = HN(false) },
+
+        { element = "sectionblock",   pdf = "NonStruct" },
+
+        { element = "section",        pdf = "Sect" },
+        { element = "sectioncaption", pdf = "Div"  },
+        { element = "sectiontitle",   pdf = "Lbl"  },
+        { element = "sectionnumber",  pdf = "Lbl"  },
+        { element = "sectioncontent", pdf = "Div"  },
+
+    }
+
+}

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-mkiv.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-mkiv.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-mkiv.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -18,182 +18,182 @@
     copyright = "ConTeXt development team",
     mapping   = {
 
-        document           = { pua = "ua1", pdf = "Document"   },
-        documentpart       = { pua = "ua1", pdf = "Div"        },
+        document           = { pdf = "Document"   },
+        documentpart       = { pdf = "Div"        },
 
-        division           = { pua = "ua1", pdf = "Div"        },
-        paragraph          = { pua = "ua1", pdf = "P"          },
-        p                  = { pua = "ua1", pdf = "P"          },
-        highlight          = { pua = "ua1", pdf = "Span"       },
-        ornament           = { pua = "ua1", pdf = "Span"       },
-        textdisplay        = { pua = "ua1", pdf = "Div"        },
-        placeholder        = { pua = "ua1", pdf = "Span"       },
+        division           = { pdf = "Div"        },
+        paragraph          = { pdf = "P"          },
+        p                  = { pdf = "P"          },
+        highlight          = { pdf = "Span"       },
+        ornament           = { pdf = "Span"       },
+        textdisplay        = { pdf = "Div"        },
+        placeholder        = { pdf = "Span"       },
 
-     -- ["break"]          = { pua = "ua1", pdf = "Div"        },
+     -- ["break"]          = { pdf = "Div"        },
 
-        construct          = { pua = "ua1", pdf = "Span"       },
-        constructleft      = { pua = "ua1", pdf = "Span"       },
-        constructright     = { pua = "ua1", pdf = "Span"       },
-        constructcontent   = { pua = "ua1", pdf = "Span"       },
+        construct          = { pdf = "Span"       },
+        constructleft      = { pdf = "Span"       },
+        constructright     = { pdf = "Span"       },
+        constructcontent   = { pdf = "Span"       },
 
-        sectionblock       = { pua = "ua1", pdf = "Div"        },
+        sectionblock       = { pdf = "Div"        },
 
-        section            = { pua = "ua1", pdf = "Sect"       },
-        sectioncaption     = { pua = "ua1", pdf = "H"          },
-        sectiontitle       = { pua = "ua1", pdf = "Span"       },
-        sectionnumber      = { pua = "ua1", pdf = "Span"       },
-        sectioncontent     = { pua = "ua1", pdf = "Div"        },
+        section            = { pdf = "Sect"       },
+        sectioncaption     = { pdf = "H"          },
+        sectiontitle       = { pdf = "Span"       },
+        sectionnumber      = { pdf = "Span"       },
+        sectioncontent     = { pdf = "Div"        },
 
-        itemgroup          = { pua = "ua1", pdf = "L"          },
-        item               = { pua = "ua1", pdf = "LI"         },
-        itemtag            = { pua = "ua1", pdf = "Lbl"        },
-        itemcontent        = { pua = "ua1", pdf = "LBody"      },
-        itemhead           = { pua = "ua1", pdf = "Div"        },
-        itembody           = { pua = "ua1", pdf = "Div"        },
+        itemgroup          = { pdf = "L"          },
+        item               = { pdf = "LI"         },
+        itemtag            = { pdf = "Lbl"        },
+        itemcontent        = { pdf = "LBody"      },
+        itemhead           = { pdf = "Div"        },
+        itembody           = { pdf = "Div"        },
 
-        items              = { pua = "ua1", pdf = "Div"        },
-        itemsymbols        = { pua = "ua1", pdf = "Div"        },
-        itemsymbol         = { pua = "ua1", pdf = "Span"       },
-        itemtexts          = { pua = "ua1", pdf = "Div"        },
-        itemtext           = { pua = "ua1", pdf = "Span"       },
+        items              = { pdf = "Div"        },
+        itemsymbols        = { pdf = "Div"        },
+        itemsymbol         = { pdf = "Span"       },
+        itemtexts          = { pdf = "Div"        },
+        itemtext           = { pdf = "Span"       },
 
-        description        = { pua = "ua1", pdf = "Div"        },
-        descriptiontag     = { pua = "ua1", pdf = "Div"        },
-        descriptioncontent = { pua = "ua1", pdf = "Div"        },
-        descriptionsymbol  = { pua = "ua1", pdf = "Span"       },
+        description        = { pdf = "Div"        },
+        descriptiontag     = { pdf = "Div"        },
+        descriptioncontent = { pdf = "Div"        },
+        descriptionsymbol  = { pdf = "Span"       },
 
-        verbatimblock      = { pua = "ua1", pdf = "Div"        },
-        verbatimlines      = { pua = "ua1", pdf = "Div"        },
-        verbatimline       = { pua = "ua1", pdf = "Code"       },
-        verbatim           = { pua = "ua1", pdf = "Code"       },
+        verbatimblock      = { pdf = "Div"        },
+        verbatimlines      = { pdf = "Div"        },
+        verbatimline       = { pdf = "Code"       },
+        verbatim           = { pdf = "Code"       },
 
-        lines              = { pua = "ua1", pdf = "Div"        },
-        line               = { pua = "ua1", pdf = "Code"       },
-        linenumber         = { pua = "ua1", pdf = "Span"       },
+        lines              = { pdf = "Div"        },
+        line               = { pdf = "Code"       },
+        linenumber         = { pdf = "Span"       },
 
-        synonym            = { pua = "ua1", pdf = "Span"       },
-        sorting            = { pua = "ua1", pdf = "Span"       },
+        synonym            = { pdf = "Span"       },
+        sorting            = { pdf = "Span"       },
 
-        register           = { pua = "ua1", pdf = "Div"        },
-        registerlocation   = { pua = "ua1", pdf = "Span"       },
-        registersection    = { pua = "ua1", pdf = "Div"        },
-        registertag        = { pua = "ua1", pdf = "Span"       },
-        registerentries    = { pua = "ua1", pdf = "Div"        },
-        registerentry      = { pua = "ua1", pdf = "Div"        },
-        registercontent    = { pua = "ua1", pdf = "Span"       },
-        registersee        = { pua = "ua1", pdf = "Span"       },
-        registerpages      = { pua = "ua1", pdf = "Span"       },
-        registerpage       = { pua = "ua1", pdf = "Span"       },
-        registerseparator  = { pua = "ua1", pdf = "Span"       },
-        registerpagerange  = { pua = "ua1", pdf = "Span"       },
+        register           = { pdf = "Div"        },
+        registerlocation   = { pdf = "Span"       },
+        registersection    = { pdf = "Div"        },
+        registertag        = { pdf = "Span"       },
+        registerentries    = { pdf = "Div"        },
+        registerentry      = { pdf = "Div"        },
+        registercontent    = { pdf = "Span"       },
+        registersee        = { pdf = "Span"       },
+        registerpages      = { pdf = "Span"       },
+        registerpage       = { pdf = "Span"       },
+        registerseparator  = { pdf = "Span"       },
+        registerpagerange  = { pdf = "Span"       },
 
-        table              = { pua = "ua1", pdf = "Table"      },
-        tablerow           = { pua = "ua1", pdf = "TR"         },
-        tablecell          = { pua = "ua1", pdf = "TD"         },
-        tableheadcell      = { pua = "ua1", pdf = "TH"         },
-        tablehead          = { pua = "ua1", pdf = "THEAD"      },
-        tablebody          = { pua = "ua1", pdf = "TBODY"      },
-        tablefoot          = { pua = "ua1", pdf = "TFOOT"      },
+        table              = { pdf = "Table"      },
+        tablerow           = { pdf = "TR"         },
+        tablecell          = { pdf = "TD"         },
+        tableheadcell      = { pdf = "TH"         },
+        tablehead          = { pdf = "THEAD"      },
+        tablebody          = { pdf = "TBODY"      },
+        tablefoot          = { pdf = "TFOOT"      },
 
-        tabulate           = { pua = "ua1", pdf = "Table"      },
-        tabulaterow        = { pua = "ua1", pdf = "TR"         },
-        tabulatecell       = { pua = "ua1", pdf = "TD"         },
-        tabulateheadcell   = { pua = "ua1", pdf = "TH"         },
-        tabulatehead       = { pua = "ua1", pdf = "THEAD"      },
-        tabulatebody       = { pua = "ua1", pdf = "TBODY"      },
-        tabulatefoot       = { pua = "ua1", pdf = "TFOOT"      },
+        tabulate           = { pdf = "Table"      },
+        tabulaterow        = { pdf = "TR"         },
+        tabulatecell       = { pdf = "TD"         },
+        tabulateheadcell   = { pdf = "TH"         },
+        tabulatehead       = { pdf = "THEAD"      },
+        tabulatebody       = { pdf = "TBODY"      },
+        tabulatefoot       = { pdf = "TFOOT"      },
 
-        list               = { pua = "ua1", pdf = "TOC"        },
-        listitem           = { pua = "ua1", pdf = "TOCI"       },
-        listtag            = { pua = "ua1", pdf = "Lbl"        },
-        listcontent        = { pua = "ua1", pdf = "P"          },
-        listdata           = { pua = "ua1", pdf = "P"          },
-        listpage           = { pua = "ua1", pdf = "Reference"  },
-        listtext           = { pua = "ua1", pdf = "Span"       },
+        list               = { pdf = "TOC"        },
+        listitem           = { pdf = "TOCI"       },
+        listtag            = { pdf = "Lbl"        },
+        listcontent        = { pdf = "P"          },
+        listdata           = { pdf = "P"          },
+        listpage           = { pdf = "Reference"  },
+        listtext           = { pdf = "Span"       },
 
-        delimitedblock     = { pua = "ua1", pdf = "BlockQuote" },
-        delimited          = { pua = "ua1", pdf = "Quote"      },
-        delimitedcontent   = { pua = "ua1", pdf = "Span"       },
-        delimitedsymbol    = { pua = "ua1", pdf = "Span"       },
+        delimitedblock     = { pdf = "BlockQuote" },
+        delimited          = { pdf = "Quote"      },
+        delimitedcontent   = { pdf = "Span"       },
+        delimitedsymbol    = { pdf = "Span"       },
 
-        subsentence        = { pua = "ua1", pdf = "Span"       },
-        subsentencecontent = { pua = "ua1", pdf = "Span"       },
-        subsentencesymbol  = { pua = "ua1", pdf = "Span"       },
+        subsentence        = { pdf = "Span"       },
+        subsentencecontent = { pdf = "Span"       },
+        subsentencesymbol  = { pdf = "Span"       },
 
-        label              = { pua = "ua1", pdf = "Span"       },
-        number             = { pua = "ua1", pdf = "Span"       },
+        label              = { pdf = "Span"       },
+        number             = { pdf = "Span"       },
 
-        float              = { pua = "ua1", pdf = "Div"        },
-        floatcaption       = { pua = "ua1", pdf = "Caption"    },
-        floatlabel         = { pua = "ua1", pdf = "Span"       },
-        floatnumber        = { pua = "ua1", pdf = "Span"       },
-        floattext          = { pua = "ua1", pdf = "Span"       },
-        floatcontent       = { pua = "ua1", pdf = "P"          },
+        float              = { pdf = "Div"        },
+        floatcaption       = { pdf = "Caption"    },
+        floatlabel         = { pdf = "Span"       },
+        floatnumber        = { pdf = "Span"       },
+        floattext          = { pdf = "Span"       },
+        floatcontent       = { pdf = "P"          },
 
-        image              = { pua = "ua1", pdf = "P"          },
-        mpgraphic          = { pua = "ua1", pdf = "P"          },
+        image              = { pdf = "P"          },
+        mpgraphic          = { pdf = "P"          },
 
-        formulaset         = { pua = "ua1", pdf = "Div"        },
-        formula            = { pua = "ua1", pdf = "Div"        },
-        formulacaption     = { pua = "ua1", pdf = "Span"       },
-        formulalabel       = { pua = "ua1", pdf = "Span"       },
-        formulanumber      = { pua = "ua1", pdf = "Span"       },
-        formulacontent     = { pua = "ua1", pdf = "P"          },
-        subformula         = { pua = "ua1", pdf = "Div"        },
+        formulaset         = { pdf = "Div"        },
+        formula            = { pdf = "Div"        },
+        formulacaption     = { pdf = "Span"       },
+        formulalabel       = { pdf = "Span"       },
+        formulanumber      = { pdf = "Span"       },
+        formulacontent     = { pdf = "P"          },
+        subformula         = { pdf = "Div"        },
 
-        link               = { pua = "ua1", pdf = "Link"       },
-        reference          = { pua = "ua1", pdf = "Span"       },
+        link               = { pdf = "Link"       },
+        reference          = { pdf = "Span"       },
 
-        navigation         = { pua = "ua1", pdf = "Div"        },
-        navigationbutton   = { pua = "ua1", pdf = "Span"       },
-        navigationmenu     = { pua = "ua1", pdf = "Div"        },
-        navigationmenuitem = { pua = "ua1", pdf = "Span"       },
-        navigationaction   = { pua = "ua1", pdf = "Span"       },
-        navigationpage     = { pua = "ua1", pdf = "Span"       },
+        navigation         = { pdf = "Div"        },
+        navigationbutton   = { pdf = "Span"       },
+        navigationmenu     = { pdf = "Div"        },
+        navigationmenuitem = { pdf = "Span"       },
+        navigationaction   = { pdf = "Span"       },
+        navigationpage     = { pdf = "Span"       },
 
-        margintextblock    = { pua = "ua1", pdf = "Span"       },
-        margintext         = { pua = "ua1", pdf = "Span"       },
-        marginanchor       = { pua = "ua1", pdf = "Span"       },
+        margintextblock    = { pdf = "Span"       },
+        margintext         = { pdf = "Span"       },
+        marginanchor       = { pdf = "Span"       },
 
-        linetext           = { pua = "ua1", pdf = "Div"        },
+        linetext           = { pdf = "Div"        },
 
        -- no math here
 
-        ignore             = { pua = "ua1", pdf = "Span"       },
-        private            = { pua = "ua1", pdf = "Span"       },
-        metadata           = { pua = "ua1", pdf = "Div"        },
-        metavariable       = { pua = "ua1", pdf = "Span"       },
+        ignore             = { pdf = "Span"       },
+        private            = { pdf = "Span"       },
+        metadata           = { pdf = "Div"        },
+        metavariable       = { pdf = "Span"       },
 
-        mid                = { pua = "ua1", pdf = "Span"       },
-        sub                = { pua = "ua1", pdf = "Span"       },
-        sup                = { pua = "ua1", pdf = "Span"       },
-        subsup             = { pua = "ua1", pdf = "Span"       },
+        mid                = { pdf = "Span"       },
+        sub                = { pdf = "Span"       },
+        sup                = { pdf = "Span"       },
+        subsup             = { pdf = "Span"       },
 
-        combination        = { pua = "ua1", pdf = "Span"       },
-        combinationpair    = { pua = "ua1", pdf = "Span"       },
-        combinationcontent = { pua = "ua1", pdf = "Span"       },
-        combinationcaption = { pua = "ua1", pdf = "Span"       },
+        combination        = { pdf = "Span"       },
+        combinationpair    = { pdf = "Span"       },
+        combinationcontent = { pdf = "Span"       },
+        combinationcaption = { pdf = "Span"       },
 
-        publications       = { pua = "ua1", pdf = "Div"        },
-        publication        = { pua = "ua1", pdf = "Div"        },
-        pubfld             = { pua = "ua1", pdf = "Span"       },
+        publications       = { pdf = "Div"        },
+        publication        = { pdf = "Div"        },
+        pubfld             = { pdf = "Span"       },
 
-        citation           = { pua = "ua1", pdf = "Span"       },
-        cite               = { pua = "ua1", pdf = "Span"       },
+        citation           = { pdf = "Span"       },
+        cite               = { pdf = "Span"       },
 
-        narrower           = { pua = "ua1", pdf = "Div"        },
+        narrower           = { pdf = "Div"        },
 
-        block              = { pua = "ua1", pdf = "Div"        },
+        block              = { pdf = "Div"        },
 
-        userdata           = { pua = "ua1", pdf = "Div"        },
+        userdata           = { pdf = "Div"        },
 
-        quantity           = { pua = "ua1", pdf = "Span"       },
-        unit               = { pua = "ua1", pdf = "Span"       },
+        quantity           = { pdf = "Span"       },
+        unit               = { pdf = "Span"       },
 
-        verse              = { pua = "ua1", pdf = "Div"        },
-        versetag           = { pua = "ua1", pdf = "Span"       },
-        verseseparator     = { pua = "ua1", pdf = "Span"       },
-        versecontent       = { pua = "ua1", pdf = "Span"       },
+        verse              = { pdf = "Div"        },
+        versetag           = { pdf = "Span"       },
+        verseseparator     = { pdf = "Span"       },
+        versecontent       = { pdf = "Span"       },
 
     }
 }

Added: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-uac.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-uac.lmt	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag-imp-uac.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,130 @@
+if not modules then modules = { } end modules ['lpdf-tag-imp-uac'] = {
+    version   = 1.001,
+    comment   = "companion to lpdf-tag.mkiv",
+    author    = "Hans Hagen & Mikael Sundqvist",
+    copyright = "PRAGMA ADE / ConTeXt Development Team",
+    license   = "see context related readme files"
+}
+
+local subruby    = { "Annot", "Artifact", "Em", "Form", "Link", "NonStruct", "Private", "Quote", "Reference", "Span", "Strong", "Sub" }
+local subtable   = { "Artifact", "NonStruct", "Private", "TR" }
+local spanlike   = { "Annot", "Artifact", "BibEntry", "Code", "Em", "FENote", "Figure", "Form", "Formula", "Lbl", "Link", "NonStruct", "Note", "Private", "Quote", "Reference", "Ruby", "Span", "Strong", "Sub", "Warichu", "contentitem" }
+local document   = { "Annot", "Art", "Artifact", "Aside", "BlockQuote", "Code", "Div", "Document", "DocumentFragment", "FENote", "Figure", "Form", "Formula", "Hn", "Index", "L", "Link", "NonStruct", "Note", "P", "Part", "Private", "Sect", "TOC", "Table", "Title" }
+local tablecell  = { "Annot", "Art", "Artifact", "BibEntry", "Code", "Div", "Em", "FENote", "Figure", "Form", "Formula", "Hn", "Index", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Private", "Quote", "Reference", "Ruby", "Sect", "Span", "Strong", "Table", "Warichu", "contentitem" }
+local rubish     = { }
+local tricky     = { "inherited" }
+local somebody   = { "Annot", "Art", "Artifact", "Aside", "BibEntry", "BlockQuote", "Code", "Div", "Em", "FENote", "Figure", "Form", "Formula", "Hn", "Index", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Quote", "Reference", "Ruby", "Sect", "Span", "Strong", "Table", "Warichu", "contentitem" }
+
+structures.tags.states = {
+    -- weird or obsolete
+    ["Caption"]          = "useless",
+    ["H"]                = "obsolete",
+    -- useless and confusing
+    ["Art"]              = "useless",
+    -- useless and obsolete
+    ["TOC"]              = "obsolete",
+    ["TOCI"]             = "obsolete",
+    ["BlockQuote"]       = "obsolete",
+    ["Quote"]            = "obsolete",
+    ["Part"]             = "useless",
+ -- ["Private"]          = true,
+    ["Document"]         = "internal",
+    ["DocumentFragment"] = "useless",
+    -- useless and irrelevant
+    ["Form"]             = "useless",
+    -- internal
+    ["Artifact"]         = "internal",
+    -- internal
+    ["Annot"]            = "internal",
+    ["Link"]             = "internal",
+    ["Reference"]        = "internal",
+    --
+    ["BibEntry"]         = "useless",
+    ["FENote"]           = "useless",
+    ["Note"]             = "useless",
+    ["Index"]            = "useless",
+    ["Title"]            = "useless",
+}
+
+structures.tags.groups = {
+    list    = { "L", "LI", "LBody" },
+    table   = { "Table", "THead", "TFoot", "TBody", "TR", "TD", "TH" },
+    ruby    = { "Ruby", "RB", "RP", "RT" },
+    warichu = { "Warichu", "WP", "WT" },
+    general = { "Hn", "Aside", "Code", "Figure", "Formula", "Hn", "Sect", "Sub" },
+    neutral = { "NonStruct", "Div", "Span", "P", "Private", "Artifact" },
+    tricky  = { "FEnote", "BlockQuote" },
+    styling = { "Em", "Strong" },
+}
+
+local pdfstates      = table.copy(structures.tags.states)      -- a copy just in case we patch is
+local pdfgroups      = table.copy(structures.tags.groups)      -- idem
+local pdfunsupported = table.copy(structures.tags.unsupported) -- idem
+
+return {
+
+    name      = "bad news",
+    version   = "1.00",
+    comment   = "This is just a file we use when documenting.",
+    author    = "Hans Hagen & Mikael Sundqvits",
+    copyright = "ConTeXt development team",
+
+    states      = pdfstates,
+    groups      = pdfgroups,
+    unsupported = pdfunsupported,
+
+    quack     = {
+        ["Annot"]            = { "Annot", "Art", "Artifact", "BibEntry", "Code", "Div", "Em", "FENote", "Figure", "Formula", "Lbl", "Link", "NonStruct", "Note", "Quote", "Ruby", "Sect", "Span", "Strong", "Sub", "Warichu", "contentitem" },
+        ["Art"]              = { "Annot", "Artifact", "Aside", "BlockQuote", "Caption", "Code", "Div", "DocumentFragment", "FENote", "Figure", "Form", "Formula", "Hn", "Index", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Sect", "TOC", "Table", "Title" },
+        ["Artifact"]         = { "Annot", "Art", "Artifact", "Aside", "BibEntry", "BlockQuote", "Code", "Div", "Document", "DocumentFragment", "Em", "FENote", "Figure", "Form", "Formula", "Hn", "Index", "L", "LBody", "LI", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Quote", "RB", "RP", "RT", "Reference", "Ruby", "Sect", "Span", "Strong", "Sub", "TBody", "TD", "TFoot", "TH", "THead", "TOC", "TOCI", "TR", "Table", "Title", "WP", "WT", "Warichu", "contentitem" },
+        ["Aside"]            = { "Annot", "Art", "Artifact", "BlockQuote", "Code", "Div", "Document", "DocumentFragment", "FENote", "Figure", "Form", "Formula", "Hn", "Index", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Reference", "Sect", "TOC", "Table", "contentitem" },
+        ["BibEntry"]         = { "Annot", "Artifact", "Div", "Em", "FENote", "Figure", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Reference", "Span", "Strong", "contentitem" },
+        ["BlockQuote"]       = { "Annot", "Art", "Artifact", "BlockQuote", "Code", "Div", "Document", "DocumentFragment", "FENote", "Figure", "Form", "Formula", "Hn", "Index", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Reference", "Sect", "TOC", "Table", "Title", "contentitem" },
+        ["Caption"]          = rubish,
+        ["Code"]             = { "Annot", "Artifact", "BibEntry", "Div", "Em", "FENote", "Link", "NonStruct", "Note", "Part", "Private", "Reference", "Span", "Strong", "contentitem" },
+        ["Div"]              = tricky,
+        ["Document"]         = document,
+        ["DocumentFragment"] = document,
+        ["Em"]               = spanlike,
+        ["FENote"]           = { "Annot", "Art", "Artifact", "Aside", "BlockQuote", "Code", "Div", "Em", "FENote", "Figure", "Form", "Formula", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Quote", "Reference", "Ruby", "Sect", "Span", "Strong", "Sub", "Table", "Warichu", "contentitem" },
+        ["Figure"]           = somebody,
+        ["Form"]             = { "Artifact", "BibEntry", "Caption", "Div", "FENote", "Lbl", "NonStruct", "Note", "Private", "contentitem" },
+        ["Formula"]          = { "Annot", "Art", "Artifact", "Aside", "BibEntry", "BlockQuote", "Code", "Div", "Em", "FENote", "Figure", "Form", "Formula", "Hn", "Index", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Private", "Quote", "Reference", "Ruby", "Span", "Strong", "Sub", "Table", "Warichu", "contentitem" },
+        ["H"]                = rubish,
+        ["Hn"]               = { "Annot", "Artifact", "BibEntry", "Code", "Em", "FENote", "Figure", "Form", "Formula", "Lbl", "Link", "NonStruct", "Note", "Private", "Quote", "Reference", "Ruby", "Sect", "Span", "Strong", "Sub", "Warichu", "contentitem" },
+        ["Index"]            = { "Annot", "Artifact", "Caption", "Div", "FENote", "Figure", "Formula", "H", "Hn", "L", "NonStruct", "Note", "P", "Part", "Private", "Reference", "Sect", "Table" },
+        ["L"]                = { "Artifact", "L", "LI", "NonStruct", "Private" },
+        ["LBody"]            = { "Annot", "Art", "Artifact", "Aside", "BibEntry", "BlockQuote", "Code", "Div", "Em", "FENote", "Figure", "Form", "Formula", "Hn", "Index", "L", "Link", "NonStruct", "Note", "P", "Part", "Private", "Quote", "Reference", "Ruby", "Sect", "Span", "Strong", "Sub", "Table", "Warichu", "contentitem" },
+        ["LI"]               = { "Artifact", "Div", "LBody", "Lbl", "NonStruct", "Private", "contentitem" },
+        ["Link"]             = { "Annot", "Art", "Artifact", "BibEntry", "Code", "Div", "Em", "FENote", "Figure", "Formula", "Lbl", "NonStruct", "Note", "Private", "Quote", "Reference", "Ruby", "Sect", "Span", "Strong", "Sub", "Warichu", "contentitem" },
+        ["NonStruct"]        = rubish,
+        ["Note"]             = { "Annot", "Art", "Artifact", "Aside", "BibEntry", "BlockQuote", "Code", "Div", "Em", "FENote", "Figure", "Form", "Formula", "Index", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Quote", "Reference", "Ruby", "Sect", "Span", "Strong", "Sub", "Table", "Warichu", "contentitem" },
+        ["P"]                = { "Annot", "Artifact", "BibEntry", "Code", "Em", "FENote", "Figure", "Form", "Formula", "L", "Lbl", "Link", "NonStruct", "Note", "Private", "Quote", "Reference", "Ruby", "Span", "Strong", "Sub", "Table", "Warichu", "contentitem" },
+        ["Part"]             = rubish,
+        ["Private"]          = { "Annot", "Art", "Artifact", "Aside", "BibEntry", "BlockQuote", "Caption", "Code", "Div", "Document", "DocumentFragment", "Em", "FENote", "Figure", "Form", "Formula", "H", "Hn", "Index", "L", "LBody", "LI", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Quote", "RB", "RP", "RT", "Reference", "Ruby", "Sect", "Span", "Strong", "Sub", "TBody", "TD", "TFoot", "TH", "THead", "TOC", "TOCI", "TR", "Table", "Title", "WP", "WT", "Warichu", "contentitem" },
+        ["Quote"]            = spanlike,
+        ["RB"]               = subruby,
+        ["RP"]               = subruby,
+        ["RT"]               = subruby,
+        ["Reference"]        = { "Annot", "Artifact", "BibEntry", "Em", "FENote", "Figure", "Lbl", "Link", "NonStruct", "Note", "Private", "Span", "Strong", "contentitem" },
+        ["Ruby"]             = { "NonStruct", "Private", "RB", "RP", "RT", "contentitem" },
+        ["Sect"]             = { "Annot", "Art", "Artifact", "Aside", "BlockQuote", "Caption", "Code", "Div", "DocumentFragment", "FENote", "Figure", "Form", "Formula", "H", "Hn", "Index", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Sect", "TOC", "Table", "Title" },
+        ["Span"]             = spanlike,
+        ["Strong"]           = spanlike,
+        ["Sub"]              = { "Annot", "Artifact", "BibEntry", "Code", "Em", "FENote", "Figure", "Form", "Formula", "L", "Lbl", "Link", "NonStruct", "Note", "Private", "Quote", "Reference", "Ruby", "Span", "Strong", "Warichu", "contentitem" },
+        ["TBody"]            = subtable,
+        ["TD"]               = tablecell,
+        ["TFoot"]            = subtable,
+        ["TH"]               = tablecell,
+        ["TOC"]              = { "Artifact", "NonStruct", "Part", "Private", "TOC", "TOCI" },
+        ["TOCI"]             = { "Artifact", "Div", "Lbl", "NonStruct", "P", "Private", "Reference", "TOC" },
+        ["TR"]               = { "Artifact", "NonStruct", "Private", "TD", "TH" },
+        ["Table"]            = { "Artifact", "Caption", "NonStruct", "Private", "TBody", "TFoot", "THead", "TR" },
+        ["THead"]            = subtable,
+        ["Title"]            = { "Annot", "Artifact", "Aside", "BibEntry", "Code", "Div", "Em", "FENote", "Figure", "Form", "Formula", "L", "Lbl", "Link", "NonStruct", "Note", "P", "Part", "Private", "Quote", "Reference", "Ruby", "Span", "Strong", "Table", "Warichu", "contentitem" },
+        ["WT"]               = subruby,
+        ["WP"]               = subruby,
+        ["Warichu"]          = { "NonStruct", "Private", "WP", "WT", "contentitem" },
+    },
+
+}

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lpdf-tag.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -6,42 +6,76 @@
     license   = "see context related readme files"
 }
 
+-- todo ; timing
+
+-- We do support tagged pdf but that bit is the worst part of the in itself
+-- impressive 'standard'. It's just a mess. The possible nesting and boundary
+-- conditions are probaly derived from some application with limitations or weird
+-- assumptions about structure. And it didn't get any better over time. Now, it
+-- might be that it's ConTeXt that is complicating matters because - at least that
+-- is the suggestion coming from comments - that other macro packages are pretty
+-- happy with it (even claiming that context is not doing it right and that there
+-- are no issues at all). That said: we have to deal with it somehow, keeping in
+-- mind that the standard changes, even with arguments that stuff gets dropped
+-- because the applications that deal with pdf can't handle for instance nesting (of
+-- e.g. headings). Validators and standards are instable and we don't expect much
+-- from applications that have to deal with it, or we'd already seen that over time.
+
 -- instead of taglist we can have a backpointer to the parent but then
 -- we also need to adapt the export, it might be a bit slower
 --
 -- maybe also make specifications a two dimensional table
 
-local next, type, tonumber = next, type, tonumber
+-- Updated july/august 2025 to match changed in specifations, validation
+-- etc. Musical timestamp: (video) Brad Mehldau performs Elliott Smith's
+-- "Colorbars" (with others), a demonstration that there can still come
+-- something good from that country in free-fall.
+
+local next, type, tonumber, rawget = next, type, tonumber, rawget
 local format, match, gmatch, find, gsub = string.format, string.match, string.gmatch, string.find, string.gsub
-local concat, sortedhash = table.concat, table.sortedhash
+local concat, sortedhash, sortedkeys, setmetatableindex = table.concat, table.sortedhash, table.sortedkeys, table.setmetatableindex
 local lpegmatch, P, S, C = lpeg.match, lpeg.P, lpeg.S, lpeg.C
-local settings_to_hash = utilities.parsers.settings_to_hash
+local settings_to_hash, settings_to_array = utilities.parsers.settings_to_hash, utilities.parsers.settings_to_array
 local formatters = string.formatters
 
 local trace_tags       = false
 local trace_info       = false
+local trace_attribute  = false
 local trace_math       = false
 local trace_blobs      = false
 local trace_internals  = false
 local trace_suspects   = false
+local trace_paragraphs = false
+local trace_objects    = false
 local trace_tree       = false
 
-trackers.register("structures.tags",           function(v) trace_tags      = v end)
-trackers.register("structures.tags.info",      function(v) trace_info      = v end)
-trackers.register("structures.tags.math",      function(v) trace_math      = v attributes.viewerlayers.enable() end) -- somehow has to happen
-trackers.register("structures.tags.blobs",     function(v) trace_blobs     = v end)
-trackers.register("structures.tags.internals", function(v) trace_internals = v end)
-trackers.register("structures.tags.suspects",  function(v) trace_suspects  = v end)
-trackers.register("structures.tags.showtree",  function(v) trace_tree      = v end)
+trackers.register("structures.tags",           function(v) trace_tags       = v end)
+trackers.register("structures.tags.showtree",  function(v) trace_tree       = v end)
+trackers.register("structures.tags.blobs",     function(v) trace_blobs      = v end)
 
+-- These are the visualized ones:
+
+local trace_visualized = false -- once we set one of those below we also check more
+
+trackers.register("structures.tags.info",      function(v) trace_visualized = true ; trace_info       = v end)
+trackers.register("structures.tags.attribute", function(v) trace_visualized = true ; trace_attribute  = v end)
+trackers.register("structures.tags.math",      function(v) trace_visualized = true ; trace_math       = v attributes.viewerlayers.enable() end) -- somehow has to happen
+trackers.register("structures.tags.internals", function(v) trace_visualized = true ; trace_internals  = v end)
+trackers.register("structures.tags.suspects",  function(v) trace_visualized = true ; trace_suspects   = v end)
+trackers.register("structures.tags.paragraphs",function(v) trace_visualized = true ; trace_paragraphs = v end)
+trackers.register("structures.tags.objects",   function(v) trace_visualized = true ; trace_objects    = v end)
+
 local detailedmath = false
 local actualtexts  = { }
 
+local handlelinks  = false
 local checklinks   = true
 
+local c_realpageno <const> = tex.iscount("realpageno")
+
 directives.register("structures.tags.math.detail", function(v) detailedmath = v end)
 
-local report_tags = logs.reporter("backend","tags")
+local report = logs.reporter("backend","tags")
 
 local pdfbackend          = backends.registered.pdf
 local nodeinjections      = pdfbackend.nodeinjections
@@ -57,7 +91,6 @@
 local pdfconstant         = lpdf.constant
 local pdfreference        = lpdf.reference
 local pdfunicode          = lpdf.unicode
-local pdfstring           = lpdf.string
 local pdfmakenametree     = lpdf.makenametree
 
 local addtocatalog        = lpdf.addtocatalog
@@ -103,7 +136,6 @@
 local getnext             = nuts.getnext
 local getlist             = nuts.getlist
 local getchar             = nuts.getchar
-local getwhd              = nuts.getwhd
 local getleader           = nuts.getleader
 local getlanguage         = nuts.getlanguage
 local getruledimensions   = nuts.getruledimensions
@@ -115,8 +147,9 @@
 local copy_node           = nuts.copy
 local tosequence          = nuts.tosequence
 
-local nextnode            = nuts.traversers.node
-local nextcontent         = nuts.traversers.content
+----- nextnode            = nuts.traversers.node
+----- nextcontent         = nuts.traversers.content
+local nextpossible        = nuts.traversers.possible
 
 local structure_kids   -- delayed
 local structure_ref    -- delayed
@@ -135,7 +168,6 @@
 local specifications      = structurestags.specifications
 local usedlabels          = structurestags.labels
 local properties          = structurestags.properties
-local overloads           = structurestags.overloads
 local usewithcare         = structurestags.usewithcare
 
 local pushtag             = structurestags.push
@@ -148,8 +180,103 @@
 local destinations        = { }
 local references          = { }
 
------ tagsplitter         = structurestags.patterns.splitter
+local pdffallback <const> = "Artifact"
 
+structurestags.where = {
+    -- only in 1.7
+    Art              = "ua1",
+    BlockQuote       = "ua1",
+    TOC              = "ua1",
+    TOCI             = "ua1",
+    Index            = "ua1",
+    Private          = "ua1",
+    Quote            = "ua1",
+    Note             = "ua1",
+    Reference        = "ua1",
+    BibEntry         = "ua1",
+    Code             = "ua1",
+    H1               = "ua1",
+    H2               = "ua1",
+    H3               = "ua1",
+    H4               = "ua1",
+    H5               = "ua1",
+    H6               = "ua1",
+    -- only in 2.0
+    DocumentFragment = "ua2",
+    Aside            = "ua2",
+    H7               = "ua2",
+    H8               = "ua2",
+    H9               = "ua2",
+    Title            = "ua2",
+    FENote           = "ua2",
+    Sub              = "ua2",
+    Em               = "ua2",
+    Strong           = "ua2",
+    Artifact         = "ua2",
+    -- rest depends on version
+}
+
+structurestags.unsupported = {
+    -- only in 1.7
+    Art              = true,
+ -- BlockQuote       = true,
+    TOC              = true,
+    TOCI             = true,
+    Index            = true,
+    Quote            = true,
+    Note             = true,
+    Reference        = true,-- internal
+    BibEntry         = true,
+    H                = true,
+    -- only in 2.0
+    DocumentFragment = true,
+    Title            = true,
+ -- FENote           = true,
+    Em               = true,
+    Strong           = true,
+    -- in both
+    Caption          = true,
+    Document         = true, -- internal
+    Form             = true,
+    Annot            = true,
+    Link             = true, -- internal
+}
+
+experiments.register("structures.tags.lr",function()
+    structurestags.unsupported.Link      = false
+    structurestags.unsupported.Reference = false
+end)
+
+structurestags.modes = {
+    H1         = "inline",
+    H2         = "inline",
+    H3         = "inline",
+    H4         = "inline",
+    H5         = "inline",
+    H6         = "inline",
+    H7         = "inline",
+    H8         = "inline",
+    H9         = "inline",
+    Lbl        = "inline",
+ -- Em         = "inline",
+ -- Strong     = "inline",
+    P          = "display",
+    FENote     = "display",
+    BlockQuote = "display",
+    NonStruct  = "mixed",
+    Sect       = "display",
+    Part       = "display",
+}
+
+setmetatableindex(structurestags.where,function(t,k)
+    -- if version 1 then if from 2 -> artifact .. todo
+    local v = version > 1 and "ua2" or "ua1"
+    t[k] = v
+    return v
+end)
+
+----- tagsplitter = structurestags.patterns.splitter
+
 -- We used to have a way to embed mathml and bib blobs independent of tagging but
 -- that was actually never really used. It used attachments and text notes but is
 -- was not really supported by viewers so we never advertized it.
@@ -162,19 +289,40 @@
 local indirectlocalkids   = false
 local indirectglobalkids  = false
 
+do
+
+    local done = false
+
+    experiments.register("structures.tags.indirect",function(v)
+        if done then
+            -- we only permit this once
+        elseif v == "global" then
+            indirectglobalkids = true
+        elseif v == "local" then
+            indirectlocalkids = true
+        elseif v then
+            indirectglobalkids = true
+            indirectlocalkids  = true
+        end
+        done = true
+    end)
+
+end
+
 -- When we are generating more pages this will be invalid but there will be an extra
 -- run anyway due to storing the final value.
 --
--- For some reason links needa struct parent an destinations an object ... smells like
+-- For some reason links need a struct parent and destinations an object ... smells like
 -- application driven stuff.
 
 local pagenumindices      = { }
 local usedpages           = false  -- internal -> structure
+local pagenum             = 0
 
 local linknumoffset       = false
 local linknumindex        = 0
 local linknumindices      = { }
-local linknumentries      = table.setmetatableindex(function(t,refatt)
+local linknumentries      = setmetatableindex(function(t,refatt)
     if not linknumoffset then
         local tagging = job.variables.collected.tagging
         if tagging then
@@ -194,12 +342,10 @@
 
 local function setlinkstructureparent(refatt,objref)
     local p = linknumentries[refatt]
- -- print("SET",refatt,p,objref)
     linknumindices[p] = objref
 end
 
 function codeinjections.getlinkstructureparent(refatt)
- -- print("GET",refatt, linknumentries[refatt])
     return linknumentries[refatt]
 end
 
@@ -212,7 +358,9 @@
         useddestinations = tagging and tagging.destinations or { }
         usedpages        = tagging and tagging.pages        or { }
     end
-    return (internal and useddestinations[internal]) or (page and usedpages[page])
+    return (internal and useddestinations[internal])
+        or (page and usedpages[page])
+--         or usedpages[1]
 end
 
 --
@@ -240,8 +388,15 @@
     mapping[original] = { target, kind or "inline" }
 end
 
-local namespaces = false
+local detailmapping  = { }
+local parentmapping  = { }
+local directmapping  = { }
+local warnedmapping  = { }
+local usernamespaces = { }
+local usernamecount  = 0
 
+-- local namespaces = false
+
 local namespaces = {
     mathml = {
         url   = "http://www.w3.org/1998/Math/MathML",
@@ -248,29 +403,45 @@
         force = false,
         known = true,
         map   = { },
+        mod   = { },
+        cap   = { },
     },
     context = {
         url   = "http://www.contextgarden.net/pdf/context",
         map   = { },
+        mod   = { },
+        cap   = { },
     },
+    recovery = {
+        url   = "http://www.contextgarden.net/pdf/recovery",
+        map   = { },
+        mod   = { },
+        cap   = { },
+    },
     user = {
         url   = "http://www.contextgarden.net/pdf/user",
         map   = { },
+        mod   = { },
+        cap   = { },
     },
     ua1 = {
         url   = "http://iso.org/pdf/ssn",
+        mod   = { },
+        cap   = { },
         force = false,
         known = true,
     },
     ua2 = {
         url   = "http://iso.org/pdf2/ssn",
+        mod   = { },
+        cap   = { },
         force = false,
         known = true,
     },
 }
 
-local missingua = table.setmetatableindex(function(t,k)
-    local v = "Div"
+local missingua = setmetatableindex(function(t,k)
+    local v = pdffallback
     t[k] = v
     return v
 end)
@@ -278,55 +449,204 @@
 statistics.register("pdf tags", function()
     local k, v = next(missingua)
     if k then
-        return format("unknown tags mapped to %s: % t",v,table.sortedkeys(missingua))
+        return format("unknown tags mapped to %s: % t",v,sortedkeys(missingua))
     end
 end)
 
 local function concattags(tags)
-    local l = { } -- table.new
     local t = tags.taglist
-    local n = #t
-    for i=1,n do
-        l[i] = t[i] or "ERROR"
+    if t then
+        local l = { } -- table.new
+        local n = #t
+        for i=1,n do
+            l[i] = t[i] or "ERROR"
+        end
+        return concat(l," ",1,n)
+    else
+        return ""
     end
-    return concat(l," ",1,n)
 end
 
-local function checkoverload(tagname,tagnameused,detail,specification)
-    local o = overloads[tagnameused]
-    if o then
-        local d = detail
-        local c = o.criterium
-        if c == "parent" or c == "parents" then
-            local p = specification.taglist[#specification.taglist-1]
-            local s = specifications[p]
-            if c == "parents" then
-                p = s.parents -- special case
-                if p then
-                    d = match(p,"%S+")
-                else
-                    d = s.detail -- just in case
+local modes       = structurestags.modes
+local where       = structurestags.where
+local unsupported = structurestags.unsupported
+
+local function registernamespace(ns,tagnameused)
+    -- user or user-XXXX
+    if ns then
+        local nsp = namespaces[ns]
+        local map
+        local mod
+        local cap
+        if nsp then
+            map = nsp.map
+            mod = nsp.mod
+            cap = nsp.cap
+        else
+            local r = pdfreserveobject()
+            map = { }
+            mod = { }
+            cap = { }
+            nsp = {
+                url = "http://www.contextgarden.net/pdf/user",
+                map = map,
+                mod = mod,
+                cap = cap,
+                num = r,
+                ref = pdfreference(r),
+            }
+            namespaces[ns] = nsp
+        end
+        local u = map[tagnameused]
+        local m = mod[tagnameused]
+        local c = cap[tagnameused]
+        if not u then
+            local uns = usernamespaces[ns]
+            local upd = uns and uns[tagnameused]
+            if upd then
+                local ua = namespaces[where[upd]]
+                ua.force = true
+                u = pdfarray {
+                    pdfconstant(upd),
+                    ua.ref
+                }
+                m = modes[upd]
+                c = upd
+                map[tagnameused] = u
+                mod[tagnameused] = m
+                cap[tagnameused] = c
+            else
+                -- todo : make more efficient
+                local prp = properties[tagnameused]
+                if prp then
+                    ns  = prp.namespace or "context"
+                    upd = prp.pdf
+                    uns = namespaces[ns]
+                    if not uns then
+                        ns  = "recovery"
+                        upd = missingua[tagnameused]
+                        uns = namespaces.recovery
+                    end
+                 else
+                    report("missing definition and/or mapping for tag %a",tagnameused)
+                    ns  = "recovery"
+                    upd = missingua[tagnameused]
+                    uns = namespaces.recovery
                 end
-            else
-                d = s.detail
+                m = modes[upd]
+                c = upd
+                local ua = namespaces[where[upd]]
+                ua.force = true
+                u = pdfarray {
+                    pdfconstant(upd),
+                    ua.ref
+                }
+                uns.map[tagnameused] = u
+                uns.mod[tagnameused] = m
+                uns.cap[tagnameused] = c
             end
         end
-        if d then
-            d = o.mapping[d]
-            if d then
-                tagname     = d.tag
-                tagnameused = tagname
-                detail      = nil
+        return ns, m, c
+    end
+end
+
+local problems = setmetatableindex("table")
+
+statistics.register("problematic tags", function()
+    if next(problems) then
+        report()
+        local maxp = 0
+        local maxa = 0
+        for page, specification in sortedhash(problems) do
+            for i=1,#specification do
+                local s = specification[i]
+                local p = s.parnumber
+                local a = s.attribute
+                if a > maxa then maxa = a end
+                if p > maxp then maxp = p end
             end
         end
+        maxp = (2 + maxp//100) * 2
+        maxa = (2 + maxa//100) * 2
+        local f = formatters["%" .. maxp .. "i  %" .. maxa .. "i : %s : %s"]
+        for page, specification in sortedhash(problems) do
+            for i=1,#specification do
+                local s = specification[i]
+                specification[i] = f(s.parnumber,s.attribute,s.tagname,s.prevtag)
+            end
+            table.sort(specification)
+            local last = false
+            report("page %s:",page)
+            report()
+            for i=1,#specification do
+                local s = specification[i]
+                if s ~= last then
+                    last = s
+                    report(s)
+                end
+            end
+            report()
+            report("check with tracker: structures.trackers.[info|attribute|paragraph]")
+            report()
+        end
     end
-    return tagname, tagnameused, detail
+end)
+
+local function checknamespace(tagname,tagnameused,detail,specification)
+    if detail then
+        local dmap = detailmapping[tagnameused]
+        if dmap then
+            local ns = dmap[detail]
+            if ns then
+                return registernamespace(ns,tagnameused)
+            end
+        end
+    end
+    local pmap = parentmapping[tagnameused]
+    if pmap and specification then
+        local l = specification.taglist
+        if l then
+            local p = l[#l-1]
+            if p then
+                local s = specifications[p]
+                local d = s.detail
+                local ns = pmap[d]
+                if ns then
+                    return registernamespace(ns,tagnameused)
+                end
+            end
+        end
+    end
+    local ns = directmapping[tagnameused]
+    if ns then
+        if warnedmapping[tagnameused] then
+            local p = problems[pagenum]
+            p[#p+1] = specification
+        end
+        return registernamespace(ns,tagnameused)
+    end
+    return registernamespace("context",tagnameused)
 end
 
+local isrolemapped = false
+local forcerolemap = false
+
+directives.register("structures.tags.rolemapped",function(v) isrolemapped = v end)
+directives.register("structures.tags.rolemap",   function(v) forcerolemap = v end)
+
+local function hasendpoints(kids,size)
+    for i=1,size do
+        if type(kids[i]) == "number" then
+            return true
+        end
+    end
+    return false
+end
+
 local function finishstructure()
     if root and #structure_kids > 0 then
-        local nums   = pdfarray()
-        local n      = 0
+        local nums = pdfarray()
+        local n    = 0
         if indirectglobalkids then
             for i=firstintree,lastintree do
                 local ti = tree[i]
@@ -334,7 +654,7 @@
                     n = n + 1 ; nums[n] = i - 1
                     n = n + 1 ; nums[n] = pdfreference(pdfflushobject(ti))
                 else
-                    report_tags("beware: missing page %i in tree", i)
+                    report("beware: missing page %i in tree", i)
                 end
             end
         else
@@ -341,7 +661,7 @@
             for i=firstintree,lastintree do
                 local ti = tree[i]
                 if not ti then
-                    report_tags("beware: missing page %i in tree", i)
+                    report("beware: missing page %i in tree", i)
                 elseif #ti > 0 then
                     n = n + 1 ; nums[n] = i - 1
                     n = n + 1 ; nums[n] = ti
@@ -348,118 +668,106 @@
                 end
             end
         end
-        local usedrolemap    = nil
-        local usednamespaces = nil
-        local originals      = { }
-        if version == 1 then
-            for k, v in next, usedmapping do
-                local k = usedlabels[k] or k
-                local p = properties[k]
-                if p then
-                    local pdf = p.pdf
-                    if not pdf then
-                        pdf = missingua[pdf]
-                    end
-                    local r = pdfconstant(pdf)
-                    if usedrolemap then
-                        usedrolemap[k] = r
-                    else
-                        usedrolemap = pdfdictionary { [k] = r }
-                    end
-                else
-                    report_tags("beware: missing property %s", k)
-                end
-            end
-        else
-            for k, v in next, usedmapping do
-                local k = usedlabels[k] or k
-                local p = properties[k]
-                if p then
-                    local s = p.namespace
-                    local n = namespaces[s]
-                    if n then
+
+        if isrolemapped then
+
+            local usedrolemap    = nil
+            local usednamespaces = nil
+            local originals      = { }
+            if version == 1 or forcerolemap then
+                for k, v in next, usedmapping do
+                    local k = usedlabels[k] or k
+                    local p = properties[k]
+                    if p then
                         local pdf = p.pdf
-                        local pua = p.pua
-                        local ua  = n
                         if not pdf then
                             pdf = missingua[pdf]
                         end
-                        if pua == "ua1" then
-                            ua = namespaces.ua1
-                            ua.force = true
-                        elseif pua == "mathml" then
-                            ua = namespaces.mathml
-                            ua.force = true
+                        local r = pdfconstant(pdf)
+                        if usedrolemap then
+                            usedrolemap[k] = r
                         else
-                            ua = namespaces.ua2
-                            ua.force = true
+                            usedrolemap = pdfdictionary { [k] = r }
                         end
-                        --
-                        -- Another piece of mid 2025 crap that we now always need to add but we keep
-                        -- the test commented as reference. The more bloat the better I guess.
-                        --
-                     -- if pdf ~= k then
-                            ua = pdfarray { pdfconstant(pdf), ua.ref }
-                            n.map[k] = ua
-                     -- end
-                        --
-                        if not usednamespaces then
-                            usednamespaces = pdfarray()
-                        end
-                        --
-                        local original = p.original
-                        if original then
-                            local o = originals[s]
-                            if not o then
-                                o = pdfdictionary()
-                                originals[s] = o
+                    else
+                        report("beware: missing property %s", k)
+                    end
+                end
+            end
+            if version > 1 then
+                for k, v in next, usedmapping do
+                    local k = usedlabels[k] or k
+                    local p = properties[k]
+                    if p then
+                        local s = p.namespace
+                        local n = namespaces[s]
+                        if n then
+                            local pdf = p.pdf
+                            if not pdf then
+                                pdf = missingua[pdf]
                             end
-                            o[k] = pdfdictionary {
-                                S = pdfconstant(original[1]),
-                                T = pdfstring(original[2]),
-                            }
+                            if not usednamespaces then
+                                usednamespaces = pdfarray()
+                            end
+                            local original = p.original
+                            if original then
+                                local o = originals[s]
+                                if not o then
+                                    o = pdfdictionary()
+                                    originals[s] = o
+                                end
+                                o[k] = pdfdictionary {
+                                    S = pdfconstant(original[1]),
+                                 -- T = pdfstring(original[2]),
+                                    T = pdfunicode(original[2]),
+                                }
+                            end
+                            --
+                        else
+                            report("beware: missing namespace %s", s)
                         end
-                        --
                     else
-                        report_tags("beware: missing namespace %s", s)
+                        report("beware: missing property %s", k)
                     end
-                else
-                    report_tags("beware: missing property %s", k)
                 end
-            end
-            if usednamespaces then
-                for k, v in sortedhash(namespaces) do
-                    local o = originals[k]
-                    if o then
-                        o = pdfreference(pdfflushobject(o))
-                    end
-                    if v.force then
-                        local n = pdfdictionary {
-                            Type           = pdfconstant("Namespace"),
-                            NS             = pdfunicode(v.url),
-                            LMTX_NameSpace = pdfconstant(k),
-                            LMTX_Originals = o,
-                        }
-                        pdfflushobject(v.num,n)
-                        usednamespaces[#usednamespaces+1] = v.ref
-                    else
-                        local map = v.map
-                        if map and next(map) then
-                            local m = pdfreference(pdfflushobject(pdfdictionary(map)))
+                if usednamespaces then
+                    for k, v in sortedhash(namespaces) do
+                        local o = originals[k]
+                        if o then
+                            o = pdfreference(pdfflushobject(o))
+                        end
+                        if v.force then
                             local n = pdfdictionary {
                                 Type           = pdfconstant("Namespace"),
                                 NS             = pdfunicode(v.url),
-                                RoleMapNS      = m,
                                 LMTX_NameSpace = pdfconstant(k),
                                 LMTX_Originals = o,
                             }
                             pdfflushobject(v.num,n)
                             usednamespaces[#usednamespaces+1] = v.ref
+                        else
+                            local map = v.map
+                            if map and next(map) then
+                                local m = pdfreference(pdfflushobject(pdfdictionary(map)))
+                                local n = pdfdictionary {
+                                    Type           = pdfconstant("Namespace"),
+                                    NS             = pdfunicode(v.url),
+                                    RoleMapNS      = m,
+                                    LMTX_NameSpace = pdfconstant(k),
+                                    LMTX_Originals = o,
+                                }
+                                pdfflushobject(v.num,n)
+                                usednamespaces[#usednamespaces+1] = v.ref
+                            end
                         end
                     end
                 end
             end
+
         end
+
+        -- we can split the loop: with and without links
+
         if indirectlocalkids then
             for i=1,nofelements do
                 local fulltag = elementsorder[i]
@@ -466,8 +774,7 @@
                 local element = elements[fulltag]
                 local kids    = element.kids
                 local knum    = element.knum
-
-                if checklinks then
+                if handlelinks and checklinks then
                     local tag = element.tag
                     if tag == "link" then
                         local ref = element.ref
@@ -482,7 +789,7 @@
                     end
                 end
 
-             -- if checklinks then
+             -- if handlelinks and checklinks then
              --     for i=1,#kids do
              --         local d = kids[i]
              --         if type(d) == "table" then
@@ -507,7 +814,8 @@
                 if dict then
                     local dnum = element.dnum
                     local kids = element.kids
-                    if checklinks then
+                    local size = #kids
+                    if handlelinks and checklinks then
                         local tag = element.tag
                         if tag == "link" then
                             local ref = element.ref
@@ -517,15 +825,15 @@
                         elseif tag == "reference" then
                             local des = element.des
                             if des then
-                                referencenumindices[des] = element.dnum
+                                referencenumindices[des] = dnum
                             end
                         elseif tag == "navigationpage" then
-                            pagenumindices[element.pnum] = element.dnum
+                            pagenumindices[element.pnum] = dnum
                         end
                     end
 
-                 -- if checklinks then
-                 --     for i=1,#kids do
+                 -- if handlelinks and checklinks then
+                 --     for i=1,size do
                  --         local d = kids[i]
                  --         if type(d) == "table" then
                  --             local refatt = element.refatt
@@ -539,9 +847,21 @@
                  --     end
                  -- end
 
---                     if #kids == 1 then
---                         dict.K = kids[1] -- always okay ?
---                     end
+                    if size == 1 then
+                        local t = type(kids[1])
+                        if t == "number" then
+                            dict.K = kids[1]
+                     -- elseif t == "table" then
+                     --     -- this needs testing on a complex document
+                     --     dict.K = kids[1]
+                        else
+                            dict.K  = kids[1]
+                            dict.Pg = nil
+                        end
+                    elseif not hasendpoints(kids,size) then
+                        dict.Pg = nil
+                    end
+
                     pdfflushobject(dnum,dict)
                 end
             end
@@ -558,10 +878,7 @@
             pages        = pagenumindices,
         }
         --
-        table.setmetatableindex(linknumindices)
---         for k, v in next, linknumindices do
---             print("CHECK",k,v)
---         end
+        setmetatableindex(linknumindices)
         for k, v in sortedhash(linknumindices) do
             if v then
                 n = n + 1 ; nums[n] = k
@@ -616,11 +933,11 @@
             local specification = specifications[fulltag]
             local pagenumber    = element.pnum
             if n == true and i > 1 and p ~= pagenumber then
-                report_tags("")
+                report("")
             end
             p = pagenumber
             if n == true or n == p then
-                report_tags("% 5i  %3i  %s (%s)",i,pagenumber,concattags(specification),(element.des and "destination") or (element.ref and "reference") or "content")
+                report("% 5i  %3i  %s (%s)",i,pagenumber,concattags(specification),(element.des and "destination") or (element.ref and "reference") or "content")
             end
         end
     end
@@ -630,7 +947,7 @@
             local shared = v[1] and "-" or "+"
             local index  = v[2]
             local text   = v[3]
-            report_tags("blob %s : %5i : %04X : %s",shared,index,index,text)
+            report("blob %s : %5i : %04X : %s",shared,index,index,text)
         end
     end
 
@@ -638,15 +955,18 @@
 
 lpdf.registerdocumentfinalizer(finishstructure,"document structure")
 
-local index, pageref, pagenum, list = 0, nil, 0, nil
+-- pagenum has been moved up
 
+local index      = 0
+local pageref    = nil
+local list       = nil
+local namespaced = false
+
 local pdf_mcr            = pdfconstant("MCR")
 local pdf_struct_element = pdfconstant("StructElem")
 local pdf_s              = pdfconstant("S")
 local pdf_objr           = pdfconstant("OBJR")
 
-local c_realpageno <const> = tex.iscount("realpageno")
-
 local function initializepage()
     index   = 0
     pagenum = texgetcount(c_realpageno)
@@ -662,7 +982,7 @@
     -- hm, can be later than 1
     if not firstintree then
         if pagenum > 1 then
-            report_tags("beware: first page in tree is %i", pagenum)
+            report("beware: first page in tree is %i", pagenum)
         end
         firstintree = pagenum
         lastintree  = pagenum
@@ -670,9 +990,10 @@
     if pagenum > lastintree then
         lastintree = pagenum
     else
-     -- report_tags("beware: page order problem in tree at page %i", pagenum)
+     -- report("beware: page order problem in tree at page %i", pagenum)
     end
     tree[pagenum] = list -- we can flush after done, todo
+    --
 end
 
 local function finishpage()
@@ -703,12 +1024,14 @@
     end
 end
 
-local visualizetags      = nil
-local visualizespecial   = nil
-local visualizeblobs     = nil
-local visualizesuspects  = nil
-local visualizeinternals = nil
-local collectedsuspects  = { }
+local visualizetags       = nil
+local visualizespecial    = nil
+local visualizeblobs      = nil
+local visualizesuspects   = nil
+local visualizeinternals  = nil
+local visualizeparagraphs = nil
+local visualizeobjects    = nil
+local collectedsuspects   = { }
 
 statistics.register("pdf tags", function()
     if #collectedsuspects > 0 then
@@ -719,24 +1042,106 @@
 
 local function checkvisualize()
     if not visualizetags then
-        visualizetags      = nodes.visualizers.register("tags")
-        visualizespecials  = nodes.visualizers.register("specials",nil,nil,2.5,true)
-        visualizeblobs     = nodes.visualizers.register("blobs",nil,nil,2.5,true)
-        visualizesuspects  = nodes.visualizers.register("suspects")
-        visualizeinternals = nodes.visualizers.register("internals")
+        visualizetags       = nodes.visualizers.register("tags")
+        visualizespecials   = nodes.visualizers.register("specials",nil,nil,2.5,true)
+        visualizeblobs      = nodes.visualizers.register("blobs",nil,nil,2.5,true)
+        visualizesuspects   = nodes.visualizers.register("suspects")
+        visualizeinternals  = nodes.visualizers.register("internals")
+        visualizeparagraphs = nodes.visualizers.register("paragraphs")
+        visualizeobjects    = nodes.visualizers.register("objects")
     end
 end
 
-local function tagtracer(name,blob)
+local function tagtracer(name)
     checkvisualize()
     return visualizetags(name), visualizetags()
 end
 
-table.setmetatableindex(tagtracers,function(t,k)
-    t[k] = tagtracer
-    return tagtracer
+setmetatableindex(tagtracers,function(t,k)
+    if trace_attribute then
+        checkvisualize()
+        local visualize = nodes.visualizers.register(k)
+        local v = function(name,specification)
+            local a = specification.attribute
+            if a then
+                name = name .. " " .. a
+            end
+            return visualize(name), visualize()
+        end
+        t[k] = v
+        return v
+    else
+        t[k] = tagtracer
+        return tagtracer
+    end
 end)
 
+local endpoints, getendpoint  do
+
+    local nofendpoints = 0
+    local trace        = false
+
+    endpoints = {
+        Part = "p",
+        Div  = "p",
+        Sect = "p",
+    }
+
+    lpdf.endpoints = endpoints
+
+    local get = function(prev,at,ap,oldmode)
+        local ptag    = prev.tag
+        local capsule = prev.capsule
+        local etag    = endpoints[capsule] -- or capsule
+     -- print("END1",ptag,capsule,etg,prev,mode)
+        if not etag then
+            if capsule == "NonStruct" then
+                local newmode = prev.mode
+                if oldmode == "display" then
+                    if newmode == "display" then
+                        -- okay
+                    else
+                        etag = "m"
+                    end
+                elseif oldmode == "inline" then
+                    if newmode == "inline" then
+                        -- okay
+                    else
+                        etag = "m"
+                    end
+                end
+            end
+        end
+     -- print("END2",ptag,capsule,etg,prev,mode)
+        if not etag then
+            if trace then
+                report("unknown endpoint for %a",ptag)
+            end
+        elseif ptag == etag then
+            -- we're okay
+        else
+            nofendpoints = nofendpoints + 1
+            local bad = etag .. ">" .. nofendpoints
+            specifications[bad] = {
+                tagname   = etag,
+                attribute = at or 0,
+                parnumber = ap or 0,
+                prevtag   = ptag,
+            }
+            if trace then
+                report("adding endpoint %a to %a",etag,ptag)
+            end
+            return bad
+        end
+    end
+
+    getendpoint = get -- we add them by default
+
+    trackers  .register("structures.tags.endpoints", function(v) trace       = v end)
+    directives.register("structures.tags.endpoints", function(v) getendpoint = v and get or false end)
+
+end
+
 local makeelement  do
 
     do
@@ -750,8 +1155,9 @@
 
         function blobfunctions.math(tagname,specification)
             local tagindex = specification.tagindex
-            local id = f_tagid(tagindex)
-            local blob = specification.blob
+            local id       = f_tagid(tagindex)
+            local blob     = specification.blob
+            local af       = nil
             if blob then
                 local blobindex = mathematics.getblobindex("pdf",blob)
                 if blobindex then
@@ -784,7 +1190,7 @@
                         shared[blobindex] = { af, blobindex }
                         btags[blob] = blobindex
                     end
-                    actualtext = mathematics.gettextblob("pdf",specification.language or "en",blob)
+                    local actualtext = mathematics.gettextblob("pdf",specification.language or "en",blob)
                     if actualtext then
                         if trace_blobs then
                             actualtexts[blob] = { index and true or false, blobindex, actualtext }
@@ -834,6 +1240,18 @@
             return visualizesuspects("S " .. "mrow"), visualizesuspects()
         end
 
+        function tagtracers.paragraph(n)
+            checkvisualize()
+            return visualizeparagraphs("P " .. n), visualizeparagraphs()
+        end
+
+        function tagtracers.objects(n)
+            if n then
+                checkvisualize()
+                return visualizeobjects("O " .. n), visualizeobjects()
+            end
+        end
+
         function tagtracers.internallink(internal)
             checkvisualize()
             return visualizeinternals("L " .. internal), visualizeinternals()
@@ -869,12 +1287,13 @@
         local bindex  = 0
         local btags   = { }
 
-        function blobfunctions.cite(tagname,specification)
+        local function citeblobs(tagname,specification)
             local detail = specification.detail
             if detail then
                 local dataset, tag = match(detail,"^(.+)::(.+)$")
                 local index = shared[tag]
-                local id = f_tagid(tag)
+                local id    = f_tagid(tag)
+                local af    = nil
                 if index then
                     af = index[1]
                     btags[tag] = index[2]
@@ -881,7 +1300,7 @@
                 else
                     bindex = bindex + 1
                     local data     = publications.datasets[dataset].luadata[tag] or "no data"
-                    local blobname = f_tagid(tag)
+                    local blobname = id -- f_tagid(tag)
                     local blobfile = f_tagfn(tag)
                     local blobdata = publications.savers.bib(false,false,{ [tag] = data }) -- converttoxml(dataset,true,false,true,false,true,true)
                     af = codeinjections.embedfile {
@@ -901,7 +1320,7 @@
                     shared[tag] = { af, blobname }
                     btags[tag] = blobname
                 end
-                actualtext = publications.meanings[tag]
+                local actualtext = publications.meanings[tag]
                 if actualtext then
                     actualtext = pdfunicode(actualtext)
                 end
@@ -922,12 +1341,110 @@
             return visualizetags(name), visualizetags()
         end
 
+        experiments.register("structure.tags.blobs.cite",function(v)
+            blobfunctions.cite = v and citeblobs or nil
+        end)
+
+        blobfunctions.cite = citeblobs -- enabled by default
+
     end
 
+    do
+
+        local f_tagid = formatters["%s-%s"]      -- todo: auto adapt to nofblobs
+        local f_tagfn = formatters["%s-%s.txt"]
+
+        local shared  = { }
+        local bindex  = 0
+        local btags   = { }
+
+        local delayed = {
+            [interfaces.variables.columns] = true,
+            [interfaces.variables.page   ] = true,
+        }
+
+        local function descriptionblobs(tagname,specification)
+            local detail = specification.detail
+            if detail then
+                local taglist = specification.taglist
+                local fulltag = taglist[#taglist]
+                local indices = structurestags.getdescriptionindex(fulltag)
+                if not indices then
+                    return
+                end
+                local data = structures.lists.collected[indices.listindex]
+                if not data then
+                    return
+                end
+                local tag = indices.noteindex
+                if not delayed[data.references.delay or false] then
+                    return
+                end
+                data = data.titledata.bookmark or data.titledata.title
+                if not data then
+                    return
+                end
+                local index = shared[tag]
+                local id    = f_tagid(detail,tag)
+                local af    = nil
+                if index then
+                    af = index[1]
+                    btags[tag] = index[2]
+                else
+                    bindex = bindex + 1
+                    local blobname = id -- f_tagid(detail,tag)
+                    local blobfile = f_tagfn(detail,tag)
+                    local blobdata = data
+                    af = codeinjections.embedfile {
+                        force          = true,
+                        data           = blobdata, -- gsub(blobdata,"\n+$",""),
+                        name           = blobname,
+                        file           = blobfile,
+                     -- hash           = hash,
+                        hash           = id,
+                        forcereference = true,
+                     -- title          = "whatever",
+                        mimetype       = "application/text",
+                        relation       = "Supplement", -- bah
+                    }
+                 -- af = pdfarray { af } -- maybe also share this
+                    af = pdfreference(pdfflushobject(pdfarray { af })) -- maybe also share this
+                    shared[tag] = { af, blobname }
+                    btags[tag] = blobname
+                end
+                local actualtext = blobname -- blobdata
+                if actualtext then
+                    actualtext = pdfunicode(actualtext)
+                end
+                return id, af, actualtext
+            end
+        end
+
+     -- function tagtracers.description(name,specification)
+     --     checkvisualize()
+     --     local detail = specification.detail
+     --     if detail then
+     --         local tag   = "..."
+     --         local bname = btags[tag]
+     --         if bname then
+     --             return visualizetags("C " .. bname), visualizetags()
+     --         end
+     --     end
+     --     return visualizetags(name), visualizetags()
+     -- end
+
+        experiments.register("structure.tags.blobs.description",function(v)
+            blobfunctions.description = v and descriptionblobs or nil
+        end)
+
+     -- blobfunctions.description = nil-- disabled by default
+
+    end
+
     local lastid = 0
     local f_id   = formatters["%X"]
 
-    local symbols = table.setmetatableindex (
+    local symbols = setmetatableindex (
         { -- None
             ["1"] = "Disc",
             ["2"] = "Circle",
@@ -941,11 +1458,17 @@
         function(t,k) return tonumber(k) and "Unordered" or "Ordered" end
     )
 
+    -- Play safe for the crappy and evolving standard. We want to validate now and
+    -- in the future without ever looking back. So, we always add an endpoint, even
+    -- when it's not needed because we don't know what will change. We use "text" as
+    -- it is a short tag "inline" or "display" could also work weren't it that one
+    -- can't know in advance what a user prefers.
+
+    -- todo: use a plugin model
+
     makeelement = function(fulltag,parent)
         local specification = specifications[fulltag]
-        local tagname       = specification and specification.tagname or "ignore"
-        local tagnameused   = tagname
-        local attributes    = nil
+        local tagname       = specification and specification.tagname or "ignore" -- we always have a specification
         -- some catches .. todo
         if tagname == "ignore" then
             return false
@@ -954,12 +1477,15 @@
             return true
         elseif tagname == "mrow" then -- todo: alttext
             return false
-        elseif tagname == "tabulatecell" then
+        end
+        local tagnameused = tagname
+        local original    = tagname
+        local attributes  = nil
+        if tagname == "tabulatecell" then
             local d = structurestags.gettabulatecell(fulltag)
             if d and d.kind == 1 then
                 tagnameused = "tabulateheadcell"
             end
---         elseif tagname == "tablecell" then
         elseif tagname == "tablecell" then
             -- will become a plugin model
             local d = structurestags.gettablecell(fulltag)
@@ -978,48 +1504,45 @@
                     }
                 end
             end
-        elseif tagname == "itemgroup" then
-            local d = structurestags.getitemgroup(fulltag)
-            if d then
-                local symbol = d.symbol
-                if symbol then
-                    attributes = pdfdictionary {
-                        ListNumbering = pdfconstant(symbols[symbol] or "None"),
-                        ContinuedList = d.continue and true or nil,
-                    }
-                end
-            end
---         elseif tagname == "mtd" then
---             -- only when in detail mode
---             local cols = specification.cols or 1 -- we could set it beforehand ... todo
---             if cols > 1 then
---                 attributes = pdfdictionary {
---                     O       = pdfconstant("Table"),
---                     ColSpan = cols,
---                 }
---             end
-     -- elseif tagname == "math" then
-     --     if specification.mode == "display" then
-     --         tagnameused = "displaymath"
-     --     else
-     --         tagnameused = "inlinemath"
-     --     end
         end
         --
-        local detail     = specification.detail
-        local userdata   = specification.userdata
+        local detail    = specification.detail
+        local userdata  = specification.userdata
+        local namespace = nil
+        local mode      = "mixed"
+        local capsule   = false
         --
         if version == 1 then
             -- not here
+            -- todo: register ns -> rolemap
         else
-            -- ugly hack
-            tagname, tagnameused, detail = checkoverload(tagname,tagnameused,detail,specification)
+            namespace, mode, capsule = checknamespace(tagname,tagnameused,detail,specification)
         end
         --
+        -- needs checking, moved
+        --
+        if tagname == "itemgroup" then
+            local data   = structurestags.getitemgroup(fulltag)
+            local symbol = symbols[data.symbol or "None"] or "None"
+            -- why do we care, we could just go none
+            attributes = pdfdictionary {
+                O             = pdfconstant("List"),
+                ListNumbering = pdfconstant(symbol),
+                ContinuedList = data.continue and true or nil,
+            }
+        elseif capsule == "L" then -- so not in level 1
+            -- We have to add something but not None, so we can have an
+            -- optional setter if needed. For now we just assume Ordered.
+         -- local symbol = props.symbol and symbols[props.symbol] or "Ordered"
+            attributes = pdfdictionary {
+                O             = pdfconstant("List"),
+                ListNumbering = pdfconstant("Ordered"),
+             -- ListNumbering = pdfconstant(symbol),
+            }
+        end
+        --
         usedmapping[tagname] = true
         --
-        -- specification.attribute is unique
-        --
         local af         = nil
         local id         = nil
         local actualtext = nil
@@ -1030,25 +1553,32 @@
                 id, af, actualtext = action(tagname,specification)
             end
         end
-        -- This can be an option but it bloats the file for little reason.
         --
-     -- if not id then
-     --     lastid = lastid + 1
-     --     id = f_id(lastid)
-     -- end
+if tagname == "sorting" then
+    actualtext = structurestags.getsorting(fulltag)
+elseif tagname == "synonym" then
+    actualtext = structurestags.getsynonym(fulltag)
+end
         --
-        local namespace = nil
-        if version > 1 then
-            local p = properties[tagname]
-            if p then
-                namespace = namespaces[p.namespace].ref or nil
-            else
-                namespace = "user"
-                properties[tagname] = { namespace = namespace, pdf = "Span", nature = "inline" }
+
+        if isrolemapped then
+            if version > 1 then
+                if namespace then
+                    namespace = namespaces[namespace].ref or nil
+                else
+                    local p = properties[tagname]
+                    if p then
+                        namespace = namespaces[p.namespace].ref or nil
+                    else
+                        namespace = nil
+                        -- do we need a fallback like:
+                     -- namespace = "user"
+                     -- properties[tagname] = { namespace = namespace, pdf = "Span", nature = "inline" }
+                    end
+                end
             end
         end
-        --
-     -- local alternate = "Who cares"
+
         local kids      = pdfarray()
         local tag       = usedlabels[tagnameused] or tagnameused
         local subtype   = pdfconstant(tag)
@@ -1056,12 +1586,13 @@
         local pkids     = parent.kids
         local element
         local dref, dnum
+        original = original ~= tagnameused and pdfconstant(original) or nil
+        -- Pg : only needed when K is integer or array with integers
         if indirectlocalkids then
             local knum = pdfreserveobject()
             local dict = pdfdictionary {
              -- Type       = pdf_struct_element, -- optional, saves bytes
                 S          = subtype,
-                ID         = id,
                 T          = detail and detail or nil,
                 P          = pref,
                 Pg         = pageref,
@@ -1071,25 +1602,27 @@
                 NS         = namespace,
              -- ActualText = actualtext or nil, -- shared object with Alt?
                 AF         = af or nil,
+                LMTX_S     = original,
             }
             dnum = pdfflushobject(dict)
             dref = pdfreference(dnum)
             element = {
-                blob = af and true or false, -- also actualtext
-                tag  = tag,
-                pnum = pagenum,
-                pref = dref,
-                kids = kids,
-                knum = knum,
-                dnum = dnum,
-                ref  = tag == "link"      and specification.reference   or nil,
-                des  = tag == "reference" and specification.destination or nil,
+                blob    = af and true or false, -- also actualtext
+                tag     = tag,
+                pnum    = pagenum,
+                pref    = dref,
+                kids    = kids,
+                knum    = knum,
+                dnum    = dnum,
+                ref     = tag == "link"      and specification.reference   or nil,
+                des     = tag == "reference" and specification.destination or nil,
+                mode    = mode,
+                capsule = capsule,
             }
         else
             local dict = pdfdictionary {
              -- Type       = pdf_struct_element, -- optional, saves bytes
                 S          = subtype,
-                ID         = id,
                 T          = detail and detail or nil,
                 P          = pref,
                 Pg         = pageref,
@@ -1099,19 +1632,23 @@
                 NS         = namespace,
              -- ActualText = actualtext or nil, -- shared object with Alt?
                 AF         = af or nil,
+                LMTX_S     = original,
+                LMTX_A     = trace_attribute and specification.attribute or nil,
             }
             dnum = pdfreserveobject()
             dref = pdfreference(dnum)
             element = {
-                blob = af and true or false, -- also actualtext
-                tag  = tag,
-                pnum = pagenum,
-                pref = dref,
-                kids = kids,
-                dict = dict,
-                dnum = dnum,
-                ref  = tag == "link"      and specification.reference   or nil,
-                des  = tag == "reference" and specification.destination or nil,
+                blob    = af and true or false, -- also actualtext
+                tag     = tag,
+                pnum    = pagenum,
+                pref    = dref,
+                kids    = kids,
+                dict    = dict,
+                dnum    = dnum,
+                ref     = tag == "link"      and specification.reference   or nil,
+                des     = tag == "reference" and specification.destination or nil,
+                mode    = mode,
+                capsule = capsule,
             }
         end
         if id and names then
@@ -1138,11 +1675,11 @@
     local kids = parent.kids
     local last = index
     index = index + 1
-    if id == "image" then
+    if id == "image" or id == "mpgraphic" then
         -- when we are in \startTEXpage .... \stopTEXpage we have not really
-        -- an element in the end of th elist as all is unstructured
+        -- an element in the end of the list as all is unstructured
         local list  = specification.taglist
-        local data  = usewithcare.images[list[#list]]
+        local data  = usewithcare[id][list[#list]] -- export image generator
         local d = pdfdictionary {
             Type = pdf_mcr,
             Pg   = pageref,
@@ -1150,29 +1687,14 @@
         }
         if data then
             local alt = data.alternativetext or ""
-            parent.dict.Alt = pdfunicode(alt ~= "" and alt or "image")
+            parent.dict.Alt = pdfunicode(alt ~= "" and alt or id)
         else
             -- not really tagged as image
         end
-        kids[#kids+1] = d
+        kids[#kids+1] = pdfreference(pdfflushobject(d))
+     -- kids[#kids+1] = d
     elseif pagenum == parent.pnum then
         kids[#kids+1] = last
-
--- if checklinks and tag == "link" then
---     local ra = range[7]
---     if ra then
---         if not references[ra] then
---             parent.refatt = ra
---             kids[#kids+1] = pdfdictionary {
---                 Type = pdf_objr,
---                 Obj  = pdfreference(0),
---                 Pg   = pageref,
---             }
---             references[ra] = index
---         end
---     end
--- end
-
     else
         local d = pdfdictionary {
             Type = pdf_mcr,
@@ -1179,8 +1701,8 @@
             Pg   = pageref,
             MCID = last,
         }
-     -- kids[#kids+1] = pdfreference(pdfflushobject(d))
-        kids[#kids+1] = d
+        kids[#kids+1] = pdfreference(pdfflushobject(d))
+     -- kids[#kids+1] = d
     end
     --
     list[index] = parent.pref -- page related list
@@ -1189,7 +1711,6 @@
 end
 
 local function makeignore(specification,range)
--- inspect(nodes.tonode(range[3]))
     return "/Artifact BMC"
 end
 
@@ -1217,12 +1738,11 @@
         return head
     elseif not tex.conditionals.c_strc_tags_global then
         return head
---         return
     end
 
---     if not enabled then
---         return
---     end
+ -- if not enabled then
+ --     return head
+ -- end
 
     local pdflanguage = languages.pdflanguage
     local listtoutf   = nodes.listtoutf
@@ -1249,24 +1769,32 @@
     local mblob = false
     local ablob = { }
 
-    if ispage then
+--     dummy link
+
+    if handlelinks and ispage then
         pushtag() -- tag_document_level
-        local ac = starttag("navigationpage")
+starttag("dummy")
+        local ac = starttag("navigationpage", { detail = pagenum } )
+stoptag()
         stoptag()
+        local n = nodepool.boundary()
+        setlink(n,getlist(head))
+        setlist(head,n)
         nofranges = nofranges + 1
-        ranges[nofranges] = { ac, "navigationpage" }
+        ranges[nofranges] = { ac, false, "navigationpage", n, n, head }
         poptag()
     end
 
- -- local function check(n,id)
- --     local at = getattr(n,a_tagged)
- --     if at then
- --         local s = taglist[at]
- --         if s then
- --             print(">>>",nodecodes[id],s.tagname)
- --         end
- --     end
- -- end
+--     if handlelinks and ispage then
+--         pushtag() -- tag_document_level
+-- starttag("dummy")
+--         local ac = starttag("navigationpage", { detail = pagenum } )
+-- stoptag()
+--         stoptag()
+--         nofranges = nofranges + 1
+--         ranges[nofranges] = { ac, false, "navigationpage" }
+--         poptag()
+--     end
 
 -- todo: survive across pages
 
@@ -1273,146 +1801,103 @@
     local lastpar   = 0
     local lastparat = 0
 
+    -- most are glyphs and lists anyway adn those take time
+
     local function collectranges(head,parent)
-        for n, id, subtype in nextnode, head do
+     -- for n, id, subtype in nextnode, head do
+     -- for n, id, subtype, list in nextcontent, head do
+        for n, id, subtype, list in nextpossible, head do
          -- check(n,id)
             if id == glyph_code then
-             -- if getchar(n) ~= 0 then
-                    local at, blob, ap = getattrs(n,a_tagged,a_mathblob,a_taggedpar)
-                    if at == 0 then
-                        at = false
-                    elseif at == 1 then
-                        at = false
-                    elseif at then
-                        --
-                    else
-                        at = false
-                    end
-
-                 -- if detailedmath then
-                 --     -- skip
-                 -- elseif blob then
-                 --     if blob == mblob then
-                 --         ranges[nofranges] = range
-                 --         last = at
-                 --     else
-                 --         mblob = blob
-                 --     end
-                 -- else
-                 --     mblob = false
-                 -- end
-                 -- if last ~= at then
-                 --     range = { at, "glyph", n, n, parent, blob } -- attr id start stop list
-                 --     nofranges = nofranges + 1
-                 --     ranges[nofranges] = range
-                 --     last = at
-                 -- elseif range then
-                 --     range[4] = n -- stop
-                 -- end
-
-                    if not blob then
-                        mblob = false
-                        if last ~= at then
--- print("A",lastpar,ap,getattr(n,a_taggedpar),last,at,utf.char(nuts.getchar(n)))
-                            range = { at, "glyph", n, n, parent } -- attr id start stop list
+                -- we no longer intercept char 0 here
+                local at, blob, ap = getattrs(n,a_tagged,a_mathblob,a_taggedpar)
+                if at == 0 then
+                    at = false
+                elseif at == 1 then
+                    at = false
+                elseif at then
+                    --
+                else
+                    at = false
+                end
+                -- no check for detailed math, see archive (2025-07)
+                if not blob then
+                    mblob = false
+                    if last ~= at then
+                        range = { at, ap or 0, "glyph", n, n, parent } -- attr id start stop list
+                        nofranges = nofranges + 1
+                        ranges[nofranges] = range
+                        last = at
+                        lastparat = at
+                        lastpar = ap
+                    elseif range then
+                        if lastpar ~= ap and at and lastparat == at then
+                         -- local specification = taglist[at]
+                            pushtag(at < tag_document_level and tag_document_level or at)
+                            local ac = starttag("break")
+                            stoptag()
+                            poptag()
+                            range = { ac, ap or 0, "break", n, false }
                             nofranges = nofranges + 1
                             ranges[nofranges] = range
+                            lastpar = ap
+                            range = { at, ap or 0, "glyph", n, n, parent } -- , false, false, ap } -- attr id start stop list
+                            nofranges = nofranges + 1
+                            ranges[nofranges] = range
                             last = at
                             lastparat = at
-                            lastpar = ap
-                        elseif range then
--- print("B",lastpar,ap,getattr(n,a_taggedpar),at,lastparat,utf.char(nuts.getchar(n)))
-                            if lastpar ~= ap and at and lastparat == at then
-                             -- local specification = taglist[at]
-                                pushtag(at < tag_document_level and tag_document_level or at)
-                                local ac = starttag("break")
-                                stoptag()
-                                poptag()
-                                range = { ac, "break", n, false }
-                                nofranges = nofranges + 1
-                                ranges[nofranges] = range
-
-                                lastpar = ap
-                                range = { at, "glyph", n, n, parent } -- , false, false, ap } -- attr id start stop list
-                                nofranges = nofranges + 1
-                                ranges[nofranges] = range
-                                last = at
-                                lastparat = at
-                            else
--- print("C",lastpar,ap,at,lastparat,utf.char(nuts.getchar(n)))
-                                range[4] = n -- stop
-                            end
+                        else
+                            range[5] = n -- stop
                         end
--- inspect(ranges)
-                 -- elseif blob == mblob and at == last then
-                    elseif blob == mblob and (last and last > 0) then
-                        if range then
-                            range[4] = n -- stop
-                        end
-                        last = at
-                    else
-                        mblob = blob
-                     -- if last ~= at then
-                            local a = ablob[blob]
-                            if not a then
-                                a = tag_document_level
-                                if at then
-                                    local t = taglist[at].taglist
-                                 -- for i=#t,1,-1 do
-                                 --     local s = specifications[t[i]]
-                                 --     if s.tagname == "math" then
-                                 --         a = s.attribute
-                                 --     end
-                                 -- end
-                                 -- we could store the index in specifications but we only need it once
-                                    for i=1,#t do
-                                        local s = specifications[t[i]]
-                                        if s.tagname == "math" then
-                                            a = s.attribute
-                                            break
-                                        end
-                                    end
+                    end
+                elseif blob == mblob and (last and last > 0) then
+                    if range then
+                        range[5] = n -- stop
+                    end
+                    last = at
+                else
+                    mblob = blob
+                    local a = ablob[blob]
+                    if not a then
+                        a = tag_document_level
+                        if at then
+                            local t = taglist[at].taglist
+                            -- no check for simple math, see archive (2025-07)
+                            -- we could store the index in specifications but we only need it once
+                            for i=1,#t do
+                                local s = specifications[t[i]]
+                                if s.tagname == "math" then
+                                    a = s.attribute
+                                    break
                                 end
-                                ablob[blob] = a
                             end
-                            range = { a, "math", n, n, parent, blob } -- attr id start stop list
-                            nofranges = nofranges + 1
-                            ranges[nofranges] = range
-                            last = at
-                     -- elseif range then
-                     --     range[4] = n -- stop
-                     -- end
+                        end
+                        ablob[blob] = a
                     end
-
-             -- end
+                    range = { a, ap or 0, "math", n, n, parent, blob } -- attr id start stop list
+                    nofranges = nofranges + 1
+                    ranges[nofranges] = range
+                    last = at
+                end
             elseif id == hlist_code or id == vlist_code then
                 local at, img = getattrs(n,a_tagged,a_image)
-                -- img can be more generic: image, mpgraphic
+                -- todo: img id 3 == mp
                 if img then
-                    range = { at or false, "image", n, n, parent } -- attr id start stop list
+                 -- combine i.e. store img number
+                    range = { at or false, false, img == 3 and "mpgraphic" or "image", n, n, parent } -- attr id start stop list
                     nofranges = nofranges + 1
                     ranges[nofranges] = range
                     last = tag_image_state
                     mblob = false
-                    --
-                    -- TODO, plugin
-                    --
-                    local specification = taglist[at] -- todo: img attr
-                    if specification and specification.tagname == "mpgraphic" then
-                        local list = getlist(n)
-                        if list then
-                            collectranges(list,n)
-                        end
-                    end
-                    --
                 elseif at == 0 then
-                    range = { false, "ignore", n, n, parent } -- attr id start stop list
+                    range = { false, false, "ignore", n, n, parent } -- attr id start stop list
                     nofranges = nofranges + 1
                     ranges[nofranges] = range
                     last = tag_ignore_state
                     mblob = false
                 else -- 1 also process
-                    if at then
+                    -- at is always true as we already checked for zero
+                    if handlelinks and at then
                         local r, d = getattrs(n,a_reference,a_destination)
                         if r and not references[r] then
                             -- bah
@@ -1421,11 +1906,17 @@
                                 at = ablob[b]
                             end
                             --
+                            -- The wrapping in a dummy is really needed as links can't be in some
+                            -- places, not even when tagged as Artifact but wrapping them in an
+                            -- Artifact actually does work.
+                            --
                             pushtag(at < tag_document_level and tag_document_level or at)
+                            starttag("dummy", { })
                             local ac = starttag("link", { reference = r })
                             stoptag()
+                            stoptag()
                             poptag()
-                            range = { ac, "link", n, false, parent } -- attr id start stop list
+                            range = { ac, false, "link", n, false, parent } -- attr id start stop list
                             nofranges = nofranges + 1
                             ranges[nofranges] = range
                             last = tag_link_state
@@ -1442,7 +1933,7 @@
                             local ac = starttag("reference", { destination = d })
                             stoptag()
                             poptag()
-                            range = { ac, "reference", n, false, parent } -- attr id start stop list
+                            range = { ac, false, "reference", n, false, parent } -- attr id start stop list
                             nofranges = nofranges + 1
                             ranges[nofranges] = range
                             last = tag_reference_state
@@ -1450,7 +1941,7 @@
                             destinations[d] = true -- ac
                         end
                     end
-                    local list = getlist(n)
+                 -- local list = getlist(n)
                     if list then
                         collectranges(list,n)
                     end
@@ -1459,12 +1950,13 @@
          --     -- can't happen
             elseif id == glue_code then
                 if subtype >= leaders_code then
-                    local leader = getleader(n)
-                    if leader then
-                        collectranges(leader,n)
+                 -- local list = getleader(n)
+                    if list then
+                        collectranges(list,n)
                     end
                 end
             elseif id == rule_code then
+                -- This is nasty: struts are also changing the state!
                 if subtype == empty_rule_code then
                     -- skip
                 else
@@ -1484,7 +1976,7 @@
                                 at = false
                             end
                             if last ~= tag_rule_state and last ~= at then
-                                range = { false, "rule", n, n, parent, blob } -- attr id start stop list
+                                range = { false, false, "rule", n, n, parent, blob } -- attr id start stop list
                                 nofranges = nofranges + 1
                                 ranges[nofranges] = range
                                 last = at
@@ -1491,7 +1983,7 @@
                                 last = tag_rule_state
                                 mblob = false
                             elseif range then
-                                range[4] = n -- stop
+                                range[5] = n -- stop
                             end
                      -- end
                     else
@@ -1505,19 +1997,16 @@
     collectranges(head)
 
     if trace_tags then
-        report_tags("")
-        report_tags(ispage and "begin page" or "begin object")
-        report_tags("")
+        report("")
+        report(ispage and "begin page" or "begin object")
+        report("")
         for i=1,nofranges do
             local range = ranges[i]
             local attr  = range[1]
-            local id    = range[2]
-            local start = range[3]
-            local stop  = range[4]
-         -- local blob  = range[6]
-         -- local par   = range[8]
+            local id    = range[3]
+            local start = range[4]
+            local stop  = range[5]
             local pdf   = ""
-
          -- if trace_tags == "pdf" then
          --     local specification = taglist[attr]
          --     if attr then
@@ -1536,28 +2025,27 @@
          --         end
          --     end
          -- end
-
             local tags  = taglist[attr]
             if tags then -- not ok ... only first lines
                 local s = concattags(tags)
                 if id == "reference" then
-                    report_tags("R %5i %s%s",attr,s,pdf)
+                    report("R %5i %s%s",attr,s,pdf)
                 elseif id == "link" then
-                    report_tags("L %5i %s%s",attr,s,pdf)
+                    report("L %5i %s%s",attr,s,pdf)
                 elseif id == "break" then
-                    report_tags("B %5i %s%s",attr,s,pdf)
+                    report("B %5i %s%s",attr,s,pdf)
                 elseif id == "navigationpage" then
-                    report_tags("P %5i %s : %i%s",attr,s,pagenum or 0,pdf)
+                    report("P %5i %s : %i%s",attr,s,pagenum or 0,pdf)
                 else
-                    report_tags("T %5i %s : %s%s",attr,s,listtoutf(start,false,true,stop),pdf)
+                    report("T %5i %s : %s%s",attr,s,listtoutf(start,false,true,stop),pdf)
                 end
             else
-                report_tags("-------")
+                report("-------")
             end
         end
-        report_tags("")
-        report_tags(ispage and "end page" or "end object")
-        report_tags("")
+        report("")
+        report(ispage and "end page" or "end object")
+        report("")
     end
 
     local top    = nil
@@ -1565,7 +2053,7 @@
 
     local blobdone = { }
 
-    local function inject(start,stop,list,literal,left,right)
+    local function inject(start,stop,list,literal,left,right) -- can move out
         local prev = getprev(start)
         if prev then
             setlink(prev,literal)
@@ -1603,15 +2091,6 @@
         end
     end
 
-    -- not ok (probably when at the start)
-
---     local function inject(start,stop,list,literal,left,right)
---         setlink(getprev(start) or list or true,literal,left or true,start)
---         setlink(stop,right or true,copy_node(EMCliteral),getnext(stop))
---     end
-
--- inspect(ranges)
-
     local language = texgetcount("mainlanguagenumber")
 
     for i=1,nofranges do
@@ -1618,21 +2097,17 @@
 
         local range = ranges[i]
         local mblob = false
-
         local attr  = range[1]
-        local id    = range[2]
-        local start = range[3]
-        local stop  = range[4]
-        local list  = range[5]
-     -- local blob = range[6]
---         local par   = range[8]
+        local id    = range[3]
+        local start = range[4]
+        local stop  = range[5]
+        local list  = range[6]
         if attr == 0 then -- should be false then
             local literal = setstate(makeignore(false,range))
             inject(start,stop,list,literal)
         elseif attr then
+            local blob = range[7]
 
-            local blob = range[6]
-
             local specification = taglist[attr]
             local currentlist   = specification.taglist
             local noftags       = #currentlist
@@ -1686,9 +2161,27 @@
                     end
                 end
             end
-
             if prev then
-
+                -- We run backwards. Integrating in the above loops also takes time
+                -- and adds tests too so we have to suffer this performance hit.
+                local pmode = false
+                local cmode = prev.mode
+                for i=noftags-1,1,-1 do
+                    local e = elements[currentlist[i]]
+                    local m = e.mode
+                    if m and m ~= "mixed" then
+                        pmode = m
+                        break
+                    end
+                end
+             -- print("MODE",prev.tag,pmode,cmode)
+                if getendpoint then
+                    local bad = getendpoint(prev,attr,range[2],pmode)
+                    if bad then
+                        prev = makeelement(bad,prev)
+                    end
+                end
+                -- we will do this more explicit
                 if id == "glyph" then
                     -- It makes little sense to check if we change a language as that can happen
                     -- mixed in a running text as well as in nested elements. One should just use
@@ -1702,11 +2195,10 @@
                                 dict.Lang = pdflanguage(lan)
                             end
                      -- else -- unreliable
-                     --     report_tags("confusing language %a range: %s",languagenumbers[lan],listtoutf(start,false,true,stop))
+                     --     report("confusing language %a range: %s",languagenumbers[lan],listtoutf(start,false,true,stop))
                      -- end
                     end
                 end
-
                 literal = setstate(makecontent(start,prev,id,specification,range))
             elseif ignore then
                 literal = setstate(makeignore(specification,range))
@@ -1713,12 +2205,23 @@
             else
                 -- maybe ignore too
             end
-
-            if literal then
+            -- make trace info artifact
+            if not literal then
+                -- skip
+            elseif not trace_visualized then
+                -- no need for checking
+                inject(start,stop,list,literal)
+            else
+                -- a lot of checking
                 local left, right
-                if trace_info or trace_math then
+                if trace_attribute then
                     local name = specification.tagname
                     if name then
+                        left, right = tagtracers[name](name,specification)
+                    end
+                elseif trace_info or trace_math then
+                    local name = specification.tagname
+                    if name then
                         left, right = tagtracers[name](name,specification,trace_math and blob or nil)
                     end
                 end
@@ -1729,7 +2232,7 @@
                         left, right = tagtracers.suspect(name)
                     end
                 end
-                if not left and trace_internals then
+                if handlelinks and not left and trace_internals then
                     if id == "link" then
                         left, right = tagtracers.internallink(attr or 0)
                     elseif id == "reference" then
@@ -1736,12 +2239,24 @@
                         left, right = tagtracers.internalreference(attr or 0)
                     end
                 end
+                if not left and trace_paragraphs then
+                    local p = range[2]
+                    if p then
+                        left, right = tagtracers.paragraph(p)
+                    end
+                end
+                if not left and trace_objects then
+                    if currentlist then
+                        local e = elements[currentlist[#currentlist]]
+                        if e then
+                            left, right = tagtracers.objects(e.dnum)
+                        end
+                    end
+                end
                 inject(start,stop,list,literal,left,right)
             end
-
             top    = currentlist
             noftop = noftags
-
         else
             local literal = setstate(makeignore(specification,range))
             inject(start,stop,list,literal)
@@ -1775,13 +2290,283 @@
         end
         if permitted then
             if trace_tags then
-                report_tags("blocking structure tags")
+                report("blocking structure tags")
             end
             permitted = false
         end
+        isrolemapped = false
+    else
+        isrolemapped = true
     end
 end
 
+do
+
+    local where  = structurestags.where
+    local modes  = structurestags.modes
+
+    local profiles = { }
+    local comment  = nil
+    local options  = { level = 0 }
+    local compact  = false  -- can be an option
+
+    function structurestags.getoption(name)
+        return options[name]
+    end
+
+    local function register(preset)
+        local filename = "lpdf-tag-imp-" .. preset .. ".lmt"
+        local fullname = resolvers.findfile(filename) or ""
+        if fullname == "" then
+            report("%s tag preset %a (file: %s)","unknown",preset,filename)
+        else
+            report("%s tag preset %a (file: %s)","using",preset,filename)
+            local data = table.load(fullname)
+            if data then
+                local includes  = data.includes
+                local mapping   = data.mapping
+                local endpoints = data.endpoints
+                local remapping = data.remapping
+                includes  = type(includes)  == "table" and #includes > 0   and includes  or nil
+                mapping   = type(mapping)   == "table" and next(mapping)   and mapping   or nil
+                endpoints = type(endpoints) == "table" and next(endpoints) and endpoints or nil
+                if mapping or includes or remapping or endpoints then
+                    local patterns = { }
+                    if remapping then
+                        for i=1,#remapping do
+                            local r = remapping[i]
+                            local e = r.element
+                            if e then
+                                local d = r.detail
+                                local p = r.parent
+                                if d then
+                                    e = e .. ":" .. d
+                                elseif p then
+                                    e = p .. "/" .. e
+                                end
+                                patterns[#patterns+1] = e
+                            end
+                        end
+                        table.sort(patterns)
+                    end
+                    profiles[#profiles+1] = {
+                        preset    = preset,
+                        name      = data.name,
+                        version   = data.version,
+                        size      = file.size(fullname),
+                        validated = data.validated,
+                        includes  = includes,
+                        mapping   = sortedkeys(mapping),
+                        remapping = patterns,
+                        endpoints = sortedkeys(endpoints),
+                    }
+                end
+                return includes, mapping, endpoints, remapping
+            end
+        end
+    end
+
+    local function namespacename(detail,parent)
+        if parent or detail then
+            usernamecount = usernamecount + 1
+            return formatters["user-%04X"](usernamecount)
+        else
+            return "user"
+        end
+    end
+
+    local function loadtags(preset,n,c,e)
+        local includes, mapping, endpoints, remapping = register(preset)
+        if includes then
+            for i=1,#includes do
+                n, c, e = loadtags(includes[i],n,c,e)
+            end
+        end
+        if endpoints then
+            for k, v in next, endpoints do
+                rawset(endpoints,k,v)
+                e = e + 1
+            end
+        end
+        -- old method
+        if mapping then
+            if not remapping then
+                remapping = { }
+            end
+            for k, v in sortedhash(mapping) do
+                local p = properties[k]
+                remapping[#remapping+1] = {
+                    element   = k,
+                    pdf       = v.pdf       or (p and p.pdf      ) or pdffallback,
+                    namespace = v.namespace or (p and p.namespace) or "user",
+                 -- nature    = v.nature    or (p and p.nature   ) or "mixed",
+                }
+            end
+            mapping = nil
+        end
+        -- new method
+        if remapping then
+            for i=1,#remapping do
+              ::continue::
+                local m = remapping[i]
+                local element = m.element
+                if element then
+                    local detail = m.detail
+                    local parent = m.parent
+                    local pdf    = m.pdf
+                    if unsupported[pdf] then
+                        report("unsupported tag %a remapped to %a",pdf,pdffallback)
+                        pdf = pdffallback
+                    end
+                    if compact then
+                        for i=1,usernamecount do
+                            local ns = namespacename(detail,parent)
+                            local usernamespace = usernamespaces[ns]
+                            if not usernamespace[element] then
+                                usernamespace[element] = pdf
+                                if detail then
+                                    local d = detailmapping[element]
+                                    if d then
+                                        d[detail] = ns
+                                    else
+                                        detailmapping[element] = { [detail] = ns }
+                                    end
+                                elseif parent then
+                                    local p = parentmapping[element]
+                                    if p then
+                                        p[parent] = ns
+                                    else
+                                        parentmapping[element] = { [parent] = ns }
+                                    end
+                                else
+                                    directmapping[element] = ns
+                                    warnedmapping[element] = m.warning
+                                end
+                                goto continue
+                            end
+                        end
+                    end
+                    local ns = namespacename(detail,parent)
+                    local u = usernamespaces[ns]
+                    if u then
+                        u[element] = pdf
+                    else
+                        usernamespaces[ns] = { [element] = pdf }
+                    end
+                    if detail then
+                        local d = detailmapping[element]
+                        if d then
+                            d[detail] = ns
+                        else
+                            detailmapping[element] = { [detail] = ns }
+                        end
+                    elseif parent then
+                        local p = parentmapping[element]
+                        if p then
+                            p[parent] = ns
+                        else
+                            parentmapping[element] = { [parent] = ns }
+                        end
+                    else
+                        directmapping[element] = ns
+                        warnedmapping[element] = m.warning
+                    end
+                end
+            end
+            c = c + #remapping -- for now
+        end
+
+        return n, c, e
+    end
+
+    local function settaggingpresets(specification)
+        local preset = specification.preset
+        if type(preset) == "string" then
+            local list  = settings_to_array(preset) -- just fetch a list
+            local level = tonumber(specification.level)
+            if level then
+                options.level = level
+            end
+            if list then
+                local n = 0
+                local c = 0
+                local e = 0
+                for i=1,#list do
+                    n, c, e = loadtags(list[i],n,c,e)
+                end
+                if n > 0 or c > 0 or e > 0 then
+                    report("%i pdf tags overloaded, %i crappy tags added, %i endpoints set, cross your fingers",n,c,e)
+                end
+            end
+        end
+    end
+
+    local disclaimer =
+[[The structure mapping is an attempt to map the internal ConTeXt structure to
+PDF tags best as possible given the constraints. It can result in a degradation
+of the original document structure. The authors take no responsonility for that.]]
+
+    local function settaggingcomment(str)
+        comment = type(str) == "string" and str or nil
+    end
+
+    local function settaggingoption(str)
+        local o = utilities.parsers.settings_to_hash(str)
+        if o.interaction then
+            handlelinks = true
+        end
+    end
+
+    function lpdf.gettaggingstatus()
+        if isrolemapped then
+            if enabled then
+                local disclaimer = pdfunicode(disclaimer)
+                local comment    = comment and pdfunicode(comment)
+                if #profiles > 0 then
+                    return {
+                        origin     = "additional basic or user maping",
+                        disclaimer = disclaimer,
+                        comment    = comment,
+                        profiles   = profiles,
+                    }
+                else
+                    return {
+                        origin     = "only build in default mapping",
+                        disclaimer = pdfunicode(disclaimer),
+                        comment    = comment,
+                    }
+                end
+            end
+        end
+    end
+
+    -- this should be a proper codeinjections:
+
+    interfaces.implement {
+        name      = "settaggingpresets",
+        actions   = settaggingpresets,
+        arguments = {
+            {
+                { "preset" },
+                { "level" },
+            }
+        }
+    }
+
+    interfaces.implement {
+        name      = "settaggingcomment",
+        actions   = settaggingcomment,
+        arguments = "string",
+    }
+
+    interfaces.implement {
+        name      = "settaggingoption",
+        actions   = settaggingoption,
+        arguments = "string",
+    }
+
+end
+
 function codeinjections.enabletags()
     if permitted and not enabled then
         structures.tags.handler = nodeinjections.addtags
@@ -1798,7 +2583,7 @@
         end
         --
         if trace_tags then
-            report_tags("enabling structure tags")
+            report("enabling structure tags")
         end
         --
         enabled = true

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/luat-usr.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/luat-usr.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/luat-usr.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -60,7 +60,7 @@
      %
      \clf_registernamedlua{#1}{#2}{\m_syst_name}%
      %
-     \frozen\instance\protected\xdefcsname\s!start#1\s!code\endcsname
+     \protected\frozen\instance\xdefcsname\s!start#1\s!code\endcsname
        {\begingroup
         \obeyluatokens
         \csname\??luacode#1\endcsname}%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/lxml-mms.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/lxml-mms.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/lxml-mms.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -380,7 +380,7 @@
 
 end
 
-local tomeaning, getlast  do
+local tomeaning  do
 
     -- we don't really need to handle mfenced
 
@@ -1135,16 +1135,12 @@
                 xmlfixattributes(x)
                 buffers.assign(type(keep_last) == "string" and keep_last or "lastmms",tostring(x))
             else
-                lastxml = false
+                -- maybe wipe the buffer
             end
             return concat(t," ",1,n)
         end
     end
 
-    getlast = function()
-        return lastxml or ""
-    end
-
 end
 
 local stripped  do

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-acc.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-acc.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-acc.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -120,23 +120,23 @@
 
 % \permanent\tolerant\protected\def\definemathtopaccent[#1]#*[#2]#*[#3]% class name top
 %   {\ifparameter#3\or
-%      \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_common                      {#1}{#2}\plusone{\number#3}\zerocount}%
+%      \protected\frozen\instance\edefcsname#2\endcsname{\math_accent_common                      {#1}{#2}\plusone{\number#3}\zerocount}%
 %    \else
-%      \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plusone{\number#2}\zerocount}%
+%      \protected\frozen\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plusone{\number#2}\zerocount}%
 %    \fi}
 
 % \permanent\tolerant\protected\def\definemathbottomaccent[#1]#*[#2]#*[#3]% class name bottom
 %   {\ifparameter#3\or
-%      \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plustwo\zerocount{\number#3}}%
+%      \protected\frozen\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plustwo\zerocount{\number#3}}%
 %    \else
-%      \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plustwo\zerocount{\number#2}}%
+%      \protected\frozen\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plustwo\zerocount{\number#2}}%
 %    \fi}
 
 % \permanent\tolerant\protected\def\definemathdoubleaccent[#1]#*[#2]#*[#3]#*[#4]% class name top bottom
 %   {\ifparameter#4\or
-%      \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plusthree{\number#3}{\number#4}}%
+%      \protected\frozen\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plusthree{\number#3}{\number#4}}%
 %    \else
-%      \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plusthree{\number#2}{\number#3}}%
+%      \protected\frozen\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plusthree{\number#2}{\number#3}}%
 %    \fi}
 
 % \installlocalcurrenthandler \??mathaccents {mathaccent}
@@ -144,28 +144,28 @@
 \permanent\tolerant\protected\def\definemathtopaccent[#1]#*[#2]#*[#3]% class name top
   {\ifparameter#3\or
      \definemathaccent[#2][#1]%
-     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plusone{\number#3}\zerocount}%
+     \protected\frozen\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plusone{\number#3}\zerocount}%
    \else
      \definemathaccent[#1]%
-     \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plusone{\number#2}\zerocount}%
+     \protected\frozen\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plusone{\number#2}\zerocount}%
    \fi}
 
 \permanent\tolerant\protected\def\definemathbottomaccent[#1]#*[#2]#*[#3]% class name bottom
   {\ifparameter#3\or
      \definemathaccent[#2][#1]%
-     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plustwo\zerocount{\number#3}}%
+     \protected\frozen\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plustwo\zerocount{\number#3}}%
    \else
      \definemathaccent[#1]%
-     \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plustwo\zerocount{\number#2}}%
+     \protected\frozen\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plustwo\zerocount{\number#2}}%
    \fi}
 
 \permanent\tolerant\protected\def\definemathdoubleaccent[#1]#*[#2]#*[#3]#*[#4]% class name top bottom
   {\ifparameter#4\or
      \definemathaccent[#2][#1]%
-     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plusthree{\number#3}{\number#4}}%
+     \protected\frozen\instance\edefcsname#2\endcsname{\math_accent_common                       {#1}{#2}\plusthree{\number#3}{\number#4}}%
    \else
      \definemathaccent[#1]%
-     \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plusthree{\number#2}{\number#3}}%
+     \protected\frozen\instance\edefcsname#1\endcsname{\math_accent_common\noexpand\currentmathaccent{#1}\plusthree{\number#2}{\number#3}}%
    \fi}
 
 %D \starttyping

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-act.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-act.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-act.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -2020,7 +2020,9 @@
             local yscale   = parameters.yscale  or 1
             local mwidth   = minus.width
             local mheight  = minus.height
+            local width    = 0
             local height   = (parameters.height  or 1) * mheight
+            local xshift   = 0
             local yshift   = (parameters.yoffset or 0) * mheight
             local loverlap = parameters.leftoverlap  or 0
             local roverlap = parameters.rightoverlap or 0

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-ali.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-ali.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-ali.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -910,15 +910,15 @@
 \installcommandhandler \??mathalignment {mathalignment} \??mathalignment
 
 \appendtoks
-              \frozen\protected\instance\edefcsname\e!start\currentmathalignment\endcsname{\math_alignment_start[\currentmathalignment]}%
-    \noaligned\frozen\protected\instance \defcsname\e!stop \currentmathalignment\endcsname{\math_alignment_stop}%
+              \protected\frozen\instance\edefcsname\e!start\currentmathalignment\endcsname{\math_alignment_start[\currentmathalignment]}%
+    \noaligned\protected\frozen\instance \defcsname\e!stop \currentmathalignment\endcsname{\math_alignment_stop}%
 \to \everydefinemathalignment
 
 % to be tested
 %
 % \appendtoks
-%               \frozen\instance\protected\defcsname\e!start\currentmathalignment\endcsname{\math_alignment_start[\currentmathalignment]}%
-%     \noaligned\frozen\instance\protected\defcsname\e!stop \currentmathalignment\endcsname{\math_alignment_stop}%
+%               \protected\frozen\instance\defcsname\e!start\currentmathalignment\endcsname{\math_alignment_start[\currentmathalignment]}%
+%     \noaligned\protected\frozen\instance\defcsname\e!stop \currentmathalignment\endcsname{\math_alignment_stop}%
 % \to \everydefinemathalignment
 
 \setupmathalignment
@@ -1210,7 +1210,7 @@
    \c!numberdistance=\zeropoint]
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\e!start\currentmathcases\endcsname{\math_cases_start[\currentmathcases]}%
+    \protected\frozen\instance\edefcsname\e!start\currentmathcases\endcsname{\math_cases_start[\currentmathcases]}%
     \frozen\instance          \defcsname \e!stop \currentmathcases\endcsname{\math_cases_stop}%
 \to \everydefinemathcases
 
@@ -1243,7 +1243,7 @@
 \appendtoks
     \edef\p_simplecommand{\mathcasesparameter\c!simplecommand}%
     \ifempty\p_simplecommand\else
-        \frozen\protected\instance\edefcsname\p_simplecommand\endcsname{\math_cases_simple[\currentmathcases]}%
+        \protected\frozen\instance\edefcsname\p_simplecommand\endcsname{\math_cases_simple[\currentmathcases]}%
     \fi
 \to \everydefinemathcases
 
@@ -1505,7 +1505,7 @@
    \c!rulethickness=\linewidth]
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\e!start\currentmathmatrix\endcsname{\math_matrix_start[\currentmathmatrix]}%
+    \protected\frozen\instance\edefcsname\e!start\currentmathmatrix\endcsname{\math_matrix_start[\currentmathmatrix]}%
     % \noaligned\protected should work here:
     \frozen\instance          \defcsname \e!stop \currentmathmatrix\endcsname{\math_matrix_stop}% no u else lookahead problem
 \to \everydefinemathmatrix
@@ -2704,7 +2704,7 @@
 \appendtoks
     \edef\p_simplecommand{\mathmatrixparameter\c!simplecommand}%
     \ifempty\p_simplecommand\else
-        \frozen\protected\instance\edefcsname\p_simplecommand\endcsname{\math_matrix_simple[\currentmathmatrix]}%
+        \protected\frozen\instance\edefcsname\p_simplecommand\endcsname{\math_matrix_simple[\currentmathmatrix]}%
     \fi
 \to \everydefinemathmatrix
 
@@ -3844,7 +3844,7 @@
    \c!textdistance=.25\emwidth]
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\e!start\currentmathsimplealign\endcsname{\math_simplealign_start[\currentmathsimplealign]}%
+    \protected\frozen\instance\edefcsname\e!start\currentmathsimplealign\endcsname{\math_simplealign_start[\currentmathsimplealign]}%
     \frozen\instance          \defcsname \e!stop \currentmathsimplealign\endcsname{\math_simplealign_stop}%
 \to \everydefinemathsimplealign
 
@@ -4160,7 +4160,7 @@
 \appendtoks
     \edef\p_simplecommand{\mathsimplealignparameter\c!simplecommand}%
     \ifempty\p_simplecommand\else
-        \frozen\protected\instance\edefcsname\p_simplecommand\endcsname{\math_align_simple[\currentmathsimplealign]}%
+        \protected\frozen\instance\edefcsname\p_simplecommand\endcsname{\math_align_simple[\currentmathsimplealign]}%
     \fi
 \to \everydefinemathsimplealign
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-del.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-del.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-del.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -86,7 +86,7 @@
 \appendtoks
     \ifcstok{\mathdelimiterparameter\c!define}\v!yes
         % we can intercept auto here
-        \frozen\instance\protected\edefcsname\currentmathdelimiter\endcsname{\mathdelimiter[\currentmathdelimiter]}%
+        \protected\frozen\instance\edefcsname\currentmathdelimiter\endcsname{\mathdelimiter[\currentmathdelimiter]}%
     \fi
 \to \everydefinemathdelimiter
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-dld.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-dld.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-dld.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -48,7 +48,7 @@
 
 \appendtoks
     \ifcstok{\mathdelimitedparameter\c!define}\v!yes
-      \frozen\protected\instance\edefcsname\currentmathdelimited\endcsname{\math_delimited_handle{\currentmathdelimited}}
+      \protected\frozen\instance\edefcsname\currentmathdelimited\endcsname{\math_delimited_handle{\currentmathdelimited}}
     \fi
 \to \everydefinemathdelimited
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-frc.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-frc.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-frc.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -121,7 +121,7 @@
    \c!symbol=\fractionbarextenderuc]
 
 \appendtoks
-    \instance\frozen\protected\edefcsname\currentmathfraction\endcsname{\math_frac{\currentmathfraction}}%
+    \protected\frozen\instance\edefcsname\currentmathfraction\endcsname{\math_frac{\currentmathfraction}}%
 \to \everydefinemathfraction
 
 % Sometimes users want control over the distances:

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-ini.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-ini.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-ini.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -2227,7 +2227,7 @@
 \installcommandhandler \??mathfunction {mathfunction} \??mathfunction
 
 \appendtoks
-    \frozen\protected\edefcsname\currentmathfunction\endcsname{\math_function_handle\plusone{\currentmathfunction}{}}% \instance
+    \protected\frozen\instance\edefcsname\currentmathfunction\endcsname{\math_function_handle\plusone{\currentmathfunction}{}}% \instance
 \to \everydefinemathfunction
 
 \aliased\let\setupmathfunctions\setupmathfunction
@@ -5013,7 +5013,7 @@
 \installcommandhandler \??mathnesting {mathnesting} \??mathnesting
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\currentmathnesting\endcsname{\math_nesting[\currentmathnesting]}%
+    \protected\frozen\instance\edefcsname\currentmathnesting\endcsname{\math_nesting[\currentmathnesting]}%
 \to \everydefinemathnesting
 
 \newconstant\c_math_boundary_old

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-noa.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-noa.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-noa.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1660,7 +1660,7 @@
 
 do
 
-    local enable = function()
+    local function enable()
         if trace_italics then
             report_italics("enabling math italics")
         end
@@ -1952,7 +1952,7 @@
         processnoads(head,numbers,"numbers")
     end
 
-    local enable = function()
+    local function enable()
         enableaction("math", "noads.handlers.numbers")
      -- if trace_numbers then
      --     report_numbers("enabling math numbers")
@@ -1972,7 +1972,7 @@
         processnoads(head,spacing,"spacing")
     end
 
-    local enable = function()
+    local function enable()
         enableaction("math", "noads.handlers.spacing")
      -- if trace_spacing then
      --     report_spacing("enabling math spacing")
@@ -1992,7 +1992,7 @@
         processnoads(head,fencing,"fencing")
     end
 
-    local enable = function()
+    local function enable()
         enableaction("math", "noads.handlers.fencing")
      -- if trace_fencing then
      --     report_fencing("enabling math fencing")
@@ -2153,12 +2153,12 @@
         processnoads(head,collapse,"collapse")
     end
 
-    local enable = function()
+    local function enable()
         enableaction("math", "noads.handlers.collapse")
         if trace_collapsing then
             report_collapsing("enabling math collapsing")
         end
-        enable = false
+        enable = false -- already onlyonce
     end
 
     implement {
@@ -2489,6 +2489,8 @@
         [v_big]    = 2,
     }
 
+    local enabled = false
+
     function mathematics.setsnapping(s)
         if not enabled then
             enableaction("math","noads.handlers.snap")
@@ -2551,9 +2553,7 @@
 --         return attr
 --     end
 --
---     local enable
---
---     enable = function()
+--     local function enable()
 --         enableaction("math", "noads.handlers.domains")
 --         if trace_domains then
 --             report_domains("enabling math domains")

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-rad.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-rad.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-rad.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -90,7 +90,7 @@
    \c!rightmargin=\zeropoint]
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\currentmathradical\endcsname{\math_radical_handle{\currentmathradical}}
+    \protected\frozen\instance\edefcsname\currentmathradical\endcsname{\math_radical_handle{\currentmathradical}}
 \to \everydefinemathradical
 
 \mutable\lettonothing\currentmathradical
@@ -260,7 +260,7 @@
    \c!mpoffset=.25\exheight]
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\currentmathornament\endcsname
+    \protected\frozen\instance\edefcsname\currentmathornament\endcsname
       {\math_ornament_handle{\currentmathornament}}%
 \to \everydefinemathornament
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/math-vfu.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/math-vfu.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/math-vfu.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -785,7 +785,7 @@
         end
         local oldparts = olddata.parts
         if oldparts then
-            newparts = fastcopy(oldparts)
+            local newparts           = fastcopy(oldparts)
             newdata.parts            = newparts
             newdata.partsorientation = olddata.partsorientation
             newdata.partsitalic      = olddata.partsitalic
@@ -831,7 +831,9 @@
 -- The following code is now only used for iwona and antykwa, so I simplified it a
 -- bit to suit that purpose. It might get even simpler.
 
-local integrals = setmetatableindex(function(t,k)
+local integrals = { } -- we want to overload
+
+setmetatableindex(integrals, function(t,k)
     integrals = tohash(mathematics.tweaks.subsets.integrals)
     return integrals[k]
 end)

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/meta-ini.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/meta-ini.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/meta-ini.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -276,17 +276,61 @@
 
 \let\meta_relocate_graphic\relax % experimental hook
 
-\def\meta_process_graphic_start
+% \def\meta_process_graphic_start
+%   {\pushMPboundingbox
+%    \dostarttaggednodetail\t!mpgraphic
+%    \setbox\b_meta_graphic\hpack\bgroup
+%      % We now make everything an artifact because it's not worth the trouble to
+%      % deal with nested text .. it will not be properly dealt with in viewers
+%      % either so why bother mixing content and artifacts.
+%      \dotaggedplaceholder
+%      \dostartignoretagging\empty}
+
+% \def\meta_process_graphic_stop
+%   {\dostopignoretagging
+%    \egroup
+%    \meta_place_graphic
+%    \meta_relocate_graphic
+%    \dostoptagged
+%    \popMPboundingbox}
+
+\aliased\lettonothing\dotagmpgraphic
+
+\def\meta_process_graphic_start_normal
   {\pushMPboundingbox
+   \setbox\b_meta_graphic\hpack\bgroup}
+
+\def\meta_process_graphic_stop_normal
+  {\egroup
+   \meta_place_graphic
+   \meta_relocate_graphic
+   \popMPboundingbox}
+
+\def\meta_process_graphic_start_tagged
+  {\pushMPboundingbox
    \dostarttaggednodetail\t!mpgraphic
-   \setbox\b_meta_graphic\hpack\bgroup
+   % only if exporting or tagging / a real nasty bit fo code as we can work inner out
+   \enforced\edef\figuredescriptiontext{\mplevelparameter\c!descriptiontext}% directly use this
+   \enforced\edef\figurealternativetext{\mplevelparameter\c!alternativetext}% directly use this
+   \ifconditional\c_grph_in_image
+     % set description if to yet set
+     \dotagfigure
+   \else
+     \dotagmpgraphic % so it will be faster then
+   \fi
+   % We use image id 3 but then also check need to check the export!
+   \setbox\b_meta_graphic\hpack attr \imageattribute \plusthree\bgroup
      % We now make everything an artifact because it's not worth the trouble to
      % deal with nested text .. it will not be properly dealt with in viewers
      % either so why bother mixing content and artifacts.
-     \dotaggedplaceholder
-     \dostartignoretagging}
+       \dotaggedplaceholder
+       \dostartignoretagging\empty
+     % We also need to prevent that there are annotations that then have no
+     % pointer to what what into tagged, unless we then point to the whole.
+     % \locationfalse % better not
+   }
 
-\def\meta_process_graphic_stop
+\def\meta_process_graphic_stop_tagged
   {\dostopignoretagging
    \egroup
    \meta_place_graphic
@@ -294,7 +338,22 @@
    \dostoptagged
    \popMPboundingbox}
 
+% we can alias in the tag enabler
 
+\def\meta_process_graphic_start
+  {\ifconditional\c_strc_tags_enabled
+     \meta_process_graphic_start_tagged
+   \else
+     \meta_process_graphic_start_normal
+   \fi}
+
+\def\meta_process_graphic_stop
+  {\ifconditional\c_strc_tags_enabled
+     \meta_process_graphic_stop_tagged
+   \else
+     \meta_process_graphic_stop_normal
+   \fi}
+
 \protected\def\meta_process_graphic_instance#1#2% used in startMPpage
   {\cdef\currentMPinstance{#1}%
    \ifempty\currentMPinstance
@@ -714,9 +773,14 @@
 
 \def\meta_uniquempgraphic_yes[#1]#*#=%
   {% ugly code but we run on top of older code
-   \resetdummyparameter\c!instance
-   \getdummyparameters[#1]%
-   \cdef\currentMPinstance{\dummyparameter\c!instance}%
+%    \resetdummyparameter\c!instance
+%    \getdummyparameters[#1]%
+%    \cdef\currentMPinstance{\dummyparameter\c!instance}%
+   %
+   \meta_bump_current_level
+   \setupcurrentmplevel[#1]%
+   \cdef\currentMPinstance{\mplevelparameter\c!instance}%
+   %
    % here we feed the instance into the analyzer
    \meta_begin_graphic_group{\ifempty\currentMPinstance\else\currentMPinstance::\fi#1}%
    \checkmpcategoryparent
@@ -788,9 +852,14 @@
 
 \def\meta_usempgraphic_yes[#1]#*#=%
   {% ugly code but we run on top of older code
-   \resetdummyparameter\c!instance
-   \getdummyparameters[#1]%
-   \cdef\currentMPinstance{\dummyparameter\c!instance}%
+%    \resetdummyparameter\c!instance
+%    \getdummyparameters[#1]%
+%    \cdef\currentMPinstance{\dummyparameter\c!instance}%
+   %
+   \meta_bump_current_level
+   \setupcurrentmplevel[#1]%
+   \cdef\currentMPinstance{\mplevelparameter\c!instance}%
+   %
    % here we feed the instance into the analyzer
    \meta_begin_graphic_group{\ifempty\currentMPinstance\else\currentMPinstance::\fi#2}%
    \ifcsname\??mpgraphic#2\endcsname
@@ -1015,11 +1084,17 @@
 
 \def\meta_start_mpcode_yes[#1]#2\stopMPcode
   {\begingroup
-   \resetdummyparameter\c!instance
-   \resetdummyparameter\c!stacking
-   \getdummyparameters[#1]%
-   \cdef\currentMPinstance{\dummyparameter\c!instance}%
-   \setmpcategoryparameter\c!stacking{\dummyparameter\c!stacking}%
+%    \resetdummyparameter\c!instance
+%    \resetdummyparameter\c!stacking
+%    \getdummyparameters[#1]%
+%    \cdef\currentMPinstance{\dummyparameter\c!instance}%
+%    \setmpcategoryparameter\c!stacking{\dummyparameter\c!stacking}%
+   %
+   \meta_bump_current_level
+   \setupcurrentmplevel[#1]%
+   \cdef\currentMPinstance{\mplevelparameter\c!instance}%
+   \setmpcategoryparameter\c!stacking{\mplevelparameter\c!stacking}%
+   %
    \ifempty\currentMPinstance
      \let\currentMPinstance\defaultMPinstance
    \fi
@@ -1119,6 +1194,22 @@
 \permanent          \def\MPstring   #1{"\begincsname\??mptext#1\endcsname\empty"}
 \permanent          \def\MPbetex    #1{btex \begincsname\??mptext#1\endcsname\space etex}
 
+%D Another helper:
+
+\installcorenamespace {mplevel}
+
+\installsetuponlycommandhandler \??mplevel {mplevel}
+
+\lettonothing\currentmplevel
+
+\newinteger\c_meta_mp_level
+
+\def\meta_bump_current_level
+  {\advanceby\c_meta_mp_level\plusone
+   \ifnum\c_meta_mp_level>\plusone
+     \cdef\currentmplevel{mp:\the\c_meta_mp_level}%
+   \fi}
+
 %D In order to communicate conveniently with the \TEX\ engine, we introduce some
 %D typesetting variables.
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/meta-pdf.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/meta-pdf.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/meta-pdf.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -46,7 +46,7 @@
      \offinterlineskip
      \setbox\MPbox\vpack\bgroup
        \dotaggedplaceholder
-       \dostartignoretagging
+       \dostartignoretagging\empty
        \ignorespaces         % not that needed
        \clf_convertmpstopdf{\MPfilename}%
        \removeunwantedspaces % not that needed

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-cnt.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-cnt.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-cnt.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -443,8 +443,8 @@
 
     end
 
-    minz = data[1][1]
-    maxz = minz
+    local minz = data[1][1]
+    local maxz = minz
 
     for i=1,nx do
         local d = data[i]
@@ -1867,8 +1867,8 @@
   -- end
      %s
      return function(f,z)
-         brightness_factor = f
-         function_value    = z
+         local brightness_factor = f
+         local function_value    = z
          return %s
      end
 ]] ]

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-pdf.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-pdf.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-pdf.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -120,6 +120,8 @@
     expandmacro("stopMPLIBtoPDF")
 end
 
+-- pdfliterals = "/Artifact BMC\n" .. pdfliterals .. "\n" .. "EMC"
+
 function pdfflusher.flushfigure(pdfliterals) -- table
     if #pdfliterals > 0 then
         pdfliterals = concat(pdfliterals,"\n")
@@ -483,8 +485,8 @@
                     local miterlimit = -1
                     local linecap    = -1
                     local linejoin   = -1
-local repeater = { }
-local repeated = 0
+                    local repeater   = { }
+                    local repeated   = 0
                     local dashed     = false
                     local linewidth  = false
                     local llx        = properties.llx

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-ptr.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-ptr.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-ptr.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -19,7 +19,7 @@
 
 local report = logs.reporter("metapost","potrace")
 
-local potracefromfile do -- this will move to another module
+local potracefromfile, potracefrompng do -- this will move to another module
 
     local newreader      = io.newreader
     local openstring     = utilities.streams.openstring

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-svg.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-svg.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/mlib-svg.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -345,10 +345,10 @@
 local percentage_x = percentage_r
 local percentage_y = percentage_r
 
-local asnumber, asnumber_r, asnumber_x, asnumber_y, asnumber_vx, asnumber_vy
+local asnumber, asnumber_p, asnumber_r, asnumber_x, asnumber_y, asnumber_vx, asnumber_vy
 local asnumber_vx_t, asnumber_vy_t
 local p_number, p_separator, p_optseparator, p_numbers, p_fournumbers, p_path
-local p_number_n, p_number_x, p_number_vx, p_number_y, p_number_vy, p_number_r
+local p_number_n, p_number_p, p_number_u, p_number_x, p_number_vx, p_number_y, p_number_vy, p_number_r
 
 do
 
@@ -436,12 +436,12 @@
 -- local function hexcolor (c) return hexhash [c] end -- directly do hexhash [c]
 -- local function hexcolor3(c) return hexhash3[c] end -- directly do hexhash3[c]
 
-local colormap  = false
+local colormap = false
 
 local function prepared(t)
     if type(t) == "table" then
-        local mapping = t.mapping or { }
-        local mapper  = t.mapper
+        local mapping  = t.mapping or { }
+        local mapper   = t.mapper
         local colormap = setmetatableindex(mapping)
         if mapper then
             setmetatableindex(colormap,function(t,k)
@@ -1228,7 +1228,7 @@
 local s_wrapped_start <const> = "draw image ("
 local f_wrapped_stop          = formatters[") shifted (0,%N) scaled %N ;"]
 
-local handletransform, handleviewbox  do
+local handletransform, handletransformstring, handleviewbox  do
 
     local sind = math.sind
 
@@ -1408,7 +1408,7 @@
 
 end
 
-do
+local handledefinitions do
 
     local handlers    = { }
     local process     = false
@@ -1418,6 +1418,7 @@
     local definitions = false
     local classstyles = false
     local tagstyles   = false
+ -- local colormap    = false
 
     local tags = {
         ["a"]                  = true,
@@ -1718,17 +1719,17 @@
                         transform = handletransformstring(transform)
                     end
 
-local tr = rawget(at,"transform")
-if tr then
-    tr = handletransformstring(tr)
-    if tr then
-        if transform then
-            transform = transform .. " " .. tr
-        else
-            transform = tr
-        end
-    end
-end
+                    local tr = rawget(at,"transform")
+                    if tr then
+                        tr = handletransformstring(tr)
+                        if tr then
+                            if transform then
+                                transform = transform .. " " .. tr
+                            else
+                                transform = tr
+                            end
+                        end
+                    end
 
                     return p, clippath, transform
                 else

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/node-fin.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/node-fin.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/node-fin.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -136,7 +136,7 @@
 
 local nsdata, nsnone, nslistwise, nsforced, nsselector
 local current, current_selector = 0, 0 -- nb, stack has a local current !
-local nsbegin, nsend, nsreset
+local nsbegin, nsend, nsreset, nsstep, nspush, nspop
 
 function states.initialize(namespace,attribute,head)
     nsdata           = namespace.data

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/node-nut.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/node-nut.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/node-nut.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -324,6 +324,7 @@
     traverse                = d_traverse,
     traversechar            = direct.traversechar,
     traversecontent         = direct.traversecontent,
+    traversepossible        = direct.traversepossible,
     traverseglyph           = direct.traverseglyph,
     traverseid              = direct.traverseid,
     traverseitalic          = direct.traverseitalic,

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/node-ref.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/node-ref.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/node-ref.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -507,8 +507,8 @@
             n = 0
         end
         u_transparency = u_transparency or transparencies.register(nil,2,.65)
-        local ucolor = u_colors[n]
-        if not ucolor then
+        local u_color = u_colors[n]
+        if not u_color then
             if n == 1 then
                 u_color = register_color(nil,'rgb',.75,0,0)
             elseif n == 2 then
@@ -596,26 +596,36 @@
     end
 
     local describe = true
+    local get      = false
 
+    updaters.register("backends.injections.latebindings",function()
+        get = structures.tags.gettagreferencedescription
+    end)
+
     directives.register("backends.references.descriptions", function(v) describe = v end)
 
-    local function makedescription(resolved)
-        if describe == "reference" then
-            return resolved.reference
-        elseif describe then
-            local first = resolved[1]
-            if not first then
+    local function makedescription(reference,resolved)
+        if describe then
+            local rd = get and get(reference)
+            if rd then
+                return rd
+            elseif describe == "reference" then
                 return resolved.reference
-            end
-            local kind = first.kind
-            if kind == "outer" then
-                return "link to file: " .. first.outer
-            elseif kind == "inner" then
-                return "link to: " .. first.inner
-            elseif kind == "special operation" then
-                return first.special .. ": " .. first.operation
             else
-                return resolved.reference
+                local first = resolved[1]
+                if not first then
+                    return resolved.reference
+                end
+                local kind = first.kind
+                if kind == "outer" then
+                    return "link to file: " .. first.outer
+                elseif kind == "inner" then
+                    return "link to: " .. first.inner
+                elseif kind == "special operation" then
+                    return first.special .. ": " .. first.operation
+                else
+                    return resolved.reference
+                end
             end
         end
     end
@@ -637,7 +647,7 @@
                 if depth  < dp then depth  = dp end
             end
          -- logs.report("temp","used: ht=%p dp=%p",height,depth)
-            local annot = injectreference(reference,width,height,depth,set,resolved.mesh,makedescription(resolved),resolved.forcemesh,rotated)
+            local annot = injectreference(reference,width,height,depth,set,resolved.mesh,makedescription(reference,resolved),resolved.forcemesh,rotated)
             if annot then
                 annot = tonut(annot) -- todo
                 nofreferences = nofreferences + 1

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/node-res.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/node-res.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/node-res.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -678,19 +678,21 @@
 
     -- these are special:
 
-    traversers.node    = nuts.traverse       (glyph)
-    traversers.char    = nuts.traversechar   (glyph)
-    traversers.glyph   = nuts.traverseglyph  (glyph)
-    traversers.list    = nuts.traverselist   (glyph)
-    traversers.content = nuts.traversecontent(glyph)
-    traversers.leader  = nuts.traverseleader (glyph)
+    traversers.node     = nuts.traverse        (glyph)
+    traversers.char     = nuts.traversechar    (glyph)
+    traversers.glyph    = nuts.traverseglyph   (glyph)
+    traversers.list     = nuts.traverselist    (glyph)
+    traversers.content  = nuts.traversecontent (glyph)
+    traversers.possible = nuts.traversepossible(glyph)
+    traversers.leader   = nuts.traverseleader  (glyph)
 
-    treversers.node    = nuts.traverse       (glyph,true)
-    treversers.char    = nuts.traversechar   (glyph,true)
-    treversers.glyph   = nuts.traverseglyph  (glyph,true)
-    treversers.list    = nuts.traverselist   (glyph,true)
-    treversers.content = nuts.traversecontent(glyph,true)
-    treversers.leader  = nuts.traverseleader (glyph,true)
+    treversers.node     = nuts.traverse        (glyph,true)
+    treversers.char     = nuts.traversechar    (glyph,true)
+    treversers.glyph    = nuts.traverseglyph   (glyph,true)
+    treversers.list     = nuts.traverselist    (glyph,true)
+    treversers.content  = nuts.traversecontent (glyph,true)
+    treversers.possible = nuts.traversepossible(glyph,true)
+    treversers.leader   = nuts.traverseleader  (glyph,true)
 
     nuts.traversers = traversers
     nuts.treversers = treversers

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/node-rul.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/node-rul.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/node-rul.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -97,7 +97,7 @@
 \aliased\let\setupbars\setupbar
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\currentbar\endcsname{\node_rules_direct{\currentbar}}%
+    \protected\frozen\instance\edefcsname\currentbar\endcsname{\node_rules_direct{\currentbar}}%
 \to \everydefinebar
 
 % \protected\def\node_rules_direct#1%
@@ -432,7 +432,7 @@
 \let\setupshifts\setupshift
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\currentshift\endcsname{\node_shifts_direct{\currentshift}}%
+    \protected\frozen\instance\edefcsname\currentshift\endcsname{\node_shifts_direct{\currentshift}}%
 \to \everydefineshift
 
 \protected\def\node_shifts_set#1% todo: check parent ! todo: move attr etc to lua
@@ -619,7 +619,7 @@
 \let\setupshadows\setupshadow
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\currentshadow\endcsname{\node_shadows_direct{\currentshadow}}%
+    \protected\frozen\instance\edefcsname\currentshadow\endcsname{\node_shadows_direct{\currentshadow}}%
 \to \everydefineshadow
 
 \protected\def\node_shadows_set#1% todo: check parent ! todo: move attr etc to lua

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/node-tra.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/node-tra.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/node-tra.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -777,7 +777,7 @@
 
 local texgetattribute = tex.getattribute
 
-function recolor(head,colormodel,color,transparency)
+local function recolor(head,colormodel,color,transparency)
     -- todo loop over content
     for n, id in nextnode, head do
         if id == glyph_code or id == rule_code then

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/pack-bck.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/pack-bck.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/pack-bck.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -65,9 +65,9 @@
 \setnewconstant\backgroundsplitmode\plusthree
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\e!start\currentbackground\endcsname{\pack_backgrounds_start [\currentbackground]}%
-    \frozen\protected\instance\edefcsname\e!stop \currentbackground\endcsname{\pack_backgrounds_stop                      }%
-    \frozen\protected\instance\edefcsname        \currentbackground\endcsname{\pack_backgrounds_direct[\currentbackground]}%
+    \protected\frozen\instance\edefcsname\e!start\currentbackground\endcsname{\pack_backgrounds_start [\currentbackground]}%
+    \protected\frozen\instance\edefcsname\e!stop \currentbackground\endcsname{\pack_backgrounds_stop                      }%
+    \protected\frozen\instance\edefcsname        \currentbackground\endcsname{\pack_backgrounds_direct[\currentbackground]}%
 \to \everydefinebackground
 
 \protected\def\pack_backgrounds_start[#tag]%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/pack-box.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/pack-box.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/pack-box.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -576,7 +576,7 @@
 
 \appendtoks
     \ifcstok{\bleedingparameter\c!define}\v!yes
-        \frozen\instance\protected\edefcsname\currentbleeding\endcsname{\pack_boxes_bleeding{\currentbleeding}}%
+        \protected\frozen\instance\edefcsname\currentbleeding\endcsname{\pack_boxes_bleeding{\currentbleeding}}%
     \fi
 \to \everydefinebleeding
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/pack-com.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/pack-com.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/pack-com.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -766,10 +766,10 @@
 \newdimension\d_pack_pairedboxes_size
 
 \appendtoks
-   \frozen\protected\instance\edefcsname\e!setup\currentpairedbox\e!endsetup\endcsname{\setuppairedbox     [\currentpairedbox]}%
-   \frozen\protected\instance\edefcsname\e!place\currentpairedbox           \endcsname{\placepairedbox     [\currentpairedbox]}% one argument is mandate anyway
-   \frozen\protected\instance\edefcsname\e!start\e!place\currentpairedbox   \endcsname{\startplacepairedbox[\currentpairedbox]}% one argument is mandate anyway
-   \frozen\protected\instance\edefcsname\e!stop\e!place \currentpairedbox   \endcsname{\stopplacepairedbox                    }%
+   \protected\frozen\instance\edefcsname\e!setup\currentpairedbox\e!endsetup\endcsname{\setuppairedbox     [\currentpairedbox]}%
+   \protected\frozen\instance\edefcsname\e!place\currentpairedbox           \endcsname{\placepairedbox     [\currentpairedbox]}% one argument is mandate anyway
+   \protected\frozen\instance\edefcsname\e!start\e!place\currentpairedbox   \endcsname{\startplacepairedbox[\currentpairedbox]}% one argument is mandate anyway
+   \protected\frozen\instance\edefcsname\e!stop\e!place \currentpairedbox   \endcsname{\stopplacepairedbox                    }%
 \to \everydefinepairedbox
 
 \permanent\tolerant\protected\def\startplacepairedbox[#1]#*[#S#2]%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/pack-mat.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/pack-mat.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/pack-mat.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -262,7 +262,7 @@
 \newdimension\d_pack_framed_mathframed
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\currentmathframed\endcsname{\pack_framed_mathframed[\currentmathframed]}%
+    \protected\frozen\instance\edefcsname\currentmathframed\endcsname{\pack_framed_mathframed[\currentmathframed]}%
 \to \everydefinemathframed
 
 \tolerant\protected\def\pack_framed_mathframed[#1]#*[#S#2]#:#3% needs testing !

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/pack-mis.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/pack-mis.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/pack-mis.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -27,7 +27,7 @@
 \installcommandhandler \??placement {placement} \??placement
 
 \appendtoks
-   \frozen\instance\protected\edefcsname\e!place\currentplacement\endcsname{\pack_placement{\currentplacement}}%
+   \protected\frozen\instance\edefcsname\e!place\currentplacement\endcsname{\pack_placement{\currentplacement}}%
 \to \everydefineplacement
 
 \setupplacement

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/pack-rul.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/pack-rul.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/pack-rul.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -92,7 +92,7 @@
   {\enforced\frozen\def#5##1##2{\ifrelax##1#6{##2}\else#4{##1}{##2}\fi}%
 %    \enforced\frozen\def#6##1{\ifcsname\??framed:##1\endcsname\??framed:##1\else\??empty\fi}% root
 \enforced\frozen\def#6##1{\ifcsname\??framed:##1\endcsname\csnamestring\else\??empty\fi}% root
-   \frozen\instance\protected\def#8%
+   \protected\frozen\instance\def#8%
      {\bgroup
       \bgroup
       \inframedtrue
@@ -101,7 +101,7 @@
       \enforced\let\framedparameterhash#3%
       \enforced\let\setupcurrentframed #7%
       \pack_framed_process_indeed}%
-   \frozen\instance\protected\def#9%
+   \protected\frozen\instance\def#9%
      {\bgroup
       \inframedtrue
       \enforced\let\currentframed      #1%
@@ -2799,9 +2799,9 @@
    \c!margin=\v!standard]
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\e!start\currentframedtext\endcsname{\pack_framed_text_start [\currentframedtext]}%
-    \frozen\instance\protected\edefcsname\e!stop \currentframedtext\endcsname{\pack_framed_text_stop                      }%
-    \frozen\instance\protected\edefcsname        \currentframedtext\endcsname{\pack_framed_text_direct[\currentframedtext]}%
+    \protected\frozen\instance\edefcsname\e!start\currentframedtext\endcsname{\pack_framed_text_start [\currentframedtext]}%
+    \protected\frozen\instance\edefcsname\e!stop \currentframedtext\endcsname{\pack_framed_text_stop                      }%
+    \protected\frozen\instance\edefcsname        \currentframedtext\endcsname{\pack_framed_text_direct[\currentframedtext]}%
 \to \everydefineframedtext
 
 \defcsname\??framedtextlocation\v!left\endcsname
@@ -3009,7 +3009,7 @@
 \to \everypresetframed
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\currentframed\endcsname{\pack_framed_defined_process[\currentframed]}%
+    \protected\frozen\instance\edefcsname\currentframed\endcsname{\pack_framed_defined_process[\currentframed]}%
 \to \everydefineframed
 
 \newinteger\c_temp_framed_crap

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-app.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-app.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-app.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -45,8 +45,8 @@
    \c!location=\v!middle]
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\e!start\currentfittingpage\endcsname{\startfittingpage[\currentfittingpage]}%
-    \frozen\instance\protected\edefcsname\e!stop \currentfittingpage\endcsname{\stopfittingpage}%
+    \protected\frozen\instance\edefcsname\e!start\currentfittingpage\endcsname{\startfittingpage[\currentfittingpage]}%
+    \protected\frozen\instance\edefcsname\e!stop \currentfittingpage\endcsname{\stopfittingpage}%
 \to \everydefinefittingpage
 
 \permanent\tolerant\protected\def\startfittingpage[#1]#*[#S#2]%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-blk.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-blk.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-blk.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -71,8 +71,9 @@
 
 -- maybe intercept nesting with error
 
-local currentpreroll = false
-local prerolled = { }
+local currentpreroll  = false
+local currentrealpage = 0
+local prerolled       = { }
 
 implement {
     name      = "startprerollpageblock",

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-cst.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-cst.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-cst.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -643,6 +643,7 @@
     end
  -- report("checking width %p, height %p, depth %p, slot (%i,%i)",boxwidth,boxheight,boxdepth,c,r)
     local nr = ceil(boxheight/(lineheight+linedepth))
+    local nc = 1
     --
     local action = methods[method]
     local cfound = false

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-cst.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-cst.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-cst.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -64,8 +64,8 @@
    \c!maxwidth=\makeupwidth]
 
 \appendtoks % could become an option
-    \frozen\instance\protected\edefcsname\e!start\currentpagegrid\endcsname{\startpagegrid[\currentpagegrid]}%
-    \frozen\instance\protected\edefcsname\e!stop \currentpagegrid\endcsname{\stoppagegrid}%
+    \protected\frozen\instance\edefcsname\e!start\currentpagegrid\endcsname{\startpagegrid[\currentpagegrid]}%
+    \protected\frozen\instance\edefcsname\e!stop \currentpagegrid\endcsname{\stoppagegrid}%
     \clf_definecolumnset {
         name {\currentpagegrid}%
     }%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-lin.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-lin.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-lin.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -442,28 +442,69 @@
 % \def\dodorlap{\hbox to \zeropoint{\box\nextbox\normalhss}\endgroup}
 % \def\dodollap{\hbox to \zeropoint{\normalhss\box\nextbox}\endgroup}
 
-\def\page_line_handle_left#align#width#distance%
+\def\page_line_handle_left_skip#distance%
+   {\kern{%
+      #distance+\d_page_lines_distance
+      \ifconditional\c_page_lines_dir_left_to_right\else+\d_page_lines_line_width\fi
+    }}
+
+\def\page_line_handle_right_skip#distance%
+  {\kern{%
+     #distance+\d_page_lines_distance
+     \ifconditional\c_page_lines_dir_left_to_right+\d_page_lines_line_width\fi
+   }}
+
+\def\page_line_handle_left
+  {\ifconditional\c_spac_lines_enabled
+     \expandafter\page_line_handle_left_lines
+   \else
+     \expandafter\page_line_handle_left_normal
+   \fi}
+
+\def\page_line_handle_right
+  {\ifconditional\c_spac_lines_enabled
+     \expandafter\page_line_handle_right_lines
+   \else
+     \expandafter\page_line_handle_right_normal
+   \fi}
+
+% running text, anything can be a line, no structure
+
+\def\page_line_handle_left_normal#align#width#distance%
+  {\dostarttaggednodetail\t!ignore
+   \llap
+     {\page_lines_number_inject#align#width%
+      \page_line_handle_left_skip{#distance}%
+      \expand\everylinenumber
+      \hss}%
+   \dostoptagged}
+
+\def\page_line_handle_right_normal#align#width#distance%
+  {\dostarttaggednodetail\t!ignore
+   \rlap
+     {\page_line_handle_right_skip{#distance}%
+      \page_lines_number_inject#align#width%
+      \expand\everylinenumber
+      \hss}%
+   \dostoptagged}
+
+% the controlled situation, so we have structure
+
+\def\page_line_handle_left_lines#align#width#distance%
   {\dostarttaggednodetail\t!linenumber
    \llap
      {\page_lines_number_inject#align#width%
       \dostarttaggednodetail\t!ignore
-      \kern{%
-        #distance+\d_page_lines_distance
-        \ifconditional\c_page_lines_dir_left_to_right\else+\d_page_lines_line_width\fi
-      }%
+      \page_line_handle_left_skip{#distance}%
       \expand\everylinenumber
       \hss
       \dostoptagged}%
    \dostoptagged}
 
-\def\page_line_handle_right#align#width#distance%
+\def\page_line_handle_right_lines#align#width#distance%
   {\dostarttaggednodetail\t!linenumber
    \rlap
-     {\dostarttaggednodetail\t!ignore
-      \kern{%
-        #distance+\d_page_lines_distance
-        \ifconditional\c_page_lines_dir_left_to_right+\d_page_lines_line_width\fi
-      }%
+     {\page_line_handle_right_skip{#distance}%
       \dostoptagged
       \page_lines_number_inject#align#width%
       \dostarttaggednodetail\t!ignore

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-mak.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-mak.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-mak.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -42,8 +42,8 @@
 \installcommandhandler \??makeup {makeup} \??makeup
 
 \appendtoks
-   \frozen\protected\instance\edefcsname\e!start\currentmakeup\e!makeup\endcsname{\startmakeup[\currentmakeup]}%
-   \frozen\protected\instance\edefcsname\e!stop \currentmakeup\e!makeup\endcsname{\stopmakeup}%
+   \protected\frozen\instance\edefcsname\e!start\currentmakeup\e!makeup\endcsname{\startmakeup[\currentmakeup]}%
+   \protected\frozen\instance\edefcsname\e!stop \currentmakeup\e!makeup\endcsname{\stopmakeup}%
    \doifelselayoutdefined\currentmakeup\donothing{\definelayout[\currentmakeup]}% new
 \to \everydefinemakeup
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-mix.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-mix.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-mix.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -107,8 +107,8 @@
 
 \appendtoks % could become an option
     \ifcstok{\mixedcolumnsparameter\c!define}\v!yes
-      \frozen\instance\protected\edefcsname\e!start\currentmixedcolumns\endcsname{\startmixedcolumns[\currentmixedcolumns]}%
-      \frozen\instance\protected\edefcsname\e!stop \currentmixedcolumns\endcsname{\stopmixedcolumns}%
+      \protected\frozen\instance\edefcsname\e!start\currentmixedcolumns\endcsname{\startmixedcolumns[\currentmixedcolumns]}%
+      \protected\frozen\instance\edefcsname\e!stop \currentmixedcolumns\endcsname{\stopmixedcolumns}%
     \fi
 \to \everydefinemixedcolumns
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-mvl.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-mvl.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-mvl.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1126,6 +1126,7 @@
         end
      -- report("checking width %p, height %p, depth %p, slot (%i,%i)",boxwidth,boxheight,boxdepth,c,r)
         local nr = ceil(boxheight/(lineheight+linedepth))
+        local nc = 0
         --
         local action = methods[method]
         local cfound = false

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-mvl.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-mvl.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-mvl.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -122,8 +122,8 @@
 
 \appendtoks % could become an option
     \ifempty\currentcolumnset\else
-      \frozen\instance\protected\edefcsname\e!start\currentcolumnset\endcsname{\startcolumnset[\currentcolumnset]}%
-      \frozen\instance\protected\edefcsname\e!stop \currentcolumnset\endcsname{\stopcolumnset}%
+      \protected\frozen\instance\edefcsname\e!start\currentcolumnset\endcsname{\startcolumnset[\currentcolumnset]}%
+      \protected\frozen\instance\edefcsname\e!stop \currentcolumnset\endcsname{\stopcolumnset}%
       \clf_definecolumnset {
         name     {\currentcolumnset}%
         nofrows  {\columnsetparameter\c!lines}%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/page-pcl.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/page-pcl.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/page-pcl.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -699,8 +699,8 @@
    \c!direction=\v!normal]
 
 \appendtoks % could become an option
-    \frozen\instance\protected\edefcsname\e!start\currentpagecolumns\endcsname{\startpagecolumns[\currentpagecolumns]}%
-    \frozen\instance\protected\edefcsname\e!stop \currentpagecolumns\endcsname{\stoppagecolumns}%
+    \protected\frozen\instance\edefcsname\e!start\currentpagecolumns\endcsname{\startpagecolumns[\currentpagecolumns]}%
+    \protected\frozen\instance\edefcsname\e!stop \currentpagecolumns\endcsname{\stoppagecolumns}%
 \to \everydefinepagecolumns
 
 \def\page_col_pickup_preceding

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/phys-dim.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/phys-dim.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/phys-dim.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -432,7 +432,7 @@
 \to \everyunits
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\currentunit\endcsname{\phys_units_direct{\currentunit}}
+    \protected\frozen\instance\edefcsname\currentunit\endcsname{\phys_units_direct{\currentunit}}
 \to \everydefineunit
 
 \protected\def\phys_units_direct#1%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-but.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-but.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-but.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -50,7 +50,7 @@
 \aliased\let\setupbuttons\setupbutton
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\currentbutton\endcsname{\scrn_button_direct{\currentbutton}}%
+    \protected\frozen\instance\edefcsname\currentbutton\endcsname{\scrn_button_direct{\currentbutton}}%
 \to \everydefinebutton
 
 \protected\def\scrn_button_direct#tag%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-fld.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-fld.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-fld.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -660,7 +660,7 @@
    \c!backgroundcolor=gray]
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\currenttooltip\endcsname{\scrn_tooltip_direct{\currenttooltip}}%
+    \protected\frozen\instance\edefcsname\currenttooltip\endcsname{\scrn_tooltip_direct{\currenttooltip}}%
 \to \everydefinetooltip
 
 \protected\def\scrn_tooltip_direct#tag%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-hlp.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-hlp.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-hlp.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -69,9 +69,9 @@
    \c!backgroundcolor=gray]
 
 \appendtoks
-    \frozen\instance\protected\edefcsname        \currenthelp\endcsname{\scrn_help_argument{\currenthelp}}%
-    \frozen\instance\protected\edefcsname\e!start\currenthelp\endcsname{\scrn_help_start   {\currenthelp}}%
-    \frozen\instance\protected\edefcsname\e!stop \currenthelp\endcsname{\scrn_help_stop                  }%
+    \protected\frozen\instance\edefcsname        \currenthelp\endcsname{\scrn_help_argument{\currenthelp}}%
+    \protected\frozen\instance\edefcsname\e!start\currenthelp\endcsname{\scrn_help_start   {\currenthelp}}%
+    \protected\frozen\instance\edefcsname\e!stop \currenthelp\endcsname{\scrn_help_stop                  }%
 \to \everydefinehelp
 
 \mutable\lettonothing\currenthelpreference

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-ini.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-ini.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-ini.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -75,9 +75,9 @@
 % interactions so a general start-stop will do
 %
 % \appendtoks
-%     \frozen\instance\protected\edefcsname        \currentinteraction\endcsname{\scrn_interaction_direct{\currentinteraction}}%
-%     \frozen\instance\protected\edefcsname\e!start\currentinteraction\endcsname{\scrn_interaction_start {\currentinteraction}}%
-%     \frozen\instance\protected\edefcsname\e!stop \currentinteraction\endcsname{\scrn_interaction_stop                       }%
+%     \protected\frozen\instance\edefcsname        \currentinteraction\endcsname{\scrn_interaction_direct{\currentinteraction}}%
+%     \protected\frozen\instance\edefcsname\e!start\currentinteraction\endcsname{\scrn_interaction_start {\currentinteraction}}%
+%     \protected\frozen\instance\edefcsname\e!stop \currentinteraction\endcsname{\scrn_interaction_stop                       }%
 % \to \everydefineinteraction
 %
 % \protected\def\scrn_interaction_direct#1%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-wid.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-wid.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/scrn-wid.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -120,9 +120,9 @@
    \fi}
 
 \appendtoks
-    \frozen\instance\protected\edefcsname        \currentattachment\endcsname{\scrn_attachment_direct[\currentattachment]}%
-    \frozen\instance\protected\edefcsname\e!start\currentattachment\endcsname{\scrn_attachment_start [\currentattachment]}%
-    \frozen\instance\protected\edefcsname\e!stop \currentattachment\endcsname{\scrn_attachment_stop                      }%
+    \protected\frozen\instance\edefcsname        \currentattachment\endcsname{\scrn_attachment_direct[\currentattachment]}%
+    \protected\frozen\instance\edefcsname\e!start\currentattachment\endcsname{\scrn_attachment_start [\currentattachment]}%
+    \protected\frozen\instance\edefcsname\e!stop \currentattachment\endcsname{\scrn_attachment_stop                      }%
 \to \everydefineattachment
 
 \permanent\tolerant\protected\def\scrn_attachment_direct[#tag]#spacer[#registered]#spacer[#S#settings]%
@@ -411,9 +411,9 @@
 \mutable\lettonothing\currentcommentwidth
 
 \appendtoks
-    \frozen\protected\instance\edefcsname        \currentcomment\endcsname{\scrn_comment_argument[\currentcomment]}%
-    \frozen\protected\instance\edefcsname\e!start\currentcomment\endcsname{\scrn_comment_start   [\currentcomment]}%
-    \frozen\protected\instance\edefcsname\e!stop \currentcomment\endcsname{\scrn_comment_stop                     }%
+    \protected\frozen\instance\edefcsname        \currentcomment\endcsname{\scrn_comment_argument[\currentcomment]}%
+    \protected\frozen\instance\edefcsname\e!start\currentcomment\endcsname{\scrn_comment_start   [\currentcomment]}%
+    \protected\frozen\instance\edefcsname\e!stop \currentcomment\endcsname{\scrn_comment_stop                     }%
 \to \everydefinecomment
 
 \tolerant\protected\def\scrn_comment_argument[#category]#spacer[#title]#spacer[#S#settings]#:#text%%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/scrp-ini.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/scrp-ini.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/scrp-ini.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -308,7 +308,7 @@
     end
 end
 
-function getscriptstatus(n)
+local function getscriptstatus(n)
     local p = propertydata[n]
     if p then
         return p.scriptstatus

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/scrp-ini.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/scrp-ini.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/scrp-ini.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -58,7 +58,7 @@
 % presets are global and are currently defined in lua
 
 % \appendtoks
-%     \frozen\instance\protected\edefcsname\currentscript\endcsname{\setscript[\currentscript]}%
+%     \protected\frozen\instance\edefcsname\currentscript\endcsname{\setscript[\currentscript]}%
 % \to \everydefinescript
 
 \permanent\protected\def\setlocalscript[#1]%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ali.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ali.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ali.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -43,8 +43,8 @@
 local alignments       = { }
 typesetters.alignments = alignments
 
-local report_realign   = logs.reporter("typesetters","margindata")
-local trace_realign    = trackers.register("typesetters.margindata", function(v) trace_margindata = v end)
+local report_realign   = logs.reporter("typesetters","realign")
+local trace_realign    = trackers.register("typesetters.realign", function(v) trace_realign = v end)
 
 local nofrealigned     = 0
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ali.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ali.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ali.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1565,7 +1565,7 @@
 % Some obsolete (old) helpers:
 
 \permanent\tolerant\protected\def\definehbox[#1]#*[#2]%
-  {\ifarguments\else\frozen\instance\protected\defcsname hbox#1\endcsname##1{\hbox to #2{\begstrut##1\endstrut\hss}}\fi}
+  {\ifarguments\else\protected\frozen\instance\defcsname hbox#1\endcsname##1{\hbox to #2{\begstrut##1\endstrut\hss}}\fi}
 
 %D Some direction related helpers:
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/spac-hor.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/spac-hor.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/spac-hor.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -812,8 +812,8 @@
    \c!default=\v!middle]
 
 \appendtoks
-   \frozen\instance\protected\edefcsname\e!start\currentnarrower\endcsname{\spac_narrower_start[\currentnarrower]}%
-   \frozen\instance\protected\edefcsname\e!stop \currentnarrower\endcsname{\spac_narrower_stop}%
+   \protected\frozen\instance\edefcsname\e!start\currentnarrower\endcsname{\spac_narrower_start[\currentnarrower]}%
+   \protected\frozen\instance\edefcsname\e!stop \currentnarrower\endcsname{\spac_narrower_stop}%
 \to \everydefinenarrower
 
 \permanent\protected\def\installnarrowermethod#1#2%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/spac-lin.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/spac-lin.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/spac-lin.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -59,7 +59,7 @@
    \c!space=\v!default]
 
 \appendtoks
-   \frozen\instance\protected\edefcsname\e!start\currentlines\endcsname{\spac_lines_start[\currentlines]}%
+   \protected\frozen\instance\edefcsname\e!start\currentlines\endcsname{\spac_lines_start[\currentlines]}%
    \frozen\instance\letcsname           \e!stop \currentlines\endcsname \spac_lines_stop
 \to \everydefinelines
 
@@ -116,13 +116,15 @@
 %D
 %D \start \showmakeup[vpenalty] \getbuffer \stop
 
+\newconditional \c_spac_lines_enabled
+
 \permanent\tolerant\protected\def\spac_lines_start[#1]%
   {\bgroup
+   \c_spac_lines_enabled\conditionaltrue
    \cdef\currentlines{#1}%
    \obeylines
    \spac_lines_start_indeed}
 
-
 \tolerant\def\spac_lines_start_indeed[#S#1]% new: optional second argument (WS)
   {\ifarguments\or
      \setupcurrentlines[#1]%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/spac-prf.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/spac-prf.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/spac-prf.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -216,8 +216,8 @@
             -- progress
             position = width
             width    = position + wd
-                p = floor((position - margin)/step + 0.5)
-                w = floor((width    + margin)/step - 0.5)
+            local p = floor((position - margin)/step + 0.5)
+            local w = floor((width    + margin)/step - 0.5)
             if p < 0 then
                 p = 0
             end
@@ -262,11 +262,10 @@
 
 local function getpagelist()
     local pagehead = texlists.pagehead
+    local pagetail = nil
     if pagehead then
         pagehead = tonut(texlists.pagehead)
         pagetail = find_node_tail(pagehead)
-    else
-        pagetail = nil
     end
     return pagehead, pagetail
 end
@@ -1027,10 +1026,10 @@
                 -- progress
                 position = width
                 width    = position + wd
-             -- p = round((position - margin)/step)
-             -- w = round((width    + margin)/step)
-                p = floor((position - margin)/step + 0.5)
-                w = floor((width    + margin)/step - 0.5)
+             -- local p = round((position - margin)/step)
+             -- local w = round((width    + margin)/step)
+                local p = floor((position - margin)/step + 0.5)
+                local w = floor((width    + margin)/step - 0.5)
                 if p < 0 then
                     p = 0
                 end
@@ -1079,31 +1078,34 @@
 
     end
 
-    getdepthprofile = function(line,step,margin,max,list)
+    local getdepthprofile = function(line,step,margin,max,list)
         return getprofile(line,step,margin,max,list,1)
     end
-    getheightprofile = function(line,step,margin,max,list)
+    local getheightprofile = function(line,step,margin,max,list)
         return getprofile(line,step,margin,max,list,0)
     end
 
-experiments.register("optimize.spacing.profile",function()
-    local getprofile = helper and helper.getprofile
-    if getprofile then
-        -- todo: pass the table directly
-        getdepthprofile = function(line,step,margin,max,list)
-            local t = { step = step, margin = margin, maximum = max, method = 1 }
-            return getprofile(line,list,t)
+    experiments.register("optimize.spacing.profile",function()
+        local getprofile = helper and helper.getprofile
+        if getprofile then
+            -- todo: pass the table directly
+            getdepthprofile = function(line,step,margin,max,list)
+                local t = { step = step, margin = margin, maximum = max, method = 1 }
+                return getprofile(line,list,t)
+            end
+            getheightprofile = function(line,step,margin,max,list)
+                local t = { step = step, margin = margin, maximum = max, method = 0 }
+                return getprofile(line,list,t)
+            end
         end
-        getheightprofile = function(line,step,margin,max,list)
-            local t = { step = step, margin = margin, maximum = max, method = 0 }
-            return getprofile(line,list,t)
-        end
-    end
-end)
+    end)
 
     local show_lineprofile = false
     local show_linedetails = false
 
+    local glue_mode = nil
+    local line_mode = nil
+
     trackers.register("profiling.lines.show", function(v)
         local visualizers = nodes.visualizers
         glue_mode = visualizers.modes.glue
@@ -1113,7 +1115,7 @@
     end)
 
     trackers.register("profiling.lines.details", function(v)
-        show_linedetail = v
+        show_linedetails = v
     end)
 
     local defaultstep   = 65536 * 2 -- 2pt
@@ -1123,7 +1125,7 @@
     -- I played with different methods (like only get depths and then on the fly check with heights
     -- but there is no gain and it is also fuzzy. So for now we just do the whole scan.
 
-    function profilelines(list,prev)
+    local function profilelines(list,prev)
 
         if not list then
             return
@@ -1230,7 +1232,7 @@
                                                     setattr(bot,a_visual,line_mode)
                                                     setattr(top,a_visual,line_mode)
                                                 end
-                                                if show_linedetail then
+                                                if show_linedetails then
                                                     report("lineskip changed from %p to %p on page %i",amount,overshoot,tex.getcount("realpageno"))
                                                 end
                                             end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ver.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ver.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ver.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -196,7 +196,10 @@
 
 local linelist_code       <const> = nodes.listcodes.line
 
-local setvisual           = function(...) setvisual = nuts.setvisual return setvisual(...) end
+local function setvisual(...)
+    setvisual = nuts.setvisual
+    return setvisual(...)
+end
 
 local properties          = nodes.properties.data
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ver.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ver.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/spac-ver.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1298,7 +1298,7 @@
    \let\minimumlinedistance\zeropoint}
 
 \overloaded\permanent\protected\def\nointerlineskip
-  {\prevdepth\ignoredepthcriterion}% -\thousandpoint
+  {\ifvmode\prevdepth\ignoredepthcriterion\fi}% -\thousandpoint
 
 \aliased\let\normaloffinterlineskip\offinterlineskip % knuth's original
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-con.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-con.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-con.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1050,66 +1050,218 @@
 \let\currentconstructionsynchronize\relax
 \let\currentconstructionattribute  \attributeunsetvalue
 
+% \def\strc_constructions_register_yes[#S#1][#S#2]% #1=optional user data #2=interfaced-settings
+%   {\begingroup                              % similar to structure so we might generalize this
+%    \setupcurrentconstruction[#2]%           % xdef's will become edef's
+%    \xdef\currentconstructionexpansion      {\constructionparameter\c!expansion}%
+%    \xdef\currentconstructionxmlsetup       {\constructionparameter\c!xmlsetup}%
+%    \xdef\currentconstructioncatcodes       {\constructionparameter\s!catcodes}%
+%    \xdef\currentconstructionlabel          {\constructionparameter\c!label}%
+%    \xdef\currentconstructionreference      {\constructionparameter\c!reference}%
+%    \xdef\currentconstructionreferencetext  {\constructionparameter\c!referencetext}%
+%    \xdef\currentconstructionreferenceprefix{\constructionparameter\c!referenceprefix}%
+%    %xdef\currentconstructionshownumber     {\constructionparameter\c!number}%
+%    \xdef\currentconstructionincrementnumber{\constructionparameter\c!incrementnumber}%
+%    \xdef\currentconstructiondelay          {\constructionparameter\c!delay}%
+%    %
+%    \ifempty\currentconstructionexpansion
+%      \glet\currentconstructionexpansion\v!no
+%    \fi
+%    %
+%    \ifempty\currentconstructionreferenceprefix
+%      \glet\currentconstructionreferenceprefix\referenceprefix
+%    \fi
+%    \ifx\currentconstructionexpansion\s!xml
+%      \xmlstartraw
+%        \xdef\currentconstructiontitle        {\constructionparameter\c!title}%
+%        \xdef\currentconstructionbookmark     {\constructionparameter\c!bookmark}%
+%        \xdef\currentconstructionmarking      {\constructionparameter\c!marking}%
+%        \xdef\currentconstructionlist         {\constructionparameter\c!list}%
+%        \xdef\currentconstructionreferencetext{\constructionparameter\c!referencetext}%
+%      \xmlstopraw
+%      \iflocation \ifempty\currentconstructionbookmark
+%        \xdef\currentconstructionbookmark{\prerolltostring{\currentconstructiontitle}}%
+%      \fi \fi
+%      \ifempty\currentconstructionlist
+%        \glet\currentconstructionlist\currentconstructiontitle
+%      \fi
+%      \glet\currentconstructioncoding\s!xml
+%    \else
+%      \ifx\currentconstructionexpansion\v!yes
+%        \xdef\currentconstructiontitle        {\constructionparameter\c!title}%
+%        \xdef\currentconstructionbookmark     {\constructionparameter\c!bookmark}%
+%        \xdef\currentconstructionmarking      {\constructionparameter\c!marking}%
+%        \xdef\currentconstructionlist         {\constructionparameter\c!list}%
+%        \xdef\currentconstructionreferencetext{\constructionparameter\c!referencetext}%
+%        \iflocation \ifempty\currentconstructionbookmark
+%          \xdef\currentconstructionbookmark{\prerolltostring{\currentconstructiontitle}}%
+%        \fi \fi
+%      \else
+%        \xdef\currentconstructiontitle        {\detokenizedconstructionparameter\c!title}%
+%        \xdef\currentconstructionbookmark     {\detokenizedconstructionparameter\c!bookmark}%
+%        \xdef\currentconstructionmarking      {\detokenizedconstructionparameter\c!marking}%
+%        \xdef\currentconstructionlist         {\detokenizedconstructionparameter\c!list}%
+%        \xdef\currentconstructionreferencetext{\detokenizedconstructionparameter\c!referencetext}%
+%        \iflocation \ifempty\currentconstructionbookmark
+%          \xdef\currentconstructionbookmark{\prerolltostring{\constructionparameter\c!title}}%
+%        \fi \fi
+%      \fi
+%      \ifempty\currentconstructionlist
+%        \glet\currentconstructionlist\currentconstructiontitle
+%      \fi
+%      \glet\currentconstructioncoding\s!tex
+%    \fi
+%    %
+%    \ifx\currentconstructiontitle\v!none % will become obsolete
+%      \global\noconstructioncaptiontrue
+%    \fi
+%    %
+%    \ifnoconstructioncaption % then why analyze anyway?
+%      \endgroup
+%      \let\currentconstructionlistnumber \relax
+%      \let\currentconstructionsynchronize\relax
+%      \let\currentconstructionattribute  \relax
+%    \else
+%      \setnextinternalreferences{construction}\currentconstructionmain % plural
+%      \relax
+%      \scratchcounter\clf_addtolist
+%         metadata {
+%             kind     {construction}
+%             name     {\currentconstructionmain}
+%           % level    structures.sections.currentlevel()
+%             catcodes \catcodetable
+%         }
+%         references {
+%             internal  \locationcount
+%             order     \locationorder
+%             reference {\currentconstructionreference}
+%             prefix    {\currentconstructionreferenceprefix}
+%           % block     {\currentsectionblock}
+%           % section   structures.sections.currentid(),
+%             delay     {\currentconstructiondelay}
+%         }
+%         titledata  {
+%             label     {\detokenize\expandafter{\currentconstructionlabel}}
+%             title     {\detokenize\expandafter{\currentconstructiontitle}}
+%         \ifx\currentconstructionbookmark\currentconstructiontitle \else
+%             bookmark  {\detokenize\expandafter{\currentconstructionbookmark}}
+%         \fi
+%         \ifx\currentconstructionreferencetext\currentconstructiontitle \else
+%             reference {\detokenize\expandafter{\currentconstructionreferencetext}}
+%         \fi
+%         \ifx\currentconstructionlist\currentconstructiontitle \else
+%             list      {\detokenize\expandafter{\currentconstructionlist}}
+%         \fi
+%         }
+%     \ifconditional\c_strc_constructions_number_state
+%         prefixdata {
+%             prefix        {\constructionparameter\c!prefix}
+%             separatorset  {\constructionparameter\c!prefixseparatorset}
+%             conversion    {\constructionparameter\c!prefixconversion}
+%             conversionset {\constructionparameter\c!prefixconversionset}
+%             set           {\constructionparameter\c!prefixset}
+%             segments      {\constructionparameter\c!prefixsegments}
+%             connector     {\constructionparameter\c!prefixconnector}
+%         }
+%         numberdata {
+%             numbers       {\currentconstructionnumber}
+%             separatorset  {\constructionparameter\c!numberseparatorset}
+%             conversion    {\constructionparameter\c!numberconversion}
+%             conversionset {\constructionparameter\c!numberconversionset}
+%             starter       {\constructionparameter\c!numberstarter}
+%             stopper       {\constructionparameter\c!numberstopper}
+%             segments      {\constructionparameter\c!numbersegments}
+%         }
+%     \else
+%        % symbol
+%     \fi
+%         userdata {\detokenize{#1}}
+%      \relax
+%    % \writestatus{constructions}{registering \currentconstruction: \number\scratchcounter}%
+%      \clf_setinternalreference
+%        prefix    {\currentconstructionreferenceprefix}%
+%        reference {\currentconstructionreference}%
+%        internal  \locationcount
+%        view      {\interactionparameter\c!focus}%
+%      \relax
+%      \expanded {%
+%        \endgroup
+%        \edef\noexpand\currentconstructionlistentry  {\the\scratchcounter}%
+%        \edef\noexpand\currentconstructionattribute  {\the\lastdestinationattribute}%
+%        \edef\noexpand\currentconstructionsynchronize{\clf_deferredenhancelist\the\scratchcounter}%
+%      }%
+%    \fi}
+
 \def\strc_constructions_register_yes[#S#1][#S#2]% #1=optional user data #2=interfaced-settings
   {\begingroup                              % similar to structure so we might generalize this
    \setupcurrentconstruction[#2]%           % xdef's will become edef's
-   \xdef\currentconstructionexpansion      {\constructionparameter\c!expansion}%
-   \xdef\currentconstructionxmlsetup       {\constructionparameter\c!xmlsetup}%
-   \xdef\currentconstructioncatcodes       {\constructionparameter\s!catcodes}%
-   \xdef\currentconstructionlabel          {\constructionparameter\c!label}%
-   \xdef\currentconstructionreference      {\constructionparameter\c!reference}%
-   \xdef\currentconstructionreferencetext  {\constructionparameter\c!referencetext}%
-   \xdef\currentconstructionreferenceprefix{\constructionparameter\c!referenceprefix}%
-   %xdef\currentconstructionshownumber     {\constructionparameter\c!number}%
-   \xdef\currentconstructionincrementnumber{\constructionparameter\c!incrementnumber}%
+   \edef\currentconstructionexpansion      {\constructionparameter\c!expansion}%
+   \edef\currentconstructionxmlsetup       {\constructionparameter\c!xmlsetup}%
+   \edef\currentconstructioncatcodes       {\constructionparameter\s!catcodes}%
+   \edef\currentconstructionlabel          {\constructionparameter\c!label}%
+   \edef\currentconstructionreference      {\constructionparameter\c!reference}%
+   \edef\currentconstructionreferencetext  {\constructionparameter\c!referencetext}%
+   \edef\currentconstructionreferenceprefix{\constructionparameter\c!referenceprefix}%
+   %edef\currentconstructionshownumber     {\constructionparameter\c!number}%
+   \edef\currentconstructionincrementnumber{\constructionparameter\c!incrementnumber}%
+   \edef\currentconstructiondelay          {\constructionparameter\c!delay}%
    %
    \ifempty\currentconstructionexpansion
-     \glet\currentconstructionexpansion\v!no
+     \let\currentconstructionexpansion\v!no
    \fi
    %
    \ifempty\currentconstructionreferenceprefix
-     \glet\currentconstructionreferenceprefix\referenceprefix
+     \let\currentconstructionreferenceprefix\referenceprefix
    \fi
    \ifx\currentconstructionexpansion\s!xml
      \xmlstartraw
-       \xdef\currentconstructiontitle        {\constructionparameter\c!title}%
-       \xdef\currentconstructionbookmark     {\constructionparameter\c!bookmark}%
-       \xdef\currentconstructionmarking      {\constructionparameter\c!marking}%
-       \xdef\currentconstructionlist         {\constructionparameter\c!list}%
-       \xdef\currentconstructionreferencetext{\constructionparameter\c!referencetext}%
+       \edef\currentconstructiontitle        {\constructionparameter\c!title}%
+       \edef\currentconstructionbookmark     {\constructionparameter\c!bookmark}%
+       \edef\currentconstructionmarking      {\constructionparameter\c!marking}%
+       \edef\currentconstructionlist         {\constructionparameter\c!list}%
+       \edef\currentconstructionreferencetext{\constructionparameter\c!referencetext}%
      \xmlstopraw
+     \iflocation \ifempty\currentconstructionbookmark % maybe also when tagging
+       \ifconditional\c_strc_tags_enabled
+         \edef\currentconstructionbookmark{\prerolltostring{\currentconstructiontitle}}%
+       \fi
+     \fi \fi
      \ifempty\currentconstructionlist
-       \glet\currentconstructionlist\currentconstructiontitle
+       \let\currentconstructionlist\currentconstructiontitle
      \fi
-     \glet\currentconstructioncoding\s!xml
+     \let\currentconstructioncoding\s!xml
    \else
      \ifx\currentconstructionexpansion\v!yes
-       \xdef\currentconstructiontitle        {\constructionparameter\c!title}%
-       \xdef\currentconstructionbookmark     {\constructionparameter\c!bookmark}%
-       \xdef\currentconstructionmarking      {\constructionparameter\c!marking}%
-       \xdef\currentconstructionlist         {\constructionparameter\c!list}%
-       \xdef\currentconstructionreferencetext{\constructionparameter\c!referencetext}%
+       \edef\currentconstructiontitle        {\constructionparameter\c!title}%
+       \edef\currentconstructionbookmark     {\constructionparameter\c!bookmark}%
+       \edef\currentconstructionmarking      {\constructionparameter\c!marking}%
+       \edef\currentconstructionlist         {\constructionparameter\c!list}%
+       \edef\currentconstructionreferencetext{\constructionparameter\c!referencetext}%
+       \iflocation \ifempty\currentconstructionbookmark % maybe also when tagging
+         \ifconditional\c_strc_tags_enabled
+           \edef\currentconstructionbookmark{\prerolltostring{\currentconstructiontitle}}%
+         \fi
+       \fi \fi
      \else
-       \xdef\currentconstructiontitle        {\detokenizedconstructionparameter\c!title}%
-       \xdef\currentconstructionbookmark     {\detokenizedconstructionparameter\c!bookmark}%
-       \xdef\currentconstructionmarking      {\detokenizedconstructionparameter\c!marking}%
-       \xdef\currentconstructionlist         {\detokenizedconstructionparameter\c!list}%
-       \xdef\currentconstructionreferencetext{\detokenizedconstructionparameter\c!referencetext}%
-       \iflocation \ifempty\currentconstructionbookmark
-         \begingroup
-         \simplifycommands
-         \xdef\currentconstructionbookmark{\detokenize\expandafter{\expanded{\constructionparameter\c!title}}}%
-         \endgroup
+       \edef\currentconstructiontitle        {\detokenizedconstructionparameter\c!title}%
+       \edef\currentconstructionbookmark     {\detokenizedconstructionparameter\c!bookmark}%
+       \edef\currentconstructionmarking      {\detokenizedconstructionparameter\c!marking}%
+       \edef\currentconstructionlist         {\detokenizedconstructionparameter\c!list}%
+       \edef\currentconstructionreferencetext{\detokenizedconstructionparameter\c!referencetext}%
+       \iflocation \ifempty\currentconstructionbookmark % maybe also when tagging
+         \ifconditional\c_strc_tags_enabled
+           \edef\currentconstructionbookmark{\prerolltostring{\constructionparameter\c!title}}%
+         \fi
        \fi \fi
      \fi
      \ifempty\currentconstructionlist
-       \glet\currentconstructionlist\currentconstructiontitle
+       \let\currentconstructionlist\currentconstructiontitle
      \fi
-     \glet\currentconstructioncoding\s!tex
+     \let\currentconstructioncoding\s!tex
    \fi
    %
    \ifx\currentconstructiontitle\v!none % will become obsolete
-     \global\noconstructioncaptiontrue
+     \noconstructioncaptiontrue
    \fi
    %
    \ifnoconstructioncaption % then why analyze anyway?
@@ -1134,6 +1286,7 @@
             prefix    {\currentconstructionreferenceprefix}
           % block     {\currentsectionblock}
           % section   structures.sections.currentid(),
+            delay     {\currentconstructiondelay}
         }
         titledata  {
             label     {\detokenize\expandafter{\currentconstructionlabel}}

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-des.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-des.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-des.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -69,9 +69,9 @@
     \fi
     % We can combine these but in tracing (or errors) using a different caller is nicer.
     \ifcstok{\descriptionparameter\c!define}\v!yes
-        \frozen\protected\instance\edefcsname        \currentdescription\endcsname{\nameddescription[\currentdescription]}%
-        \frozen\protected\instance\edefcsname\e!start\currentdescription\endcsname{\startnameddescription[\currentdescription]}%
-        \frozen\protected\instance \defcsname \e!stop\currentdescription\endcsname{\stopnameddescription}%
+        \protected\frozen\instance\edefcsname        \currentdescription\endcsname{\nameddescription[\currentdescription]}%
+        \protected\frozen\instance\edefcsname\e!start\currentdescription\endcsname{\startnameddescription[\currentdescription]}%
+        \protected\frozen\instance \defcsname \e!stop\currentdescription\endcsname{\stopnameddescription}%
     \fi
 \to \everydefinedescription
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-enu.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-enu.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-enu.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -138,12 +138,12 @@
      \edefcsname\??enumeration#tag:\s!parent\endcsname{\??enumeration#parent}%
    \fi
    \ifcstok{\enumerationparameter\c!define}\v!yes
-     \frozen\protected\instance\edefcsname\e!next #tag\endcsname{\strc_enumerations_next{#tag}{\number#level}}%  obsolete
-     \frozen\protected\instance\edefcsname\c!reset#tag\endcsname{\strc_enumerations_reset{#tag}{\number#level}}% obsolete
-     %frozen\protected\instance\edefcsname\c!set  #tag\endcsname{\strc_enumerations_set{#tag}{\number#level}}%   obsolete
-     \frozen\protected\instance\edefcsname        #tag\endcsname{\namedenumeration[#tag]}%
-     \frozen\protected\instance\edefcsname\e!start#tag\endcsname{\startnamedenumeration[#tag]}%
-     \frozen\protected\instance \defcsname\e!stop #tag\endcsname{\stopnamedenumeration}%
+     \protected\frozen\instance\edefcsname\e!next #tag\endcsname{\strc_enumerations_next{#tag}{\number#level}}%  obsolete
+     \protected\frozen\instance\edefcsname\c!reset#tag\endcsname{\strc_enumerations_reset{#tag}{\number#level}}% obsolete
+     %protected\frozen\instance\edefcsname\c!set  #tag\endcsname{\strc_enumerations_set{#tag}{\number#level}}%   obsolete
+     \protected\frozen\instance\edefcsname        #tag\endcsname{\namedenumeration[#tag]}%
+     \protected\frozen\instance\edefcsname\e!start#tag\endcsname{\startnamedenumeration[#tag]}%
+     \protected\frozen\instance \defcsname\e!stop #tag\endcsname{\stopnamedenumeration}%
    \fi}
 
 \lettonothing\m_strc_enumeration_sub

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-flt.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-flt.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-flt.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -271,19 +271,19 @@
    \strc_floats_define_commands{#1}{#2}}
 
 \def\strc_floats_define_commands#1#2%
-  {\frozen\protected\instance\edefcsname\e!place      \e!listof#2\endcsname{\strc_lists_place[#1]}% call will change
-   \frozen\protected\instance\edefcsname\e!complete   \e!listof#2\endcsname{\strc_lists_complete[#1][#2]}% call will change
-   \frozen\protected\instance\edefcsname\e!place               #1\endcsname{\placefloat[#1]}%
-   \frozen\protected\instance\edefcsname\e!start       \e!place#1\endcsname{\startplacefloat[#1]}%
-   \frozen\protected\instance\edefcsname\e!stop        \e!place#1\endcsname{\stopplacefloat}%
-   \frozen\protected\instance\edefcsname\e!start        #1\e!text\endcsname{\startfloattext[#1]}%
-   \frozen\protected\instance\edefcsname\e!stop         #1\e!text\endcsname{\stopfloattext}%
-   \frozen\protected\instance\edefcsname\e!start\e!place#1\e!text\endcsname{\startplacefloattext[#1]}%
-   \frozen\protected\instance\edefcsname\e!stop \e!place#1\e!text\endcsname{\stopplacefloattext}%
+  {\protected\frozen\instance\edefcsname\e!place      \e!listof#2\endcsname{\strc_lists_place[#1]}% call will change
+   \protected\frozen\instance\edefcsname\e!complete   \e!listof#2\endcsname{\strc_lists_complete[#1][#2]}% call will change
+   \protected\frozen\instance\edefcsname\e!place               #1\endcsname{\placefloat[#1]}%
+   \protected\frozen\instance\edefcsname\e!start       \e!place#1\endcsname{\startplacefloat[#1]}%
+   \protected\frozen\instance\edefcsname\e!stop        \e!place#1\endcsname{\stopplacefloat}%
+   \protected\frozen\instance\edefcsname\e!start        #1\e!text\endcsname{\startfloattext[#1]}%
+   \protected\frozen\instance\edefcsname\e!stop         #1\e!text\endcsname{\stopfloattext}%
+   \protected\frozen\instance\edefcsname\e!start\e!place#1\e!text\endcsname{\startplacefloattext[#1]}%
+   \protected\frozen\instance\edefcsname\e!stop \e!place#1\e!text\endcsname{\stopplacefloattext}%
    % these will become obsolete:
-   \frozen\instance\protected\edefcsname\e!reserve               #1\endcsname{\strc_floats_reserve[#1]}%
-   \frozen\instance\protected\edefcsname\e!start\e!reserve#1\e!text\endcsname{\strc_floats_start_reserve_text[#1]}%
-   \frozen\instance\protected\edefcsname\e!stop \e!reserve#1\e!text\endcsname{\strc_floats_stop_reserve_text}}
+   \protected\frozen\instance\edefcsname\e!reserve               #1\endcsname{\strc_floats_reserve[#1]}%
+   \protected\frozen\instance\edefcsname\e!start\e!reserve#1\e!text\endcsname{\strc_floats_start_reserve_text[#1]}%
+   \protected\frozen\instance\edefcsname\e!stop \e!reserve#1\e!text\endcsname{\strc_floats_stop_reserve_text}}
 
 %D Fallback float body:
 
@@ -1044,6 +1044,8 @@
    \fi
    \splitfloat{\strc_floats_place_next_box_normal}}
 
+\newinteger\c_strc_float_nesting
+
 \protected\def\strc_floats_place_next_box_normal
   {\ifconditional\c_page_floats_some_waiting
      % this was \checkwaitingfloats spread all over
@@ -1055,8 +1057,20 @@
      % but which should be done before using box \floatbox
    \fi
    \page_margin_strc_floats_before % todo: each float handler gets a before
-   \global\insidefloattrue
-   \dostarttaggedchained\t!float\currentfloat\currentfloat\??float
+   \ifinsidefloat
+     \dostarttaggedchained\t!subfloat\currentfloat\currentfloat\??float
+   \else
+     \dostarttaggedchained\t!float\currentfloat\currentfloat\??float
+   \fi
+   \global\advanceby\c_strc_float_nesting\plusone
+   \ifcase\c_strc_float_nesting
+     % of course not
+   \or
+     % we start nestign (likely a float combination)
+     \global\insidefloattrue
+   \else
+     % well ... we'll see
+   \fi
    \page_margin_strc_floats_set_hsize % todo: each float handler gets a set_hsize
    \expand\everyinsidefloat
    \strc_floats_analyze_variables_one
@@ -1491,7 +1505,16 @@
    % place the float
    \strc_floats_set_box
    \strc_floats_get_box
-   \global\insidefloatfalse}
+   \ifcase\c_strc_float_nesting
+     % error
+   \or
+     % back at the outer level
+     \global\c_strc_float_nesting\zerocount
+     \global\insidefloatfalse
+   \else
+     % nested float (probably combination)
+     \global\advanceby\c_strc_float_nesting\minusone
+   \fi}
 
 \newdimension\availablefloatwidth
 \newdimension\availablefloatheight

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ind.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ind.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ind.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -60,12 +60,12 @@
 \newdimension\d_strc_indentedtexts_distance
 
 \appendtoks
-   \frozen\instance\protected\edefcsname\e!start\currentindentedtext\endcsname{\strc_indentedtexts_start{\currentindentedtext}\c_strc_indentedtexts_nesting}%
-   \frozen\instance\protected\edefcsname\e!stop \currentindentedtext\endcsname{\strc_indentedtexts_stop}%
+   \protected\frozen\instance\edefcsname\e!start\currentindentedtext\endcsname{\strc_indentedtexts_start{\currentindentedtext}\c_strc_indentedtexts_nesting}%
+   \protected\frozen\instance\edefcsname\e!stop \currentindentedtext\endcsname{\strc_indentedtexts_stop}%
    % to be avoided ... might go away
-   \frozen\instance\protected\edefcsname            \currentindentedtext\endcsname{\strc_indentedtexts_direct{\currentindentedtext}{0}}%
-   \frozen\instance\protected\edefcsname      \v!sub\currentindentedtext\endcsname{\strc_indentedtexts_direct{\currentindentedtext}{1}}%
-   \frozen\instance\protected\edefcsname\v!sub\v!sub\currentindentedtext\endcsname{\strc_indentedtexts_direct{\currentindentedtext}{2}}%
+   \protected\frozen\instance\edefcsname            \currentindentedtext\endcsname{\strc_indentedtexts_direct{\currentindentedtext}{0}}%
+   \protected\frozen\instance\edefcsname      \v!sub\currentindentedtext\endcsname{\strc_indentedtexts_direct{\currentindentedtext}{1}}%
+   \protected\frozen\instance\edefcsname\v!sub\v!sub\currentindentedtext\endcsname{\strc_indentedtexts_direct{\currentindentedtext}{2}}%
 \to \everydefineindentedtext
 
 \protected\def\strc_indentedtexts_start#1#2% we need to get rid of \spr

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-itm.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-itm.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-itm.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -346,9 +346,9 @@
 \aliased\let\setupitemgroups\setupitemgroup
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\e!start\currentitemgroup           \endcsname{\startitemgroup[\currentitemgroup]}%
-    \frozen\instance\protected\edefcsname\e!stop \currentitemgroup           \endcsname{\stopitemgroup}%
-    \frozen\instance\protected\edefcsname\e!setup\currentitemgroup\e!endsetup\endcsname{\setupitemgroup[\currentitemgroup]}% obsolete
+    \protected\frozen\instance\edefcsname\e!start\currentitemgroup           \endcsname{\startitemgroup[\currentitemgroup]}%
+    \protected\frozen\instance\edefcsname\e!stop \currentitemgroup           \endcsname{\stopitemgroup}%
+    \protected\frozen\instance\edefcsname\e!setup\currentitemgroup\e!endsetup\endcsname{\setupitemgroup[\currentitemgroup]}% obsolete
     \let\currentparentitemgroup\currentitemgroup
     \definecounter[\v_strc_itemgroups_counter]%
 \to \everydefineitemgroup
@@ -2180,9 +2180,9 @@
    \strc_itemgroups_table_pickup}
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\e!stop \currentitemgroup\v!table\endcsname
+    \protected\frozen\instance\edefcsname\e!stop \currentitemgroup\v!table\endcsname
       {}% {\strc_itemgroups_stop_table}
-    \frozen\instance\protected\edefcsname\e!start\currentitemgroup\v!table\endcsname
+    \protected\frozen\instance\edefcsname\e!start\currentitemgroup\v!table\endcsname
       {\strc_itemgroups_start_table[\currentitemgroup]}%
 \to \everydefineitemgroup
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lab.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lab.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lab.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -60,15 +60,15 @@
      \edefcsname\??label#1:\s!parent\endcsname{\??label#3}%
    \fi
    \ifconditional\c_strc_constructions_define_commands
-     \frozen\instance\protected\edefcsname\e!next #1\endcsname{\strc_labels_next {#1}{\number#2}}% obsolete
-     \frozen\instance\protected\edefcsname\v!reset#1\endcsname{\strc_labels_reset{#1}{\number#2}}% obsolete % should be \e!reset anyway
-     %frozen\instance\protected\edefcsname\c!set  #1\endcsname{\strc_labels_set  {#1}{\number#2}}% obsolete
+     \protected\frozen\instance\edefcsname\e!next #1\endcsname{\strc_labels_next {#1}{\number#2}}% obsolete
+     \protected\frozen\instance\edefcsname\v!reset#1\endcsname{\strc_labels_reset{#1}{\number#2}}% obsolete % should be \e!reset anyway
+     %protected\frozen\instance\edefcsname\c!set  #1\endcsname{\strc_labels_set  {#1}{\number#2}}% obsolete
      \ifcsname\v!current#1\endcsname
        % we play safe
      \else
        \protected\edefcsname\v!current#1\endcsname{\strc_labels_current{#1}}%          % obsolete % should be \e!current anyway
      \fi
-     \frozen\instance\protected\edefcsname#1\endcsname{\strc_labels_command[#1]}%
+     \protected\frozen\instance\edefcsname#1\endcsname{\strc_labels_command[#1]}%
    \fi}
 
 % todo: \strc_labels_command for user

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lnt.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lnt.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lnt.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -47,9 +47,9 @@
      \pushmacro\currentnote
      \cdef\currentnote{#1}
      \letcsname\??linenote\currentnote\expandafter\endcsname\csname\currentnote\endcsname % use copy command
-     \frozen\instance\protected\edefcsname        \currentnote\endcsname{\strc_linenotes_direct{\currentnote}}%
-     \frozen\instance\protected\edefcsname\e!start\currentnote\endcsname{\strc_linenotes_start {\currentnote}}%
-     \frozen\instance\protected\edefcsname\e!stop \currentnote\endcsname{\strc_linenotes_stop                }%
+     \protected\frozen\instance\edefcsname        \currentnote\endcsname{\strc_linenotes_direct{\currentnote}}%
+     \protected\frozen\instance\edefcsname\e!start\currentnote\endcsname{\strc_linenotes_start {\currentnote}}%
+     \protected\frozen\instance\edefcsname\e!stop \currentnote\endcsname{\strc_linenotes_stop                }%
      \expand\everydefinelinenote
      \popmacro\currentnote
    \fi}

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lst.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lst.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lst.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -436,7 +436,7 @@
 
 local enhanced = { }
 
-local synchronizepage = function(r)  -- bah ... will move
+local function synchronizepage(r)  -- bah ... will move
     synchronizepage = references.synchronizepage
     return synchronizepage(r)
 end
@@ -1181,17 +1181,23 @@
 
 function lists.label(n,default)
     local l = lists.result[n]
-    local t = l.titledata
+    local t = l and l.titledata
     return t and t.label or default or ""
 end
 
-function lists.sectionnumber(name,n,spec)
-    local data = lists.result[n]
-    local sectiondata = sections.collected[data.references.section]
-    -- hm, prefixnumber?
-    typesetnumber(sectiondata,"prefix",spec,sectiondata) -- data happens to contain the spec too
+function lists.label(n,default)
+    local l = lists.result[n]
+    local t = l and l.titledata
+    return t and t.label or default or ""
 end
 
+
+function lists.bookmark(n,default)
+    local l = lists.result[n]
+    local t = l and l.titledata
+    return t and t.bookmark or default or ""
+end
+
 -- some basics (todo: helpers for pages)
 
 function lists.title(name,n,tag) -- tag becomes obsolete
@@ -1345,7 +1351,8 @@
                     { "internal", "integer" },
                     { "block" },
                     { "section", "integer" },
-                    { "location" },
+                    { "location" }, -- publications
+                    { "delay" },    -- notes
                     { "prefix" },
                     { "reference" },
                     { "view" },
@@ -1502,6 +1509,7 @@
 implement { name = "listexternal",   actions = { lists.external,   context }, arguments = "integer" }
 implement { name = "listlocation",   actions = { lists.location,   context }, arguments = "integer" }
 implement { name = "listlabel",      actions = { lists.label,      context }, arguments = { "integer", "string" } }
+implement { name = "listbookmark",   actions = { lists.bookmark,   context }, arguments = { "integer", "string" } }
 implement { name = "listgroupindex", actions = { lists.groupindex, context }, arguments = "2 strings", }
 
 implement { name = "listrawnumber",   actions = { lists.rawnumber,   context }, arguments = { "string", "integer" } }

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lst.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lst.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-lst.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -534,8 +534,53 @@
 \permanent\def\usestructurelistprocessor#tag%
   {\begincsname\??structurelistprocessor#tag\endcsname}
 
+\mutable\lettonothing\currentlistentrydescription
+
+% begin of of tagging horror
+
 \aliased\let\dotaglistlocation\relax
 
+\def\strc_lists_prerolled_list
+  {\prerolltostring{%
+     \strc_lists_placement_check
+     \dostartignoretagging\empty
+     \doifelsetext{\labeltext\currentlist}%
+       {\labeltext\currentlist}%
+       {\currentlist\space}%
+     \ifconditional\c_lists_show_number
+       \structurelistgenericnumber
+       \space :
+     \fi
+     \clf_listbookmark{\currentlistindex}\empty\relax
+    %\structurelistgenerictitle
+     \ifconditional\c_lists_has_page\relax
+       \space at %
+       \doifelsetext{\labeltext\v!page}%
+         {\labeltext\v!page}%
+         {\v!page\space}%
+       \structurelistpagenumber
+     \fi
+     \dostopignoretagging
+  }}
+
+\def\strc_lists_add_list_description
+  {\ifexporting\orelse\iflocation
+     \ifnum\a_strc_lists_reference=\attributeunsetvalue\else
+       \edef\tempstring{%
+         %\clf_listbookmark{\currentlistindex}\empty
+         \strc_lists_prerolled_list
+       }%
+     % \writestatus{!!!!!}{\tempstring}%
+       \dotagsetreferencedescription
+         \a_strc_lists_reference
+         \tempstring
+     \fi
+   \fi}
+
+\lettonothing\dotagmarklist
+
+% end of tagging horror
+
 \def\strc_lists_entry_process_default
   {no list method}
 
@@ -547,6 +592,7 @@
    \ifcsname\??structurelistprocessor\currentlistmethod             \endcsname\lastnamedcs\orelse
    \ifcsname\??structurelistprocessor\currentlist                   \endcsname\lastnamedcs\else
                                                          \strc_lists_entry_process_default\fi
+   \dotagmarklist % here, as we need to know the attributes (assumes no grouping)
    \dostoptagged
    \listextraparameter\c!after}
 
@@ -901,6 +947,34 @@
     \dontconvertfont % (**) this has to become an option (see publ)
 \to \t_lists_every_renderingtext
 
+% because these tests happen often and because we're dealing with
+% rather complex composed data we have special conditionals; keep
+% in mind that testing for empty fails due to tagging being applied
+
+\def\strc_lists_placement_check
+  {\c_lists_show_page\conditionalfalse % necessary?
+   \processcommacommand[\listparameter\c!pagenumber]\strc_lists_process_pagenumber
+   \ifconditional\c_lists_has_page \else
+     \doifelsestructurelisthaspage
+       {\c_lists_has_page\conditionaltrue}%
+       {\c_lists_has_page\conditionalfalse}%
+   \fi
+   % always forces number placement (in bib we use a forced number)
+   \edef\p_headnumber{\listparameter\c!headnumber}%
+   \ifx\p_headnumber\v!always
+     \c_lists_has_number\conditionaltrue
+     \c_lists_show_number\conditionaltrue
+   \else
+     \doifelsestructurelisthasnumber
+       {\c_lists_has_number\conditionaltrue}%
+       {\c_lists_has_number\conditionalfalse}%
+     \ifx\p_headnumber\v!yes
+       \c_lists_show_number\conditionaltrue
+     \else
+       \c_lists_show_number\conditionalfalse
+     \fi
+   \fi}
+
 \appendtoks
     % because we want to avoid redundant lua calls we expand the
     % location beforehand
@@ -907,43 +981,7 @@
     \ifempty\currentlistentrylocation
         \enforced\edef\currentlistentrylocation{\structurelistlocation}% needs attention
     \fi
-    % because these tests happen often and because we're dealing with
-    % rather complex composed data we have special conditionals; keep
-    % in mind that testing for empty fails do to tagging being applied
-%   \edef\p_pagenumber{\listparameter\c!pagenumber}%
-%   \ifx\p_pagenumber\v!always
-%     \c_lists_has_page\conditionaltrue
-%     \c_lists_show_page\conditionaltrue
-%   \else
-%     \doifelsestructurelisthaspage{\c_lists_has_page\conditionaltrue}{\c_lists_has_page\conditionalfalse}%
-%     \ifx\p_pagenumber\v!yes
-%       \c_lists_show_page\conditionaltrue
-%     \else
-%       \c_lists_show_page\conditionalfalse
-%     \fi
-%   \fi
-    \c_lists_show_page\conditionalfalse % necessary?
-    \processcommacommand[\listparameter\c!pagenumber]\strc_lists_process_pagenumber
-    \ifconditional\c_lists_has_page \else
-      \doifelsestructurelisthaspage
-        {\c_lists_has_page\conditionaltrue}%
-        {\c_lists_has_page\conditionalfalse}%
-    \fi
-    % always forces number placement (in bib we use a forced number)
-    \edef\p_headnumber{\listparameter\c!headnumber}%
-    \ifx\p_headnumber\v!always
-      \c_lists_has_number\conditionaltrue
-      \c_lists_show_number\conditionaltrue
-    \else
-      \doifelsestructurelisthasnumber
-        {\c_lists_has_number\conditionaltrue}%
-        {\c_lists_has_number\conditionalfalse}%
-      \ifx\p_headnumber\v!yes
-        \c_lists_show_number\conditionaltrue
-      \else
-        \c_lists_show_number\conditionalfalse
-      \fi
-    \fi
+    \strc_lists_placement_check
     \strc_lists_interaction_check
 \to \t_lists_every_renderingsetup
 
@@ -1182,7 +1220,7 @@
         }
     }% new
     \endgraf % new, else problems with nointerlinespace and prevdepth
-    \nointerlineskip % anders verkeerde spatiering bij multi-line
+    \ifvmode\nointerlineskip\fi % anders verkeerde spatiering bij multi-line
     \endgraf
     \allowbreak
     \listparameter\c!after

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-mat.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-mat.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-mat.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -142,8 +142,8 @@
 
 \appendtoks
     \expanded{\definelist[\currentformula]}% is expansion needed?
-    \frozen\instance\protected\edefcsname\e!start\currentformula\v!formula\endcsname{\strc_formulas_start_formula{\currentformula}}%
-    \frozen\instance\protected\edefcsname\e!stop \currentformula\v!formula\endcsname{\strc_formulas_stop_formula}%
+    \protected\frozen\instance\edefcsname\e!start\currentformula\v!formula\endcsname{\strc_formulas_start_formula{\currentformula}}%
+    \protected\frozen\instance\edefcsname\e!stop \currentformula\v!formula\endcsname{\strc_formulas_stop_formula}%
 \to \everydefineformula
 
 \definelist[\v!formula]
@@ -161,8 +161,8 @@
 \let\strc_formulas_stop_formula \relax % defined later
 
 \permanent\tolerant\protected\def\defineformulaalternative[#1]#*[#2]#*[#3]%
-  {\frozen\instance\protected\defcsname\e!start#1\v!formula\endcsname{#2}%
-   \frozen\instance\protected\defcsname\e!stop #1\v!formula\endcsname{#3}}
+  {\protected\frozen\instance\defcsname\e!start#1\v!formula\endcsname{#2}%
+   \protected\frozen\instance\defcsname\e!stop #1\v!formula\endcsname{#3}}
 
 % sp = single line paragraph sd = single line display
 % mp = multi  line paragraph md = multi  line display

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-not.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-not.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-not.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -21,8 +21,9 @@
 % todo: more p_strc_notations_* (outside trial loop)
 % todo: see if we can now use \insertpenalties (>0 == some left)
 
-\ifdefined\dotagsetnotesymbol \else \aliased\let\dotagsetnotesymbol\relax \fi
-\ifdefined\dotagsetnotation   \else \aliased\let\dotagsetnotation  \relax \fi
+\ifdefined\dotagsetnotesymbol       \else \aliased\let\dotagsetnotesymbol      \relax              \fi
+\ifdefined\dotagsetnotation         \else \aliased\let\dotagsetnotation        \relax              \fi
+\ifdefined\dotagsetdescriptionindex \else \aliased\let\dotagsetdescriptionindex\gobbletwoarguments \fi
 
 %D \LMTX\ testcase:
 %D
@@ -142,11 +143,11 @@
      \edefcsname\??note    #tag:\s!parent\endcsname{\??note#parent}% see later for \s!note
      \edefcsname\??notation#tag:\s!parent\endcsname{\??notation#parent}%
    \fi
-   \instance\protected\edefcsname\e!next #tag\endcsname{\strc_notations_next{#tag}{\number#level}}% obsolete
-   \instance\protected\edefcsname\c!reset#tag\endcsname{\strc_notations_reset{#tag}{\number#level}}% obsolete
-   \instance\protected\edefcsname        #tag\endcsname{\strc_notations_command[#tag]}%
-   \instance\protected\edefcsname\e!start#tag\endcsname{\strc_notations_start[#tag]}%
-   \instance\protected\edefcsname\e!stop #tag\endcsname{\strc_notations_stop}}
+   \protected\instance\edefcsname\e!next #tag\endcsname{\strc_notations_next{#tag}{\number#level}}% obsolete
+   \protected\instance\edefcsname\c!reset#tag\endcsname{\strc_notations_reset{#tag}{\number#level}}% obsolete
+   \protected\instance\edefcsname        #tag\endcsname{\strc_notations_command[#tag]}%
+   \protected\instance\edefcsname\e!start#tag\endcsname{\strc_notations_start[#tag]}%
+   \protected\instance\edefcsname\e!stop #tag\endcsname{\strc_notations_stop}}
 
 \lettonothing\m_strc_notation_sub
 
@@ -270,11 +271,11 @@
    \fi[#2]}
 
 \def\strc_notations_command_setups[#S#1]%
-  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,\c!referencetext=,#1]%
+  {\strc_constructions_register[][\c!delay={\noteparameter\c!location},\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,\c!referencetext=,#1]%
    \strc_notations_wrapup}
 
 \tolerant\def\strc_notations_command_reference[#1]#*#=%
-  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=,\c!referencetext=]%
+  {\strc_constructions_register[][\c!delay={\noteparameter\c!location},\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=,\c!referencetext=]%
    \strc_notations_wrapup}
 
 \def\strc_notations_wrapup
@@ -316,7 +317,7 @@
    \strc_notations_pickup_yes}
 
 \protected\def\strc_notations_start_setups_indeed[#S#1]#*#2%
-  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#2},\c!bookmark=,\c!list=,\c!referencetext=,#1]%
+  {\strc_constructions_register[][\c!delay={\noteparameter\c!location},\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#2},\c!bookmark=,\c!list=,\c!referencetext=,#1]%
    \strc_notations_wrapup}
 
 \protected\def\strc_notations_start_reference#1[#S#2]%
@@ -324,7 +325,7 @@
    \strc_notations_pickup_yes}
 
 \protected\def\strc_notations_start_reference_indeed[#1]#*#2%
-  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=,\c!referencetext=]%
+  {\strc_constructions_register[][\c!delay={\noteparameter\c!location},\c!label={\descriptionparameter\c!text},\c!reference={#1},\c!title={#2},\c!bookmark=,\c!list=,\c!referencetext=]%
    \strc_notations_wrapup}
 
 \protected\def\strc_notations_stop
@@ -409,6 +410,8 @@
    \c!xmlsetup=,
    \s!catcodes=]
 
+%D Insertions are part of notes.c!delay
+
 %D Insertions are part of notes.
 
 % \installcorenamespace{noteinsertion}
@@ -1345,6 +1348,11 @@
      \noteparameter\c!inbetween
    \fi}
 
+\def\strc_notes_save_indices
+  {\dotagsetdescriptionindex
+      \currentnotenumber
+      \currentconstructionlistentry}
+
 \permanent\protected\def\handlenoteitself#tag#id%
   {\edef\currentnotenumber{#id}%
    \cdef\currentnote{#tag}%
@@ -1364,8 +1372,11 @@
    \begstrut
    \strc_references_flush_destination_nodes
    \strc_notes_set_destination_attribute_text
-   \ifconditional\c_strc_notes_flushed\else
-     \strc_notes_inject_text\relax
+   \ifconditional\c_strc_notes_flushed
+   \else
+       \strc_notes_save_indices % horrible hack (for tagging attachments)
+       \strc_notes_inject_text
+       \relax
    \fi
    \ifvmode\obeydepth\else\endstrut\fi % \obeydepth is new per 2015-01-10
    \strc_constructions_stored_stop

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ref.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ref.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ref.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -533,6 +533,7 @@
     end
     local action = trace_external and
         function(s)
+local structure = references.structure
             if structure then
                 for i=1,#structure do
                     local si = structure[i]
@@ -577,6 +578,7 @@
             if not derived_g[s] then
                 derived_g[s] = entry -- first wins
             end
+local structure = references.structure
             if structure then
                 for i=1,#structure do
                     local si = structure[i]
@@ -628,7 +630,7 @@
 --                             else
 --                                 derived_c = nil
 --                             end
-                            structure = references.structure
+                            local structure = references.structure
                             if structure then
                                 structure = resolvers.jobs.namelist(structure,namestack)
                                 references.namestack = structure
@@ -2624,7 +2626,7 @@
 
 function genericfilters.number(data,what,prefixspec,numberspec)
     if data then
-        numberdata = lists.reordered(data) -- data.numberdata
+        local numberdata = lists.reordered(data) -- data.numberdata
         if numberdata then
             helpers.prefix(data,prefixspec)
             sections.typesetnumber(numberdata,"number",numberspec,numberdata)

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ref.mklx
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ref.mklx	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-ref.mklx	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1391,7 +1391,7 @@
 \installcommandhandler \??referenceformat {referenceformat} \??referenceformat
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\currentreferenceformat\endcsname{\strc_references_apply_format{\currentreferenceformat}}%
+    \protected\frozen\instance\edefcsname\currentreferenceformat\endcsname{\strc_references_apply_format{\currentreferenceformat}}%
 \to \everydefinereferenceformat
 
 \setupreferenceformat

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-reg.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-reg.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-reg.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1143,6 +1143,7 @@
         local entries    = { }
         local nofentries = 0
         local multiple   = false
+        local metadata   = false -- needs chcking
         for i=1,#list do
             if used[list[i]] then
                 multiple = true
@@ -1162,26 +1163,25 @@
             end
             if d then
                 local e = d.entries
---                 local u = u and { u.prefix } or nil
-local u = multiple and { string.formatters["%03i"](i) } or nil -- maybe prefix but then how about main
+             -- local u = u and { u.prefix } or nil
+                local u = multiple and { string.formatters["%03i"](i) } or nil -- maybe prefix but then how about main
                 for i=1,#e do
                     -- see has no pagedata
                     local ei = e[i]
                     local external = ei.external
-if multiple and ei.metadata.kind == "see" and external then
-    -- too messy, could be an option but useless
-else
-
-                    nofentries = nofentries + 1
-                    entries[nofentries] = ei
-                    if u then
-                        local eil = ei.list
-                        eil[#eil+1] = u
-if external then
-                        ei.external = l -- this is the (current) abstract tag, used for prefix
-end
+                    if multiple and ei.metadata.kind == "see" and external then
+                     -- too messy, could be an option but useless
+                    else
+                        nofentries = nofentries + 1
+                        entries[nofentries] = ei
+                        if u then
+                            local eil = ei.list
+                            eil[#eil+1] = u
+                            if external then
+                                ei.external = l -- this is the (current) abstract tag, used for prefix
+                            end
+                        end
                     end
-end
                 end
                 if not metadata then
                     metadata = d.metadata

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-reg.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-reg.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-reg.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -179,13 +179,13 @@
       \definemixedcolumns[\currentregister][\v!register]% first as otherwise it overloads start/stop
       \clf_defineregister{\currentregister}{\registerparameter\c!referencemethod}%
       \expanded{\presetheadtext[\currentregister=\Word{\currentregister}]}%
-      \frozen\instance\protected\edefcsname\currentregister\endcsname{\strc_registers_insert_entry[\currentregister]}%
-      \frozen\instance\protected\edefcsname\e!see\currentregister\endcsname{\strc_registers_insert_see[\currentregister]}%
-      %frozen\instance\protected\edefcsname\e!coupled\currentregister\endcsname{\dolinkedregister{\currentregister}}%
+      \protected\frozen\instance\edefcsname\currentregister\endcsname{\strc_registers_insert_entry[\currentregister]}%
+      \protected\frozen\instance\edefcsname\e!see\currentregister\endcsname{\strc_registers_insert_see[\currentregister]}%
+      %protected\frozen\instance\edefcsname\e!coupled\currentregister\endcsname{\dolinkedregister{\currentregister}}%
       % historic ballast
-      \frozen\instance\protected\edefcsname\e!place\currentregister\endcsname{\placeregister[\currentregister]}%
-      \frozen\instance\protected\edefcsname\e!complete\currentregister\endcsname{\completeregister[\currentregister]}%
-      \frozen\instance\protected\edefcsname\e!setup\currentregister\e!endsetup\endcsname{\setupregister[\currentregister]}%
+      \protected\frozen\instance\edefcsname\e!place\currentregister\endcsname{\placeregister[\currentregister]}%
+      \protected\frozen\instance\edefcsname\e!complete\currentregister\endcsname{\completeregister[\currentregister]}%
+      \protected\frozen\instance\edefcsname\e!setup\currentregister\e!endsetup\endcsname{\setupregister[\currentregister]}%
       \dorecurse\c_strc_registers_maxlevel{% weird, expanded should not be needed
         \expanded{\defineregister[\currentregister:\recurselevel][\currentregister]}%
        %\defineregister[\currentregister:\recurselevel][\currentregister]%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-sec.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-sec.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-sec.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -504,8 +504,8 @@
 \to \everyredefinehead
 
 \appendtoks
-   \frozen\instance\protected\edefcsname\e!start\currenthead\endcsname{\strc_sectioning_start[\currenthead]}%
-   \frozen\instance\protected\edefcsname\e!stop \currenthead\endcsname{\strc_sectioning_stop [\currenthead]}%
+   \protected\frozen\instance\edefcsname\e!start\currenthead\endcsname{\strc_sectioning_start[\currenthead]}%
+   \protected\frozen\instance\edefcsname\e!stop \currenthead\endcsname{\strc_sectioning_stop [\currenthead]}%
 \to \everydefinehead
 
 % so \subject as well as \section will need two commands when ownnumber
@@ -516,9 +516,9 @@
     \ifempty\currenthead
       % top level
     \orelse\ifcstok{\headparameter\c!ownnumber}\v!yes
-      \instance\protected\edefcsname\currenthead\endcsname{\strc_sectioning_handle_own[\currenthead]}
+      \protected\instance\edefcsname\currenthead\endcsname{\strc_sectioning_handle_own[\currenthead]}
     \else
-      \instance\protected\edefcsname\currenthead\endcsname{\strc_sectioning_handle_nop[\currenthead]}%
+      \protected\instance\edefcsname\currenthead\endcsname{\strc_sectioning_handle_nop[\currenthead]}%
     \fi
 \to \everysetuphead
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-syn.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-syn.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-syn.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -299,10 +299,11 @@
     local lasttag  = nil
     local lasttag  = nil
     local nofdone  = 0
+    local done     = nil
     for k=1,#result do
         local entry = result[k]
         local first, tag = firstofsplit(entry)
-        if tag ~= lasttag then
+        if tag ~= lasttag or not done then
          -- if trace_registers then
          --     report_registers("splitting at %a",tag)
          -- end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-syn.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-syn.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-syn.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -271,12 +271,12 @@
 \permanent\tolerant\protected\def\definesynonyms[#1]#*[#2]#*[#3]#*[#4]% name plural \meaning \use
   {\ifnum\lastarguments=\plusfour
      \protected\instance\def#4##1{\strc_synonyms_insert{#1}{##1}}% name tag
-     \frozen\instance\protected\defcsname#1\endcsname{\definesynonym[\v!no][#1]}% \name
+     \protected\frozen\instance\defcsname#1\endcsname{\definesynonym[\v!no][#1]}% \name
    \else
-     \frozen\instance\protected\defcsname#1\endcsname{\definesynonym[\v!yes][#1]}% \name
+     \protected\frozen\instance\defcsname#1\endcsname{\definesynonym[\v!yes][#1]}% \name
    \fi
    \ifparameter#3\or
-     \frozen\instance\protected\def#3##1{\strc_synonyms_insert_meaning{#1}{##1}}% \meaning
+     \protected\frozen\instance\def#3##1{\strc_synonyms_insert_meaning{#1}{##1}}% \meaning
    \fi
    \cdef\currentsynonym{#1}%
    %
@@ -295,9 +295,9 @@
      %
      % These will go away. Actually the overloads catched this empty case!
      %
-     \frozen\instance\protected\defcsname\e!setup #2\e!endsetup\endcsname{\setupsynonyms[#1]}% obsolete definition
-     \frozen\instance\protected\defcsname\e!place   \e!listof#2\endcsname{\placelistofsynonyms[#1]}% accepts extra argument
-     \frozen\instance\protected\defcsname\e!complete\e!listof#2\endcsname{\completelistofsynonyms[#1]}%
+     \protected\frozen\instance\defcsname\e!setup #2\e!endsetup\endcsname{\setupsynonyms[#1]}% obsolete definition
+     \protected\frozen\instance\defcsname\e!place   \e!listof#2\endcsname{\placelistofsynonyms[#1]}% accepts extra argument
+     \protected\frozen\instance\defcsname\e!complete\e!listof#2\endcsname{\completelistofsynonyms[#1]}%
    \fi}
 
 % \abbreviation[XXX][321]{321}{Three, Two, One} : optional sort key
@@ -561,9 +561,9 @@
      \else
        \protected\instance\def#3##1{\strc_sorting_insert{#1}{##1}}%
      \fi
-     \frozen\instance\protected\defcsname#1\endcsname{\definesort[\v!no][#1]}%
+     \protected\frozen\instance\defcsname#1\endcsname{\definesort[\v!no][#1]}%
    \else
-     \frozen\instance\protected\defcsname#1\endcsname{\definesort[\v!yes][#1]}%
+     \protected\frozen\instance\defcsname#1\endcsname{\definesort[\v!yes][#1]}%
    \fi
    \cdef\currentsorting{#1}%
    \c_strc_constructions_define_commands\conditionalfalse
@@ -582,9 +582,9 @@
      %
      \presetheadtext[#2=\Word{#2}]%
      %
-     \frozen\instance\protected\defcsname\e!setup #2\e!endsetup\endcsname{\setupsorting[#1]}% obsolete definition
-     \frozen\instance\protected\defcsname\e!place   \e!listof#2\endcsname{\placelistofsorts[#1]}%
-     \frozen\instance\protected\defcsname\e!complete\e!listof#2\endcsname{\completelistofsorts[#1]}%
+     \protected\frozen\instance\defcsname\e!setup #2\e!endsetup\endcsname{\setupsorting[#1]}% obsolete definition
+     \protected\frozen\instance\defcsname\e!place   \e!listof#2\endcsname{\placelistofsorts[#1]}%
+     \protected\frozen\instance\defcsname\e!complete\e!listof#2\endcsname{\completelistofsorts[#1]}%
    \fi}
 
 \permanent\tolerant\protected\def\definesort[#1]#*[#2]#*[#3]%
@@ -667,6 +667,8 @@
    \fastsetup{\??simplelistrenderings::\v!sorting}%
 \stopsetups
 
+% todo: prerolltostring -> alt text (currently we just use the tag)
+
 \startsetups [\??simplelistrenderings::\v!sorting]
     \begingroup
     \dostarttaggedchained\t!sorting\currentsorting\currentsorting\??simplelist

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tag.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tag.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tag.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -100,332 +100,277 @@
 -- Some NonStruct might become Part, Sect or Sub in which case titles and tage become Lbl
 -- but only when validators don't bark on it and the main structure is kept.
 
--- Well, so now NonStruct is also no longer an option and we needed to adapt. What a waste
--- of time. For now we go Span and Div but maybe all will become Div or Part or ... whatever
--- passes the test.
+local properties = allocate { -- todo: more "record = true" to improve formatting
 
-local properties     = allocate { -- todo: more "record = true" to improve formatting
+    document           = { namespace = "context", nature = "display", pdf = "Document"  },
+    documentpart       = { namespace = "context", nature = "display", pdf = "Part"      },
 
-    document           = { namespace = "context", nature = "display", pdf = "Document"         },
-    documentpart       = { namespace = "context", nature = "display", pdf = "DocumentFragment" },
+    text               = { namespace = "context", nature = "inline",  pdf = "Span"      },
+ -- span               = { namespace = "context", nature = "inline",  pdf = "Span"      },
+ -- div                = { namespace = "context", nature = "display", pdf = "Div"       },
 
-    division           = { namespace = "context", nature = "display", pdf = "Part" },
-    paragraph          = { namespace = "context", nature = "mixed",   pdf = "P"    },
-    subparagraph       = { namespace = "context", nature = "mixed",   pdf = "P"    },
-    p                  = { namespace = "context", nature = "mixed",   pdf = "P"    },
-    highlight          = { namespace = "context", nature = "inline",  pdf = "Span" }, -- was NonStruct
-    ornament           = { namespace = "context", nature = "inline",  pdf = "Span" }, -- was NonStruct
-    textdisplay        = { namespace = "context", nature = "display", pdf = "Div"  }, -- was NonStruct
-    placeholder        = { namespace = "context", nature = "inline",  pdf = "Span" }, -- was NonStruct
-    ["break"]          = { namespace = "context", nature = "display", pdf = "Div"  }, -- was NonStruct
+    p                  = { namespace = "context", nature = "mixed",   pdf = "P"         }, -- display
+    t                  = { namespace = "context", nature = "mixed",   pdf = "Span"      }, -- inline
+    m                  = { namespace = "context", nature = "mixed",   pdf = "Artifact"  }, -- mixed
 
-    construct          = { namespace = "context", nature = "inline",  pdf = "Span" }, -- was NonStruct
-    constructleft      = { namespace = "context", nature = "inline",  pdf = "Span" }, -- was NonStruct
-    constructright     = { namespace = "context", nature = "inline",  pdf = "Span" }, -- was NonStruct
-    constructcontent   = { namespace = "context", nature = "inline",  pdf = "Span" }, -- was NonStruct
+ -- l                  = { namespace = "context", nature = "mixed",   pdf = "Link"      }, -- for testing
+ -- r                  = { namespace = "context", nature = "mixed",   pdf = "Reference" }, -- for testing
 
-    sectionblock       = { namespace = "context", nature = "display", pdf = "Div"  }, -- was NonStruct
+    dummy              = { namespace = "context", nature = "mixed",   pdf = "Artifact"  }, -- for testing
+    crumpy             = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, -- for testing
 
-    section            = { namespace = "context", nature = "display", pdf = "Div"  }, -- was NonStruct
-    sectioncaption     = { namespace = "context", nature = "display", pdf = "Div", record = true },
-    sectiontitle       = { namespace = "context", nature = "mixed",   pdf = "Div"  }, -- was NonStruct
-    sectionnumber      = { namespace = "context", nature = "mixed",   pdf = "Div"  }, -- was NonStruct
-    sectioncontent     = { namespace = "context", nature = "display", pdf = "Div"  }, -- was NonStruct
+    division           = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    paragraph          = { namespace = "context", nature = "mixed",   pdf = "P"         },
+    subparagraph       = { namespace = "context", nature = "mixed",   pdf = "P"         },
+    highlight          = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    ornament           = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    textdisplay        = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    placeholder        = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    ["break"]          = { namespace = "context", nature = "display", pdf = "Artifact"  },
 
-    itemgroup          = { namespace = "context", nature = "display", pdf = "Div"  }, -- was NonStruct
-    item               = { namespace = "context", nature = "display", pdf = "Div"  }, -- was NonStruct
-    itemtag            = { namespace = "context", nature = "mixed",   pdf = "Div"  }, -- was NonStruct
-    itemcontent        = { namespace = "context", nature = "mixed",   pdf = "Div"  }, -- was NonStruct
-    itemhead           = { namespace = "context", nature = "display", pdf = "Div"  }, -- was NonStruct
-    itembody           = { namespace = "context", nature = "display", pdf = "Div"  }, -- was NonStruct
+    construct          = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    constructleft      = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    constructright     = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    constructcontent   = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    items              = { namespace = "context", nature = "display", pdf = "Table" },
-    itemsymbols        = { namespace = "context", nature = "mixed",   pdf = "TR"    },
-    itemsymbol         = { namespace = "context", nature = "inline",  pdf = "TD"    },
-    itemtexts          = { namespace = "context", nature = "mixed",   pdf = "TR"    },
-    itemtext           = { namespace = "context", nature = "inline",  pdf = "TD"    },
+    sectionblock       = { namespace = "context", nature = "display", pdf = "NonStruct" },
 
-    description        = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    descriptiontag     = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    descriptioncontent = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    descriptionsymbol  = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
+    section            = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    sectioncaption     = { namespace = "context", nature = "display", pdf = "NonStruct" , record = true },
+    sectionnumber      = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    sectiontitle       = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    sectioncontent     = { namespace = "context", nature = "display", pdf = "NonStruct" },
 
-    verbatimblock      = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    verbatimlines      = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    verbatimline       = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    verbatim           = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
+    itemgroup          = { namespace = "context", nature = "display", pdf = "NonStruct" }, -- L
+    item               = { namespace = "context", nature = "display", pdf = "NonStruct" }, -- LI
+    itemtag            = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, -- Lbl
+    itemcontent        = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, -- LBody
+    itemhead           = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    itembody           = { namespace = "context", nature = "display", pdf = "NonStruct" },
 
-    lines              = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    line               = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    linenumber         = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
+    items              = { namespace = "context", nature = "display", pdf = "Table"     },
+    itemsymbols        = { namespace = "context", nature = "mixed",   pdf = "TR"        },
+    itemsymbol         = { namespace = "context", nature = "inline",  pdf = "TD"        },
+    itemtexts          = { namespace = "context", nature = "mixed",   pdf = "TR"        },
+    itemtext           = { namespace = "context", nature = "inline",  pdf = "TD"        },
 
-    synonym            = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
-    sorting            = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
+    description        = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    descriptiontag     = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, -- Lbl
+    descriptioncontent = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    descriptionsymbol  = { namespace = "context", nature = "inline",  pdf = "NonStruct" }, -- Lbl
 
-    register           = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    registerlocation   = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
-    registersection    = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    registertag        = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    registerentries    = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    registerentry      = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    registercontent    = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    registersee        = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    registerpages      = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    registerpage       = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    registerseparator  = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
-    registerpagerange  = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
+    verbatimblock      = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    verbatimlines      = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    verbatimline       = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, -- Code
+    verbatim           = { namespace = "context", nature = "inline",  pdf = "NonStruct" }, -- Code
 
-    table              = { namespace = "context", nature = "display", pdf = "Table" },
-    tablerow           = { namespace = "context", nature = "display", pdf = "TR"    },
-    tablecell          = { namespace = "context", nature = "mixed",   pdf = "TD"    },
-    tableheadcell      = { namespace = "context", nature = "mixed",   pdf = "TH"    },
-    tablehead          = { namespace = "context", nature = "display", pdf = "THEAD" },
-    tablebody          = { namespace = "context", nature = "display", pdf = "TBODY" },
-    tablefoot          = { namespace = "context", nature = "display", pdf = "TFOOT" },
+    lines              = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    line               = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    linenumber         = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    tabulate           = { namespace = "context", nature = "display", pdf = "Table" },
-    tabulaterow        = { namespace = "context", nature = "display", pdf = "TR"    },
-    tabulatecell       = { namespace = "context", nature = "mixed",   pdf = "TD"    },
-    tabulateheadcell   = { namespace = "context", nature = "mixed",   pdf = "TH"    },
-    tabulatehead       = { namespace = "context", nature = "display", pdf = "THEAD" },
-    tabulatebody       = { namespace = "context", nature = "display", pdf = "TBODY" },
-    tabulatefoot       = { namespace = "context", nature = "display", pdf = "TFOOT" },
+    synonym            = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    sorting            = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    list               = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    listitem           = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    listtag            = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    listcontent        = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    listdata           = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    listpage           = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    listtext           = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
+    register           = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    registerlocation   = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    registersection    = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    registertag        = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    registerentries    = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    registerentry      = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    registercontent    = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    registersee        = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    registerpages      = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    registerpage       = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    registerseparator  = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    registerpagerange  = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
 
-    delimitedblock     = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    delimited          = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
-    delimitedcontent   = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
-    delimitedsymbol    = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
+    table              = { namespace = "context", nature = "display", pdf = "Table",    },
+    tablerow           = { namespace = "context", nature = "display", pdf = "TR",       },
+    tablecell          = { namespace = "context", nature = "mixed",   pdf = "TD",       },
+    tableheadcell      = { namespace = "context", nature = "mixed",   pdf = "TH",       },
+    tablehead          = { namespace = "context", nature = "display", pdf = "THEAD",    },
+    tablebody          = { namespace = "context", nature = "display", pdf = "TBODY",    },
+    tablefoot          = { namespace = "context", nature = "display", pdf = "TFOOT",    },
 
-    subsentence        = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
-    subsentencecontent = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
-    subsentencesymbol  = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
+    tabulate           = { namespace = "context", nature = "display", pdf = "Table",    },
+    tabulaterow        = { namespace = "context", nature = "display", pdf = "TR",       },
+    tabulatecell       = { namespace = "context", nature = "mixed",   pdf = "TD",       },
+    tabulateheadcell   = { namespace = "context", nature = "mixed",   pdf = "TH",       },
+    tabulatehead       = { namespace = "context", nature = "display", pdf = "THEAD",    },
+    tabulatebody       = { namespace = "context", nature = "display", pdf = "TBODY",    },
+    tabulatefoot       = { namespace = "context", nature = "display", pdf = "TFOOT",    },
 
-    label              = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    number             = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
+    list               = { namespace = "context", nature = "display", pdf = "NonStruct" }, -- TOC
+    listitem           = { namespace = "context", nature = "display", pdf = "NonStruct" }, -- TOCI
+    listtag            = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, -- Lbl
+    listcontent        = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, --
+    listdata           = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, --
+    listpage           = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, --
+    listtext           = { namespace = "context", nature = "inline",  pdf = "NonStruct" }, --
 
-    float              = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    floatcaption       = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    floatlabel         = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
-    floatnumber        = { namespace = "context", nature = "inline",  pdf = "Span"  }, -- was NonStruct
-    floattext          = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    floatcontent       = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
+    delimitedblock     = { namespace = "context", nature = "display", pdf = "NonStruct" }, -- BlockQuote
+    delimited          = { namespace = "context", nature = "inline",  pdf = "NonStruct" }, -- Quote
+    delimitedcontent   = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    delimitedsymbol    = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    image              = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    mpgraphic          = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
+    subsentence        = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    subsentencecontent = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    subsentencesymbol  = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    formulaset         = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    formula            = { namespace = "context", nature = "display", pdf = "Div"   }, -- was NonStruct
-    formulacaption     = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    formulalabel       = { namespace = "context", nature = "mixed",   pdf = "Div"   }, -- was NonStruct
-    formulanumber      = { namespace = "context", nature = "mixed",   pdf = "Div"   },
-    formulacontent     = { namespace = "context", nature = "display", pdf = "Div"   },
-    subformula         = { namespace = "context", nature = "display", pdf = "Div"   },
+    label              = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    number             = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
 
-    link               = { namespace = "context", nature = "inline",  pdf = "Link"  },
-    reference          = { namespace = "context", nature = "inline",  pdf = "Span"  },
+    float              = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    floatcaption       = { namespace = "context", nature = "mixed",   pdf = "NonStruct" }, -- Lbl
+    floatlabel         = { namespace = "context", nature = "inline",  pdf = "NonStruct" }, -- Lbl
+    floatnumber        = { namespace = "context", nature = "inline",  pdf = "NonStruct" }, -- Lbl
+    floattext          = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    floatcontent       = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    subfloat           = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
 
-    navigation         = { namespace = "context", nature = "mixed",   pdf = "Div"   },
-    navigationbutton   = { namespace = "context", nature = "mixed",   pdf = "Div"   },
-    navigationmenu     = { namespace = "context", nature = "display", pdf = "Div"   },
-    navigationmenuitem = { namespace = "context", nature = "display", pdf = "Div"   },
-    navigationaction   = { namespace = "context", nature = "display", pdf = "Div"   },
-    navigationpage     = { namespace = "context", nature = "inline",  pdf = "Span"  },
+    image              = { namespace = "context", nature = "mixed",   pdf = "Artifact"  },
+    mpgraphic          = { namespace = "context", nature = "mixed",   pdf = "Artifact"  },
 
-    margintextblock    = { namespace = "context", nature = "inline",  pdf = "Span"  },
-    margintext         = { namespace = "context", nature = "inline",  pdf = "Span"  },
-    marginanchor       = { namespace = "context", nature = "inline",  pdf = "Span"  },
+    formulaset         = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    formula            = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    formulacaption     = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    formulalabel       = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    formulanumber      = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    formulacontent     = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    subformula         = { namespace = "context", nature = "display", pdf = "NonStruct" },
 
-    linetext           = { namespace = "context", nature = "inline",  pdf = "Span"  },
+    link               = { namespace = "context", nature = "inline",  pdf = "Link"      },
+    reference          = { namespace = "context", nature = "inline",  pdf = "Artifact"  },
 
- -- math               = { namespace = "mathml",  nature = "inline",  pdf = "math"  },
-    math               = { namespace = "context", nature = "inline",  pdf = "Span"  },
-    inlinemath         = { namespace = "context", nature = "inline",  pdf = "Span"  },
-    displaymath        = { namespace = "context", nature = "display", pdf = "Div"   },
+    navigation         = { namespace = "context", nature = "mixed",   pdf = "Artifact"  },
+    navigationbutton   = { namespace = "context", nature = "mixed",   pdf = "Artifact"  },
+    navigationmenu     = { namespace = "context", nature = "display", pdf = "Artifact"  },
+    navigationmenuitem = { namespace = "context", nature = "display", pdf = "Artifact"  },
+    navigationaction   = { namespace = "context", nature = "display", pdf = "Artifact"  },
+    navigationpage     = { namespace = "context", nature = "inline",  pdf = "Artifact"  },
 
+    margintextblock    = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    margintext         = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    marginanchor       = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+
+    linetext           = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+
+ -- math               = { namespace = "mathml",  nature = "inline",  pdf = "math"      },
+    math               = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    inlinemath         = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    displaymath        = { namespace = "context", nature = "display", pdf = "NonStruct" },
+
     -- these are wrapped in math and only used in detailed math mode
 
- -- mn                 = { namespace = "mathml",  nature = "mixed",   pua = "mathml", pdf = "mn"            },
- -- mi                 = { namespace = "mathml",  nature = "mixed",   pua = "mathml", pdf = "mi"            },
- -- mo                 = { namespace = "mathml",  nature = "mixed",   pua = "mathml", pdf = "mo"            },
- -- ms                 = { namespace = "mathml",  nature = "mixed",   pua = "mathml", pdf = "ms"            },
-    mrow               = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "mrow"          },
- -- msubsup            = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "msubsup"       },
- -- msub               = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "msub"          },
- -- msup               = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "msup"          },
- -- merror             = { namespace = "mathml",  nature = "mixed",   pua = "mathml", pdf = "merror"        },
- -- munderover         = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "munderover"    },
- -- munder             = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "munder"        },
- -- mover              = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "mover"         },
- -- mtext              = { namespace = "mathml",  nature = "mixed",   pua = "mathml", pdf = "mtext"         },
- -- mfrac              = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "mfrac"         },
- -- mroot              = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "mroot"         },
- -- msqrt              = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "msqrt"         },
- -- mfenced            = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "mfenced"       },
- -- maction            = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "maction"       },
- -- mmultiscripts      = { namespace = "mathml",  nature = "display", pua = "mathml", pdf = "mmultiscripts" },
- -- mprescripts        = { namespace = "mathml",  nature = "mixed",   pua = "mathml", pdf = "mprescripts"   },
+ -- mn                 = { namespace = "mathml",  nature = "mixed",   pdf = "mn"            },
+ -- mi                 = { namespace = "mathml",  nature = "mixed",   pdf = "mi"            },
+ -- mo                 = { namespace = "mathml",  nature = "mixed",   pdf = "mo"            },
+ -- ms                 = { namespace = "mathml",  nature = "mixed",   pdf = "ms"            },
+    mrow               = { namespace = "mathml",  nature = "display", pdf = "mrow"          },
+ -- msubsup            = { namespace = "mathml",  nature = "display", pdf = "msubsup"       },
+ -- msub               = { namespace = "mathml",  nature = "display", pdf = "msub"          },
+ -- msup               = { namespace = "mathml",  nature = "display", pdf = "msup"          },
+ -- merror             = { namespace = "mathml",  nature = "mixed",   pdf = "merror"        },
+ -- munderover         = { namespace = "mathml",  nature = "display", pdf = "munderover"    },
+ -- munder             = { namespace = "mathml",  nature = "display", pdf = "munder"        },
+ -- mover              = { namespace = "mathml",  nature = "display", pdf = "mover"         },
+ -- mtext              = { namespace = "mathml",  nature = "mixed",   pdf = "mtext"         },
+ -- mfrac              = { namespace = "mathml",  nature = "display", pdf = "mfrac"         },
+ -- mroot              = { namespace = "mathml",  nature = "display", pdf = "mroot"         },
+ -- msqrt              = { namespace = "mathml",  nature = "display", pdf = "msqrt"         },
+ -- mfenced            = { namespace = "mathml",  nature = "display", pdf = "mfenced"       },
+ -- maction            = { namespace = "mathml",  nature = "display", pdf = "maction"       },
+ -- mmultiscripts      = { namespace = "mathml",  nature = "display", pdf = "mmultiscripts" },
+ -- mprescripts        = { namespace = "mathml",  nature = "mixed",   pdf = "mprescripts"   },
 
-    mn                 = { namespace = "context", nature = "mixed",   pdf = "Span" },
-    mi                 = { namespace = "context", nature = "mixed",   pdf = "Span" },
-    mo                 = { namespace = "context", nature = "mixed",   pdf = "Span" },
-    ms                 = { namespace = "context", nature = "mixed",   pdf = "Span" },
-    mrow               = { namespace = "context", nature = "display", pdf = "Span" },
-    msubsup            = { namespace = "context", nature = "display", pdf = "Span" },
-    msub               = { namespace = "context", nature = "display", pdf = "Span" },
-    msup               = { namespace = "context", nature = "display", pdf = "Span" },
-    merror             = { namespace = "context", nature = "mixed",   pdf = "Span" },
-    munderover         = { namespace = "context", nature = "display", pdf = "Span" },
-    munder             = { namespace = "context", nature = "display", pdf = "Span" },
-    mover              = { namespace = "context", nature = "display", pdf = "Span" },
-    mtext              = { namespace = "context", nature = "mixed",   pdf = "Span" },
-    mfrac              = { namespace = "context", nature = "display", pdf = "Span" },
-    mroot              = { namespace = "context", nature = "display", pdf = "Span" },
-    msqrt              = { namespace = "context", nature = "display", pdf = "Span" },
-    mfenced            = { namespace = "context", nature = "display", pdf = "Span" },
-    maction            = { namespace = "context", nature = "display", pdf = "Span" },
-    mmultiscripts      = { namespace = "context", nature = "display", pdf = "Span" },
-    mprescripts        = { namespace = "context", nature = "mixed",   pdf = "Span" },
+    mn                 = { namespace = "context",  nature = "mixed",   pdf = "Span"      },
+    mi                 = { namespace = "context",  nature = "mixed",   pdf = "Span"      },
+    mo                 = { namespace = "context",  nature = "mixed",   pdf = "Span"      },
+    ms                 = { namespace = "context",  nature = "mixed",   pdf = "Span"      },
+    mrow               = { namespace = "context",  nature = "display", pdf = "Span"      },
+    msubsup            = { namespace = "context",  nature = "display", pdf = "Span"      },
+    msub               = { namespace = "context",  nature = "display", pdf = "Span"      },
+    msup               = { namespace = "context",  nature = "display", pdf = "Span"      },
+    merror             = { namespace = "context",  nature = "mixed",   pdf = "Span"      },
+    munderover         = { namespace = "context",  nature = "display", pdf = "Span"      },
+    munder             = { namespace = "context",  nature = "display", pdf = "Span"      },
+    mover              = { namespace = "context",  nature = "display", pdf = "Span"      },
+    mtext              = { namespace = "context",  nature = "mixed",   pdf = "Span"      },
+    mfrac              = { namespace = "context",  nature = "display", pdf = "Span"      },
+    mroot              = { namespace = "context",  nature = "display", pdf = "Span"      },
+    msqrt              = { namespace = "context",  nature = "display", pdf = "Span"      },
+    mfenced            = { namespace = "context",  nature = "display", pdf = "Span"      },
+    maction            = { namespace = "context",  nature = "display", pdf = "Span"      },
+    mmultiscripts      = { namespace = "context",  nature = "display", pdf = "Span"      },
+    mprescripts        = { namespace = "context",  nature = "mixed",   pdf = "Span"      },
 
     -- these are internal ones
 
-    mstack             = { namespace = "context", nature = "display", pdf = "Span" },
-    mstacker           = { namespace = "context", nature = "display", pdf = "Span" },
-    mstackertop        = { namespace = "context", nature = "display", pdf = "Span" },
-    mstackerbot        = { namespace = "context", nature = "display", pdf = "Span" },
-    mstackermid        = { namespace = "context", nature = "display", pdf = "Span" },
-    mextensible        = { namespace = "context", nature = "display", pdf = "Span" },
-    mdelimited         = { namespace = "context", nature = "display", pdf = "Span" },
-    mdelimitedstack    = { namespace = "context", nature = "display", pdf = "Span" },
-    mfunction          = { namespace = "context", nature = "mixed",   pdf = "Span" },
-    mfunctionstack     = { namespace = "context", nature = "display", pdf = "Span" },
-    mfraction          = { namespace = "context", nature = "display", pdf = "Span" },
-    mfractionstack     = { namespace = "context", nature = "display", pdf = "Span" },
-    munit              = { namespace = "context", nature = "mixed",   pdf = "Span" },
-    mdigits            = { namespace = "context", nature = "mixed",   pdf = "Span" },
-    mc                 = { namespace = "context", nature = "mixed",   pdf = "Span" },
+    mstack             = { namespace = "context", nature = "display", pdf = "Span"      },
+    mstacker           = { namespace = "context", nature = "display", pdf = "Span"      },
+    mstackertop        = { namespace = "context", nature = "display", pdf = "Span"      },
+    mstackerbot        = { namespace = "context", nature = "display", pdf = "Span"      },
+    mstackermid        = { namespace = "context", nature = "display", pdf = "Span"      },
+    mextensible        = { namespace = "context", nature = "display", pdf = "Span"      },
+    mdelimited         = { namespace = "context", nature = "display", pdf = "Span"      },
+    mdelimitedstack    = { namespace = "context", nature = "display", pdf = "Span"      },
+    mfunction          = { namespace = "context", nature = "mixed",   pdf = "Span"      },
+    mfunctionstack     = { namespace = "context", nature = "display", pdf = "Span"      },
+    mfraction          = { namespace = "context", nature = "display", pdf = "Span"      },
+    mfractionstack     = { namespace = "context", nature = "display", pdf = "Span"      },
+    munit              = { namespace = "context", nature = "mixed",   pdf = "Span"      },
+    mdigits            = { namespace = "context", nature = "mixed",   pdf = "Span"      },
+    mc                 = { namespace = "context", nature = "mixed",   pdf = "Span"      },
 
     -- these are also wrapped
 
-    mtable             = { namespace = "mathml",  nature = "display", pdf = "mtable" },
-    mtr                = { namespace = "mathml",  nature = "display", pdf = "mtr"    },
-    mtd                = { namespace = "mathml",  nature = "display", pdf = "mtd"    },
+    mtable             = { namespace = "mathml",  nature = "display", pdf = "mtable",   },
+    mtr                = { namespace = "mathml",  nature = "display", pdf = "mtr",      },
+    mtd                = { namespace = "mathml",  nature = "display", pdf = "mtd",      },
 
-    -- some more
+    ignore             = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    private            = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    metadata           = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    metavariable       = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
 
-    ignore             = { namespace = "context", nature = "mixed",   pdf = "Div"  },
-    private            = { namespace = "context", nature = "mixed",   pdf = "Div"  },
-    metadata           = { namespace = "context", nature = "display", pdf = "Div"  },
-    metavariable       = { namespace = "context", nature = "mixed",   pdf = "Div"  },
+    mid                = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    sub                = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    sup                = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    subsup             = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    mid                = { namespace = "context", nature = "inline",  pdf = "Span" },
-    sub                = { namespace = "context", nature = "inline",  pdf = "Span" },
-    sup                = { namespace = "context", nature = "inline",  pdf = "Span" },
-    subsup             = { namespace = "context", nature = "inline",  pdf = "Span" },
+    combination        = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    combinationpair    = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    combinationcontent = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    combinationcaption = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
 
-    combination        = { namespace = "context", nature = "display", pdf = "Div"  },
-    combinationpair    = { namespace = "context", nature = "display", pdf = "Div"  },
-    combinationcontent = { namespace = "context", nature = "mixed",   pdf = "Div"  },
-    combinationcaption = { namespace = "context", nature = "mixed",   pdf = "Div"  },
+    publications       = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    publication        = { namespace = "context", nature = "mixed",   pdf = "NonStruct" },
+    pubfld             = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    publications       = { namespace = "context", nature = "display", pdf = "Div"  },
-    publication        = { namespace = "context", nature = "mixed",   pdf = "Div"  },
-    pubfld             = { namespace = "context", nature = "inline",  pdf = "Span" },
+    citation           = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    cite               = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    citation           = { namespace = "context", nature = "inline",  pdf = "Span" },
-    cite               = { namespace = "context", nature = "inline",  pdf = "Span" },
+    narrower           = { namespace = "context", nature = "display", pdf = "NonStruct" },
 
-    narrower           = { namespace = "context", nature = "display", pdf = "Div"  },
+    block              = { namespace = "context", nature = "display", pdf = "NonStruct" },
 
-    block              = { namespace = "context", nature = "display", pdf = "Div"  },
+    userdata           = { namespace = "context", nature = "display", pdf = "NonStruct" },
 
-    userdata           = { namespace = "context", nature = "display", pdf = "Div"  },
+    quantity           = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    unit               = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    quantity           = { namespace = "context", nature = "inline",  pdf = "Span" },
-    unit               = { namespace = "context", nature = "inline",  pdf = "Span" },
+    verse              = { namespace = "context", nature = "display", pdf = "NonStruct" },
+    versetag           = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    verseseparator     = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
+    versecontent       = { namespace = "context", nature = "inline",  pdf = "NonStruct" },
 
-    verse              = { namespace = "context", nature = "display", pdf = "Div"  },
-    versetag           = { namespace = "context", nature = "inline",  pdf = "Span" },
-    verseseparator     = { namespace = "context", nature = "inline",  pdf = "Span" },
-    versecontent       = { namespace = "context", nature = "inline",  pdf = "Span" },
+--     navigationpage     = { namespace = "context", nature = "inline",  pdf = "Link"  },
 
 }
 
-local overloads = allocate {
-    -- this is needed for crappy pdf support
-}
-
 tags.properties = properties
-tags.overloads  = overloads
+tags.overloads  = allocate { }
 
-directives.register("backend.usetags", function(v)
-    if type(v) == "string" then
-        local fullname = resolvers.findfile("lpdf-tag-imp-"..v..".lmt") or ""
-        if fullname ~= "" then
-            local n = 0
-            local c = 0
-            local data = table.load(fullname)
-            if data then
-                local merge = data.mapping
-                if merge then
-                    for k, v in next, merge do
-                        local p = properties[k]
-                        if p and p.pdf ~= v.pdf then
-                            p.pdf = v.pdf
-                            p.pua = v.pua or p.pua
-                            n = n + 1
-                        end
-                    end
-                end
-                merge = data.overloads
-                if merge then
-                    for maintag, details in sortedhash(merge) do
-                        local mapping = details.mapping
-                        if mapping then
-                            local okay = { }
-                            for detail, spec in sortedhash(mapping) do
-                                local tag = spec.tag
-                                local pdf = spec.pdf
-                                local pua = spec.pua
-                                if tag and pdf and pua then
-                                    if properties[tag] then
-                                        report_tags("tag %a can't be overloaded",tag)
-                                    else
-                                        okay[detail] = spec
-                                        properties[tag] = spec
-                                        spec.namespace = "user"
-                                        spec.original  = { maintag, detail }
-                                        c = c + 1
-                                    end
-                                else
-                                    report_tags("tag %a needs pdf and pua field",tag)
-                                end
-                            end
-                            if next(okay) then
-                                overloads[maintag] = {
-                                    criterium = details.criterium,
-                                    mapping   = okay,
-                                }
-                            end
-                        else
-                            report_tags("tag %a overload needs mapping",tag)
-                        end
-                    end
-                end
-            end
-            report_tags("%i pdf tags overloaded, %i crappy tags added, cross your fingers",n,c)
-        end
-    end
-end)
-
-
 local patterns = setmetatableindex(function(t,tag)
     local v = topattern("^" .. tag .. ">")
     t[tag] = v
@@ -640,8 +585,21 @@
             attribute = tag_document_level
         end
         insert(tagstack, { texgetattribute(a_tagged), stacksize, stack[stacksize], chain })
-        chain            = attribute and { unpack(taglist[attribute].taglist) } or { }
-        stacksize        = #chain
+        if attribute then
+            local t = taglist[attribute]
+            if t then
+                chain     = { unpack(t.taglist) }
+                stacksize = #chain
+            else
+                chain    = { }
+                stacksize = 1
+            end
+        else
+            chain     = { }
+            stacksize = 1
+        end
+     -- chain            = attribute and { unpack(taglist[attribute].taglist) } or { }
+     -- stacksize        = #chain
         stack[stacksize] = attribute
     end
 
@@ -872,3 +830,55 @@
     public    = true,
     actions   = tags.pop
 }
+
+-- bonus
+
+do
+
+    function tags.analyze()
+     -- local taglist = tags.taglist
+        local used = setmetatableindex("number")
+        local head = setmetatableindex("number")
+     -- inspect(list)
+        for i=1,#taglist do
+            local l = taglist[i]
+            local tagname = l.tagname
+            local taglist = l.taglist
+            if tagname == "section" then
+                local detail = l.detail
+                head[detail] = head[detail] + 1
+            end
+            used[tagname] = used[tagname] + 1
+        end
+        if next(used) then
+            report_tags()
+            report_tags("used tags")
+            report_tags()
+            for k, v in sortedhash(used) do
+                report_tags("%4i  %s",v,k)
+            end
+            report_tags()
+        end
+        if next(head) then
+            report_tags("used heads")
+            report_tags()
+            for k, v in sortedhash(head) do
+                report_tags("%4i  %s",v,k)
+            end
+            report_tags()
+        end
+    end
+
+    local enabled
+
+    trackers.register("structures.tags.analyze", function(v)
+        enabled = true
+    end)
+
+    statistics.register("structure tags", function()
+        if enabled then
+            tags.analyze()
+        end
+    end)
+
+end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tag.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tag.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tag.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -177,6 +177,7 @@
 \definetagconstant{floattext}
 \definetagconstant{floatnumber}
 \definetagconstant{floatcontent}
+\definetagconstant{subfloat}
 
 \definetagconstant{image}
 
@@ -260,7 +261,7 @@
 
 % the real code
 
-\definesystemattribute[tagged][public]
+\definesystemattribute[tagged][public,pickup] % pickup added
 \definesystemattribute[image] [public]
 
 % \setelementbackendtag [#1][#2] % define at the lua end
@@ -389,7 +390,7 @@
      \enforced\let\dostarttaggednodetail\gobbleoneargument
      \enforced\let\dostarttaggedchained \gobblefourarguments
      \enforced\let\dostoptagged         \donothing
-     \enforced\let\dostartignoretagging \donothing
+     \enforced\let\dostartignoretagging \gobbleoneargument
      \enforced\let\dostopignoretagging  \donothing
      \enforced\let\dotagdocumentpush    \donothing
      \enforced\let\dotagdocumentpop     \donothing
@@ -499,6 +500,23 @@
   [\c!state=\v!stop,
    \c!method=\v!auto]
 
+% We now have a proper key instead of a directive:
+
+\appendtoks
+    \ifempty{\taggingparameter\c!preset}\else
+        \clf_settaggingpresets
+          preset {\lastnamedcs}%
+          level  {\taggingparameter\c!level}%
+        \relax
+    \fi
+    \ifempty{\taggingparameter\c!comment}\else
+        \clf_settaggingcomment{\lastnamedcs}%
+    \fi
+    \ifempty{\taggingparameter\c!option}\else
+        \clf_settaggingoption{\lastnamedcs}%
+    \fi
+\to \everysetuptagging
+
 % Cf suggestion by Wolfgang we now have named paragraphs. Watch out, the content
 % is grouped but only when we have an instance.
 %
@@ -551,7 +569,8 @@
 \def\strc_tags_document_start_indeed
   {\glet\strc_tags_document_start_indeed\relax
    \dostarttaggednodetail\t!document
-   \dostarttaggednodetail\t!documentpart} % ua2 demands at least one level more
+   \dostarttaggednodetail\t!documentpart
+   } % ua2 demands at least one level more
 
 \def\strc_tags_document_stop_indeed
   {\glet\strc_tags_document_stop_indeed\relax
@@ -756,7 +775,6 @@
    \clf_strc_tags_parcounter_pop
    \endlocalcontrol}
 
-
 \permanent\protected\def\strc_tags_parcounter_reset
   {\c_attr_taggedpar\attributeunsetvalue}
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tnt.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tnt.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-tnt.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -56,7 +56,7 @@
    \c!n=10] % * will use the real space
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\currenttextnote\endcsname{\educ_textnote[\currenttextnote]}%
+    \protected\frozen\instance\edefcsname\currenttextnote\endcsname{\educ_textnote[\currenttextnote]}%
 \to \everydefinetextnote
 
 \tolerant\protected\def\educ_textnote[#1]#*[#S#2]#:#3%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/strc-usr.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/strc-usr.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/strc-usr.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -92,8 +92,8 @@
 \installcommandhandler \????userdataalternative {userdataalternative} \????userdataalternative
 
 \appendtoks
-    \frozen\protected\instance\edefcsname\e!start\currentuserdata\endcsname{\userdata_start_instance{\currentuserdata}}%
-    \frozen\protected\instance\letcsname \e!stop \currentuserdata\endcsname\userdata_stop_instance
+    \protected\frozen\instance\edefcsname\e!start\currentuserdata\endcsname{\userdata_start_instance{\currentuserdata}}%
+    \protected\frozen\instance\letcsname \e!stop \currentuserdata\endcsname\userdata_stop_instance
 \to \everydefineuserdata
 
 \permanent\protected\def\startuserdata

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/supp-box.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/supp-box.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/supp-box.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -2789,7 +2789,8 @@
 \appendtoks
     \permanent\def\prerolltostring#1%
       {\beginlocalcontrol
-       \setbox\b_syst_boxes\hbox{\expand\everypreroll#1}%
+       % hbox can fails when we have vskips (mail to list)
+       \setbox\b_syst_boxes\vpack{\expand\everypreroll#1}%
        \expanded
          {\setbox\b_syst_boxes\emptybox
           \endlocalcontrol

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/syst-aux.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/syst-aux.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/syst-aux.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -27,6 +27,9 @@
 
 local pattern           = C(utf8character^-1) * C(P(1)^0)
 
+local boolean_value <const> = tokens.values.boolean
+----- string_value  <const> = tokens.values.string
+
 implement {
     name      = "getfirstcharacter",
     arguments = "string",
@@ -247,11 +250,18 @@
 
 do
 
-    -- Quite probably we don't yet have characters loaded so we delay some
-    -- aliases.
+    -- These are old helpers from early mkiv and I['ll update them when checking the
+    -- cld manual which might result in a few more here and we now also avoid clf_
+    -- prefixing. In the end, very few users need to apply such low level helpers
+    -- because we operate at the typesetting level. Low level messing around with
+    -- e.g. casing (or any unicode/utf property for that matter) might as well be an
+    -- indication that you're doing something wrong.
 
-    local _lower_, _upper_, _strip_
+    -- Quite probably we don't yet have characters loaded so we delay some aliases
+    -- and redefine the mappers.
 
+    local _lower_, _upper_, _shape_, _strip_
+
     _lower_ = function(s)
         if characters and characters.lower then
             _lower_ = characters.lower
@@ -268,6 +278,14 @@
         return string.upper(s)
     end
 
+    _shape_ = function(s)
+        if characters and characters.shape then
+            _shape_ = characters.shape
+            return _shape_(s)
+        end
+        return s
+    end
+
     _strip_ = function(s)
         -- or utf.strip
         if string.strip then
@@ -277,14 +295,44 @@
         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
+ -- 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 }
+ -- implement { name = "upper", arguments = "string", actions = upper }
+ -- implement { name = "lower", arguments = "string", actions = lower }
+ -- implement { name = "strip", arguments = "string", actions = strip }
 
+    implement {
+        name      = "utfupper",
+        public    = true,
+        arguments = "string",
+        actions   = function(s) context(_upper_(s)) end,
+    }
+
+    implement {
+        name      = "utflower",
+        public    = true,
+        arguments = "string",
+        actions   = function(s) context(_lower_(s)) end,
+    }
+
+    implement {
+        name      = "utfshape",
+        public    = true,
+        arguments = "string",
+        actions   = function(s) context(_shape_(s)) end,
+    }
+
+    implement {
+        name      = "utfstrip",
+        public    = true,
+        arguments = "string",
+        actions   = function(s) context(_strip_(s)) end,
+    }
+
+    -- what more ... depends on what users want but no requests so far
+
 end
 
 implement {
@@ -384,8 +432,6 @@
 context.firstofoneargument     = ctx_firstofoneargument
 context.gobbleoneargument      = ctx_gobbleoneargument
 
-local boolean_value <const> = tokens.values.boolean
-
 local hash = utilities.parsers.hashes.settings_to_set
 
 implement {

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/syst-aux.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/syst-aux.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/syst-aux.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -5911,12 +5911,23 @@
 %D These macros are sort of obsolete as we never use uppercase this way. But
 %D nevertheless we provide them:
 
-\permanent\def\utfupper#1{\clf_upper{#1}} % expandable
-\permanent\def\utflower#1{\clf_lower{#1}} % expandable
+% Defined at the \LUA\ end (which saves us one step. I need to check the macro
+% tables for more candidates):
+%
+% \permanent\def\utfupper#1{\clf_upper{#1}} % expandable
+% \permanent\def\utflower#1{\clf_lower{#1}} % expandable
+% \permanent\def\utfshape#1{\clf_shape{#1}} % expandable
+% \permanent\def\utfstrip#1{\clf_strip{#1}} % expandable
 
-\permanent\protected\def\uppercasestring#1\to#2{\dodoglobal\edef#2{\clf_upper{#1}}}
-\permanent\protected\def\lowercasestring#1\to#2{\dodoglobal\edef#2{\clf_lower{#1}}}
+% This are obsolete because we can just do an \type {\edef} and avoid the
+% somewhat weird \type {\to} interface.
 
+% \permanent\protected\def\uppercasestring#1\to#2{\dodoglobal\edef#2{\clf_upper{#1}}}
+% \permanent\protected\def\lowercasestring#1\to#2{\dodoglobal\edef#2{\clf_lower{#1}}}
+
+\permanent\protected\def\uppercasestring#1\to#2{\dodoglobal\edef#2{\utfupper{#1}}}
+\permanent\protected\def\lowercasestring#1\to#2{\dodoglobal\edef#2{\utflower{#1}}}
+
 %D \macros
 %D   {handletokens}
 %D

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/tabl-mis.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/tabl-mis.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/tabl-mis.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -152,7 +152,7 @@
 \appendtoks
     \frozen\instance\letcsname\e!next\currentparagraphs\endcsname\nextparagraphs
     \frozen\instance\letcsname\currentparagraphs\endcsname\nextparagraphs
-    \frozen\instance\protected\edefcsname\e!start\currentparagraphs\endcsname{\startparagraphs[\currentparagraphs]}%
+    \protected\frozen\instance\edefcsname\e!start\currentparagraphs\endcsname{\startparagraphs[\currentparagraphs]}%
     \frozen\instance\letcsname\e!stop\currentparagraphs\endcsname\stopparagraphs
     \localcontrolledrepeat \paragraphsparameter\c!n
       {\expanded

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/tabl-xtb.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/tabl-xtb.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/tabl-xtb.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -682,7 +682,7 @@
         end
     elseif nofwide > 0 then
         while true do
-            done = false
+            local done = false
             local available = (widetotal + delta) / nofwide
             if trace_xtable then
                 report_xtable("shrink check, total %p, delta %p, columns %s, fixed %p",widetotal,delta,nofwide,available)

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/trac-bld.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/trac-bld.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/trac-bld.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -54,6 +54,7 @@
 local forced     = { } -- we can combine forced and ignored but then we can't disable
 local ignored    = { } -- the callback easily
 local detail     = false
+local trace      = false
 local enabled    = false
 local ejecting   = false
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/trac-inf.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/trac-inf.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/trac-inf.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -427,7 +427,6 @@
             for k, v in sortedhash(h) do
                 if v ~= 0 then
                     report("  hyphenation state     : %-10s  %7i",k,v)
-                    done = true
                 end
             end
      -- end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/trac-riv.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/trac-riv.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/trac-riv.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -123,8 +123,8 @@
             -- progress
             position = width
             width    = position + wd
-            p = floor((position - margin)/step + 0.5)
-            w = floor((width    + margin)/step - 0.5)
+            local p = floor((position - margin)/step + 0.5)
+            local w = floor((width    + margin)/step - 0.5)
             if p < 0 then
                 p = 0
             end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/trac-vis.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/trac-vis.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/trac-vis.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -11,7 +11,7 @@
 
 local node, nodes, attributes, tex = node, nodes, attributes, tex
 local type, tonumber, next, rawget = type, tonumber, next, rawget
-local gmatch, gsub, sub = string.gmatch, string.gsub, string.sub
+local gmatch, sub = string.gmatch, string.sub
 local formatters = string.formatters
 local round = math.round
 
@@ -187,8 +187,9 @@
     l_glyph, l_discretionary, l_expansion, l_fontkern, l_italic, l_marginkern, l_space,
     l_math, l_mathkern, l_mathshape,
     l_dir, l_whatsit,
-    l_mark, l_insert, l_boundary
- -- l_user
+    l_mark, l_insert, l_boundary,
+ -- l_user,
+    l_mathshapekern, l_par
 
 local enabled = false
 local layers  = { }
@@ -568,7 +569,7 @@
     return caches[name]
 end
 
-local fontkern, italiccorrection, marginkern, mathkern do
+local fontkern, italiccorrection, marginkern, mathkern, mathshapekern do
 
     local f_cache = caches["fontkern"]
     local i_cache = caches["italiccorrection"]
@@ -1246,7 +1247,7 @@
 
 end
 
-local ruledglue, ruledmathglue do
+local ruledglue, ruledmathglue, ruledspace do
 
     local effectiveglue         = nuts.effectiveglue
     local iszeroglue            = nuts.iszeroglue
@@ -1455,6 +1456,8 @@
         return v
     end)
 
+    local gsub = string.gsub
+
     local temphack = setmetatableindex(function(t,k)
         local v = mathvalues[k]
         if v then
@@ -1573,7 +1576,7 @@
                 end
                 if a then
                     local p = getprev(current)
-                    local b, e
+                    local b, e, rule
                     for n in traverseid(math_code,current) do
                         e = n
                         break

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/typo-del.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/typo-del.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/typo-del.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -413,9 +413,9 @@
 
 \appendtoks
     \expandafter\newinteger\csname\??delimitedtextlevel\currentdelimitedtext\endcsname
-    \frozen\instance\protected\edefcsname\currentdelimitedtext        \endcsname{\delimitedtext[\currentdelimitedtext]}%
-    \frozen\instance\protected\edefcsname\e!start\currentdelimitedtext\endcsname{\startdelimitedtext[\currentdelimitedtext]}%
-    \frozen\instance\protected\edefcsname\e!stop \currentdelimitedtext\endcsname{\stopdelimitedtext}%
+    \protected\frozen\instance\edefcsname\currentdelimitedtext        \endcsname{\delimitedtext[\currentdelimitedtext]}%
+    \protected\frozen\instance\edefcsname\e!start\currentdelimitedtext\endcsname{\startdelimitedtext[\currentdelimitedtext]}%
+    \protected\frozen\instance\edefcsname\e!stop \currentdelimitedtext\endcsname{\stopdelimitedtext}%
 \to \everydefinedelimitedtext
 
 \setupdelimitedtext

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/typo-dif.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/typo-dif.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/typo-dif.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -55,7 +55,7 @@
     end
 end
 
-function longestcommon(first,second)
+local function longestcommon(first,second)
     local m = #first
     local n = #second
     local t = newindex(m)
@@ -140,6 +140,7 @@
 local list       = { }
 local collect    = false
 local mark       = false
+local special    = false
 
 collectors[v_character] = function(data,head)
     local unic = false

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/typo-itc.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/typo-itc.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/typo-itc.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -637,7 +637,7 @@
     end
 end
 
-local enabletext = function()
+local function enabletext()
     if enable then
         enable()
     end
@@ -648,7 +648,7 @@
     textokay   = true
 end
 
-local enablemath = function()
+local function enablemath()
     if enable then
         enable()
     end

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/typo-krn.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/typo-krn.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/typo-krn.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -62,7 +62,7 @@
 %D Here we need to keep the groupedcommand solution as it is used as modifier.
 
 \appendtoks
-  \frozen\instance\protected\edefcsname\currentcharacterkerning\endcsname
+  \protected\frozen\instance\edefcsname\currentcharacterkerning\endcsname
     {\doifelsenextoptional
        {\typo_kerning_apply_yes{\currentcharacterkerning}}%
        {\typo_kerning_apply_nop{\currentcharacterkerning}}}%

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/typo-mar.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/typo-mar.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/typo-mar.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -136,7 +136,7 @@
    \c!align=\margindataparameter\c!align]
 
 \appendtoks
-    \frozen\instance\protected\edefcsname\currentmargindata\endcsname{\margindata[\currentmargindata]}%
+    \protected\frozen\instance\edefcsname\currentmargindata\endcsname{\margindata[\currentmargindata]}%
 \to \everydefinemargindata
 
 \newconditional\inhibitmargindata      % This one is used at the Lua end!
@@ -154,6 +154,9 @@
 \appendtoks
     \forgetall
     \tf
+%     \pickupdirectionattribute
+%     \pickupscriptattribute
+    \pickuptaggedattribute
     \resetallattributes % \deactivatecolor % needed, but maybe we should switch to maintextcolor: \onlyinheritmaintextcolor
     \pickupattributes
 \to \everymargindatacontent

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/typo-stc.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/typo-stc.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/typo-stc.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -57,9 +57,9 @@
         \clf_newstacking{\currentstacking}{\stackingparameter\c!number}%
     \relax
     \ifcstok{\stackingparameter\c!define}\v!yes
-        \frozen\instance\protected\edefcsname        \currentstacking\endcsname{\typo_stacking{\currentstacking}}%
-        \frozen\instance\protected\edefcsname\e!start\currentstacking\endcsname{\typo_stacking_start{\currentstacking}}%
-        \frozen\instance\protected\edefcsname\e!stop \currentstacking\endcsname{\typo_stacking_stop}%
+        \protected\frozen\instance\edefcsname        \currentstacking\endcsname{\typo_stacking{\currentstacking}}%
+        \protected\frozen\instance\edefcsname\e!start\currentstacking\endcsname{\typo_stacking_start{\currentstacking}}%
+        \protected\frozen\instance\edefcsname\e!stop \currentstacking\endcsname{\typo_stacking_stop}%
     \fi
 \to \everydefinestacking
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/typo-swp.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/typo-swp.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/typo-swp.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -39,8 +39,8 @@
 
 \appendtoks
     \ifcstok{\rowsparameter\c!define}\v!yes
-      \frozen\protected\instance\edefcsname\e!start\currentrows\endcsname{\startrows[\currentrows]}%
-      \frozen\protected\instance\defcsname \e!stop \currentrows\endcsname{\stoprows}%
+      \protected\frozen\instance\edefcsname\e!start\currentrows\endcsname{\startrows[\currentrows]}%
+      \protected\frozen\instance\defcsname \e!stop \currentrows\endcsname{\stoprows}%
     \fi
 \to \everydefinerows
 

Modified: trunk/Master/texmf-dist/tex/context/base/mkxl/typo-tal.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/base/mkxl/typo-tal.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/base/mkxl/typo-tal.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -134,7 +134,6 @@
             signs      = validsigns,
         }
         datasets[column] = dataset
-        used = true
     end
     return dataset
 end

Modified: trunk/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/modules/mkiv/m-nodechart.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -115,7 +115,7 @@
             if components then
                 commands.flow_set_connection("rl","",tostring(components))
                 commands.flow_stop_cell()
-                n = flow_nodes_to_chart { head = components, comment = "component",x = x+2, y = y-1 }
+                flow_nodes_to_chart { head = components, comment = "component",x = x+2, y = y-1 }
             else
                 commands.flow_stop_cell()
             end
@@ -129,7 +129,7 @@
                 end
                 commands.flow_stop_cell()
                 if pre then
-                    n = flow_nodes_to_chart { head = pre, comment = "prebreak", x = x+1, y = y-1 }
+                    flow_nodes_to_chart { head = pre, comment = "prebreak", x = x+1, y = y-1 }
                 end
             else
                 if pre then
@@ -143,13 +143,13 @@
                 end
                 commands.flow_stop_cell()
                 if pre then
-                    n = flow_nodes_to_chart{ head = pre, comment = "prebreak", x = x+1, y = y-1 }
+                    flow_nodes_to_chart { head = pre, comment = "prebreak", x = x+1, y = y-1 }
                 end
                 if rep then
-                    n = flow_nodes_to_chart{ head = rep, comment = "replacement", x = x+3, y = y-1 }
+                    flow_nodes_to_chart { head = rep, comment = "replacement", x = x+3, y = y-1 }
                 end
                 if pos then
-                    n = flow_nodes_to_chart{ head = pos, comment = "postbreak", x = x+2, y = y-1 }
+                    flow_nodes_to_chart { head = pos, comment = "postbreak", x = x+2, y = y-1 }
                 end
             end
         elseif nodecode == "hlist" then
@@ -157,7 +157,7 @@
             if list then
                 commands.flow_set_connection("rl","",tostring(list))
                 commands.flow_stop_cell()
-                n = flow_nodes_to_chart { head = list, comment = "list", x = x+2, y = y-1 }
+                flow_nodes_to_chart { head = list, comment = "list", x = x+2, y = y-1 }
             else
                 commands.flow_stop_cell()
             end

Modified: trunk/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/modules/mkiv/s-fonts-shapes.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -16,7 +16,7 @@
 local space, dontleavehmode, glyph, getvalue = context.space, context.dontleavehmode, context.glyph, context.getvalue
 local formatters = string.formatters
 
-function char(id,k)
+local function char(id,k)
     dontleavehmode()
     glyph(id,k)
 end

Modified: trunk/Master/texmf-dist/tex/context/modules/mkiv/s-present-stepper.mkiv
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkiv/s-present-stepper.mkiv	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/modules/mkiv/s-present-stepper.mkiv	2025-08-18 19:08:11 UTC (rev 76089)
@@ -224,6 +224,8 @@
 
 \continueifinputfile{s-present-stepper.mkiv}
 
+% \nopdfcompression
+
 \usemodule[present-common]
 
 \inputpresentationfile{examples/present-stepper-001.tex}

Modified: trunk/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.lua
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/modules/mkiv/x-asciimath.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -976,7 +976,7 @@
 local collected_digits   = { }
 local collected_filename = "asciimath-digits.lua"
 
-function numbermess(s)
+local function numbermess(s)
     if splitmethod then
         local d = lpegmatch(splitmethod,s,1,digitseparator,digitsymbol)
         if not d and symbolmethod then
@@ -1597,7 +1597,7 @@
     return t
 end
 
-function collapse_limits(t)
+local function collapse_limits(t)
     local n, m, i = #t, 0, 1
     while i <= n do
         m = m + 1
@@ -1937,7 +1937,7 @@
     end
 end
 
-function collect(fpattern,element,collected,indexed)
+local function collect(fpattern,element,collected,indexed)
     local element   = element or "am"
     local mpattern  = formatters["<%s>(.-)</%s>"](element,element)
     local filenames = resolvers.findtexfile(fpattern)
@@ -1971,7 +1971,7 @@
     return collected, indexed
 end
 
-function filter(root,pattern,collected,indexed)
+local function filter(root,pattern,collected,indexed)
     if not pattern or pattern == "" then
         pattern = "am"
     end

Modified: trunk/Master/texmf-dist/tex/context/modules/mkxl/m-dirtree.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkxl/m-dirtree.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/modules/mkxl/m-dirtree.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -108,6 +108,8 @@
 
 \startluacode
     local gmatch     = string.gmatch
+    local find       = string.find
+    local gsub       = string.gsub
     local concat     = table.concat
     local insert     = table.insert
     local remove     = table.remove
@@ -172,18 +174,34 @@
     local nameonly, suffix = file.nameonly, file.suffix
 
     dirtree.entries = {
-        default = function(str)
+        default = function(kind,str)
             return str
         end,
-        split = function(str)
-            return "\\dirtreeentry{" .. nameonly(str) .. "}{" .. suffix(str) .. "}"
+        split = function(kind,str)
+            local n = nameonly(str)
+            local s = suffix(str)
+            if n == "" and s == "" then
+                kind = 0
+            end
+            return "\\dirtreeentry{" .. kind .. "}{" .. n .. "}{" .. s .. "}"
         end,
     }
 
-    function dirtree.show(tree,symbolset,direntry)
+    function dirtree.show(tree,symbolset,direntry,dirstoo)
 
+        local dirs
+
         if type(tree) == "string" then
-            tree = dir.glob(tree)
+            tree, dirs = dir.glob(tree,nil,dirstoo)
+
+            if dirstoo then
+             -- table.merge(tree,dirs)
+                for i=1,#dirs do
+                    tree[#tree+1] = dirs[i] .. "*"
+                end
+                table.sort(tree)
+            end
+
         end
 
         if type(tree) ~= "table" then
@@ -215,14 +233,15 @@
 
         if #tree > 0 then
             for i=1,#tree do
-                local d = false
+                local d = false -- catches "./"
                 local r = result
-                for s in gmatch(tree[i],"[^/]+") do
+                local t = tree[i]
+                for s in gmatch(t,"[^/]+") do
                     if d then
                         local rs = r[s]
                         if not rs then
                             rs = { }
-                            r[s] = { }
+                            r[s] = rs --  { }
                         end
                         r = rs
                     else
@@ -233,32 +252,46 @@
         else
             -- assume a hash
         end
+        local level = 0
+        local con   = { }
 
-        local level  = 0
-        local con    = { }
-
         local function show(result,level)
             local list = sortedkeys(result)
             local size = #list
             for i=1,size do
-                local l = list[i]
-                local r = result[l]
-                local sub = next(r)
+                local l    = list[i]
+                local r    = result[l]
+                local sub  = next(r)
+                local kind = 0
                 if level == 1 then
                     -- nothing special to do
+                    kind = 1
                 elseif size == 1 then
                     insert(con,sub and yes_one or nop_one)
+                    kind = 2
                 elseif i == 1 then
                     insert(con,sub and yes_first or nop_first)
+                    kind = 3
                 elseif i == size then
                     insert(con,sub and yes_last or nop_last)
+                    kind = 4
                 else
                     insert(con,sub and yes_else or nop_else)
+                    kind = 5
                 end
+                if find(l,"%*$") then
+                    l = gsub(l,"%*$","")
+                    if kind == 1 then
+                        kind = 6
+                    else
+                        kind = 7
+                    end
+                end
+                local entry = direntry(kind,l)
                 if level == 1 then
-                    output[#output+1] = direntry(l)
+                    output[#output+1] = entry
                 else
-                    output[#output+1] = concat(con) .. (sub and yes_space or nop_space) .. direntry(l)
+                    output[#output+1] = concat(con) .. (sub and yes_space or nop_space) .. entry
                 end
                 if sub then
                     if size == 1 then
@@ -302,11 +335,16 @@
 %      \typebuffer[dirtree]
 %    \endgroup}
 
-\let\dirtreeentry\firstofoneargument
+\let\dirtreeentry\gobblethreearguments % can change
 
-\permanent\protected\def\showdirtree[#1]%
+\permanent\tolerant\protected\def\showdirtree[#1]#*[#2]%
   {\begingroup
-     \ctxlua{utilities.dirtree.show("#1","private","split")}
+     % maybe handle options in show
+     \iftok{#2}{empty}%
+       \ctxlua{utilities.dirtree.show("#1","private","split",true)}
+     \else
+       \ctxlua{utilities.dirtree.show("#1","private","split",false)}
+     \fi
      \startlines
      \getbuffer[dirtree]
      \stoplines
@@ -328,24 +366,43 @@
   % \protected\def\dirtreeentry#1#2%
   %   {\doifelsesomething{#2}{\color[dirtree:#2]{#1.#2}}{#1}}
 
-    \protected\def\dirtreeentry#1#2%
-      {\ifparameter#2\or
-         \color[dirtree:#2]{#1.#2}%
+    \definefontsynonym[dirtreefont][file:seguiemj.ttf*default,colored]
+
+    \definesymbol[dirtree:open] [\getglyph{dirtreefont}{📂}]
+    \definesymbol[dirtree:close][\getglyph{dirtreefont}{📁}]
+    \definesymbol[dirtree:text] [\getglyph{dirtreefont}{📄}]
+
+    \protected\def\dirtreeentry#1#2#3%
+      {\ifparameter#3\or
+         \color[dirtree:#3]{#2.#3}%
        \else
-         #1%
+         #2%
        \fi}
 
+%     \startcolumns
+%        % \showdirtree[t:/texmf/tex/context/base/**]
+%        \showdirtree[./**]
+%     \stopcolumns
+
+    \protected\def\dirtreeentry#1#2#3%
+      {\ifparameter#3\or
+         \symbol[dirtree:text]\color[dirtree:#3]{#2.#3}%
+       \orelse\ifnum#1>\plusfive
+         \symbol[dirtree:close]#2%
+       \else
+         \symbol[dirtree:open]#2%
+       \fi}
+
     \startcolumns
        % \showdirtree[t:/texmf/tex/context/base/**]
-         \showdirtree[./**]
+       \showdirtree[./**][empty]
     \stopcolumns
 
-    \startluacode
-     -- local list   = dir.glob("t:/texmf/tex/context/base/**")
-        local list   = dir.glob("./**")
-        local output = utilities.dirtree.show(list,"unicode","default")
+%     \startluacode
+%      -- local list   = dir.glob("t:/texmf/tex/context/base/**")
+%         local list   = dir.glob("./**")
+%         local output = utilities.dirtree.show(list,"unicode","default")
+%         inspect(output)
+%     \stopluacode
 
-        inspect(output)
-    \stopluacode
-
 \stoptext

Modified: trunk/Master/texmf-dist/tex/context/modules/mkxl/s-math-verbatim.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkxl/s-math-verbatim.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/modules/mkxl/s-math-verbatim.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -53,6 +53,13 @@
 \definefont[MyMathFontBold][MonoMathBaseBold]
 \definefont[MyTextFont]    [MonoTextBase]
 
+% Todo, be specific
+
+\definetyping[mathtyping][style=MyMathFont]
+\definetype  [mathtype]  [style=MyMathFont]
+
+% Then these can go:
+
 \setuptyping
   [style=MyMathFont]
 

Added: trunk/Master/texmf-dist/tex/context/modules/mkxl/s-signals-example.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkxl/s-signals-example.mkxl	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/modules/mkxl/s-signals-example.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,67 @@
+% signal=squid
+% signal=quadrant
+% signal=segment
+% signal=runner
+% signal=qr
+
+% also see squidtest.tex for feedback
+
+%D \module
+%D   [       file=s-signals-example.tex,
+%D        version=2025.05.01,
+%D          title=\CONTEXT\ Style File,
+%D       subtitle=A test for the signal gadget,
+%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.
+
+\enabledirectives[system.feedback]
+
+\setupbodyfont
+  [pagella,10pt]
+
+\setuppapersize
+  [S6][S6]
+
+\newinteger\SignalsExampleRuns
+
+\SignalsExampleRuns {200+100*\cldcontext{math.mod(os.time(),11)}}
+
+\startsetups[signals-zelensky]
+
+    \dorecurse {\SignalsExampleRuns} {
+
+        \samplefile{zelensky}
+        \removeunwantedspaces
+        \nbsp
+        (Volodymyr Zelensky)
+
+        \blank
+
+        \doifmode {signals-delay} {
+            \ctxlua{os.sleep(0.0025)}
+        }
+
+        \doifmode {signals-error} {
+            \JustIgnorePutinAndTrump % unknown command
+        }
+    }
+
+\stopsetups
+
+\continueifinputfile{s-signals-example.mkxl}
+
+% \SignalsExampleRuns   50
+% \SignalsExampleRuns  250
+% \SignalsExampleRuns 1000
+
+% \enablemode[signals-delay]
+% \enablemode[signals-error]
+
+\starttext
+    \setups[signals-zelensky]
+\stoptext

Modified: trunk/Master/texmf-dist/tex/context/modules/mkxl/s-squid.mkxl
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkxl/s-squid.mkxl	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/modules/mkxl/s-squid.mkxl	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1,3 +1,6 @@
+
+
+
 % signal=squid
 
 %D \module
@@ -620,9 +623,7 @@
 \stopbuffer
 
 \startMPdefinitions
-    def signal_text(expr s) =
-        signal_all_leds;
-%         signal_all_inner_leds;
+    def signal_just_text(expr s) =
         for i=1 upto 24 :
             if (substring(i-1,i) of s) == "+" :
                 signal_one_led(i,"squid:busy");
@@ -632,50 +633,107 @@
         endfor ;
     enddef ;
 
-    string characters[];
+    def signal_text(expr s) =
+        signal_all_leds ;
+        signal_just_text(s) ;
+    enddef ;
 
-    characters[ASCII "A"] := "+++++!!+++-----+++!!++++" ;
-    characters[ASCII "B"] := "------------------------" ;
-    characters[ASCII "C"] := "+++------+++++++++++++++" ;
-    characters[ASCII "D"] := "------------------------" ;
-    characters[ASCII "E"] := "++---!!!---++++++!!!++++" ;
-    characters[ASCII "F"] := "------------------------" ;
-    characters[ASCII "G"] := "------------------------" ;
-    characters[ASCII "H"] := "------------------------" ;
-    characters[ASCII "I"] := "+++++++++++++-----------" ;
-    characters[ASCII "J"] := "++++++++++++++++--------" ;
-    characters[ASCII "K"] := "------------------------" ;
-    characters[ASCII "L"] := "+--------+++++++++++++++" ;
-    characters[ASCII "M"] := "!!++++++++-!!!-++++++++!" ;
-    characters[ASCII "N"] := "++++++++++-----+++++++++" ;
-    characters[ASCII "O"] := "++++++++++++++++++++++++" ;
-    characters[ASCII "P"] := "------------------------" ;
-    characters[ASCII "Q"] := "------------------------" ;
-    characters[ASCII "R"] := "------------------------" ;
-    characters[ASCII "S"] := "------------------------" ;
-    characters[ASCII "T"] := "!!+++------!!!------+++!" ;
-    characters[ASCII "U"] := "------------------------" ;
-    characters[ASCII "V"] := "------------------------" ;
-    characters[ASCII "W"] := "------------------------" ;
-    characters[ASCII "X"] := "-+++-----+++--+++----+++" ;
-    characters[ASCII "Y"] := "------------------------" ;
-    characters[ASCII "Z"] := "------------------------" ;
+    string signal_characters[];
 
+    signal_characters[ASCII "A"] := "+++++!!+++-----+++!!++++" ;
+    signal_characters[ASCII "B"] := "------------------------" ;
+    signal_characters[ASCII "C"] := "+++------+++++++++++++++" ;
+    signal_characters[ASCII "D"] := "------------------------" ;
+    signal_characters[ASCII "E"] := "++---!!!---++++++!!!++++" ;
+    signal_characters[ASCII "F"] := "------------------------" ;
+    signal_characters[ASCII "G"] := "------------------------" ;
+    signal_characters[ASCII "H"] := "------------------------" ;
+    signal_characters[ASCII "I"] := "+++++++++++++-----------" ;
+    signal_characters[ASCII "J"] := "++++++++++++++++--------" ;
+    signal_characters[ASCII "K"] := "------------------------" ;
+    signal_characters[ASCII "L"] := "+--------+++++++++++++++" ;
+    signal_characters[ASCII "M"] := "!!++++++++-!!!-++++++++!" ;
+    signal_characters[ASCII "N"] := "++++++++++-----+++++++++" ;
+    signal_characters[ASCII "O"] := "++++++++++++++++++++++++" ;
+    signal_characters[ASCII "P"] := "------------------------" ;
+    signal_characters[ASCII "Q"] := "------------------------" ;
+    signal_characters[ASCII "R"] := "------------------------" ;
+    signal_characters[ASCII "S"] := "------------------------" ;
+    signal_characters[ASCII "T"] := "!!+++------!!!------+++!" ;
+    signal_characters[ASCII "U"] := "------------------------" ;
+    signal_characters[ASCII "V"] := "------------------------" ;
+    signal_characters[ASCII "W"] := "------------------------" ;
+    signal_characters[ASCII "X"] := "-+++-----+++--+++----+++" ;
+    signal_characters[ASCII "Y"] := "------------------------" ;
+    signal_characters[ASCII "Z"] := "------------------------" ;
+
+    signal_characters[ASCII "0"] := "------------------------" ;
+    signal_characters[ASCII "1"] := "+-----------+-----------" ;
+    signal_characters[ASCII "2"] := "-+---------+-+---------+" ;
+    signal_characters[ASCII "3"] := "++---------+++---------+" ;
+    signal_characters[ASCII "4"] := "-++-------++-++-------++" ;
+    signal_characters[ASCII "5"] := "+++-------+++++-------++" ;
+    signal_characters[ASCII "6"] := "-+++-----+++-+++-----+++" ;
+    signal_characters[ASCII "7"] := "++++-----+++++++-----+++" ;
+    signal_characters[ASCII "8"] := "-++++---++++-++++---++++" ;
+    signal_characters[ASCII "9"] := "+++++---+++++++++---++++" ;
+
     vardef signal_character(expr c) =
-        image ( signal_text(characters[if string c : ASCII c else : c fi]) )
+        image ( signal_text(signal_characters[if string c : ASCII c else : c fi]) )
     enddef ;
 
+    string signal_digits_one[];
+    string signal_digits_two[];
+
+    signal_digits_one[0] := "------------------------" ;
+    signal_digits_one[1] := "+-----------------------" ;
+    signal_digits_one[2] := "-+---------------------+" ;
+    signal_digits_one[3] := "++---------------------+" ;
+    signal_digits_one[4] := "-++-------------------++" ;
+    signal_digits_one[5] := "+++-------------------++" ;
+    signal_digits_one[6] := "-+++-----------------+++" ;
+    signal_digits_one[7] := "++++-----------------+++" ;
+    signal_digits_one[8] := "-++++---------------++++" ;
+    signal_digits_one[9] := "+++++---------------++++" ;
+
+    signal_digits_two[0] := "------------------------" ;
+    signal_digits_two[1] := "------------+-----------" ;
+    signal_digits_two[2] := "-----------+-+----------" ;
+    signal_digits_two[3] := "-----------+++----------" ;
+    signal_digits_two[4] := "----------++-++---------" ;
+    signal_digits_two[5] := "----------+++++---------" ;
+    signal_digits_two[6] := "---------+++-+++--------" ;
+    signal_digits_two[7] := "---------+++++++--------" ;
+    signal_digits_two[8] := "--------++++-++++-------" ;
+    signal_digits_two[9] := "--------+++++++++-------" ;
+
+    vardef signal_counter(expr n) =
+        image (
+            if (n >= 0) and (n <= 99) :
+            message(n mod 10) ;
+                signal_all_leds ;
+                signal_just_text(signal_digits_one[n mod 10]) ;
+                signal_just_text(signal_digits_two[n div 10]) ;
+            fi
+        )
+    enddef ;
+
 \stopMPdefinitions
 
 \startbuffer[squid-009]
     \startMPcode
         numeric n ; n := 0;
-        for i = (ASCII "A") upto (ASCII "Z") :
-            pair a ; a := ((n mod 6) * 25mm, -(n div 6) * 25mm) ;
-            n := n + 1 ;
-            draw signal_character(i) ysized 20mm shifted a ;
-            draw textext (char i) shifted a ;
-        endfor ;
+        def TempLoop(expr f, t) =
+            pair a ;
+            for i = (ASCII f) upto (ASCII t) :
+                a := ((n mod 6) * 25mm, -(n div 6) * 25mm) ;
+                n := n + 1 ;
+                draw signal_character(i) ysized 20mm shifted a ;
+                draw textext (char i) shifted a ;
+            endfor ;
+        enddef ;
+        TempLoop("A","Z");
+        TempLoop("0","9");
     \stopMPcode
 \stopbuffer
 
@@ -691,19 +749,51 @@
     \stopMPcode
 \stopbuffer
 
+\startbuffer[squid-011]
+    \startMPcode
+        numeric n ; n := 0 ;
+        pair a ;
+        for i=0 upto 9 :
+            for j=0 upto 9 :
+                a := (j*17.5mm,-i*17.5mm) ;
+                draw signal_counter(n) ysized 15mm shifted a ;
+                draw textext (decimal n) shifted a ;
+                n := n + 1 ;
+            endfor ;
+        endfor ;
+    \stopMPcode
+\stopbuffer
+
+\startbuffer[squid-012]
+    \startMPcode
+        numeric n ; n := 0 ;
+        pair a ;
+        for i=0 upto 5 :
+            for j=0 upto 8 :
+                a := (j*17.5mm,-i*17.5mm) ;
+                draw signal_counter(round(0 randomized 99)) ysized 15mm shifted a ;
+                n := n + 1 ;
+            endfor ;
+        endfor ;
+    \stopMPcode
+\stopbuffer
+
+
 \continueifinputfile{s-squid.mkxl}
 
 \starttext
-    \startTEXpage\getbuffer[squid-001]\stopTEXpage
-    \startTEXpage\getbuffer[squid-002]\stopTEXpage
-    \startTEXpage\getbuffer[squid-003]\stopTEXpage
-    \startTEXpage\getbuffer[squid-004]\stopTEXpage
-    \startTEXpage\getbuffer[squid-005]\stopTEXpage
-    \startTEXpage\getbuffer[squid-006]\stopTEXpage
-    \startTEXpage\getbuffer[squid-007]\stopTEXpage
-    \startTEXpage\getbuffer[squid-008]\stopTEXpage
-    \startTEXpage\getbuffer[squid-009]\stopTEXpage
-    \startTEXpage\getbuffer[squid-010]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-001]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-002]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-003]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-004]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-005]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-006]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-007]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-008]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-009]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-010]\stopTEXpage
+%     \startTEXpage\getbuffer[squid-011]\stopTEXpage
+    \startTEXpage\getbuffer[squid-012]\stopTEXpage
 \stoptext
 
 \stopmodule

Modified: trunk/Master/texmf-dist/tex/context/modules/mkxl/x-asciimath.lmt
===================================================================
--- trunk/Master/texmf-dist/tex/context/modules/mkxl/x-asciimath.lmt	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/context/modules/mkxl/x-asciimath.lmt	2025-08-18 19:08:11 UTC (rev 76089)
@@ -982,7 +982,7 @@
 local collected_digits   = { }
 local collected_filename = "asciimath-digits.lua"
 
-function numbermess(s)
+local function numbermess(s)
     if splitmethod then
         local d = lpegmatch(splitmethod,s,1,digitseparator,digitsymbol)
         if not d and symbolmethod then
@@ -1648,7 +1648,7 @@
     return t
 end
 
-function collapse_limits(t)
+local function collapse_limits(t)
     local n, m, i = #t, 0, 1
     while i <= n do
         m = m + 1
@@ -1992,7 +1992,7 @@
     end
 end
 
-function collect(fpattern,element,collected,indexed)
+local function collect(fpattern,element,collected,indexed)
     local element   = element or "am"
     local mpattern  = formatters["<%s>(.-)</%s>"](element,element)
     local filenames = resolvers.findtexfile(fpattern)
@@ -2026,7 +2026,7 @@
     return collected, indexed
 end
 
-function filter(root,pattern,collected,indexed)
+local function filter(root,pattern,collected,indexed)
     if not pattern or pattern == "" then
         pattern = "am"
     end

Added: trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-cn.llg
===================================================================
--- trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-cn.llg	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-cn.llg	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,10 @@
+return {
+    name     = "Chinese",
+    version  = "1.00",
+    comment  = "Some Chinese stuff",
+    author   = "Hans Hagen",
+    metadata = {
+        pdftag = "zh",
+        export = "zh",
+    }
+}

Added: trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-deo.llg
===================================================================
--- trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-deo.llg	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-deo.llg	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,10 @@
+return {
+    name     = "German (1901)",
+    version  = "1.00",
+    comment  = "Some old German ortography stuff",
+    author   = "Hans Hagen",
+    metadata = {
+        pdftag = "de-1901",
+        export = "de-1901",
+    }
+}

Added: trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-farsi.llg
===================================================================
--- trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-farsi.llg	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-farsi.llg	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,10 @@
+return {
+    name     = "Farsi",
+    version  = "1.00",
+    comment  = "Some Farsi stuff",
+    author   = "Hans Hagen",
+    metadata = {
+        pdftag = "fa",
+        export = "fa",
+    }
+}

Added: trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-kr.llg
===================================================================
--- trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-kr.llg	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-kr.llg	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,10 @@
+return {
+    name     = "Korean",
+    version  = "1.00",
+    comment  = "Some Korean stuff",
+    author   = "Hans Hagen",
+    metadata = {
+        pdftag = "ko",
+        export = "ko",
+    }
+}

Added: trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-ua.llg
===================================================================
--- trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-ua.llg	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/patterns/mkxl/lang-ua.llg	2025-08-18 19:08:11 UTC (rev 76089)
@@ -0,0 +1,10 @@
+return {
+    name     = "Ukranian",
+    version  = "1.00",
+    comment  = "Some Ukranian stuff",
+    author   = "Hans Hagen",
+    metadata = {
+        pdftag = "uk",
+        export = "uk",
+    }
+}

Modified: trunk/Master/texmf-dist/tex/luatex/context/luatex-fonts-merged.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/context/luatex-fonts-merged.lua	2025-08-18 19:02:37 UTC (rev 76088)
+++ trunk/Master/texmf-dist/tex/luatex/context/luatex-fonts-merged.lua	2025-08-18 19:08:11 UTC (rev 76089)
@@ -1,6 +1,6 @@
 -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
 -- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date  : 2025-07-27 21:43
+-- merge date  : 2025-08-17 17:57
 
 do -- begin closure to overcome local limits and interference
 
@@ -24195,7 +24195,7 @@
 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_cleanup=false  trackers.register("otf.cleanups",function(v) trace_cleanup=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
@@ -27686,6 +27686,7 @@
 local checkmarks=false
 local spaces=false
 local sweepnode=nil
+local sweeptype=nil
 local sweephead={} 
 local notmatchpre={} 
 local notmatchpost={} 
@@ -37525,6 +37526,7 @@
  local size=attr and attr.size or 0
  local time=attr and attr.modification or 0
  local sub=tonumber(sub)
+ local data=nil
  if size>0 and (kind=="otf" or kind=="ttf" or kind=="tcc") then
   local hash=makehash(filename,sub,instance)
   data=containers.read(cache,hash)



More information about the tex-live-commits mailing list.